Subversion Repositories eduke32

Compare Revisions

Ignore whitespace Rev 1676 → Rev 1677

/polymer/eduke32/Makefile
110,6 → 110,7
$(OBJ)/actors.$o \
$(OBJ)/anim.$o \
$(OBJ)/config.$o \
$(OBJ)/demo.$o \
$(OBJ)/gamedef.$o \
$(OBJ)/gameexec.$o \
$(OBJ)/gamevars.$o \
116,6 → 117,7
$(OBJ)/global.$o \
$(OBJ)/menus.$o \
$(OBJ)/namesdyn.$o \
$(OBJ)/net.$o \
$(OBJ)/player.$o \
$(OBJ)/premap.$o \
$(OBJ)/savegame.$o \
/polymer/eduke32/Makefile.deps
1,9 → 1,11
duke3d_h=$(EINC)/build.h $(EINC)/polymer.h $(EINC)/pragmas.h $(EINC)/compat.h $(EINC)/cache1d.h $(EINC)/baselayer.h $(SRC)/jmact/file_lib.h $(SRC)/jmact/keyboard.h $(SRC)/jmact/control.h $(INC)/gamedefs.h $(INC)/function.h $(INC)/config.h $(INC)/sounds.h $(INC)/rts.h $(INC)/_rts.h $(INC)/soundefs.h $(JAUDIOLIBDIR)/include/fx_man.h $(JAUDIOLIBDIR)/include/music.h $(INC)/namesdyn.h $(INC)/funct.h $(INC)/duke3d.h
gamedef_h=$(SRC)/gamedef.h
duke3d_h=$(EINC)/build.h $(EINC)/polymer.h $(EINC)/pragmas.h $(EINC)/compat.h $(EINC)/cache1d.h $(EINC)/baselayer.h $(SRC)/jmact/file_lib.h $(SRC)/jmact/keyboard.h $(SRC)/jmact/control.h $(INC)/gamedefs.h $(INC)/function.h $(INC)/config.h $(INC)/sounds.h $(INC)/rts.h $(INC)/_rts.h $(INC)/soundefs.h $(JAUDIOLIBDIR)/include/fx_man.h $(JAUDIOLIBDIR)/include/music.h $(INC)/namesdyn.h $(INC)/duke3d.h $(INC)/player.h $(INC)/sector.h $(INC)/game.h $(INC)/actors.h
 
$(OBJ)/game.$o: $(SRC)/game.c $(SRC)/jmact/scriplib.h $(duke3d_h) $(INC)/osdfuncs.h $(INC)/osdcmds.h $(INC)/grpscan.h
gamedef_h=$(SRC)/gamedef.h $(SRC)/gameexec.h $(SRC)/gamevars.h
 
$(OBJ)/game.$o: $(SRC)/game.c $(SRC)/jmact/scriplib.h $(duke3d_h) $(INC)/osdfuncs.h $(INC)/osdcmds.h $(INC)/grpscan.h $(INC)/demo.h
$(OBJ)/actors.$o: $(SRC)/actors.c $(duke3d_h)
$(OBJ)/anim.$o: $(SRC)/anim.c $(duke3d_h) $(SRC)/jmact/animlib.h
$(OBJ)/demo.$o: $(SRC)/demo.c $(duke3d_h)
$(OBJ)/gamedef.$o: $(SRC)/gamedef.c $(duke3d_h) $(gamedef_h)
$(OBJ)/gameexec.$o: $(SRC)/gameexec.c $(SRC)/gamestructures.c $(duke3d_h) $(gamedef_h)
$(OBJ)/gamestructures.$o: $(SRC)/gamestructures.c $(duke3d_h) $(gamedef_h)
12,6 → 14,7
$(OBJ)/mdump.$o: $(SRC)/mdump.cpp $(SRC)/mdump.h
$(OBJ)/menus.$o: $(SRC)/menus.c $(duke3d_h) $(SRC)/jmact/mouse.h
$(OBJ)/namesdyn.$o: $(SRC)/namesdyn.c $(duke3d_h)
$(OBJ)/net.$o: $(SRC)/net.c $(duke3d_h)
$(OBJ)/player.$o: $(SRC)/player.c $(duke3d_h)
$(OBJ)/premap.$o: $(SRC)/premap.c $(duke3d_h) $(EINC)/osd.h
$(OBJ)/savegame.$o: $(SRC)/savegame.c $(duke3d_h)
/polymer/eduke32/Makefile.msvc
72,6 → 72,7
GAMEOBJS=$(OBJ)\game.$o \
$(OBJ)\actors.$o \
$(OBJ)\anim.$o \
$(OBJ)\demo.$o \
$(OBJ)\gamedef.$o \
$(OBJ)\gameexec.$o \
$(OBJ)\gamevars.$o \
78,6 → 79,7
$(OBJ)\global.$o \
$(OBJ)\menus.$o \
$(OBJ)\namesdyn.$o \
$(OBJ)\net.$o \
$(OBJ)\player.$o \
$(OBJ)\premap.$o \
$(OBJ)\savegame.$o \
/polymer/eduke32/SEHELP.HLP
1,35 → 1,35
-SECTOR EFFECTOR HELP-
-Sector Effector Help-
 
0 : ROTATED SECTOR
1 : PIVOT SPRITE FOR SE 0
2 : EARTHQUAKE
3 : RANDOM LIGHTS AFTER SHOT OUT
4 : RANDOM LIGHTS
6 : SUBWAY
7 : TRANSPORT (UNDERWATER ST 1 or 2)
8 : UP OPEN DOOR LIGHTS
9 : DOWN OPEN DOOR LIGHTS
10 : DOOR AUTO CLOSE (H=DELAY)
11 : ROTATE SECTOR DOOR
12 : LIGHT SWITCH
13 : C-9 EXPLOSIVE
14 : SUBWAY CAR
15 : SLIDE DOOR (ST 25)
16 : ROTATE REACTOR SECTOR
17 : ELEVATOR TRANSPORT (ST 15)
18 : INCREMENTAL SECTOR RISE/FALL
19 : SHOT TOUCHPLATE CIELING DOWN
20 : BRIDGE (ST 27)
21 : DROP FLOOR (ST 28)
22 : PRONG (ST 29)
23 : TRANSPORT DESTINATION (H=SE 7)
24 : CONVAIRBELT
25 : ENGINE
28 : LIGHTNING (H= TILE#4890)
27 : CAMERA FOR PLAYBACK
29 : FLOAT
30 : 2 WAY TRAIN (ST=31)
31 : FLOOR RISE
32 : CEILING FALL
33 : SPAWN JIB W/QUAKE
36 : SKRINK RAY SHOOTER
0 : Rotating Sector
1 : Pivot Sprite for SE 0
2 : Earthquake
3 : Random Lights After Shot Out
4 : Random Lights
6 : Subway
7 : Teleporter
8 : Up Open Door Lights
9 : Down Open Door Lights
10 : Door Auto Close (Hitag = Delay)
11 : Rotate Sector Door
12 : Light Switch
13 : C-9 Explosive
14 : Subway Car
15 : Slide Door (ST 25)
16 : Rotate Reactor Sector
17 : Elevator Transport (ST 15)
18 : Incremental Sector Rise/Fall
19 : Explosion Lowers Ceiling
20 : Stretch (ST 27)
21 : Drop Floor (ST 28)
22 : Teeth Door Prong (ST 29)
23 : One-Way Teleporter Destination
24 : Conveyor Belt or Water Current
25 : Engine Piston
27 : Demo Camera
28 : Lightning
29 : Float (for Waves)
30 : Two-Way Train (ST 31)
31 : Floor Rise/Fall
32 : Ceiling Rise/Fall
33 : Earthquake Debris
36 : Projectile Shooter
/polymer/eduke32/STHELP.HLP
1,24 → 1,25
-SECTOR TAGS HELP-
-Sector Tags Help-
 
1 : WATER (SE 7)
2 : UNDERWATER (SE 7)
9 : STAR TREK DOORS
15 : ELEVATOR TRANSPORT (SE 17)
16 : ELEVATOR PLATFORM DOWN
17 : ELEVATOR PLATFORM UP
18 : ELEVATOR DOWN
19 : ELEVATOR UP
20 : CEILING DOOR
21 : FLOOR DOOR
22 : SPLIT DOOR
23 : SWING DOOR
25 : SLIDE DOOR (SE 15)
26 : SPLIT STAR TREK DOOR
27 : BRIDGE (SE 20)
28 : DROP FLOOR (SE 21)
29 : TEETH DOOR (SE 22)
30 : ROTATE RISE BRIDGE
31 : 2 WAY TRAIN (SE=30)
10000+ : 1 TIME SOUND
32767 : SECRET ROOM
65535 : END OF LEVEL
1 : Above Water (SE 7)
2 : Underwater (SE 7)
9 : Sliding Star Trek Doors
15 : Elevator Transport (SE 17)
16 : Elevator Platform Down
17 : Elevator Platform Up
18 : Elevator Down
19 : Elevator Up
20 : Ceiling Door
21 : Floor Door
22 : Splitting Door
23 : Swinging Door
25 : Sliding Door (SE 15)
26 : Splitting Star Trek Door
27 : Stretch (SE 20)
28 : Drop Floor (SE 21)
29 : Teeth Door Prong (SE 22)
30 : Rotate and Rise Bridge
31 : Two-Way Train (SE 30)
10+++ : One-Time Sound
32767 : Secret Room
65534 : End Of Level with Message
65535 : End Of Level
/polymer/eduke32/build/include/build.h
696,8 → 696,7
void hash_free(hashtable_t *t);
int32_t hash_findcase(hashtable_t *t, const char *s);
int32_t hash_find(hashtable_t *t, const char *s);
void hash_replace(hashtable_t *t, const char *s, int32_t key);
void hash_add(hashtable_t *t, const char *s, int32_t key);
void hash_add(hashtable_t *t, const char *s, int32_t key, int32_t replace);
 
#ifdef POLYMER
# include "polymer.h"
/polymer/eduke32/build/include/cache1d.h
36,6 → 36,8
int32_t ktell(int32_t handle);
void kclose(int32_t handle);
 
typedef struct { intptr_t *hand; int32_t leng; char *lock ; } cactype;
 
enum {
CACHE1D_FIND_FILE = 1,
CACHE1D_FIND_DIR = 2,
/polymer/eduke32/build/src/cache1d.c
64,7 → 64,6
char zerochar = 0;
intptr_t cachestart = 0;
int32_t cacnum = 0, agecount = 0;
typedef struct { intptr_t *hand; int32_t leng; char *lock ; } cactype;
cactype cac[MAXCACHEOBJECTS];
static int32_t lockrecip[200];
 
/polymer/eduke32/build/src/defs.c
13,7 → 13,7
#include "kplib.h"
#include "quicklz.h"
 
enum
enum scripttoken_t
{
T_EOF = -2,
T_ERROR = -1,
80,190 → 80,9
};
 
typedef struct { char *text; int32_t tokenid; } tokenlist;
static tokenlist basetokens[] =
{
{ "include", T_INCLUDE },
{ "#include", T_INCLUDE },
{ "define", T_DEFINE },
{ "#define", T_DEFINE },
 
// deprecated style
{ "definetexture", T_DEFINETEXTURE },
{ "defineskybox", T_DEFINESKYBOX },
{ "definetint", T_DEFINETINT },
{ "definemodel", T_DEFINEMODEL },
{ "definemodelframe",T_DEFINEMODELFRAME },
{ "definemodelanim", T_DEFINEMODELANIM },
{ "definemodelskin", T_DEFINEMODELSKIN },
{ "selectmodelskin", T_SELECTMODELSKIN },
{ "definevoxel", T_DEFINEVOXEL },
{ "definevoxeltiles",T_DEFINEVOXELTILES },
 
// new style
 
{ "model", T_MODEL },
{ "voxel", T_VOXEL },
{ "skybox", T_SKYBOX },
{ "tint", T_TINT },
{ "texture", T_TEXTURE },
{ "tile", T_TEXTURE },
{ "music", T_MUSIC },
{ "sound", T_SOUND },
 
// other stuff
{ "undefmodel", T_UNDEFMODEL },
{ "undefmodelrange", T_UNDEFMODELRANGE },
{ "undefmodelof", T_UNDEFMODELOF },
{ "undeftexture", T_UNDEFTEXTURE },
{ "undeftexturerange", T_UNDEFTEXTURERANGE },
{ "alphahack", T_ALPHAHACK },
{ "alphahackrange", T_ALPHAHACKRANGE },
{ "spritecol", T_SPRITECOL },
{ "2dcol", T_2DCOL },
{ "fogpal", T_FOGPAL },
{ "loadgrp", T_LOADGRP },
{ "dummytile", T_DUMMYTILE },
{ "dummytilerange", T_DUMMYTILERANGE },
{ "setuptile", T_SETUPTILE },
{ "setuptilerange", T_SETUPTILERANGE },
{ "animtilerange", T_ANIMTILERANGE },
{ "cachesize", T_CACHESIZE },
{ "dummytilefrompic",T_IMPORTTILE },
{ "tilefromtexture", T_TILEFROMTEXTURE },
};
 
static tokenlist modeltokens[] =
static int32_t getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens)
{
{ "scale", T_SCALE },
{ "shade", T_SHADE },
{ "zadd", T_ZADD },
{ "frame", T_FRAME },
{ "anim", T_ANIM },
{ "skin", T_SKIN },
{ "detail", T_DETAIL },
{ "glow", T_GLOW },
{ "specular", T_SPECULAR },
{ "normal", T_NORMAL },
{ "hud", T_HUD },
{ "flags", T_FLAGS },
};
 
static tokenlist modelframetokens[] =
{
{ "pal", T_PAL },
{ "frame", T_FRAME },
{ "name", T_FRAME },
{ "tile", T_TILE },
{ "tile0", T_TILE0 },
{ "tile1", T_TILE1 },
{ "smoothduration", T_SMOOTHDURATION },
};
 
static tokenlist modelanimtokens[] =
{
{ "frame0", T_FRAME0 },
{ "frame1", T_FRAME1 },
{ "fps", T_FPS },
{ "flags", T_FLAGS },
};
 
static tokenlist modelskintokens[] =
{
{ "pal", T_PAL },
{ "file", T_FILE },
{ "surf", T_SURF },
{ "surface", T_SURF },
{ "intensity", T_PARAM },
{ "scale", T_PARAM },
{ "detailscale", T_PARAM },
{ "specpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
{ "specfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
};
 
static tokenlist modelhudtokens[] =
{
{ "tile", T_TILE },
{ "tile0", T_TILE0 },
{ "tile1", T_TILE1 },
{ "xadd", T_XADD },
{ "yadd", T_YADD },
{ "zadd", T_ZADD },
{ "angadd", T_ANGADD },
{ "hide", T_HIDE },
{ "nobob", T_NOBOB },
{ "flipped",T_FLIPPED},
{ "nodepth",T_NODEPTH},
};
 
static tokenlist voxeltokens[] =
{
{ "tile", T_TILE },
{ "tile0", T_TILE0 },
{ "tile1", T_TILE1 },
{ "scale", T_SCALE },
};
 
static tokenlist skyboxtokens[] =
{
{ "tile" ,T_TILE },
{ "pal" ,T_PAL },
{ "ft" ,T_FRONT },{ "front" ,T_FRONT },{ "forward",T_FRONT },
{ "rt" ,T_RIGHT },{ "right" ,T_RIGHT },
{ "bk" ,T_BACK },{ "back" ,T_BACK },
{ "lf" ,T_LEFT },{ "left" ,T_LEFT },{ "lt" ,T_LEFT },
{ "up" ,T_TOP },{ "top" ,T_TOP },{ "ceiling",T_TOP },{ "ceil" ,T_TOP },
{ "dn" ,T_BOTTOM },{ "bottom" ,T_BOTTOM },{ "floor" ,T_BOTTOM },{ "down" ,T_BOTTOM }
};
 
static tokenlist tinttokens[] =
{
{ "pal", T_PAL },
{ "red", T_RED },{ "r", T_RED },
{ "green", T_GREEN },{ "g", T_GREEN },
{ "blue", T_BLUE },{ "b", T_BLUE },
{ "flags", T_FLAGS }
};
 
static tokenlist texturetokens[] =
{
{ "pal", T_PAL },
{ "detail", T_DETAIL },
{ "glow", T_GLOW },
{ "specular",T_SPECULAR },
{ "normal", T_NORMAL },
};
 
static tokenlist texturetokens_pal[] =
{
{ "file", T_FILE },{ "name", T_FILE },
{ "alphacut", T_ALPHACUT },
{ "detailscale", T_XSCALE }, { "scale", T_XSCALE }, { "xscale", T_XSCALE }, { "intensity", T_XSCALE },
{ "yscale", T_YSCALE },
{ "specpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
{ "specfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
{ "nocompress", T_NOCOMPRESS },
{ "nodownsize", T_NODOWNSIZE },
};
 
static tokenlist sound_musictokens[] =
{
{ "id", T_ID },
{ "file", T_FILE },
};
 
static tokenlist tilefromtexturetokens[] =
{
{ "file", T_FILE },
{ "name", T_FILE },
{ "alphacut", T_ALPHACUT },
{ "xoffset", T_XOFFSET },
{ "xoff", T_XOFFSET },
{ "yoffset", T_YOFFSET },
{ "yoff", T_YOFFSET },
};
 
static int32_t getatoken(scriptfile *sf, tokenlist *tl, int32_t ntokens)
{
char *tok;
int32_t i;
 
271,7 → 90,7
tok = scriptfile_gettoken(sf);
if (!tok) return T_EOF;
 
for (i=0; i<ntokens; i++)
for (i=ntokens-1; i>=0; i--)
{
if (!Bstrcasecmp(tok, tl[i].text))
return tl[i].tokenid;
297,6 → 116,58
{
int32_t tokn;
char *cmdtokptr;
 
static const tokenlist basetokens[] =
{
{ "include", T_INCLUDE },
{ "#include", T_INCLUDE },
{ "define", T_DEFINE },
{ "#define", T_DEFINE },
 
// deprecated style
{ "definetexture", T_DEFINETEXTURE },
{ "defineskybox", T_DEFINESKYBOX },
{ "definetint", T_DEFINETINT },
{ "definemodel", T_DEFINEMODEL },
{ "definemodelframe",T_DEFINEMODELFRAME },
{ "definemodelanim", T_DEFINEMODELANIM },
{ "definemodelskin", T_DEFINEMODELSKIN },
{ "selectmodelskin", T_SELECTMODELSKIN },
{ "definevoxel", T_DEFINEVOXEL },
{ "definevoxeltiles",T_DEFINEVOXELTILES },
 
// new style
{ "model", T_MODEL },
{ "voxel", T_VOXEL },
{ "skybox", T_SKYBOX },
{ "tint", T_TINT },
{ "texture", T_TEXTURE },
{ "tile", T_TEXTURE },
{ "music", T_MUSIC },
{ "sound", T_SOUND },
 
// other stuff
{ "undefmodel", T_UNDEFMODEL },
{ "undefmodelrange", T_UNDEFMODELRANGE },
{ "undefmodelof", T_UNDEFMODELOF },
{ "undeftexture", T_UNDEFTEXTURE },
{ "undeftexturerange", T_UNDEFTEXTURERANGE },
{ "alphahack", T_ALPHAHACK },
{ "alphahackrange", T_ALPHAHACKRANGE },
{ "spritecol", T_SPRITECOL },
{ "2dcol", T_2DCOL },
{ "fogpal", T_FOGPAL },
{ "loadgrp", T_LOADGRP },
{ "dummytile", T_DUMMYTILE },
{ "dummytilerange", T_DUMMYTILERANGE },
{ "setuptile", T_SETUPTILE },
{ "setuptilerange", T_SETUPTILERANGE },
{ "animtilerange", T_ANIMTILERANGE },
{ "cachesize", T_CACHESIZE },
{ "dummytilefrompic",T_IMPORTTILE },
{ "tilefromtexture", T_TILEFROMTEXTURE },
};
 
while (1)
{
if (quitevent) return 0;
594,6 → 465,17
int32_t alphacut = 255;
int32_t xoffset = 0, yoffset = 0;
 
static const tokenlist tilefromtexturetokens[] =
{
{ "file", T_FILE },
{ "name", T_FILE },
{ "alphacut", T_ALPHACUT },
{ "xoffset", T_XOFFSET },
{ "xoff", T_XOFFSET },
{ "yoffset", T_YOFFSET },
{ "yoff", T_YOFFSET },
};
 
if (scriptfile_getsymbol(script,&tile)) break;
if (scriptfile_getbraces(script,&textureend)) break;
while (script->textptr < textureend)
1031,6 → 913,22
double scale=1.0, mzadd=0.0;
int32_t shadeoffs=0, pal=0, flags=0;
 
static const tokenlist modeltokens[] =
{
{ "scale", T_SCALE },
{ "shade", T_SHADE },
{ "zadd", T_ZADD },
{ "frame", T_FRAME },
{ "anim", T_ANIM },
{ "skin", T_SKIN },
{ "detail", T_DETAIL },
{ "glow", T_GLOW },
{ "specular", T_SPECULAR },
{ "normal", T_NORMAL },
{ "hud", T_HUD },
{ "flags", T_FLAGS },
};
 
modelskin = lastmodelskin = 0;
seenframe = 0;
 
1066,6 → 964,17
int32_t ftilenume = -1, ltilenume = -1, tilex = 0;
double smoothduration = 0.1f;
 
static const tokenlist modelframetokens[] =
{
{ "pal", T_PAL },
{ "frame", T_FRAME },
{ "name", T_FRAME },
{ "tile", T_TILE },
{ "tile0", T_TILE0 },
{ "tile1", T_TILE1 },
{ "smoothduration", T_SMOOTHDURATION },
};
 
if (scriptfile_getbraces(script,&frameend)) break;
while (script->textptr < frameend)
{
1135,6 → 1044,14
int32_t flags = 0;
double dfps = 1.0;
 
static const tokenlist modelanimtokens[] =
{
{ "frame0", T_FRAME0 },
{ "frame1", T_FRAME1 },
{ "fps", T_FPS },
{ "flags", T_FLAGS },
};
 
if (scriptfile_getbraces(script,&animend)) break;
while (script->textptr < animend)
{
1190,6 → 1107,19
int32_t palnum = 0, surfnum = 0;
double param = 1.0, specpower = 1.0, specfactor = 1.0;
 
static const tokenlist modelskintokens[] =
{
{ "pal", T_PAL },
{ "file", T_FILE },
{ "surf", T_SURF },
{ "surface", T_SURF },
{ "intensity", T_PARAM },
{ "scale", T_PARAM },
{ "detailscale", T_PARAM },
{ "specpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
{ "specfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
};
 
if (scriptfile_getbraces(script,&skinend)) break;
while (script->textptr < skinend)
{
1266,6 → 1196,21
int32_t ftilenume = -1, ltilenume = -1, tilex = 0, flags = 0;
double xadd = 0.0, yadd = 0.0, zadd = 0.0, angadd = 0.0;
 
static const tokenlist modelhudtokens[] =
{
{ "tile", T_TILE },
{ "tile0", T_TILE0 },
{ "tile1", T_TILE1 },
{ "xadd", T_XADD },
{ "yadd", T_YADD },
{ "zadd", T_ZADD },
{ "angadd", T_ANGADD },
{ "hide", T_HIDE },
{ "nobob", T_NOBOB },
{ "flipped",T_FLIPPED},
{ "nodepth",T_NODEPTH},
};
 
if (scriptfile_getbraces(script,&frameend)) break;
while (script->textptr < frameend)
{
1355,6 → 1300,14
char *fn, *modelend;
int32_t tile0 = MAXTILES, tile1 = -1, tilex = -1;
 
static const tokenlist voxeltokens[] =
{
{ "tile", T_TILE },
{ "tile0", T_TILE0 },
{ "tile1", T_TILE1 },
{ "scale", T_SCALE },
};
 
if (scriptfile_getstring(script,&fn)) break; //voxel filename
if (nextvoxid == MAXVOXELS) { initprintf("Maximum number of voxels already defined.\n"); break; }
#ifdef SUPERBUILD
1410,6 → 1363,18
char *fn[6] = {0,0,0,0,0,0}, *modelend, happy=1, *tfn = NULL;
int32_t i, tile = -1, pal = 0,ii;
 
static const tokenlist skyboxtokens[] =
{
{ "tile" ,T_TILE },
{ "pal" ,T_PAL },
{ "ft" ,T_FRONT },{ "front" ,T_FRONT },{ "forward",T_FRONT },
{ "rt" ,T_RIGHT },{ "right" ,T_RIGHT },
{ "bk" ,T_BACK },{ "back" ,T_BACK },
{ "lf" ,T_LEFT },{ "left" ,T_LEFT },{ "lt" ,T_LEFT },
{ "up" ,T_TOP },{ "top" ,T_TOP },{ "ceiling",T_TOP },{ "ceil" ,T_TOP },
{ "dn" ,T_BOTTOM },{ "bottom" ,T_BOTTOM },{ "floor" ,T_BOTTOM },{ "down" ,T_BOTTOM }
};
 
if (scriptfile_getbraces(script,&modelend)) break;
while (script->textptr < modelend)
{
1467,6 → 1432,15
int32_t red=255, green=255, blue=255, pal=-1, flags=0;
char *tintend;
 
static const tokenlist tinttokens[] =
{
{ "pal", T_PAL },
{ "red", T_RED },{ "r", T_RED },
{ "green", T_GREEN },{ "g", T_GREEN },
{ "blue", T_BLUE },{ "b", T_BLUE },
{ "flags", T_FLAGS }
};
 
if (scriptfile_getbraces(script,&tintend)) break;
while (script->textptr < tintend)
{
1499,6 → 1473,15
char *texturetokptr = script->ltextptr, *textureend;
int32_t tile=-1, token;
 
static const tokenlist texturetokens[] =
{
{ "pal", T_PAL },
{ "detail", T_DETAIL },
{ "glow", T_GLOW },
{ "specular",T_SPECULAR },
{ "normal", T_NORMAL },
};
 
if (scriptfile_getsymbol(script,&tile)) break;
if (scriptfile_getbraces(script,&textureend)) break;
while (script->textptr < textureend)
1514,6 → 1497,18
double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
char flags = 0;
 
static const tokenlist texturetokens_pal[] =
{
{ "file", T_FILE },{ "name", T_FILE },
{ "alphacut", T_ALPHACUT },
{ "detailscale", T_XSCALE }, { "scale", T_XSCALE }, { "xscale", T_XSCALE }, { "intensity", T_XSCALE },
{ "yscale", T_YSCALE },
{ "specpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
{ "specfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
{ "nocompress", T_NOCOMPRESS },
{ "nodownsize", T_NODOWNSIZE },
};
 
if (scriptfile_getsymbol(script,&pal)) break;
if (scriptfile_getbraces(script,&palend)) break;
while (script->textptr < palend)
1586,6 → 1581,18
double xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
char flags = 0;
 
static const tokenlist texturetokens_pal[] =
{
{ "file", T_FILE },{ "name", T_FILE },
{ "alphacut", T_ALPHACUT },
{ "detailscale", T_XSCALE }, { "scale", T_XSCALE }, { "xscale", T_XSCALE }, { "intensity", T_XSCALE },
{ "yscale", T_YSCALE },
{ "specpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
{ "specfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
{ "nocompress", T_NOCOMPRESS },
{ "nodownsize", T_NODOWNSIZE },
};
 
if (scriptfile_getbraces(script,&detailend)) break;
while (script->textptr < detailend)
{
1767,9 → 1774,15
}
break;
 
case T_SOUND:
case T_MUSIC:
{
char *dummy, *dummy2;
static const tokenlist sound_musictokens[] =
{
{ "id", T_ID },
{ "file", T_FILE },
};
 
if (scriptfile_getbraces(script,&dummy)) break;
while (script->textptr < dummy)
1787,26 → 1800,6
}
break;
 
case T_SOUND:
{
char *dummy, *dummy2;
 
if (scriptfile_getbraces(script,&dummy)) break;
while (script->textptr < dummy)
{
switch (getatoken(script,sound_musictokens,sizeof(sound_musictokens)/sizeof(tokenlist)))
{
case T_ID:
scriptfile_getsymbol(script,(int32_t *)&dummy2);
break;
case T_FILE:
scriptfile_getstring(script,&dummy2);
break;
}
}
}
break;
 
default:
initprintf("Unknown token.\n"); break;
}
/polymer/eduke32/build/src/engine.c
12122,9 → 12122,8
t->items = 0;
}
 
#if 1
// djb3 algorithm
inline uint32_t HASH_getcode(const char *s)
static inline uint32_t hash_getcode(const char *s)
{
uint32_t h = 5381;
int32_t ch;
12134,101 → 12133,47
 
return h;
}
#else
inline uint32_t HASH_getcode(const char *s)
{
int32_t i=0, fact=1;
while (*s)
{
i+=*s;
i+=1<<fact;
s++;
}
return i;
}
#endif
 
void hash_add(hashtable_t *t, const char *s, int32_t key)
void hash_add(hashtable_t *t, const char *s, int32_t key, int32_t replace)
{
hashitem_t *cur, *prev=NULL;
int32_t code;
 
if (!s)
return;
if (t->items == NULL)
{
initprintf("hash_add(): table not initialized!\n");
initprintf("hash_replace(): table not initialized!\n");
return;
}
code = HASH_getcode(s)%t->size;
 
code = hash_getcode(s) % t->size;
cur = t->items[code];
 
if (!cur)
{
cur=Bcalloc(1,sizeof(hashitem_t));
cur->string=Bstrdup(s);
cur->key=key;
cur->next=NULL;
t->items[code]=cur;
cur = (hashitem_t *)Bcalloc(1,sizeof(hashitem_t));
cur->string = Bstrdup(s);
cur->key = key;
cur->next = NULL;
t->items[code] = cur;
return;
}
 
do
{
if (Bstrcmp(s,cur->string)==0)
return;
prev=cur;
cur=cur->next;
}
while (cur);
 
cur=Bcalloc(1,sizeof(hashitem_t));
cur->string=Bstrdup(s);
cur->key=key;
cur->next=NULL;
prev->next=cur;
}
 
void hash_replace(hashtable_t *t, const char *s, int32_t key)
{
hashitem_t *cur, *prev=NULL;
int32_t code;
 
if (t->items==NULL)
{
initprintf("hash_replace(): table not initialized!\n");
return;
}
code=HASH_getcode(s)%t->size;
cur=t->items[code];
 
if (!cur)
{
cur=Bcalloc(1,sizeof(hashitem_t));
cur->string=Bstrdup(s);
cur->key=key;
cur->next=NULL;
t->items[code]=cur;
return;
}
 
do
{
if (Bstrcmp(s,cur->string)==0)
if (Bstrcmp(s,cur->string) == 0)
{
cur->key=key;
if (replace) cur->key = key;
return;
}
prev=cur;
cur=cur->next;
prev = cur;
}
while (cur);
while ((cur = cur->next));
 
cur=Bcalloc(1,sizeof(hashitem_t));
cur->string=Bstrdup(s);
cur->key=key;
cur->next=NULL;
prev->next=cur;
cur = (hashitem_t *)Bcalloc(1,sizeof(hashitem_t));
cur->string = Bstrdup(s);
cur->key = key;
cur->next = NULL;
prev->next = cur;
}
 
int32_t hash_find(hashtable_t *t, const char *s)
12235,18 → 12180,19
{
hashitem_t *cur;
 
if (t->items==NULL)
if (t->items == NULL)
{
initprintf("hash_find(): table not initialized!\n");
return -1;
}
cur=t->items[HASH_getcode(s)%t->size];
while (cur)
{
 
if ((cur = t->items[hash_getcode(s) % t->size]) == NULL) return -1;
do
if (Bstrcmp(s,cur->string) == 0)
return cur->key;
cur=cur->next;
}
while ((cur = cur->next));
 
return -1;
}
 
12254,18 → 12200,19
{
hashitem_t *cur;
 
if (t->items==NULL)
if (t->items == NULL)
{
initprintf("hash_findcase(): table not initialized!\n");
return -1;
}
cur=t->items[HASH_getcode(s)%t->size];
while (cur)
{
 
if ((cur=t->items[hash_getcode(s)%t->size]) == NULL) return -1;
 
do
if (Bstrcasecmp(s,cur->string) == 0)
return cur->key;
cur=cur->next;
}
while ((cur=cur->next));
 
return -1;
}
 
/polymer/eduke32/build/src/osd.c
165,7 → 165,7
 
cvars = (osdcvar_t *)Brealloc(cvars, (osdnumcvars + 1) * sizeof(osdcvar_t));
 
hash_replace(&h_cvars, cvar->name, osdnumcvars);
hash_add(&h_cvars, cvar->name, osdnumcvars, 1);
 
switch (cvar->type & (CVAR_BOOL|CVAR_INT|CVAR_UINT|CVAR_FLOAT|CVAR_DOUBLE))
{
1920,9 → 1920,9
newsymb->next = t;
}
}
hash_replace(&h_osd, name, osdnumsymbols);
hash_add(&h_osd, name, osdnumsymbols, 1);
name = Bstrtolower(Bstrdup(name));
hash_replace(&h_osd, name, osdnumsymbols);
hash_add(&h_osd, name, osdnumsymbols, 1);
Bfree((void *)name);
osdsymbptrs[osdnumsymbols++] = newsymb;
return newsymb;
/polymer/eduke32/build/src/polymost.c
1282,7 → 1282,7
curcacheindex->offset = foffset;
curcacheindex->len = fsize;
curcacheindex->next = (texcacheindex *)Bcalloc(1, sizeof(texcacheindex));
hash_replace(&h_texcache, Bstrdup(fname), numcacheentries);
hash_add(&h_texcache, Bstrdup(fname), numcacheentries, 1);
cacheptrs[numcacheentries++] = curcacheindex;
curcacheindex = curcacheindex->next;
}
1515,7 → 1515,7
}
else OSD_Printf("wtf?\n");
 
hash_add(&h_texcache, Bstrdup(cachefn), numcacheentries);
hash_add(&h_texcache, Bstrdup(cachefn), numcacheentries, 0);
cacheptrs[numcacheentries++] = curcacheindex;
curcacheindex = curcacheindex->next;
}
/polymer/eduke32/build/src/winlayer.c
541,7 → 541,7
// initsystem() -- init systems
//
 
static void printsysversion(void)
static void win_printversion(void)
{
const char *ver = "";
 
617,7 → 617,7
frameplace=0;
lockcount=0;
 
printsysversion();
win_printversion();
 
#if defined(USE_OPENGL) && defined(POLYMOST)
if (loadgldriver(getenv("BUILD_GLDRV")))
/polymer/eduke32/eduke32.vcxproj
109,11 → 109,23
<ClInclude Include="build\include\msvc\inttypes.h" />
<ClInclude Include="build\include\msvc\stdint.h" />
<ClInclude Include="build\src\engine_priv.h" />
<ClInclude Include="source\actors.h" />
<ClInclude Include="source\anim.h" />
<ClInclude Include="source\demo.h" />
<ClInclude Include="source\game.h" />
<ClInclude Include="source\gameexec.h" />
<ClInclude Include="source\gamevars.h" />
<ClInclude Include="source\global.h" />
<ClInclude Include="source\menus.h" />
<ClInclude Include="source\net.h" />
<ClInclude Include="source\player.h" />
<ClInclude Include="source\premap.h" />
<ClInclude Include="source\savegame.h" />
<ClInclude Include="source\sector.h" />
<ClInclude Include="source\_functio.h" />
<ClInclude Include="source\_rts.h" />
<ClInclude Include="source\config.h" />
<ClInclude Include="source\duke3d.h" />
<ClInclude Include="source\funct.h" />
<ClInclude Include="source\function.h" />
<ClInclude Include="source\gamedef.h" />
<ClInclude Include="source\gamedefs.h" />
199,6 → 211,7
<ClCompile Include="source\anim.c" />
<ClCompile Include="source\astub.c" />
<ClCompile Include="source\config.c" />
<ClCompile Include="source\demo.c" />
<ClCompile Include="source\game.c" />
<ClCompile Include="source\gamedef.c" />
<ClCompile Include="source\gameexec.c" />
216,6 → 229,7
<ClCompile Include="source\mpu401.c" />
<ClCompile Include="source\music.c" />
<ClCompile Include="source\namesdyn.c" />
<ClCompile Include="source\net.c" />
<ClCompile Include="source\osdcmds.c" />
<ClCompile Include="source\osdfuncs.c" />
<ClCompile Include="source\player.c" />
/polymer/eduke32/eduke32.vcxproj.filters
162,9 → 162,6
<ClInclude Include="source\duke3d.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\funct.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\function.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
318,6 → 315,45
<ClInclude Include="build\include\prlights.h">
<Filter>build\headers</Filter>
</ClInclude>
<ClInclude Include="source\sector.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\gameexec.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\actors.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\player.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\gamevars.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\net.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\global.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\game.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\premap.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\menus.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\savegame.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\anim.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
<ClInclude Include="source\demo.h">
<Filter>eduke32\headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="build\src\a-c.c">
596,6 → 632,12
<ClCompile Include="build\src\rawinput.c">
<Filter>build\source</Filter>
</ClCompile>
<ClCompile Include="source\net.c">
<Filter>eduke32\source</Filter>
</ClCompile>
<ClCompile Include="source\demo.c">
<Filter>eduke32\source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Makefile.msvc">
/polymer/eduke32/m32help.hlp
18,24 → 18,23
6. Sprite (sprite without sector - map is corrupt)
 
Some commands work differently depending on the currently selected object.
To solve ambiguous between sector and wall/sprite, one usually must press
ALT to work with wall/sprite instead of sectors.
Press ALT to work with a wall or sprite instead of any adjacent sectors.
 
^14RSHIFT^O select vertex/sprites
^14RALT^O select sectors
^14WHELL^O zoom
^14WHELL+ALT^O move camera and zoom
^14WHEEL^O zoom
^14WHEEL+ALT^O move camera and zoom
^14LEFT BUTTON^O drag sectors/vertex/sprites
^14RIGHT BUTTON^O move camera
^14RIGHT MIDDLE^O move camera
^P
LSHIFT show coords
LSHIFT show coordinates
F1 show help
F9 show the Sector Tags help
M set extra of sector
M+ALT set extra of wall/sprite
/ Reset panning, repeat and flags to defaults
/+SHIFT set xrepeat to yrepeat(makes square)
/ Reset panning, size and flags to defaults
/+SHIFT make square - set xrepeat to yrepeat
 
KP_4 scaling sprite horizontally
KP_6 scaling sprite horizontally
66,9 → 65,9
F12+SHIFT inverted screenshot
 
B toggle blocking
B+SHIFT toggle one side blocking for wall
F+ALT set the first wall of sector
O ornament sprite onto wall
B+SHIFT toggle one-sided blocking for a wall
F+ALT set the first wall of a sector
O ornament sprite flat onto wall
 
, rotate sprite/selected sectors
. rotate sprite/selected sectors
91,14 → 90,14
H+CTRL toggle hitscan sensitivity
H+CTRL+SHIFT toggle hitscan sensitivity
 
P set sector pal
P set sector palette
E set sprite status list
TAB show sector data
TAB+CTRL show wall/sprite data
TAB+ALT show wall/sprite data (Windows may trigger on this shortcut)
TAB+ALT show wall/sprite data (The Windows cool switch may trigger when used.)
 
LCTRL+RSHIFT select all walls of the current sector(point at a wall and holding
CTRL, press SHIFT).
LCTRL+RSHIFT select all walls of the current sector
(point at a wall and, holding CTRL, press SHIFT)
 
A zoom in
Z zoom out
110,8 → 109,8
S+ALT make inner sector
C duplicate sectors/sprites
C start circle attached to a wall
KP + increase amount of walls in circle
KP - decrease amount of walls in circle
KP_+ increase amount of walls in circle
KP_- decrease amount of walls in circle
SPACE start/end drawing of sector, end drawing of circle
LENTER check all pointers for the current sector
LSHIFT+LCTRL+LENTER check ALL pointers (manual attempt to recover map)
124,13 → 123,12
RENETER switch to 3D mode
ESC menu
 
' A toggle autosave(every 3 minutes)
' N toggle noclip
' A toggle autosave (every 3 minutes)
' N toggle clipping
S+CTRL save map
L+CTRL load map
^P
Mouse pointer always points(see info about it at the bottom of the screen) at
one of these objects:
The mouse pointer always points at one of these objects:
1. wall
2. ceiling of sector
3. floor of sector
137,17 → 135,17
4. sprite
5. masked wall (non-transparent or semi-transparent wall between sectors)
 
It's important to understand this concept:
Some commands work differently depending on the current object(the object the
mouse points at).
Some commands manipulate only with current object, and some commands
manipulate with sprites/sectors selected(hereinafter referred to as
"selected") in 2D mode and some commands work globally.
It's important to understand this concept.
Some commands work differently depending on the "current object",the object
the mouse points at.
Some commands only manipulate the "current object", but other commands
manipulate the sprites and sectors which are "selected" in 2D mode.
Other commands work globally.
 
Mouse buttons:
^14LEFT^O lock the current object. The current object won't be
changing as long as the button is pressed.
^14LEFT+MIDDLE^O toggle mouse look
^14LEFT^O lock the current object. The current object won't
change as long as the button is pressed.
^14LEFT+MIDDLE^O toggle mouselook
^14WHEEL^O change shade/visibility
^14LEFT+WHEEL^O change tile
^14RIGHT+WHEEL^O move object up/down
173,7 → 171,7
RIGHT+RCTRL move right
A move up
Z move down
F4+ALT Toggle showing the first wall
F4+ALT toggle showing the first wall
+LSHIFT speed up movements
 
LEFT turn left
184,13 → 182,13
' V set sector visibility
; V set sector visibility on all selected sectors
V choose tile
3 toggle Sector over Sector. See documentation here(http://www.users.on.net/~triforce/cduke3d/)
3 toggle "sector over sector".
F3 toggle mouselook
' BACKSPACE clear all flags for wall/sprite
' P paste palette to all selected sectors
; P paste palette to all selected sectors & sprites
DEL delete sprite
F6 toggle automatic SECTOREFFECTOR help
F6 toggle automatic Sector Effector help
F7 toggle automatic sector tag help
 
, rotate sprite
203,20 → 201,20
CAPS LOCK cycle zmode
' Z cycle zmode
' M set the extra of the current object
1 toggle one sided sprite/wall
1 toggle one-sided flag of sprite/wall
2 toggle bottom wall swapping
O set top or bottom orientation of wall
O ornament sprite onto wall
M toggle masking wall
O ornament sprite flat onto wall
M toggle masked wall
H toggle hitscan sensitivity
H+SHIFT toggle one side hitscan sensitivity for the wall
' H set hitag of the current object
 
KP_MINUS shades down individual sector/wall/sprite or selected sectors
KP_MINUS darkens shade of individual sector/wall/sprite or selected sectors
KP_MINUS+ALT decreases visibility of sector or selected sectors
KP_MINUS+ALT+SHIFT slowly decreases visibility of sector or selected sectors
KP_MINUS+ALT+CTRL decreases global visibility
KP_PLUS shades up individual sector/wall/sprite or selected sectors
KP_PLUS lightens shade individual sector/wall/sprite or selected sectors
KP_PLUS+ALT increases visibility of sector or selected sectors
KP_PLUS+ALT+SHIFT slowly increases visibility of sector or selected sectors
KP_PLUS+ALT+CTRL increases global visibility
230,14 → 228,14
F flip the current object
F+ALT set the first wall of sector
 
PAGE UP move up selected sprites or sectors
PAGE DN move down selected sprites or sectors
PAGE UP+CTRL put selected sprites on ceiling
PAGE DN+CTRL put selected sprites on ground
PAGE UP move selected sprites or sectors up
PAGE DN move selected sprites or sectors down
PAGE UP+CTRL move selected sprites to ceiling
PAGE DN+CTRL move selected sprites to floor
+CTRL speed up movement
+END slow down movement
+HOME slow down movement even more
Note: CTRL, HOME, END are modifiers so they work with mouse too.
Note: CTRL, HOME, END are modifiers, so they work with the mouse too.
 
' D cycle skill level
' X toggle sprite shade preview
244,9 → 242,8
' W toggle sprite display
' Y toggle purple background
' C copy shade from the clipboard to all objects in the map which are the same
tile as the tile of the object that in the clipboard. It works separately for
sectors/walls/sprites depending on the current object. (I hope somebody who
understands this, will clarify this)
tile as the tile of the object in the clipboard. It works separately for
sectors/walls/sprites depending on the current object.
' T set lotag
' H set hitag
' S set shade
260,18 → 257,15
 
LENTER+CTRL+SHIFT autoshade wall
' LENTER paste picnum only
LENTER+SHIFT paste some visaul(shading+pal) properties of the clipboard on
sector/wall/sprite
LENTER+CTRL paste some visaul(picnum+shading+pal) properties of the clipboard
on sector/wall/sprite
LENTER paste all(picnum+shading+pal+flags+tags+extra) properties of the
clipboard on sector/wall/sprite
LENTER+SHIFT paste shade and palette onto the current object
LENTER+CTRL paste picnum, shading, and palette onto the current object
LENTER paste all properties onto the current object
 
' A toggle autosave. The interval is configurable in the cfg
' A toggle autosave. The interval is configurable in the .cfg.
(by default: every 3 minutes)
 
' N toggle noclip for the camera
N+CTRL toggle noclip sprites
' N toggle clipping for the camera
N+CTRL toggle clipping for sprites
 
S+CTRL save map
L+CTRL load map
283,53 → 277,53
F9 reload and activate maphacks
F10 disable maphacks
 
C toggle center sprite
ALT+C replace all tiles in the map with one from the clipboard
C toggle center sprite (cstat 128)
ALT+C replace all tiles in the map with the clipboard
 
[ slopes up fast
[+RSHIFT slope up with medium speed
[+LSHIFT slope up slowly
[+ALT align slope to the floor of adjoining sector
] slope down fast
]+RSHIFT slope down with medium speed
]+LSHIFT slope down slowly
]+ALT align slope to the ceiling of adjoining sector
[ increases slope quickly
[+RSHIFT increases slope with medium speed
[+LSHIFT increases slope slowly
[+ALT align slope to the floor of an adjoining sector
] decreases slope quickly
]+RSHIFT decreases slope with medium speed
]+LSHIFT decreases slope slowly
]+ALT align slope to the ceiling of an adjoining sector
 
KP_4 panning floor/ceiling horizontally
KP_6 panning floor/ceiling horizontally
KP_2 panning floor/ceiling vertically
KP_8 panning floor/ceiling vertically
KP_4 scaling wall/sprite horizontally
KP_6 scaling wall/sprite horizontally
KP_2 scaling wall/sprite vertically
KP_8 scaling wall/sprite vertically
+SHIFT force panning(for walls)
+KP_5 speed up
KP_4 pan floor/ceiling horizontally
KP_6 pan floor/ceiling horizontally
KP_2 pan floor/ceiling vertically
KP_8 pan floor/ceiling vertically
KP_4 scale wall/sprite horizontally
KP_6 scale wall/sprite horizontally
KP_2 scale wall/sprite vertically
KP_8 scale wall/sprite vertically
+SHIFT force panning (for walls)
+KP_5 increase speed
 
/ Reset panning, repeat and flags to defaults
/+SHIFT set xrepeat to yrepeat(makes square)
/ Reset panning, size and flags to defaults
/+SHIFT make square - set xrepeat to yrepeat
 
P enable/disable parallax
P+CTRL change parallax type(works only in classic render)
P+ALT change pal of sector/wall/sprite
D+ALT adjust clip distance of the sprite
P+CTRL change parallax type (only in 8-bit classic renderer)
P+ALT change palette of sector/wall/sprite
D+ALT adjust clipping distance of the sprite
T translucence for sprites/masked walls
S insert sprite
RENTER switch to 2D mode
KP_ENTER switch to 2D mode
^P
After pressing V key in 3D mode, mapster32 switches to "select tile" mode.
After pressing V in 3D mode, the editor enters tile browsing.
 
Keys:
KP / zoom in
KP * zoom out
KP_/ zoom in
KP_* zoom out
UP/DOWN/LEFT/RIGHT/PAGE UP/PAGE DOWN movements
G goto specified tile
U goto start of user defined art (3584)
A goto start of Atomic edition's art (4096)
E goto start of extended art (6144,9216)
G go to specified tile
U go to start of user defined art (3584)
A go to start of Atomic edition's art (4096)
E go to start of extended art (6144, 9216)
 
V select from all tiles
T select from pre-defined tileset
T select from pre-defined tileset (tiles.cfg)
Z tile zoom
ESC cancel
ENTER accept
340,59 → 334,60
WHEEL scroll
RIGHT smooth scrolling
^P
0 : ROTATED SECTOR
1 : PIVOT SPRITE FOR SE 0
2 : EARTHQUAKE
3 : RANDOM LIGHTS AFTER SHOT OUT
4 : RANDOM LIGHTS
6 : SUBWAY
7 : TRANSPORT (UNDERWATER ST 1 or 2)
8 : UP OPEN DOOR LIGHTS
9 : DOWN OPEN DOOR LIGHTS
10 : DOOR AUTO CLOSE (H=DELAY)
11 : ROTATE SECTOR DOOR
12 : LIGHT SWITCH
13 : C-9 EXPLOSIVE
14 : SUBWAY CAR
15 : SLIDE DOOR (ST 25)
16 : ROTATE REACTOR SECTOR
17 : ELEVATOR TRANSPORT (ST 15)
18 : INCREMENTAL SECTOR RISE/FALL
19 : SHOT TOUCHPLATE CIELING DOWN
20 : BRIDGE (ST 27)
21 : DROP FLOOR (ST 28)
22 : PRONG (ST 29)
23 : TRANSPORT DESTINATION (H=SE 7)
24 : CONVAIRBELT
25 : ENGINE
28 : LIGHTNING (H= TILE#4890)
27 : CAMERA FOR PLAYBACK
29 : FLOAT
30 : 2 WAY TRAIN (ST=31)
31 : FLOOR RISE
32 : CEILING FALL
33 : SPAWN JIB W/QUAKE
36 : SKRINK RAY SHOOTER
0 : Rotating Sector
1 : Pivot Sprite for SE 0
2 : Earthquake
3 : Random Lights After Shot Out
4 : Random Lights
6 : Subway
7 : Teleporter
8 : Up Open Door Lights
9 : Down Open Door Lights
10 : Door Auto Close (Hitag = Delay)
11 : Rotate Sector Door
12 : Light Switch
13 : C-9 Explosive
14 : Subway Car
15 : Slide Door (ST 25)
16 : Rotate Reactor Sector
17 : Elevator Transport (ST 15)
18 : Incremental Sector Rise/Fall
19 : Explosion Lowers Ceiling
20 : Stretch (ST 27)
21 : Drop Floor (ST 28)
22 : Teeth Door Prong (ST 29)
23 : One-Way Teleporter Destination
24 : Conveyor Belt or Water Current
25 : Engine Piston
27 : Demo Camera
28 : Lightning
29 : Float (for Waves)
30 : Two-Way Train (ST 31)
31 : Floor Rise/Fall
32 : Ceiling Rise/Fall
33 : Earthquake Debris
36 : Projectile Shooter
^P
1 : WATER (SE 7)
2 : UNDERWATER (SE 7)
9 : STAR TREK DOORS
15 : ELEVATOR TRANSPORT (SE 17)
16 : ELEVATOR PLATFORM DOWN
17 : ELEVATOR PLATFORM UP
18 : ELEVATOR DOWN
19 : ELEVATOR UP
20 : CEILING DOOR
21 : FLOOR DOOR
22 : SPLIT DOOR
23 : SWING DOOR
25 : SLIDE DOOR (SE 15)
26 : SPLIT STAR TREK DOOR
27 : BRIDGE (SE 20)
28 : DROP FLOOR (SE 21)
29 : TEETH DOOR (SE 22)
30 : ROTATE RISE BRIDGE
31 : 2 WAY TRAIN (SE=30)
10000+ : 1 TIME SOUND
32767 : SECRET ROOM
65535 : END OF LEVEL
1 : Above Water (SE 7)
2 : Underwater (SE 7)
9 : Sliding Star Trek Doors
15 : Elevator Transport (SE 17)
16 : Elevator Platform Down
17 : Elevator Platform Up
18 : Elevator Down
19 : Elevator Up
20 : Ceiling Door
21 : Floor Door
22 : Splitting Door
23 : Swinging Door
25 : Sliding Door (SE 15)
26 : Splitting Star Trek Door
27 : Stretch (SE 20)
28 : Drop Floor (SE 21)
29 : Teeth Door Prong (SE 22)
30 : Rotate and Rise Bridge
31 : Two-Way Train (SE 30)
10+++ : One-Time Sound
32767 : Secret Room
65534 : End Of Level with Message
65535 : End Of Level
/polymer/eduke32/source/funct.h
File deleted
/polymer/eduke32/source/actors.c
21,8 → 21,9
//-------------------------------------------------------------------------
 
#include "duke3d.h"
#include "actors.h"
#include "gamedef.h"
#include "compat.h"
#include "gameexec.h"
 
#if KRANDDEBUG
# define ACTOR_INLINE
95,9 → 96,7
int32_t i=g_numInterpolations-1;
 
if (--g_interpolationLock)
{
return;
}
 
for (; i>=0; i--) *curipos[i] = bakipos[i];
}
663,7 → 662,7
#define LIGHTRAD (s->yrepeat * tilesizy[s->picnum+(T5?(*(intptr_t *)T5) + *(((intptr_t *)T5)+2) * T4:0)])
#define LIGHTRAD2 (((s->yrepeat) + (rand()%(s->yrepeat>>2))) * tilesizy[s->picnum+(T5?(*(intptr_t *)T5) + *(((intptr_t *)T5)+2) * T4:0)])
 
inline void G_AddGameLight(int32_t radius, int32_t srcsprite, int32_t zoffset, int32_t range, int32_t color, int32_t priority)
void G_AddGameLight(int32_t radius, int32_t srcsprite, int32_t zoffset, int32_t range, int32_t color, int32_t priority)
{
#ifdef POLYMER
spritetype *s = &sprite[srcsprite];
1338,7 → 1337,7
x = g_spriteGravity;
}
 
if (s->z < (sector[sect].floorz-FOURSLEIGHT))
if (s->z < (sector[sect].floorz-ZOFFSET))
{
s->zvel += x;
if (s->zvel > 6144)
1696,7 → 1695,7
s->ang = l;
}
 
switch(T1)
switch (T1)
{
default:
p = A_FindPlayer(s,&x);
3224,7 → 3223,7
if (sprite[g_player[p].ps->i].extra > 0)
A_PlaySound(DUKE_UNDERWATER,j);
g_player[p].ps->opos.z = g_player[p].ps->pos.z =
sector[sprite[OW].sectnum].ceilingz;
sector[sprite[OW].sectnum].ceilingz;
 
/*
g_player[p].ps->posvel.x = 4096-(krand()&8192);
3246,7 → 3245,7
A_PlaySound(DUKE_GASP,j);
 
g_player[p].ps->opos.z = g_player[p].ps->pos.z =
sector[sprite[OW].sectnum].floorz;
sector[sprite[OW].sectnum].floorz;
 
g_player[p].ps->jumping_toggle = 1;
g_player[p].ps->jumping_counter = 0;
3732,27 → 3731,27
s->z = sector[sect].ceilingz+(32<<8);
 
#ifdef POLYMER
/*
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].sector = s->sectnum;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].x = s->x;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].y = s->y;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].z = s->z + 10248;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].range = 8192;
/*
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].sector = s->sectnum;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].x = s->x;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].y = s->y;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].z = s->z + 10248;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].range = 8192;
 
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].angle = s->ang;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].horiz = 100;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].radius = 256;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].faderadius = 200;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].angle = s->ang;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].horiz = 100;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].radius = 256;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].faderadius = 200;
 
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].color[0] = 255;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].color[1] = 255;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].color[2] = 255;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].color[0] = 255;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].color[1] = 255;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].color[2] = 255;
 
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].priority = PR_LIGHT_PRIO_MAX_GAME;
gamelights[gamelightcount&(PR_MAXLIGHTS-1)].priority = PR_LIGHT_PRIO_MAX_GAME;
 
if (gamelightcount < PR_MAXLIGHTS)
gamelightcount++;
*/
if (gamelightcount < PR_MAXLIGHTS)
gamelightcount++;
*/
#endif // POLYMER
 
if (!g_netServer && ud.multimode < 2)
4390,7 → 4389,7
{
A_Fall(i);
 
if ((sector[sect].lotag != 1 || actor[i].floorz != sector[sect].floorz) && s->z >= actor[i].floorz-(FOURSLEIGHT) && s->yvel < 3)
if ((sector[sect].lotag != 1 || actor[i].floorz != sector[sect].floorz) && s->z >= actor[i].floorz-(ZOFFSET) && s->yvel < 3)
{
if (s->yvel > 0 || (s->yvel == 0 && actor[i].floorz == sector[sect].floorz))
A_PlaySound(PIPEBOMB_BOUNCE,i);
5163,7 → 5162,7
 
p = A_FindPlayer(s,&x);
 
s->z = actor[i].floorz-(FOURSLEIGHT);
s->z = actor[i].floorz-(ZOFFSET);
 
if (t[2] < 32)
{
5292,7 → 5291,7
if (s->zvel > 4096) s->zvel = 4096;
if (sect < 0) KILLIT(i);
 
if (s->z == actor[i].floorz-(FOURSLEIGHT) && t[0] < 3)
if (s->z == actor[i].floorz-(ZOFFSET) && t[0] < 3)
{
s->zvel = -((3-t[0])<<8)-(krand()&511);
if (sector[sect].lotag == 2)
8005,8 → 8004,8
{
int32_t x, y;
 
if ((s->cstat & 32768) || A_CheckSpriteFlags(i, SPRITE_NOLIGHT) ||
!inside(s->x+((sintable[(s->ang+512)&2047])>>9), s->y+((sintable[(s->ang)&2047])>>9), s->sectnum))
if ((s->cstat & 32768) || A_CheckSpriteFlags(i, SPRITE_NOLIGHT) ||
!inside(s->x+((sintable[(s->ang+512)&2047])>>9), s->y+((sintable[(s->ang)&2047])>>9), s->sectnum))
{
if (actor[i].lightptr != NULL)
{
8078,33 → 8077,33
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), LIGHTRAD, 80+(80<<8)+(255<<16),PR_LIGHT_PRIO_LOW_GAME);
break;
case GROWSPARK__STATIC:
{
int32_t x = ((sintable[(s->ang+512)&2047])>>6);
int32_t y = ((sintable[(s->ang)&2047])>>6);
{
int32_t x = ((sintable[(s->ang+512)&2047])>>6);
int32_t y = ((sintable[(s->ang)&2047])>>6);
 
s->x -= x;
s->y -= y;
s->x -= x;
s->y -= y;
 
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 2048, 255+(95<<8),PR_LIGHT_PRIO_HIGH_GAME);
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 2048, 255+(95<<8),PR_LIGHT_PRIO_HIGH_GAME);
 
s->x += x;
s->y += y;
}
break;
s->x += x;
s->y += y;
}
break;
case SHRINKEREXPLOSION__STATIC:
{
int32_t x = ((sintable[(s->ang+512)&2047])>>6);
int32_t y = ((sintable[(s->ang)&2047])>>6);
{
int32_t x = ((sintable[(s->ang+512)&2047])>>6);
int32_t y = ((sintable[(s->ang)&2047])>>6);
 
s->x -= x;
s->y -= y;
s->x -= x;
s->y -= y;
 
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 2048, 128+(255<<8)+(128<<16),PR_LIGHT_PRIO_HIGH_GAME);
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 2048, 128+(255<<8)+(128<<16),PR_LIGHT_PRIO_HIGH_GAME);
 
s->x += x;
s->y += y;
}
break;
s->x += x;
s->y += y;
}
break;
case FREEZEBLAST__STATIC:
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), LIGHTRAD<<2, 128+(128<<8)+(255<<16),PR_LIGHT_PRIO_HIGH_GAME);
break;
8154,8 → 8153,8
{
int32_t x, y;
 
if ((s->cstat & 32768) || A_CheckSpriteFlags(i, SPRITE_NOLIGHT) ||
!inside(s->x+((sintable[(s->ang+512)&2047])>>9), s->y+((sintable[(s->ang)&2047])>>9), s->sectnum))
if ((s->cstat & 32768) || A_CheckSpriteFlags(i, SPRITE_NOLIGHT) ||
!inside(s->x+((sintable[(s->ang+512)&2047])>>9), s->y+((sintable[(s->ang)&2047])>>9), s->sectnum))
{
if (actor[i].lightptr != NULL)
{
/polymer/eduke32/source/actors.h
0,0 → 1,202
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __actors_h__
#define __actors_h__
 
#define MAXSLEEPDIST 16384
#define SLEEPTIME 1536
#define ZOFFSET (1<<8)
 
#define STAT_DEFAULT 0
#define STAT_ACTOR 1
#define STAT_ZOMBIEACTOR 2
#define STAT_EFFECTOR 3
#define STAT_PROJECTILE 4
#define STAT_MISC 5
#define STAT_STANDABLE 6
#define STAT_LOCATOR 7
#define STAT_ACTIVATOR 8
#define STAT_TRANSPORT 9
#define STAT_PLAYER 10
#define STAT_FX 11
#define STAT_FALLER 12
#define STAT_DUMMYPLAYER 13
 
// Defines the motion characteristics of an actor
enum amoveflags_t {
face_player = 1,
geth = 2,
getv = 4,
random_angle = 8,
face_player_slow = 16,
spin = 32,
face_player_smart = 64,
fleeenemy = 128,
jumptoplayer = 257,
seekplayer = 512,
furthestdir = 1024,
dodgebullet = 4096
};
 
// Defines for 'useractor' keyword
enum uactortypes_t {
notenemy,
enemy,
enemystayput
};
 
#pragma pack(push,1)
typedef struct {
int32_t workslike, cstat; // 8b
int32_t hitradius, range, flashcolor; // 12b
int16_t spawns, sound, isound, vel; // 8b
int16_t decal, trail, tnum, drop; // 8b
int16_t offset, bounces, bsound; // 6b
int16_t toffset; // 2b
int16_t extra, extra_rand; // 4b
int8_t sxrepeat, syrepeat, txrepeat, tyrepeat; // 4b
int8_t shade, xrepeat, yrepeat, pal; // 4b
int8_t velmult; // 1b
uint8_t clipdist; // 1b
int8_t filler[6]; // 6b
} projectile_t;
 
typedef struct {
intptr_t t_data[10]; // 40b/80b sometimes used to hold pointers to con code
 
int16_t picnum,ang,extra,owner; //8b
int16_t movflag,tempang,timetosleep; //6b
 
int32_t flags, bposx,bposy,bposz; //16b
int32_t floorz,ceilingz,lastvx,lastvy; //16b
int32_t lasttransport; //4b
 
int16_t lightId, lightcount, lightmaxrange, cgg; //8b
int16_t actorstayput, dispicnum, shootzvel; // 6b
 
#ifdef POLYMER
_prlight *lightptr; //4b/8b
#else
void *lightptr;
#endif
 
projectile_t *projectile; //4b/8b
 
int8_t filler[16]; // pad struct to 128 bytes
} actor_t;
 
// this struct needs to match the beginning of actor_t above
typedef struct {
intptr_t t_data[10]; // 40b/80b sometimes used to hold pointers to con code
 
int16_t picnum,ang,extra,owner; //8b
int16_t movflag,tempang,timetosleep; // 6b
 
int32_t flags; // 4b
} netactor_t;
#pragma pack(pop)
 
enum sflags_t {
SPRITE_SHADOW = 0x00000001,
SPRITE_NVG = 0x00000002,
SPRITE_NOSHADE = 0x00000004,
SPRITE_PROJECTILE = 0x00000008,
SPRITE_DECAL = 0x00000010,
SPRITE_BADGUY = 0x00000020,
SPRITE_NOPAL = 0x00000040,
SPRITE_NOEVENTCODE = 0x00000080,
SPRITE_NOLIGHT = 0x00000100,
SPRITE_USEACTIVATOR = 0x00000200,
SPRITE_NULL = 0x00000400, // null sprite in multiplayer
};
 
// custom projectiles
enum pflags_t {
PROJECTILE_HITSCAN = 0x00000001,
PROJECTILE_RPG = 0x00000002,
PROJECTILE_BOUNCESOFFWALLS = 0x00000004,
PROJECTILE_BOUNCESOFFMIRRORS = 0x00000008,
PROJECTILE_KNEE = 0x00000010,
PROJECTILE_WATERBUBBLES = 0x00000020,
PROJECTILE_TIMED = 0x00000040,
PROJECTILE_BOUNCESOFFSPRITES = 0x00000080,
PROJECTILE_SPIT = 0x00000100,
PROJECTILE_COOLEXPLOSION1 = 0x00000200,
PROJECTILE_BLOOD = 0x00000400,
PROJECTILE_LOSESVELOCITY = 0x00000800,
PROJECTILE_NOAIM = 0x00001000,
PROJECTILE_RANDDECALSIZE = 0x00002000,
PROJECTILE_EXPLODEONTIMER = 0x00004000,
PROJECTILE_RPG_IMPACT = 0x00008000,
PROJECTILE_RADIUS_PICNUM = 0x00010000,
PROJECTILE_ACCURATE_AUTOAIM = 0x00020000,
PROJECTILE_FORCEIMPACT = 0x00040000,
PROJECTILE_REALCLIPDIST = 0x00080000,
PROJECTILE_ACCURATE = 0x00100000,
};
 
extern actor_t actor[MAXSPRITES];
extern char ActorType[MAXTILES];
extern int16_t SpriteCacheList[MAXTILES][3];
extern int32_t SpriteFlags[MAXTILES];
extern int32_t block_deletesprite;
extern int32_t g_noEnemies;
extern int32_t otherp;
extern int32_t ticrandomseed;
extern intptr_t *actorLoadEventScrptr[MAXTILES];
extern intptr_t *actorscrptr[MAXTILES];
extern intptr_t *g_parsingActorPtr;
extern projectile_t DefaultProjectileData[MAXTILES];
extern projectile_t ProjectileData[MAXTILES];
extern projectile_t SpriteProjectile[MAXSPRITES];
 
void A_AddToDeleteQueue(int32_t i);
int32_t A_CheckEnemySprite(spritetype *s);
int32_t A_CheckEnemyTile(int32_t pn);
int32_t A_CheckSwitchTile(int32_t i);
void A_DeleteSprite(int32_t s);
void A_DoGuts(int32_t sp,int32_t gtype,int32_t n);
void A_DoGutsDir(int32_t sp,int32_t gtype,int32_t n);
int32_t A_IncurDamage(int32_t sn);
void A_MoveCyclers(void);
void A_MoveDummyPlayers(void);
int32_t A_MoveSprite(int32_t spritenum,const vec3_t *change,uint32_t cliptype);
void A_PlayAlertSound(int32_t i);
void A_RadiusDamage(int32_t i,int32_t r,int32_t hp1,int32_t hp2,int32_t hp3,int32_t hp4);
int32_t A_SetSprite(int32_t i,uint32_t cliptype);
void A_SpawnMultiple(int32_t sp,int32_t pic,int32_t n);
 
void G_AddGameLight(int32_t radius,int32_t srcsprite,int32_t zoffset,int32_t range,int32_t color,int32_t priority);
int32_t G_CheckForSpaceCeiling(int32_t sectnum);
int32_t G_CheckForSpaceFloor(int32_t sectnum);
void G_DoInterpolations(int32_t smoothratio);
void G_MoveWorld(void);
extern inline void G_RestoreInterpolations(void);
void G_SetInterpolation(int32_t *posptr);
void G_StopInterpolation(int32_t *posptr);
extern inline void G_UpdateInterpolations(void);
 
void Sect_ClearInterpolation(int32_t i);
void Sect_SetInterpolation(int32_t i);
 
#endif
/polymer/eduke32/source/anim.h
0,0 → 1,35
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __anim_h__
#define __anim_h__
 
void G_PlayAnim(const char *fn,char t);
void endanimvol43(int32_t fr);
void endanimvol42(int32_t fr);
void endanimvol41(int32_t fr);
void intro42animsounds(int32_t fr);
void first4animsounds(int32_t fr);
void intro4animsounds(int32_t fr);
void logoanimsounds(int32_t fr);
void endanimsounds(int32_t fr);
#endif
/polymer/eduke32/source/astub.c
381,7 → 381,7
{
int32_t i = 0;
spritetype *tspri = (spritetype *)Bcalloc(1, sizeof(spritetype) * numsprites),
*spri = &tspri[0];
*spri = &tspri[0];
mapstate->sprites = (spritetype *)Bcalloc(1, sizeof(spritetype) * numsprites);
 
for (j=0; j<MAXSPRITES && i < numsprites; j++)
813,7 → 813,8
{
static char tempbuf[64];
 
static const char *tags[] = {
static const char *tags[] =
{
"ROTATED SECTOR", // 0
"PIVOT SPRITE FOR SE 0",
"EARTHQUAKE",
1692,7 → 1693,7
Bmemcpy(disptext[i], helppage[curhp]->line[j], 80);
printext16(8, ydim-overridepm16y+28+i*9, editorcolors[10],
(j==highlightline && curhp==highlighthp
&& totalclock-lasthighlighttime<120*5) ?
&& totalclock-lasthighlighttime<120*5) ?
editorcolors[1] : -1,
disptext[i], 0);
}
1864,7 → 1865,7
// SoundToggle = 1;
 
while (keystatus[KEYSC_ESC]==0 && keystatus[KEYSC_Q]==0 && keystatus[KEYSC_F2]==0
&& keystatus[buildkeys[BK_MODE2D_3D]]==0) // quickjump to 3d mode
&& keystatus[buildkeys[BK_MODE2D_3D]]==0) // quickjump to 3d mode
{
begindrawing();
CLEARLINES2D(0, ydim16, 0);
2101,7 → 2102,7
{
if ((g_sounds[s->lotag].m&2))
{
x = dist((spritetype*)&pos,s);
x = dist((spritetype *)&pos,s);
if (x < ht && (T1&1) == 0 && FX_VoiceAvailable(g_sounds[s->lotag].pr-1))
{
if (g_numEnvSoundsPlaying == NumVoices)
2109,7 → 2110,7
for (j = headspritestat[0]; j >= 0; j = nextspritestat[j])
{
if (s->picnum == MUSICANDSFX && j != i && sprite[j].lotag < 999 &&
(sprite[j].filler&1) == 1 && dist(&sprite[j],(spritetype*)&pos) > x)
(sprite[j].filler&1) == 1 && dist(&sprite[j],(spritetype *)&pos) > x)
{
S_StopEnvSound(sprite[j].lotag,j);
break;
2341,7 → 2342,7
for (j=0; j<MAXSPRITES; j++) // restore ceiling or floor for the draw both sectors
{
if (sprite[j].picnum==SECTOREFFECTOR &&
sprite[j].lotag==k+2 && sprite[j].hitag==sprite[floor1].hitag)
sprite[j].lotag==k+2 && sprite[j].hitag==sprite[floor1].hitag)
{
if (k==40)
{
3205,7 → 3206,7
return iTile;
}
 
static const char * GetTilePixels(int32_t idTile)
static const char *GetTilePixels(int32_t idTile)
{
char *pPixelData = 0;
 
3229,7 → 3230,7
int32_t XPos, YPos;
int32_t XOffset, YOffset;
int32_t i;
const char * pRawPixels;
const char *pRawPixels;
int32_t TileSizeX, TileSizeY;
int32_t DivInc,MulInc;
char *pScreen;
4034,8 → 4035,8
break;
 
case SEARCH_SPRITE:
drawtileinfo("Current", WIND1X, WIND1Y, sprite[searchwall].picnum, sprite[searchwall].shade,
sprite[searchwall].pal, sprite[searchwall].cstat, sprite[searchwall].lotag,
drawtileinfo("Current", WIND1X, WIND1Y, sprite[searchwall].picnum, sprite[searchwall].shade,
sprite[searchwall].pal, sprite[searchwall].cstat, sprite[searchwall].lotag,
sprite[searchwall].hitag, sprite[searchwall].extra);
 
Bsprintf(lines[num++], "Repeat: %d,%d", sprite[searchwall].xrepeat, sprite[searchwall].yrepeat);
4285,7 → 4286,7
tsign -= PRESSED_KEYSC(COMMA);
tsign += PRESSED_KEYSC(PERIOD);;
 
if (tsign) // , . Search & fix panning to the left/right (3D)
if (tsign) // , . Search & fix panning to the left/right (3D)
{
if (AIMING_AT_SPRITE)
{
4551,9 → 4552,8
if (sector[highlightsector[i]].visibility == 240)
sector[highlightsector[i]].visibility = 239;
}
else
if (sector[highlightsector[i]].visibility == 239)
sector[highlightsector[i]].visibility = 240;
else if (sector[highlightsector[i]].visibility == 239)
sector[highlightsector[i]].visibility = 240;
}
k--;
}
4569,9 → 4569,8
if (sector[searchsector].visibility == 240)
sector[searchsector].visibility = 239;
}
else
if (sector[searchsector].visibility == 239)
sector[searchsector].visibility = 240;
else if (sector[searchsector].visibility == 239)
sector[searchsector].visibility = 240;
k--;
}
message("Sector %d visibility %d",searchsector,sector[searchsector].visibility);
4798,8 → 4797,8
if (AIMING_AT_WALL || AIMING_AT_CEILING)
{
int16_t sect = k ? highlightsector[0] :
((AIMING_AT_WALL && eitherSHIFT && wall[searchwall].nextsector>=0) ?
wall[searchwall].nextsector : searchsector);
((AIMING_AT_WALL && eitherSHIFT && wall[searchwall].nextsector>=0) ?
wall[searchwall].nextsector : searchsector);
 
for (j=0; j<(k?k:1); j++, sect=highlightsector[j])
{
5210,7 → 5209,7
}
}
else
sprite[searchwall].lotag = getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0);
sprite[searchwall].lotag = getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0);
}
}
 
6243,7 → 6242,7
{
if (did_wrap)
break;
 
did_wrap = 1;
gs_cursprite &= (MAXSPRITES-1);
}
6373,11 → 6372,11
{
static int32_t counter = 0;
static int32_t omx = 0, omy = 0;
/*
static int32_t opointhighlight, olinehighlight, ocursectornum;
/*
static int32_t opointhighlight, olinehighlight, ocursectornum;
 
if (pointhighlight == opointhighlight && linehighlight == olinehighlight && cursectornum == ocursectornum)
*/
if (pointhighlight == opointhighlight && linehighlight == olinehighlight && cursectornum == ocursectornum)
*/
if (omx == mousxplc && omy == mousyplc)
{
if (counter < 6)
6385,15 → 6384,15
}
else if (counter > 0)
counter--;
 
omx = mousxplc;
omy = mousyplc;
 
/*
opointhighlight = pointhighlight;
olinehighlight = linehighlight;
ocursectornum = cursectornum;
*/
/*
opointhighlight = pointhighlight;
olinehighlight = linehighlight;
ocursectornum = cursectornum;
*/
 
if (counter >= 2 && totalclock >= 120*6)
{
6433,7 → 6432,7
extern int32_t showtags;
 
showtags ^= 1;
printmessage16("Show tags %s", ONOFF( showtags));
printmessage16("Show tags %s", ONOFF(showtags));
}
else if (eitherALT) //ALT
{
6659,8 → 6658,8
for (i=curwallnum; i>=0 && i<numwalls; i+=tsign)
{
if ((wall[i].picnum==wall[curwall].picnum)
&& (search_lotag==0 || search_lotag==wall[i].lotag)
&& (search_hitag==0 || search_hitag==wall[i].hitag))
&& (search_lotag==0 || search_lotag==wall[i].lotag)
&& (search_hitag==0 || search_hitag==wall[i].hitag))
{
pos.x = wall[i].x - (wall[i].x-POINT2(i).x)/2;
pos.y = wall[i].y - (wall[i].y-POINT2(i).y)/2;
6971,7 → 6970,7
int32_t i = 1, j, maxlen=0, *lengths;
char *c, *k;
 
mapster32_fullpath = (char*)argv[0];
mapster32_fullpath = (char *)argv[0];
 
if (argc > 1)
{
7339,7 → 7338,7
if (!Bstrcasecmp(parm->name, "pk_turnaccel"))
{
if (showval)
OSD_Printf("Turning acceleration+declaration is %d\n", pk_turnaccel);
OSD_Printf("Turning acceleration+declaration is %d\n", pk_turnaccel);
else
{
pk_turnaccel = atoi(parm->parms[0]);
7350,7 → 7349,7
else if (!Bstrcasecmp(parm->name, "pk_turndecel"))
{
if (showval)
OSD_Printf("Turning deceleration is %d\n", pk_turndecel);
OSD_Printf("Turning deceleration is %d\n", pk_turndecel);
else
{
pk_turndecel = atoi(parm->parms[0]);
7367,7 → 7366,7
else if (!Bstrcasecmp(parm->name, "pk_uedaccel"))
{
if (showval)
OSD_Printf("UnrealEd mouse navigation acceleration is %d\n", pk_uedaccel);
OSD_Printf("UnrealEd mouse navigation acceleration is %d\n", pk_uedaccel);
else
{
pk_uedaccel = atoi(parm->parms[0]);
8609,7 → 8608,7
GAME_getrowheight,*/
0,0,0,0,0,
GAME_clearbackground,
(int32_t(*)(void))GetTime,
(int32_t( *)(void))GetTime,
NULL
);
#endif
9298,7 → 9297,7
NULL,
NULL,
NULL,
(int32_t(*)(void))GetTime,
(int32_t( *)(void))GetTime,
NULL
);
}
9312,7 → 9311,7
GAME_getrowheight,*/
0,0,0,0,0,
GAME_clearbackground,
(int32_t(*)(void))GetTime,
(int32_t( *)(void))GetTime,
NULL
);
}
10213,7 → 10212,7
char edittext[80];
static int32_t col=0, row=0;
int32_t i, j, k;
int32_t rowmax[3]={6,5,6}, dispwidth[3] = {24,24,28};
int32_t rowmax[3]= {6,5,6}, dispwidth[3] = {24,24,28};
int32_t xpos[3] = {8,200,400}, ypos = ydim-STATUS2DSIZ+48;
 
static char *labels[7][3] =
/polymer/eduke32/source/config.c
51,7 → 51,7
 
hashtable_t h_gamefuncs = { NUMGAMEFUNCTIONS<<1, NULL };
 
int32_t CONFIG_FunctionNameToNum(char * func)
int32_t CONFIG_FunctionNameToNum(char *func)
{
int32_t i;
 
77,7 → 77,7
===================
*/
 
char * CONFIG_FunctionNumToName(int32_t func)
char *CONFIG_FunctionNumToName(int32_t func)
{
if ((unsigned)func >= (unsigned)NUMGAMEFUNCTIONS)
return NULL;
93,7 → 93,7
*/
 
 
int32_t CONFIG_AnalogNameToNum(char * func)
int32_t CONFIG_AnalogNameToNum(char *func)
{
 
if (!Bstrcasecmp(func,"analog_turning"))
117,7 → 117,7
}
 
 
char * CONFIG_AnalogNumToName(int32_t func)
char *CONFIG_AnalogNumToName(int32_t func)
{
switch (func)
{
712,38 → 712,38
SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "ScreenBPP", &ud.config.ScreenBPP);
if (ud.config.ScreenBPP < 8) ud.config.ScreenBPP = 32;
 
#ifdef POLYMER
#ifdef POLYMER
SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "Polymer", &dummy);
if (dummy > 0 && ud.config.ScreenBPP >= 16) glrendmode = 4;
else glrendmode = 3;
#endif
 
/*
/*
 
SCRIPT_GetNumber(ud.config.scripthandle, "Misc", "Color",&ud.color);
G_CheckPlayerColor((int32_t *)&ud.color,-1);
g_player[0].ps->palookup = g_player[0].pcolor = ud.color;
tempbuf[0] = 0;
SCRIPT_GetString(ud.config.scripthandle, "Misc", "CrosshairColor",&tempbuf[0]);
if (tempbuf[0])
{
char *ptr = strtok(tempbuf,",");
palette_t temppal;
char *palptr = (char *)&temppal;
SCRIPT_GetNumber(ud.config.scripthandle, "Misc", "Color",&ud.color);
G_CheckPlayerColor((int32_t *)&ud.color,-1);
g_player[0].ps->palookup = g_player[0].pcolor = ud.color;
tempbuf[0] = 0;
SCRIPT_GetString(ud.config.scripthandle, "Misc", "CrosshairColor",&tempbuf[0]);
if (tempbuf[0])
{
char *ptr = strtok(tempbuf,",");
palette_t temppal;
char *palptr = (char *)&temppal;
 
i = 0;
while (ptr != NULL && i < 3)
{
palptr[i++] = atoi(ptr);
ptr = strtok(NULL,",");
}
if (i == 3)
{
Bmemcpy(&CrosshairColors,&temppal,sizeof(palette_t));
DefaultCrosshairColors.f = 1;
}
}
*/
i = 0;
while (ptr != NULL && i < 3)
{
palptr[i++] = atoi(ptr);
ptr = strtok(NULL,",");
}
if (i == 3)
{
Bmemcpy(&CrosshairColors,&temppal,sizeof(palette_t));
DefaultCrosshairColors.f = 1;
}
}
*/
 
SCRIPT_GetNumber(ud.config.scripthandle, "Misc", "Executions",&ud.executions);
 
/polymer/eduke32/source/config.h
37,4 → 37,11
 
void CONFIG_MapKey(int32_t which, kb_scancode key1, kb_scancode oldkey1, kb_scancode key2, kb_scancode oldkey2);
 
int32_t CONFIG_FunctionNameToNum(char *func);
char *CONFIG_FunctionNumToName(int32_t func);
int32_t CONFIG_AnalogNameToNum(char *func);
char *CONFIG_AnalogNumToName(int32_t func);
void CONFIG_SetDefaults(void);
void CONFIG_ReadKeys(void);
 
#endif
/polymer/eduke32/source/demo.c
0,0 → 1,696
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#include "duke3d.h"
#include "demo.h"
 
char firstdemofile[80] = { '\0' };
 
FILE *g_demo_filePtr = (FILE *)NULL;
int32_t g_demo_cnt;
int32_t g_demo_goalCnt=0;
int32_t g_demo_totalCnt;
int32_t g_demo_soundToggle;
int32_t g_demo_paused=0;
int32_t g_demo_rewind=0;
int32_t g_demo_showStats=1;
int32_t g_demo_recFilePtr;
 
static int32_t demo_hasdiffs, demorec_diffs=1, demorec_difftics = 2*(TICRATE/TICSPERFRAME);
int32_t demoplay_diffs=1;
int32_t demorec_diffs_cvar=1;
int32_t demorec_force_cvar=0;
int32_t demorec_difftics_cvar = 2*(TICRATE/TICSPERFRAME);
int32_t demorec_diffcompress_cvar=1;
int32_t demorec_synccompress_cvar=1;
int32_t demorec_seeds_cvar=1;
int32_t demoplay_showsync=1;
 
static int32_t demo_synccompress=1, demorec_seeds=1, demo_hasseeds;
 
static void dorestoremodes(int32_t menu)
{
if (menu) g_player[myconnectindex].ps->gm |= MODE_MENU;
else g_player[myconnectindex].ps->gm &= ~MODE_MENU;
g_player[myconnectindex].ps->gm &= ~MODE_GAME;
g_player[myconnectindex].ps->gm |= MODE_DEMO;
}
 
void demo_preparewarp(void)
{
if (!g_demo_paused)
{
g_demo_soundToggle = ud.config.SoundToggle;
ud.config.SoundToggle = 0;
}
FX_StopAllSounds();
S_ClearSoundLocks();
}
 
extern int32_t sv_loadsnapshot(int32_t fil, int32_t *ret_hasdiffs, int32_t *ret_demoticcnt, int32_t *ret_synccompress);
 
int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
{
char d[14];
int32_t i;
 
Bstrcpy(d, "edemo_.edm");
 
if (g_whichDemo == 10)
d[5] = 'x';
else
d[5] = '0' + g_whichDemo;
 
if (g_whichDemo == 1 && firstdemofile[0] != 0)
{
if ((g_demo_recFilePtr = kopen4loadfrommod(firstdemofile,g_loadFromGroupOnly)) == -1) return(0);
}
else if ((g_demo_recFilePtr = kopen4loadfrommod(d,g_loadFromGroupOnly)) == -1) return(0);
 
i=sv_loadsnapshot(g_demo_recFilePtr, &demo_hasdiffs, &g_demo_totalCnt, &demo_synccompress);
if (i==0)
{
demo_hasseeds = demo_synccompress&2;
demo_synccompress &= 1;
 
i = g_demo_totalCnt/(TICRATE/TICSPERFRAME);
OSD_Printf("demo duration: %d min %d sec\n", i/60, i%60);
 
g_demo_cnt=1;
ud.reccnt = 0;
 
ud.god = ud.cashman = ud.eog = ud.showallmap = 0;
ud.clipping = ud.scrollmode = ud.overhead_on = 0; //= ud.pause_on = 0;
 
// G_NewGame(ud.volume_number,ud.level_number,ud.player_skill);
// G_ResetTimers();
totalclock = ototalclock = lockclock = 0;
 
return 1;
}
else
{
OSD_Printf(OSD_ERROR "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
kclose(g_demo_recFilePtr);
return 0;
}
#if 0
corrupt:
OSD_Printf(OSD_ERROR "Demo %d header is corrupt.\n",g_whichDemo);
ud.reccnt = 0;
kclose(g_demo_recFilePtr);
return 0;
#endif
}
 
#if KRANDDEBUG
extern void krd_enable(int32_t which);
extern int32_t krd_print(const char *filename);
#endif
 
void G_OpenDemoWrite(void)
{
char d[14];
int32_t i, demonum=1;
extern int32_t sv_saveandmakesnapshot(FILE* fil, int32_t recdiffs, int32_t diffcompress, int32_t synccompress);
 
if (ud.recstat == 2) kclose(g_demo_recFilePtr);
 
if ((g_player[myconnectindex].ps->gm&MODE_GAME) && g_player[myconnectindex].ps->dead_flag)
{
Bstrcpy(ScriptQuotes[122], "CANNOT START DEMO RECORDING WHEN DEAD!");
P_DoQuote(122, g_player[myconnectindex].ps);
ud.recstat = ud.m_recstat = 0;
return;
}
 
if (demorec_diffs_cvar && !demorec_force_cvar)
for (i=1; i<g_scriptSize-2; i++)
{
intptr_t w=script[i];
if ((w&0x0fff)==CON_RESIZEARRAY && (w>>12) && script[i+1]>=0 && script[i+1]<g_gameArrayCount)
{
OSD_Printf("\nThe CON code possibly contains a RESIZEARRAY command.\n");
OSD_Printf("Gamearrays that change their size during the game are unsupported by\n");
OSD_Printf("the demo recording system. If you are sure that the code doesn't\n");
OSD_Printf("contain a RESIZEARRAY command, you can force recording with the\n");
OSD_Printf("`demorec_force' cvar. Alternatively, you can disable diff recording\n");
OSD_Printf("with the `demorec_diffs' cvar.\n\n");
Bstrcpy(ScriptQuotes[122], "FAILED STARTING DEMO RECORDING. SEE OSD FOR DETAILS.");
P_DoQuote(122, g_player[myconnectindex].ps);
ud.recstat = ud.m_recstat = 0;
return;
}
}
 
while (1)
{
if (demonum == 10000) return;
Bsprintf(d, "edemo%d.edm", demonum++);
g_demo_filePtr = fopen(d, "rb");
if (g_demo_filePtr == NULL) break;
Bfclose(g_demo_filePtr);
}
 
if ((g_demo_filePtr = fopen(d,"wb")) == NULL) return;
 
i=sv_saveandmakesnapshot(g_demo_filePtr, demorec_diffs_cvar, demorec_diffcompress_cvar,
demorec_synccompress_cvar|(demorec_seeds_cvar<<1));
if (i)
{
Bstrcpy(ScriptQuotes[122], "FAILED STARTING DEMO RECORDING. SEE OSD FOR DETAILS.");
P_DoQuote(122, g_player[myconnectindex].ps);
Bfclose(g_demo_filePtr), g_demo_filePtr=NULL;
ud.recstat = ud.m_recstat = 0;
return;
}
demorec_seeds = demorec_seeds_cvar;
demorec_diffs = demorec_diffs_cvar;
demo_synccompress = demorec_synccompress_cvar;
demorec_difftics = demorec_difftics_cvar;
 
Bstrcpy(ScriptQuotes[122], "DEMO RECORDING STARTED");
P_DoQuote(122, g_player[myconnectindex].ps);
 
ud.reccnt = 0;
ud.recstat = ud.m_recstat = 1; //
 
#if KRANDDEBUG
krd_enable(1);
#endif
 
g_demo_cnt = 1;
}
 
 
static uint8_t g_demo_seedbuf[RECSYNCBUFSIZ];
 
static void dowritesync()
{
int16_t tmpreccnt;
 
fwrite("sYnC", 4, 1, g_demo_filePtr);
tmpreccnt = (int16_t)ud.reccnt;
fwrite(&tmpreccnt, sizeof(int16_t), 1, g_demo_filePtr);
if (demorec_seeds)
fwrite(g_demo_seedbuf, 1, ud.reccnt, g_demo_filePtr);
 
if (demo_synccompress)
dfwrite(recsync, sizeof(input_t), ud.reccnt, g_demo_filePtr);
else //if (demo_synccompress==0)
fwrite(recsync, sizeof(input_t), ud.reccnt, g_demo_filePtr);
ud.reccnt = 0;
}
 
void G_DemoRecord(void)
{
int16_t i;
extern uint32_t sv_writediff(FILE *fil);
 
g_demo_cnt++;
 
if (demorec_diffs && (g_demo_cnt%demorec_difftics == 1))
{
sv_writediff(g_demo_filePtr);
demorec_difftics = demorec_difftics_cvar;
}
 
if (demorec_seeds)
g_demo_seedbuf[ud.reccnt] = (uint8_t)(randomseed>>24);
 
TRAVERSE_CONNECT(i)
{
Bmemcpy(&recsync[ud.reccnt], g_player[i].sync, sizeof(input_t));
ud.reccnt++;
}
 
if (ud.reccnt > RECSYNCBUFSIZ-MAXPLAYERS || (demorec_diffs && (g_demo_cnt%demorec_difftics == 0)))
dowritesync();
}
 
void G_CloseDemoWrite(void)
{
extern void sv_freemem();
 
if (ud.recstat == 1)
{
if (ud.reccnt > 0)
dowritesync();
 
fwrite("EnD!", 4, 1, g_demo_filePtr);
 
if (fseek(g_demo_filePtr, 20, SEEK_SET))
perror("G_CloseDemoWrite: fseek");
else
fwrite(&g_demo_cnt, sizeof(g_demo_cnt), 1, g_demo_filePtr);
 
ud.recstat = ud.m_recstat = 0;
fclose(g_demo_filePtr);
 
sv_freemem();
 
Bstrcpy(ScriptQuotes[122], "DEMO RECORDING STOPPED");
P_DoQuote(122, g_player[myconnectindex].ps);
}
#if KRANDDEBUG
krd_print("krandrec.log");
#endif
}
 
static int32_t g_whichDemo = 1;
extern int32_t sv_updatestate(int32_t frominit);
 
static int32_t doupdatestate(int32_t frominit)
{
int32_t j,k;
j = g_player[myconnectindex].ps->gm&MODE_MENU;
k = sv_updatestate(frominit);
// tmpdifftime = g_demo_cnt+12;
dorestoremodes(j);
if (k) OSD_Printf("sv_updatestate() returned %d.\n", k);
return k;
}
 
#define CORRUPT(code) do { corruptcode=code; goto corrupt; } while(0)
 
#define DOREADSYNC(code) do \
{ \
uint16_t si; \
int32_t i; \
if (kread(g_demo_recFilePtr, &si, sizeof(uint16_t)) != (int32_t)sizeof(uint16_t)) CORRUPT(code); \
i = si; \
if (demo_hasseeds) \
{ \
if (kread(g_demo_recFilePtr, g_demo_seedbuf, i) != i) CORRUPT(code); \
} \
if (demo_synccompress) \
{ \
if (kdfread(recsync, sizeof(input_t), i, g_demo_recFilePtr) != i) CORRUPT(code+1); \
} \
else \
if (kread(g_demo_recFilePtr, recsync, sizeof(input_t)*i) != (int32_t)sizeof(input_t)*i) CORRUPT(code+2); \
ud.reccnt = i; \
} while (0)
 
 
int32_t G_PlaybackDemo(void)
{
int32_t bigi, j, k, initsyncofs = 0, lastsyncofs = 0, lastsynctic = 0, lastsyncclock = 0;
int32_t foundemo = 0, corruptcode, outofsync=0;
static int32_t in_menu = 0;
// static int32_t tmpdifftime=0;
 
if (ready2send) return 0;
 
RECHECK:
 
#if KRANDDEBUG
if (foundemo)
krd_print("krandplay.log");
#endif
 
in_menu = g_player[myconnectindex].ps->gm&MODE_MENU;
 
pub = NUMPAGES;
pus = NUMPAGES;
 
flushperms();
if ((!g_netServer && ud.multimode < 2)) foundemo = G_OpenDemoRead(g_whichDemo);
if (foundemo == 0)
{
if (g_whichDemo > 1)
{
g_whichDemo = 1;
goto RECHECK;
}
fadepal(0,0,0, 0,63,7);
P_SetGamePalette(g_player[myconnectindex].ps, palette, 1); // JBF 20040308
G_DrawBackground();
M_DisplayMenus();
//g_player[myconnectindex].ps->palette = palette;
nextpage();
fadepal(0,0,0, 63,0,-7);
ud.reccnt = 0;
}
else
{
ud.recstat = 2;
g_whichDemo++;
if (g_whichDemo == 10) g_whichDemo = 1;
 
g_player[myconnectindex].ps->gm &= ~MODE_GAME;
g_player[myconnectindex].ps->gm |= MODE_DEMO;
 
// if (G_EnterLevel(MODE_DEMO))
// {
// OSD_Printf("G_PlaybackDemo: G_EnterLevel\n");
// ud.recstat = foundemo = 0;
// }
//
lastsyncofs = ktell(g_demo_recFilePtr);
initsyncofs = lastsyncofs;
lastsynctic = g_demo_cnt;
lastsyncclock = totalclock;
outofsync = 0;
#if KRANDDEBUG
krd_enable(2);
#endif
}
 
if (foundemo == 0 || in_menu || KB_KeyWaiting() || numplayers > 1)
{
FX_StopAllSounds();
S_ClearSoundLocks();
g_player[myconnectindex].ps->gm |= MODE_MENU;
}
 
ready2send = 0;
bigi = 0;
 
KB_FlushKeyboardQueue();
 
// OSD_Printf("ticcnt=%d, total=%d\n", g_demo_cnt, g_demo_totalCnt);
while (g_demo_cnt < g_demo_totalCnt || foundemo==0)
{
if (foundemo && (!g_demo_paused || g_demo_goalCnt))
{
if (g_demo_goalCnt>0 && g_demo_goalCnt < g_demo_cnt) // rewind
{
k = g_player[myconnectindex].ps->gm&MODE_MENU;
if (g_demo_goalCnt > lastsynctic)
{
if (doupdatestate(0)==0)
{
g_demo_cnt = lastsynctic;
klseek(g_demo_recFilePtr, lastsyncofs, SEEK_SET);
ud.reccnt = 0;
 
totalclock = ototalclock = lockclock = lastsyncclock;
}
else CORRUPT(-1);
}
else
{
//loadfrombeg:
// j = sv_loadsnapshot(g_demo_recFilePtr, &g_demo_totalCnt);
j = doupdatestate(1);
if (!j)
{
klseek(g_demo_recFilePtr, initsyncofs, SEEK_SET);
g_levelTextTime = 0;
 
g_demo_cnt = 1;
ud.reccnt = 0;
 
// ud.god = ud.cashman = ud.eog = ud.showallmap = 0;
// ud.clipping = ud.scrollmode = ud.overhead_on = ud.pause_on = 0;
 
totalclock = ototalclock = lockclock = 0;
}
else CORRUPT(0);
}
dorestoremodes(k);
}
 
while (totalclock >= (lockclock+TICSPERFRAME)
// || (ud.reccnt > (TICRATE/TICSPERFRAME)*2 && ud.pause_on)
|| (g_demo_goalCnt>0 && g_demo_cnt<g_demo_goalCnt))
{
if (ud.reccnt<=0)
{
char tmpbuf[4];
 
if (ud.reccnt<0)
{
OSD_Printf("G_PlaybackDemo: ud.reccnt<0!\n");
CORRUPT(1);
}
 
bigi = 0;
//reread:
if (kread(g_demo_recFilePtr, tmpbuf, 4) != 4) CORRUPT(2);
 
if (Bmemcmp(tmpbuf, "sYnC", 4)==0)
DOREADSYNC(3);
else if (demo_hasdiffs && Bmemcmp(tmpbuf, "dIfF", 4)==0)
{
extern int32_t sv_readdiff(int32_t fil);
 
k=sv_readdiff(g_demo_recFilePtr);
if (k)
{
OSD_Printf("sv_readdiff() returned %d.\n", k);
CORRUPT(6);
}
else
{
lastsyncofs = ktell(g_demo_recFilePtr);
lastsynctic = g_demo_cnt;
lastsyncclock = totalclock;
if (kread(g_demo_recFilePtr, tmpbuf, 4) != 4) CORRUPT(7);
if (Bmemcmp(tmpbuf, "sYnC", 4)) CORRUPT(8);
DOREADSYNC(9);
 
if ((g_demo_goalCnt==0 && demoplay_diffs) ||
(g_demo_goalCnt>0 && ud.reccnt/ud.multimode >= g_demo_goalCnt-g_demo_cnt))
{
doupdatestate(0);
}
}
}
else if (Bmemcmp(tmpbuf, "EnD!", 4)==0)
goto nextdemo;
else CORRUPT(12);
 
if (0)
{
corrupt:
OSD_Printf(OSD_ERROR "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
nextdemo:
foundemo = 0;
ud.reccnt = 0;
kclose(g_demo_recFilePtr);
g_player[myconnectindex].ps->gm |= MODE_MENU;
if (g_demo_goalCnt>0)
{
g_demo_goalCnt=0;
ud.config.SoundToggle = g_demo_soundToggle;
}
goto RECHECK;
}
}
 
if (demo_hasseeds)
outofsync = (uint8_t)(randomseed>>24) != g_demo_seedbuf[bigi];
 
TRAVERSE_CONNECT(j)
{
copybufbyte(&recsync[bigi], &inputfifo[0][j], sizeof(input_t));
bigi++;
ud.reccnt--;
}
g_demo_cnt++;
 
if (!g_demo_paused)
{
// assumption that ud.multimode doesn't change in a demo may not be true
// sometime in the future v v v v v v v v v
if (g_demo_goalCnt==0 || !demo_hasdiffs || ud.reccnt/ud.multimode>=g_demo_goalCnt-g_demo_cnt)
G_DoMoveThings(); // increases lockclock by TICSPERFRAME
else
lockclock += TICSPERFRAME;
}
else
{
k = ud.config.SoundToggle;
ud.config.SoundToggle = 0;
G_DoMoveThings();
ud.config.SoundToggle = k;
}
 
ototalclock += TICSPERFRAME;
 
if (g_demo_goalCnt > 0)
{
totalclock += TICSPERFRAME;
 
// OSD_Printf("t:%d, l+T:%d; cnt:%d, goal:%d%s", totalclock, (lockclock+TICSPERFRAME),
// g_demo_cnt, g_demo_goalCnt, g_demo_cnt>=g_demo_goalCnt?" ":"\n");
if (g_demo_cnt>=g_demo_goalCnt)
{
g_demo_goalCnt = 0;
ud.config.SoundToggle = g_demo_soundToggle;
}
}
}
}
else if (foundemo && g_demo_paused)
{
totalclock = lockclock;
}
 
if (foundemo == 0)
G_DrawBackground();
else
{
G_HandleLocalKeys();
 
// j = min(max((totalclock-lockclock)*(65536/TICSPERFRAME),0),65536);
 
j = min(max((totalclock - ototalclock) * (65536 / 4),0),65536);
if (g_demo_paused && g_demo_rewind)
j = 65536-j;
 
G_DrawRooms(screenpeek,j);
G_DisplayRest(j);
 
if ((g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
{
if (demoplay_showsync && outofsync)
gametext(160,100,"OUT OF SYNC",0,2+8+16);
 
if (g_demo_showStats)
{
// if (g_demo_cnt<tmpdifftime)
// gametext(160,100,"DIFF",0,2+8+16);
// {
// char buf[32];
// Bsprintf(buf, "RC:%4d TC:%5d", ud.reccnt, g_demo_cnt);
// gametext(160,100,buf,0,2+8+16);
// }
 
j=g_demo_cnt/(TICRATE/TICSPERFRAME);
Bsprintf(buf, "%02d:%02d", j/60, j%60);
gametext(18,16,buf,0,2+8+16);
 
rotatesprite(60<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16,0,0,(xdim*95)/320,ydim-1);
rotatesprite(90<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16,(xdim*95)/320,0,(xdim*125)/320,ydim-1);
rotatesprite(120<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16,(xdim*125)/320,0,(xdim*155)/320,ydim-1);
rotatesprite(150<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16,(xdim*155)/320,0,xdim-1,ydim-1);
 
j = (182<<16) - ((((120*(g_demo_totalCnt-g_demo_cnt))<<4)/g_demo_totalCnt)<<12);
rotatesprite(j,(16<<16)+(1<<15),32768,0,SLIDEBAR+1,0,0,2+8+16,0,0,xdim-1,ydim-1);
 
j=(g_demo_totalCnt-g_demo_cnt)/(TICRATE/TICSPERFRAME);
Bsprintf(buf, "-%02d:%02d%s", j/60, j%60, g_demo_paused?" ^15PAUSED":"");
gametext(194,16,buf,0,2+8+16);
}
}
 
if ((g_netServer || ud.multimode > 1) && g_player[myconnectindex].ps->gm)
Net_GetPackets();
 
if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex)
gametext(160,60,"PRESS F1 TO ACCEPT, F2 TO DECLINE",0,2+8+16);
}
 
if ((g_player[myconnectindex].ps->gm&MODE_MENU) && (g_player[myconnectindex].ps->gm&MODE_EOL))
goto RECHECK;
 
if (KB_KeyPressed(sc_Escape) && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0 && (g_player[myconnectindex].ps->gm&MODE_TYPE) == 0)
{
KB_ClearKeyDown(sc_Escape);
FX_StopAllSounds();
S_ClearSoundLocks();
g_player[myconnectindex].ps->gm |= MODE_MENU;
ChangeToMenu(0);
S_MenuSound();
}
 
if (g_player[myconnectindex].ps->gm&MODE_TYPE)
{
Net_EnterMessage();
if ((g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE)
g_player[myconnectindex].ps->gm = MODE_MENU;
}
else
{
if (ud.recstat != 2)
M_DisplayMenus();
if ((g_netServer || ud.multimode > 1) && g_currentMenu != 20003 && g_currentMenu != 20005 && g_currentMenu != 210)
{
ControlInfo noshareinfo;
CONTROL_GetInput(&noshareinfo);
if (BUTTON(gamefunc_SendMessage))
{
KB_FlushKeyboardQueue();
CONTROL_ClearButton(gamefunc_SendMessage);
g_player[myconnectindex].ps->gm = MODE_TYPE;
typebuf[0] = 0;
inputloc = 0;
}
}
}
 
G_PrintGameQuotes();
 
if (ud.last_camsprite != ud.camerasprite)
{
ud.last_camsprite = ud.camerasprite;
ud.camera_time = totalclock+(TICRATE*2);
}
 
if (VOLUMEONE)
{
if (ud.show_help == 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
rotatesprite((320-50)<<16,9<<16,65536L,0,BETAVERSION,0,0,2+8+16+128,0,0,xdim-1,ydim-1);
}
handleevents();
Net_GetPackets();
nextpage();
 
if (g_player[myconnectindex].ps->gm == MODE_GAME)
{
if (foundemo)
{
#if KRANDDEBUG
krd_print("krandplay.log");
#endif
kclose(g_demo_recFilePtr);
}
return 0;
}
}
ud.multimode = numplayers; // fixes 2 infinite loops after watching demo
kclose(g_demo_recFilePtr);
 
#if 0
{
uint32_t crcv;
// sync checker
+ initcrc32table();
crc32init(&crcv);
crc32block(&crcv, (char *)wall, sizeof(wall));
crc32block(&crcv, (char *)sector, sizeof(sector));
crc32block(&crcv, (char *)sprite, sizeof(sprite));
crc32finish(&crcv);
initprintf("Checksum = %08X\n",crcv);
}
#endif
 
if (g_player[myconnectindex].ps->gm&MODE_MENU) goto RECHECK;
#if KRANDDEBUG
if (foundemo)
krd_print("krandplay.log");
#endif
return 1;
}
/polymer/eduke32/source/demo.h
0,0 → 1,60
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __demo_h__
#define __demo_h__
 
extern FILE *g_demo_filePtr;
extern char firstdemofile[80];
 
extern int32_t demoplay_diffs;
extern int32_t demoplay_showsync;
extern int32_t demorec_diffcompress_cvar;
extern int32_t demorec_diffs_cvar;
extern int32_t demorec_difftics_cvar;
extern int32_t demorec_force_cvar;
extern int32_t demorec_seeds_cvar;
extern int32_t demorec_synccompress_cvar;
extern int32_t g_demo_cnt;
extern int32_t g_demo_goalCnt;
extern int32_t g_demo_paused;
extern int32_t g_demo_recFilePtr;
extern int32_t g_demo_rewind;
extern int32_t g_demo_showStats;
extern int32_t g_demo_soundToggle;
extern int32_t g_demo_totalCnt;
 
int32_t G_OpenDemoRead(int32_t g_whichDemo);
int32_t G_PlaybackDemo(void);
int32_t sv_loadsnapshot(int32_t fil,int32_t *ret_hasdiffs,int32_t *ret_demoticcnt,int32_t *ret_synccompress);
int32_t sv_updatestate(int32_t frominit);
void demo_preparewarp(void);
void G_CloseDemoWrite(void);
void G_DemoRecord(void);
void G_OpenDemoWrite(void);
 
#if KRANDDEBUG
int32_t krd_print(const char *filename);
void krd_enable(int32_t which);
#endif
 
#endif
/polymer/eduke32/source/duke3d.h
20,8 → 20,8
*/
//-------------------------------------------------------------------------
 
#ifndef _duke3d_h_
# define _duke3d_h_
#ifndef __duke3d_h__
#define __duke3d_h__
 
#ifdef __cplusplus
extern "C" {
31,88 → 31,84
#include "compat.h"
#include "a.h"
#include "build.h"
 
#ifdef POLYMER
# include "polymer.h"
#include "polymer.h"
#else
#ifdef POLYMOST
# include "polymost.h"
#include "polymost.h"
#endif
#endif
 
#include "cache1d.h"
#include "pragmas.h"
 
#include "baselayer.h"
#include "file_lib.h"
#include "keyboard.h"
#include "mathutil.h"
#include "fx_man.h"
 
#include "function.h"
#define APPNAME "EDuke32"
#define VERSION "2.0.0devel"
#define HEAD2 APPNAME" "VERSION
 
#include "macros.h"
#define GAMEDUKE 0
#define GAMENAM 1
#define GAMEWW2 3
 
#include "enet/enet.h"
#define VOLUMEALL (g_Shareware == 0)
#define PLUTOPAK (g_scriptVersion == 14)
#define VOLUMEONE (g_Shareware == 1)
 
extern ENetHost * g_netServer;
extern ENetHost * g_netClient;
extern ENetPeer * g_netClientPeer;
#define NAM (g_gameType & 1)
#define WW2GI (g_gameType & 2)
 
enum netchan_t
{
CHAN_MOVE, // unreliable movement packets
CHAN_GAMESTATE, // gamestate changes... frags, respawns, player names, etc
CHAN_SYNC, // client join sync packets
CHAN_CHAT, // chat and RTS
CHAN_MISC, // whatever else
CHAN_MAX
};
// increase by 3, because atomic GRP adds 1, and Shareware adds 2
#define BYTEVERSION_JF 195
#define BYTEVERSION_13 27
#define BYTEVERSION_14 116
#define BYTEVERSION_15 117
#define BYTEVERSION (BYTEVERSION_JF+(PLUTOPAK?1:(VOLUMEONE<<1)))
 
#define APPNAME "EDuke32"
#define VERSION " 2.0.0devel"
// this is checked against http://eduke32.com/VERSION
extern const char *s_buildDate;
#define HEAD2 APPNAME VERSION
#define NUMPAGES 1
 
#define HORIZ_MIN -99
#define HORIZ_MAX 299
#define RECSYNCBUFSIZ 2520 //2520 is the (LCM of 1-8)*3
#define MOVEFIFOSIZ 2
 
extern int32_t g_scriptVersion, g_Shareware, g_gameType;
#define MAXVOLUMES 7
#define MAXLEVELS 32
#define MAXGAMETYPES 16
 
#define GAMEDUKE 0
#define GAMENAM 1
#define GAMEWW2 3
// used as a constant to satisfy all of the calculations written with ticrate = 26 in mind
#define GAMETICSPERSEC 26
#define REALGAMETICSPERSEC 30
// this used to be TICRATE/GAMETICSPERSEC, which was 120/26 = 4.615~ truncated to 4 by integer division
#define TICSPERFRAME 4
#define TICRATE 120
 
#define VOLUMEALL (g_Shareware==0)
#define PLUTOPAK (g_scriptVersion==14)
#define VOLUMEONE (g_Shareware==1)
#define NAM (g_gameType&1)
#define WW2GI (g_gameType&2)
#define MAXQUOTES 16384
#define MAXQUOTELEN 128
#define OBITQUOTEINDEX MAXQUOTES-128
#define SUICIDEQUOTEINDEX MAXQUOTES-32
 
#define MAXSLEEPDIST 16384
#define SLEEPTIME 24*64
#define NO 0
#define YES 1
 
#define BYTEVERSION_13 27
#define BYTEVERSION_14 116
#define BYTEVERSION_15 117
#define PACKBUF_SIZE 65535
 
#define BYTEVERSION_JF 195 // increase by 3, because atomic GRP adds 1, and Shareware adds 2
#define TILE_SAVESHOT (MAXTILES-1)
#define TILE_LOADSHOT (MAXTILES-3)
#define TILE_TILT (MAXTILES-2)
#define TILE_ANIM (MAXTILES-4)
#define TILE_VIEWSCR (MAXTILES-5)
 
#define BYTEVERSION (BYTEVERSION_JF+(PLUTOPAK?1:(VOLUMEONE<<1))) // JBF 20040116: different data files give different versions
// JBF 20040604: sync is a function on some platforms
#define sync dsync
 
#define NUMPAGES 1
 
#define AUTO_AIM_ANGLE 48
#define RECSYNCBUFSIZ 2520 //2520 is the (LCM of 1-8)*3
#define MOVEFIFOSIZ 2
 
#define FOURSLEIGHT (1<<8)
 
#define MAXVOLUMES 7
#define MAXLEVELS 32
 
 
#include "file_lib.h"
#include "namesdyn.h"
#include "function.h"
#include "macros.h"
#include "gamedefs.h"
#include "keyboard.h"
#include "mathutil.h"
#include "function.h"
#include "fx_man.h"
#include "config.h"
#include "sounds.h"
#include "control.h"
119,1004 → 115,17
#include "_rts.h"
#include "rts.h"
#include "soundefs.h"
 
#include "music.h"
#include "player.h"
#include "actors.h"
#include "global.h"
#include "sector.h"
#include "net.h"
#include "game.h"
#include "gamedef.h"
#include "gameexec.h"
#include "gamevars.h"
 
#include "namesdyn.h"
 
#define TICRATE (120)
#define GAMETICSPERSEC 26 // used as a constant to satisfy all of the calculations written with ticrate = 26 in mind
#define TICSPERFRAME 4 // this used to be TICRATE/GAMETICSPERSEC which was 4.615~ truncated to 4 by integer division
#define REALGAMETICSPERSEC 30
 
#define MAXSOUNDS 2560
 
#define STAT_DEFAULT 0
#define STAT_ACTOR 1
#define STAT_ZOMBIEACTOR 2
#define STAT_EFFECTOR 3
#define STAT_PROJECTILE 4
#define STAT_MISC 5
#define STAT_STANDABLE 6
#define STAT_LOCATOR 7
#define STAT_ACTIVATOR 8
#define STAT_TRANSPORT 9
#define STAT_PLAYER 10
#define STAT_FX 11
#define STAT_FALLER 12
#define STAT_DUMMYPLAYER 13
 
#define ALT_IS_PRESSED ( KB_KeyPressed( sc_RightAlt ) || KB_KeyPressed( sc_LeftAlt ) )
#define SHIFTS_IS_PRESSED ( KB_KeyPressed( sc_RightShift ) || KB_KeyPressed( sc_LeftShift ) )
#define RANDOMSCRAP A_InsertSprite(s->sectnum,s->x+(krand()&255)-128,s->y+(krand()&255)-128,s->z-(8<<8)-(krand()&8191),SCRAP6+(krand()&15),-8,48,48,krand()&2047,(krand()&63)+64,-512-(krand()&2047),i,5)
 
#define PHEIGHT (38<<8)
 
enum GameMode_t {
MODE_MENU = 0x00000001,
MODE_DEMO = 0x00000002,
MODE_GAME = 0x00000004,
MODE_EOL = 0x00000008,
MODE_TYPE = 0x00000010,
MODE_RESTART = 0x00000020,
MODE_SENDTOWHOM = 0x00000040,
};
 
#define MAXANIMWALLS 512
#define MAXINTERPOLATIONS MAXSPRITES
 
#define MAXQUOTES 16384
 
#define FIRST_OBITUARY_QUOTE MAXQUOTES-128
#define FIRST_SUICIDE_QUOTE MAXQUOTES-32
 
#define MAXCYCLERS 1024
 
#define MAXANIMATES 256
 
// Defines the motion characteristics of an actor
 
enum ActorMoveFlags_t {
face_player = 1,
geth = 2,
getv = 4,
random_angle = 8,
face_player_slow = 16,
spin = 32,
face_player_smart = 64,
fleeenemy = 128,
jumptoplayer = 257,
seekplayer = 512,
furthestdir = 1024,
dodgebullet = 4096
};
 
// Some misc #defines
#define NO 0
#define YES 1
 
// Defines for 'useractor' keyword
 
enum UserActorTypes_t {
notenemy,
enemy,
enemystayput
};
 
// Player Actions.
 
enum PlayerActionFlags_t {
pstanding = 1,
pwalking = 2,
prunning = 4,
pducking = 8,
pfalling = 16,
pjumping = 32,
phigher = 64,
pwalkingback = 128,
prunningback = 256,
pkicking = 512,
pshrunk = 1024,
pjetpack = 2048,
ponsteroids = 4096,
ponground = 8192,
palive = 16384,
pdead = 32768,
pfacing = 65536
};
 
enum DukeInventory_t {
GET_STEROIDS,
GET_SHIELD,
GET_SCUBA,
GET_HOLODUKE,
GET_JETPACK,
GET_DUMMY1,
GET_ACCESS,
GET_HEATS,
GET_DUMMY2,
GET_FIRSTAID,
GET_BOOTS,
GET_MAX
};
 
enum DukeWeapon_t {
KNEE_WEAPON,
PISTOL_WEAPON,
SHOTGUN_WEAPON,
CHAINGUN_WEAPON,
RPG_WEAPON,
HANDBOMB_WEAPON,
SHRINKER_WEAPON,
DEVISTATOR_WEAPON,
TRIPBOMB_WEAPON,
FREEZE_WEAPON,
HANDREMOTE_WEAPON,
GROW_WEAPON,
MAX_WEAPONS
};
 
#define deletesprite A_DeleteSprite
void A_DeleteSprite(int32_t s);
 
#pragma pack(push,1)
 
typedef struct {
uint32_t bits; // 4b
int16_t fvel, svel; // 4b
int8_t avel, horz; // 2b
int8_t extbits, filler; // 2b
} input_t;
 
#define sync dsync // JBF 20040604: sync is a function on some platforms
extern input_t recsync[RECSYNCBUFSIZ];
 
extern int32_t movefifosendplc;
 
typedef struct {
int16_t voice;
int16_t i;
} SOUNDOWNER;
 
#define MAXSOUNDINSTANCES 8
 
typedef struct {
int32_t length, num, soundsiz; // 12b
char *filename, *ptr, *filename1; // 12b/24b
SOUNDOWNER SoundOwner[MAXSOUNDINSTANCES]; // 32b
int16_t ps,pe,vo; // 6b
char pr,m; // 2b
} sound_t;
 
extern volatile char g_soundlocks[MAXSOUNDS];
extern sound_t g_sounds[MAXSOUNDS];
 
typedef struct {
int16_t wallnum, tag;
} animwalltype;
 
extern animwalltype animwall[MAXANIMWALLS];
 
extern int16_t g_numAnimWalls;
extern int32_t probey;
 
extern char typebuflen;
extern char typebuf[141];
extern int32_t g_musicSize;
extern int32_t msx[2048],msy[2048];
extern int16_t cyclers[MAXCYCLERS][6],g_numCyclers;
extern char szPlayerName[32];
 
struct savehead {
char name[19];
int32_t numplr,volnum,levnum,plrskl;
char boardfn[BMAX_PATH];
};
 
typedef struct {
vec3_t camera;
int32_t const_visibility,uw_framerate;
int32_t camera_time,folfvel,folavel,folx,foly,fola;
int32_t reccnt,crosshairscale;
 
int32_t runkey_mode,statusbarscale,mouseaiming,weaponswitch,drawweapon; // JBF 20031125
int32_t democams,color,msgdisptime,statusbarmode;
int32_t m_noexits,noexits,autovote,automsg,idplayers;
int32_t team, viewbob, weaponsway, althud, weaponscale, textscale;
 
int32_t entered_name,screen_tilting,shadows,fta_on,executions,auto_run;
int32_t coords,tickrate,levelstats,m_coop,coop,screen_size,lockout,crosshair;
int32_t playerai,angleinterpolation,obituaries;
 
int32_t respawn_monsters,respawn_items,respawn_inventory,recstat,monsters_off,brightness;
int32_t m_respawn_items,m_respawn_monsters,m_respawn_inventory,m_recstat,m_monsters_off,detail;
int32_t m_ffire,ffire,m_player_skill,m_level_number,m_volume_number,multimode;
int32_t player_skill,level_number,volume_number,m_marker,marker,mouseflip;
 
int32_t configversion;
 
int16_t cameraang, camerasect, camerahoriz;
int16_t pause_on,from_bonus;
int16_t camerasprite,last_camsprite;
int16_t last_level,secretlevel, bgstretch;
 
struct {
int32_t UseJoystick;
int32_t UseMouse;
int32_t AutoAim;
int32_t ShowOpponentWeapons;
int32_t MouseDeadZone,MouseBias;
int32_t SmoothInput;
 
// JBF 20031211: Store the input settings because
// (currently) jmact can't regurgitate them
int32_t MouseFunctions[MAXMOUSEBUTTONS][2];
int32_t MouseDigitalFunctions[MAXMOUSEAXES][2];
int32_t MouseAnalogueAxes[MAXMOUSEAXES];
int32_t MouseAnalogueScale[MAXMOUSEAXES];
int32_t JoystickFunctions[MAXJOYBUTTONS][2];
int32_t JoystickDigitalFunctions[MAXJOYAXES][2];
int32_t JoystickAnalogueAxes[MAXJOYAXES];
int32_t JoystickAnalogueScale[MAXJOYAXES];
int32_t JoystickAnalogueDead[MAXJOYAXES];
int32_t JoystickAnalogueSaturate[MAXJOYAXES];
uint8_t KeyboardKeys[NUMGAMEFUNCTIONS][2];
 
//
// Sound variables
//
int32_t FXDevice;
int32_t MusicDevice;
int32_t FXVolume;
int32_t MusicVolume;
int32_t SoundToggle;
int32_t MusicToggle;
int32_t VoiceToggle;
int32_t AmbienceToggle;
 
int32_t NumVoices;
int32_t NumChannels;
int32_t NumBits;
int32_t MixRate;
 
int32_t ReverseStereo;
 
//
// Screen variables
//
 
int32_t ScreenMode;
 
int32_t ScreenWidth;
int32_t ScreenHeight;
int32_t ScreenBPP;
 
int32_t ForceSetup;
int32_t NoAutoLoad;
 
int32_t scripthandle;
int32_t setupread;
 
int32_t CheckForUpdates;
int32_t LastUpdateCheck;
int32_t useprecache;
} config;
 
char overhead_on,last_overhead,showweapons;
char god,warp_on,cashman,eog,showallmap;
char show_help,scrollmode,clipping;
char ridecule[10][40];
char savegame[10][22];
char pwlockout[128],rtsname[128];
char display_bonus_screen;
char show_level_text;
} user_defs;
 
typedef struct {
int32_t ox,oy,oz;
int16_t oa,os;
} PlayerSpawn_t;
 
extern char g_numPlayerSprites;
 
extern int32_t fricxv,fricyv;
 
// TODO: make a dummy player struct for interpolation and sort the first members
// of this struct into the same order so we can just memcpy it and get rid of the
// mywhatever type globals
 
typedef struct {
vec3_t pos, opos, posvel;
int32_t bobposx, bobposy;
int32_t truefz, truecz, player_par;
int32_t randomflamex, exitx, exity;
int32_t runspeed, max_player_health, max_shield_amount;
 
uint32_t interface_toggle_flag;
 
uint8_t *palette;
 
uint16_t max_actors_killed, actors_killed;
uint16_t gotweapon, zoom;
 
int16_t loogiex[64], loogiey[64], sbs, sound_pitch;
 
int16_t ang, oang, angvel, cursectnum, look_ang, last_extra, subweapon;
int16_t max_ammo_amount[MAX_WEAPONS], ammo_amount[MAX_WEAPONS], inv_amount[GET_MAX];
int16_t wackedbyactor, pyoff, opyoff;
 
int16_t horiz, horizoff, ohoriz, ohorizoff;
int16_t newowner, jumping_counter, airleft;
int16_t fta, ftq, access_wallnum, access_spritenum;
int16_t got_access, weapon_ang, visibility;
int16_t somethingonplayer, on_crane, i, one_parallax_sectnum;
int16_t random_club_frame, one_eighty_count;
int16_t dummyplayersprite, extra_extra8;
int16_t actorsqu, timebeforeexit, customexitsound, last_pissed_time;
 
int16_t weaprecs[MAX_WEAPONS], weapon_sway, crack_time, bobcounter;
 
int16_t orotscrnang, rotscrnang, dead_flag; // JBF 20031220: added orotscrnang
int16_t holoduke_on, pycount;
 
uint8_t max_secret_rooms, secret_rooms;
uint8_t frag, fraggedself, quick_kick, last_quick_kick;
uint8_t return_to_center, reloading, weapreccnt;
uint8_t aim_mode, auto_aim, weaponswitch, movement_lock, team;
uint8_t tipincs, hbomb_hold_delay, frag_ps, kickback_pic;
 
uint8_t gm, on_warping_sector, footprintcount, hurt_delay;
uint8_t hbomb_on, jumping_toggle, rapid_fire_hold, on_ground;
uint8_t inven_icon, buttonpalette, over_shoulder_on, show_empty_weapon;
 
uint8_t jetpack_on, spritebridge, lastrandomspot;
uint8_t scuba_on, footprintpal, heat_on, invdisptime;
 
uint8_t holster_weapon, falling_counter, footprintshade;
uint8_t refresh_inventory, last_full_weapon;
 
uint8_t toggle_key_flag, knuckle_incs, knee_incs, access_incs;
uint8_t walking_snd_toggle, palookup, hard_landing, fist_incs;
 
int8_t numloogs, loogcnt, scream_voice, transporter_hold;
int8_t last_weapon, cheat_phase, weapon_pos, wantweaponfire, curr_weapon;
 
palette_t pals;
 
char name[32];
} DukePlayer_t;
 
#define PACKBUF_SIZE 65535
extern char tempbuf[2048], packbuf[PACKBUF_SIZE], menutextbuf[128];
 
extern int32_t g_spriteGravity;
 
extern int32_t g_impactDamage,g_actorRespawnTime,g_itemRespawnTime;
extern int32_t g_startArmorAmount, g_maxPlayerHealth;
 
#define MOVFIFOSIZ 256
 
extern int16_t SpriteDeletionQueue[1024],g_spriteDeleteQueuePos,g_spriteDeleteQueueSize;
extern user_defs ud;
extern int16_t g_globalRandom;
extern char buf[1024]; //My own generic input buffer
 
#define MAXQUOTELEN 128
 
extern char *ScriptQuotes[MAXQUOTES],*ScriptQuoteRedefinitions[MAXQUOTES];
extern char ready2send;
 
void VM_ScriptInfo(void);
extern intptr_t *script,*insptr,*labelcode,*labeltype;
extern int32_t g_numLabels,g_numDefaultLabels;
extern int32_t g_scriptSize;
extern char *label;
extern intptr_t *actorscrptr[MAXTILES],*g_parsingActorPtr;
extern intptr_t *actorLoadEventScrptr[MAXTILES];
extern char ActorType[MAXTILES];
 
extern char g_musicIndex;
extern char EnvMusicFilename[MAXVOLUMES+1][BMAX_PATH];
extern int16_t camsprite;
 
typedef struct {
int32_t workslike, cstat; // 8b
int32_t hitradius, range, flashcolor; // 12b
int16_t spawns, sound, isound, vel; // 8b
int16_t decal, trail, tnum, drop; // 8b
int16_t offset, bounces, bsound; // 6b
int16_t toffset; // 2b
int16_t extra, extra_rand; // 4b
int8_t sxrepeat, syrepeat, txrepeat, tyrepeat; // 4b
int8_t shade, xrepeat, yrepeat, pal; // 4b
int8_t velmult; // 1b
uint8_t clipdist; // 1b
int8_t filler[6]; // 6b
} projectile_t;
 
typedef struct {
intptr_t t_data[10]; // 40b/80b sometimes used to hold pointers to con code
 
int16_t picnum,ang,extra,owner; //8b
int16_t movflag,tempang,timetosleep; //6b
 
int32_t flags, bposx,bposy,bposz; //16b
int32_t floorz,ceilingz,lastvx,lastvy; //16b
int32_t lasttransport; //4b
 
int16_t lightId, lightcount, lightmaxrange, cgg; //8b
int16_t actorstayput, dispicnum, shootzvel; // 6b
 
#ifdef POLYMER
_prlight *lightptr; //4b/8b
#else
void *lightptr;
#endif
 
projectile_t *projectile; //4b/8b
 
int8_t filler[16]; // pad struct to 128 bytes
} ActorData_t;
 
// this struct needs to match the beginning of ActorData_t above
typedef struct {
intptr_t t_data[10]; // 40b/80b sometimes used to hold pointers to con code
 
int16_t picnum,ang,extra,owner; //8b
int16_t movflag,tempang,timetosleep; // 6b
 
int32_t flags; // 4b
} NetActorData_t;
 
extern ActorData_t actor[MAXSPRITES];
 
extern input_t loc;
extern input_t recsync[RECSYNCBUFSIZ];
extern input_t avg;
 
extern int32_t numplayers, myconnectindex;
extern int32_t connecthead, connectpoint2[MAXPLAYERS]; //Player linked list variables (indeces, not connection numbers)
extern int32_t screenpeek;
 
extern int32_t g_currentMenu;
extern int32_t tempwallptr,g_animateCount;
extern int32_t lockclock;
extern intptr_t frameplace;
extern char display_mirror,g_loadFromGroupOnly,g_RTSPlaying;
 
extern int32_t g_groupFileHandle;
extern int32_t ototalclock;
 
extern int32_t *animateptr[MAXANIMATES];
extern int32_t animategoal[MAXANIMATES];
extern int32_t animatevel[MAXANIMATES];
extern int16_t neartagsector, neartagwall, neartagsprite;
extern int32_t neartaghitdist;
extern int16_t animatesect[MAXANIMATES];
extern int32_t vel,svel,angvel,horiz;
 
extern int16_t g_mirrorWall[64], g_mirrorSector[64], g_mirrorCount;
 
#include "funct.h"
 
extern int32_t g_screenCapture;
extern char EpisodeNames[MAXVOLUMES][33];
extern char SkillNames[5][33];
 
extern int32_t g_currentFrameRate;
 
#define MAXGAMETYPES 16
extern char GametypeNames[MAXGAMETYPES][33];
extern int32_t GametypeFlags[MAXGAMETYPES];
extern char g_numGametypes;
 
enum GametypeFlags_t {
GAMETYPE_COOP = 0x00000001,
GAMETYPE_WEAPSTAY = 0x00000002,
GAMETYPE_FRAGBAR = 0x00000004,
GAMETYPE_SCORESHEET = 0x00000008,
GAMETYPE_DMSWITCHES = 0x00000010,
GAMETYPE_COOPSPAWN = 0x00000020,
GAMETYPE_ACCESSCARDSPRITES = 0x00000040,
GAMETYPE_COOPVIEW = 0x00000080,
GAMETYPE_COOPSOUND = 0x00000100,
GAMETYPE_OTHERPLAYERSINMAP = 0x00000200,
GAMETYPE_ITEMRESPAWN = 0x00000400,
GAMETYPE_MARKEROPTION = 0x00000800,
GAMETYPE_PLAYERSFRIENDLY = 0x00001000,
GAMETYPE_FIXEDRESPAWN = 0x00002000,
GAMETYPE_ACCESSATSTART = 0x00004000,
GAMETYPE_PRESERVEINVENTORYDEATH = 0x00008000,
GAMETYPE_TDM = 0x00010000,
GAMETYPE_TDMSPAWN = 0x00020000
};
 
extern char g_numVolumes;
 
extern int32_t g_lastSaveSlot;
extern int32_t g_restorePalette;
 
extern int32_t cachecount;
extern char boardfilename[BMAX_PATH];
extern uint8_t waterpal[768],slimepal[768],titlepal[768],drealms[768],endingpal[768],*animpal;
extern char currentboardfilename[BMAX_PATH];
extern char cachedebug,g_earthquakeTime;
extern char lumplockbyte[11];
 
//DUKE3D.H - replace the end "my's" with this
extern vec3_t my;
extern vec3_t my, omy, myvel;
extern int16_t myhoriz, omyhoriz, myhorizoff, omyhorizoff, g_skillSoundID;
extern int16_t myang, omyang, mycursectnum, myjumpingcounter;
extern char myjumpingtoggle, myonground, myhardlanding,myreturntocenter;
 
extern int16_t BlimpSpawnSprites[15];
 
//DUKE3D.H:
 
#pragma pack(pop)
typedef struct {
int16_t got_access, last_extra, inv_amount[GET_MAX], curr_weapon, holoduke_on;
int16_t last_weapon, weapon_pos, kickback_pic;
int16_t ammo_amount[MAX_WEAPONS], frag[MAXPLAYERS];
uint16_t gotweapon;
char inven_icon, jetpack_on, heat_on;
} DukeStatus_t;
#pragma pack(push,1)
 
extern DukeStatus_t sbar;
extern int32_t g_cameraDistance, g_cameraClock, g_playerFriction, g_showShareware;
extern int32_t g_gameQuit;
 
extern int32_t playerswhenstarted;
extern int8_t multiwho, multipos, multiwhat, multiflag;
 
extern char pus,pub;
extern int32_t g_damageCameras,g_freezerSelfDamage,g_tripbombLaserMode;
extern int32_t g_numFreezeBounces,g_rpgBlastRadius,g_pipebombBlastRadius,g_tripbombBlastRadius;
extern int32_t g_shrinkerBlastRadius,g_morterBlastRadius,g_bouncemineBlastRadius,g_seenineBlastRadius;
extern int32_t everyothertime;
 
extern int32_t g_numInterpolations, startofdynamicinterpolations;
extern int32_t g_interpolationLock;
extern int32_t oldipos[MAXINTERPOLATIONS];
extern int32_t bakipos[MAXINTERPOLATIONS];
extern int32_t *curipos[MAXINTERPOLATIONS];
extern int16_t g_numClouds,clouds[128],cloudx[128],cloudy[128];
extern int32_t cloudtotalclock;
extern int32_t g_myAimMode, g_myAimStat, g_oldAimStat;
extern uint32_t g_moveThingsCount;
 
#define IFISGLMODE if (getrendermode() >= 3)
#define IFISSOFTMODE if (getrendermode() < 3)
 
#define TILE_SAVESHOT (MAXTILES-1)
#define TILE_LOADSHOT (MAXTILES-3)
#define TILE_TILT (MAXTILES-2)
#define TILE_ANIM (MAXTILES-4)
#define TILE_VIEWSCR (MAXTILES-5)
 
// the order of these can't be changed or else compatibility with EDuke 2.0 mods will break
enum GameEvent_t {
EVENT_INIT,
EVENT_ENTERLEVEL,
EVENT_RESETWEAPONS,
EVENT_RESETINVENTORY,
EVENT_HOLSTER,
EVENT_LOOKLEFT,
EVENT_LOOKRIGHT,
EVENT_SOARUP,
EVENT_SOARDOWN,
EVENT_CROUCH,
EVENT_JUMP,
EVENT_RETURNTOCENTER,
EVENT_LOOKUP,
EVENT_LOOKDOWN,
EVENT_AIMUP,
EVENT_FIRE,
EVENT_CHANGEWEAPON,
EVENT_GETSHOTRANGE,
EVENT_GETAUTOAIMANGLE,
EVENT_GETLOADTILE,
EVENT_CHEATGETSTEROIDS,
EVENT_CHEATGETHEAT,
EVENT_CHEATGETBOOT,
EVENT_CHEATGETSHIELD,
EVENT_CHEATGETSCUBA,
EVENT_CHEATGETHOLODUKE,
EVENT_CHEATGETJETPACK,
EVENT_CHEATGETFIRSTAID,
EVENT_QUICKKICK,
EVENT_INVENTORY,
EVENT_USENIGHTVISION,
EVENT_USESTEROIDS,
EVENT_INVENTORYLEFT,
EVENT_INVENTORYRIGHT,
EVENT_HOLODUKEON,
EVENT_HOLODUKEOFF,
EVENT_USEMEDKIT,
EVENT_USEJETPACK,
EVENT_TURNAROUND,
EVENT_DISPLAYWEAPON,
EVENT_FIREWEAPON,
EVENT_SELECTWEAPON,
EVENT_MOVEFORWARD,
EVENT_MOVEBACKWARD,
EVENT_TURNLEFT,
EVENT_TURNRIGHT,
EVENT_STRAFELEFT,
EVENT_STRAFERIGHT,
EVENT_WEAPKEY1,
EVENT_WEAPKEY2,
EVENT_WEAPKEY3,
EVENT_WEAPKEY4,
EVENT_WEAPKEY5,
EVENT_WEAPKEY6,
EVENT_WEAPKEY7,
EVENT_WEAPKEY8,
EVENT_WEAPKEY9,
EVENT_WEAPKEY10,
EVENT_DRAWWEAPON,
EVENT_DISPLAYCROSSHAIR,
EVENT_DISPLAYREST,
EVENT_DISPLAYSBAR,
EVENT_RESETPLAYER,
EVENT_INCURDAMAGE,
EVENT_AIMDOWN,
EVENT_GAME,
EVENT_PREVIOUSWEAPON,
EVENT_NEXTWEAPON,
EVENT_SWIMUP,
EVENT_SWIMDOWN,
EVENT_GETMENUTILE,
EVENT_SPAWN,
EVENT_LOGO,
EVENT_EGS,
EVENT_DOFIRE,
EVENT_PRESSEDFIRE,
EVENT_USE,
EVENT_PROCESSINPUT,
EVENT_FAKEDOMOVETHINGS,
EVENT_DISPLAYROOMS,
EVENT_KILLIT,
EVENT_LOADACTOR,
EVENT_DISPLAYBONUSSCREEN,
EVENT_DISPLAYMENU,
EVENT_DISPLAYMENUREST,
EVENT_DISPLAYLOADINGSCREEN,
EVENT_ANIMATESPRITES,
EVENT_NEWGAME,
MAXEVENTS
};
 
// store global game definitions
 
 
 
enum GamevarFlags_t {
MAXGAMEVARS = 2048, // must be a power of two
MAXVARLABEL = 26,
GAMEVAR_PERPLAYER = 0x00000001, // per-player variable
GAMEVAR_PERACTOR = 0x00000002, // per-actor variable
GAMEVAR_USER_MASK = (0x00000001|0x00000002),
GAMEVAR_RESET = 0x00000008, // marks var for to default
GAMEVAR_DEFAULT = 0x00000100, // allow override
GAMEVAR_SECRET = 0x00000200, // don't dump...
GAMEVAR_NODEFAULT = 0x00000400, // don't reset on actor spawn
GAMEVAR_SYSTEM = 0x00000800, // cannot change mode flags...(only default value)
GAMEVAR_READONLY = 0x00001000, // values are read-only (no setvar allowed)
GAMEVAR_INTPTR = 0x00002000, // plValues is a pointer to an int32_t
GAMEVAR_SYNCCHECK = 0x00004000, // throw warnings during compile if used in local event
GAMEVAR_SHORTPTR = 0x00008000, // plValues is a pointer to a short
GAMEVAR_CHARPTR = 0x00010000, // plValues is a pointer to a char
GAMEVAR_NORESET = 0x00020000, // var values are not reset when restoring map state
GAMEVAR_SPECIAL = 0x00040000, // flag for structure member shortcut vars
GAMEVAR_NOMULTI = 0x00080000, // don't attach to multiplayer packets
};
 
enum GamearrayFlags_t {
MAXGAMEARRAYS = (MAXGAMEVARS>>2), // must be lower than MAXGAMEVARS
MAXARRAYLABEL = MAXVARLABEL,
GAMEARRAY_NORMAL = 0,
GAMEARRAY_NORESET = 0x00000001,
};
 
typedef struct {
union {
intptr_t lValue;
intptr_t *plValues; // array of values when 'per-player', or 'per-actor'
} val;
intptr_t lDefault;
uintptr_t dwFlags;
char *szLabel;
} gamevar_t;
 
typedef struct {
char *szLabel;
int32_t *plValues; // array of values
intptr_t size;
intptr_t bReset;
} gamearray_t;
 
extern gamevar_t aGameVars[MAXGAMEVARS];
extern gamearray_t aGameArrays[MAXGAMEARRAYS];
extern int32_t g_gameVarCount;
extern int32_t g_gameArrayCount;
 
extern int32_t SpriteFlags[MAXTILES];
 
enum SpriteFlags_t {
SPRITE_SHADOW = 0x00000001,
SPRITE_NVG = 0x00000002,
SPRITE_NOSHADE = 0x00000004,
SPRITE_PROJECTILE = 0x00000008,
SPRITE_DECAL = 0x00000010,
SPRITE_BADGUY = 0x00000020,
SPRITE_NOPAL = 0x00000040,
SPRITE_NOEVENTCODE = 0x00000080,
SPRITE_NOLIGHT = 0x00000100,
SPRITE_USEACTIVATOR = 0x00000200,
SPRITE_NULL = 0x00000400, // null sprite in multiplayer
};
 
extern int16_t SpriteCacheList[MAXTILES][3];
 
extern int32_t g_iReturnVarID;
extern int32_t g_iWeaponVarID;
extern int32_t g_iWorksLikeVarID;
extern int32_t g_iZRangeVarID;
extern int32_t g_iAngRangeVarID;
extern int32_t g_iAimAngleVarID;
extern int32_t g_iLoTagID; // var ID of "LOTAG"
extern int32_t g_iHiTagID; // var ID of "HITAG"
extern int32_t g_iTextureID; // var ID of "TEXTURE"
 
extern char g_bEnhanced; // are we 'enhanced' (more minerals, etc)
 
extern char g_szBuf[1024];
 
#define NAM_GRENADE_LIFETIME 120
#define NAM_GRENADE_LIFETIME_VAR 30
 
extern intptr_t *aplWeaponClip[MAX_WEAPONS]; // number of items in clip
extern intptr_t *aplWeaponReload[MAX_WEAPONS]; // delay to reload (include fire)
extern intptr_t *aplWeaponFireDelay[MAX_WEAPONS]; // delay to fire
extern intptr_t *aplWeaponHoldDelay[MAX_WEAPONS]; // delay after release fire button to fire (0 for none)
extern intptr_t *aplWeaponTotalTime[MAX_WEAPONS]; // The total time the weapon is cycling before next fire.
extern intptr_t *aplWeaponFlags[MAX_WEAPONS]; // Flags for weapon
extern intptr_t *aplWeaponShoots[MAX_WEAPONS]; // what the weapon shoots
extern intptr_t *aplWeaponSpawnTime[MAX_WEAPONS]; // the frame at which to spawn an item
extern intptr_t *aplWeaponSpawn[MAX_WEAPONS]; // the item to spawn
extern intptr_t *aplWeaponShotsPerBurst[MAX_WEAPONS]; // number of shots per 'burst' (one ammo per 'burst'
extern intptr_t *aplWeaponWorksLike[MAX_WEAPONS]; // What original the weapon works like
extern intptr_t *aplWeaponInitialSound[MAX_WEAPONS]; // Sound made when initialy firing. zero for no sound
extern intptr_t *aplWeaponFireSound[MAX_WEAPONS]; // Sound made when firing (each time for automatic)
extern intptr_t *aplWeaponSound2Time[MAX_WEAPONS]; // Alternate sound time
extern intptr_t *aplWeaponSound2Sound[MAX_WEAPONS]; // Alternate sound sound ID
extern intptr_t *aplWeaponReloadSound1[MAX_WEAPONS]; // Sound of magazine being removed
extern intptr_t *aplWeaponReloadSound2[MAX_WEAPONS]; // Sound of magazine being inserted
extern intptr_t *aplWeaponSelectSound[MAX_WEAPONS]; // Sound for weapon selection
extern intptr_t *aplWeaponFlashColor[MAX_WEAPONS]; // Color for polymer muzzle flash
 
extern int32_t g_timerTicsPerSecond;
 
enum WeaponFlags_t {
WEAPON_SPAWNTYPE1 = 0x00000000, // just spawn
WEAPON_HOLSTER_CLEARS_CLIP = 0x00000001, // 'holstering' clears the current clip
WEAPON_GLOWS = 0x00000002, // weapon 'glows' (shrinker and grower)
WEAPON_AUTOMATIC = 0x00000004, // automatic fire (continues while 'fire' is held down
WEAPON_FIREEVERYOTHER = 0x00000008, // during 'hold time' fire every frame
WEAPON_FIREEVERYTHIRD = 0x00000010, // during 'hold time' fire every third frame
WEAPON_RANDOMRESTART = 0x00000020, // restart for automatic is 'randomized' by RND 3
WEAPON_AMMOPERSHOT = 0x00000040, // uses ammo for each shot (for automatic)
WEAPON_BOMB_TRIGGER = 0x00000080, // weapon is the 'bomb' trigger
WEAPON_NOVISIBLE = 0x00000100, // weapon use does not cause user to become 'visible'
WEAPON_THROWIT = 0x00000200, // weapon 'throws' the 'shoots' item...
WEAPON_CHECKATRELOAD = 0x00000400, // check weapon availability at 'reload' time
WEAPON_STANDSTILL = 0x00000800, // player stops jumping before actual fire (like tripbomb in duke)
WEAPON_SPAWNTYPE2 = 0x00001000, // spawn like shotgun shells
WEAPON_SPAWNTYPE3 = 0x00002000, // spawn like chaingun shells
WEAPON_SEMIAUTO = 0x00004000, // cancel button press after each shot
WEAPON_RELOAD_TIMING = 0x00008000, // special casing for pistol reload sounds
WEAPON_RESET = 0x00010000 // cycle weapon back to frame 1 if fire is held, 0 if not
};
 
#define TRIPBOMB_TRIPWIRE 0x00000001
#define TRIPBOMB_TIMER 0x00000002
 
#define PIPEBOMB_REMOTE 0x00000001
#define PIPEBOMB_TIMER 0x00000002
 
// custom projectiles
 
enum ProjectileFlags_t {
PROJECTILE_HITSCAN = 0x00000001,
PROJECTILE_RPG = 0x00000002,
PROJECTILE_BOUNCESOFFWALLS = 0x00000004,
PROJECTILE_BOUNCESOFFMIRRORS = 0x00000008,
PROJECTILE_KNEE = 0x00000010,
PROJECTILE_WATERBUBBLES = 0x00000020,
PROJECTILE_TIMED = 0x00000040,
PROJECTILE_BOUNCESOFFSPRITES = 0x00000080,
PROJECTILE_SPIT = 0x00000100,
PROJECTILE_COOLEXPLOSION1 = 0x00000200,
PROJECTILE_BLOOD = 0x00000400,
PROJECTILE_LOSESVELOCITY = 0x00000800,
PROJECTILE_NOAIM = 0x00001000,
PROJECTILE_RANDDECALSIZE = 0x00002000,
PROJECTILE_EXPLODEONTIMER = 0x00004000,
PROJECTILE_RPG_IMPACT = 0x00008000,
PROJECTILE_RADIUS_PICNUM = 0x00010000,
PROJECTILE_ACCURATE_AUTOAIM = 0x00020000,
PROJECTILE_FORCEIMPACT = 0x00040000,
PROJECTILE_REALCLIPDIST = 0x00080000,
PROJECTILE_ACCURATE = 0x00100000,
};
 
extern projectile_t ProjectileData[MAXTILES], DefaultProjectileData[MAXTILES], SpriteProjectile[MAXSPRITES];
 
// logo control
 
enum LogoFlags_t {
LOGO_ENABLED = 0x00000001,
LOGO_PLAYANIM = 0x00000002,
LOGO_PLAYMUSIC = 0x00000004,
LOGO_3DRSCREEN = 0x00000008,
LOGO_TITLESCREEN = 0x00000010,
LOGO_DUKENUKEM = 0x00000020,
LOGO_THREEDEE = 0x00000040,
LOGO_PLUTOPAKSPRITE = 0x00000080,
LOGO_SHAREWARESCREENS = 0x00000100,
LOGO_TENSCREEN = 0x00000200
};
 
extern int32_t g_numRealPalettes;
extern int32_t g_scriptDebug;
 
#define MAXCHEATLEN 20
#define NUMCHEATCODES (int32_t)(sizeof(CheatStrings)/sizeof(CheatStrings[0]))
 
extern char CheatKeys[2];
extern char CheatStrings[][MAXCHEATLEN];
 
extern int16_t WeaponPickupSprites[MAX_WEAPONS];
 
extern int32_t g_numQuoteRedefinitions;
 
extern char setupfilename[BMAX_PATH];
 
typedef struct {
// this needs to have a copy of everything related to the map/actor state
// see savegame.c
int32_t animategoal[MAXANIMATES], animatevel[MAXANIMATES], g_animateCount;
int32_t animateptr[MAXANIMATES];
int32_t lockclock;
int32_t msx[2048], msy[2048];
int32_t randomseed, g_globalRandom;
intptr_t *vars[MAXGAMEVARS];
 
int16_t SpriteDeletionQueue[1024],g_spriteDeleteQueuePos;
int16_t animatesect[MAXANIMATES];
int16_t cyclers[MAXCYCLERS][6];
int16_t g_mirrorWall[64], g_mirrorSector[64], g_mirrorCount;
int16_t g_numAnimWalls;
int16_t g_numClouds,clouds[128],cloudx[128],cloudy[128];
int16_t g_numCyclers;
int16_t headspritesect[MAXSECTORS+1];
int16_t headspritestat[MAXSTATUS+1];
int16_t nextspritesect[MAXSPRITES];
int16_t nextspritestat[MAXSPRITES];
int16_t numsectors;
int16_t numwalls;
int16_t prevspritesect[MAXSPRITES];
int16_t prevspritestat[MAXSPRITES];
int16_t pskyoff[MAXPSKYTILES], pskybits;
 
uint8_t g_earthquakeTime;
uint8_t g_numPlayerSprites;
uint8_t scriptptrs[MAXSPRITES];
uint8_t show2dsector[(MAXSECTORS+7)>>3];
 
ActorData_t actor[MAXSPRITES];
PlayerSpawn_t g_playerSpawnPoints[MAXPLAYERS];
animwalltype animwall[MAXANIMWALLS];
sectortype sector[MAXSECTORS];
spriteext_t spriteext[MAXSPRITES];
spritetype sprite[MAXSPRITES];
walltype wall[MAXWALLS];
} mapstate_t;
 
extern void G_SaveMapState(mapstate_t *save);
extern void G_RestoreMapState(mapstate_t *save);
 
typedef struct {
int32_t partime, designertime;
char *name, *filename, *musicfn, *alt_musicfn;
mapstate_t *savedstate;
} map_t;
 
extern map_t MapInfo[(MAXVOLUMES+1)*MAXLEVELS]; // +1 volume for "intro", "briefing" music
 
typedef struct {
DukePlayer_t *ps;
input_t *sync;
 
int32_t netsynctime;
int16_t ping, filler;
int32_t pcolor, pteam;
uint8_t frags[MAXPLAYERS], wchoice[MAX_WEAPONS];
 
char vote, gotvote, playerreadyflag, playerquitflag;
char user_name[32];
} playerdata_t;
 
extern input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
extern PlayerSpawn_t g_playerSpawnPoints[MAXPLAYERS];
extern playerdata_t g_player[MAXPLAYERS];
#include "funct.h"
 
// key bindings stuff
typedef struct {
char *name;
int32_t id;
} keydef_t;
 
extern keydef_t ConsoleKeys[];
extern char *ConsoleButtons[];
 
extern char *g_grpNamePtr, *g_gameNamePtr;
extern char g_modDir[BMAX_PATH];
 
extern hashtable_t h_gamevars;
extern hashtable_t h_arrays;
extern hashtable_t h_keywords;
extern hashtable_t h_gamefuncs;
extern hashtable_t h_labels;
 
enum DukePacket_t
{
PACKET_MASTER_TO_SLAVE,
PACKET_SLAVE_TO_MASTER,
 
PACKET_NUM_PLAYERS,
PACKET_PLAYER_INDEX,
PACKET_PLAYER_DISCONNECTED,
PACKET_PLAYER_SPAWN,
PACKET_FRAG,
PACKET_REQUEST_GAMESTATE,
PACKET_LOAD_GAME,
PACKET_VERSION,
PACKET_AUTH,
PACKET_PLAYER_READY,
PACKET_MAP_STREAM,
 
// any packet with an ID higher than PACKET_BROADCAST is rebroadcast by server
// so hacked clients can't create fake server packets and get the server to
// send them to everyone
// newer versions of the netcode also make this determination based on which
// channel the packet was broadcast on
 
PACKET_BROADCAST,
PACKET_NEW_GAME,
PACKET_RTS,
PACKET_CLIENT_INFO,
PACKET_MESSAGE,
PACKET_USER_MAP,
 
PACKET_MAP_VOTE,
PACKET_MAP_VOTE_INITIATE,
PACKET_MAP_VOTE_CANCEL,
};
 
enum NetDisconnect_t
{
DISC_BAD_PASSWORD = 1,
DISC_KICKED,
DISC_BANNED
};
 
#pragma pack(pop)
 
#ifdef __cplusplus
}
#endif
/polymer/eduke32/source/game.c
43,9 → 43,14
#include "crc32.h"
#include "hightile.h"
#include "control.h"
 
#include "enet/enet.h"
#include "quicklz.h"
#include "net.h"
#include "premap.h"
#include "gameexec.h"
#include "menus.h"
#include "savegame.h"
#include "anim.h"
#include "demo.h"
 
#define ROTATESPRITE_MAX 2048
 
68,26 → 73,7
static int32_t usecwd = 0;
#endif /* _WIN32 */
 
/*
this should be lower than the MTU size by at least the size of the UDP and ENet headers
or else fragmentation will occur
*/
#define SYNCPACKETSIZE 1366
 
ENetHost * g_netServer = NULL;
ENetHost * g_netClient = NULL;
ENetPeer * g_netClientPeer = NULL;
int32_t g_netPort = 23513;
int32_t g_netDisconnect = 0;
// sprites of these statnums are synced to clients by the server
int8_t g_netStatnums[] = { STAT_PROJECTILE, STAT_STANDABLE, STAT_ACTIVATOR, STAT_TRANSPORT,
STAT_EFFECTOR, STAT_ACTOR, STAT_ZOMBIEACTOR, STAT_MISC };
char g_netPassword[32];
int32_t g_netSync = 0;
int32_t g_quitDeadline = 0;
int32_t g_netPlayersWaiting = 0;
int32_t g_netServerMode = 0;
 
int32_t g_scriptSanityChecks = 1;
 
int32_t g_cameraDistance = 0, g_cameraClock = 0;
114,7 → 100,6
char g_modDir[BMAX_PATH] = "/";
 
uint8_t waterpal[768], slimepal[768], titlepal[768], drealms[768], endingpal[768], *animpal;
static char firstdemofile[80] = { '\0' };
static int32_t g_skipDefaultCons = 0;
 
int32_t voting = -1;
122,25 → 107,11
 
static int32_t g_Debug = 0;
 
extern int32_t numlumps;
extern int32_t rts_numlumps;
 
static FILE *g_demo_filePtr = (FILE *)NULL;
static int32_t g_demo_cnt, g_demo_goalCnt=0, g_demo_totalCnt, g_demo_soundToggle;
static int32_t g_demo_paused=0, g_demo_rewind=0, g_demo_showStats=1;
static int32_t g_demo_recFilePtr;
 
static int32_t demo_hasdiffs, demorec_diffs=1, demorec_difftics = 2*(TICRATE/TICSPERFRAME);
int32_t demoplay_diffs=1, demorec_diffs_cvar=1, demorec_force_cvar=0;
int32_t demorec_difftics_cvar = 2*(TICRATE/TICSPERFRAME);
int32_t demorec_diffcompress_cvar=1;
int32_t demorec_synccompress_cvar=1;
int32_t demorec_seeds_cvar=1, demoplay_showsync=1;
static int32_t demo_synccompress=1, demorec_seeds=1, demo_hasseeds;
 
int32_t g_restorePalette = 0, g_screenCapture = 0, g_noEnemies = 0;
static int32_t g_noLogoAnim = 0;
static int32_t g_noLogo = 0;
static int32_t g_chatPlayer = -1;
 
char defaultduke3dgrp[BMAX_PATH] = "duke3d.grp";
static char defaultduke3ddef[BMAX_PATH] = "duke3d.def";
157,7 → 128,7
int32_t g_gameType = 0;
 
#define MAXUSERQUOTES 6
static int32_t quotebot, quotebotgoal;
int32_t quotebot, quotebotgoal;
static int32_t user_quote_time[MAXUSERQUOTES];
static char user_quote[MAXUSERQUOTES][178];
// char typebuflen,typebuf[41];
176,16 → 147,9
static void G_DrawCameraText(int16_t i);
GAME_STATIC GAME_INLINE int32_t G_MoveLoop(void);
static void G_DoOrderScreen(void);
GAME_STATIC int32_t G_DoMoveThings(void);
GAME_STATIC int32_t G_PlaybackDemo(void);
 
static char recbuf[180];
 
extern void computergetinput(int32_t snum, input_t *syn);
 
#define USERQUOTE_LEFTOFFSET 5
#define USERQUOTE_RIGHTOFFSET 14
 
#define quotepulseshade (sintable[(totalclock<<5)&2047]>>11)
 
int32_t althud_numbertile = 2930;
218,7 → 182,7
return r;
}
 
enum
enum gametokens
{
T_EOF = -2,
T_ERROR = -1,
242,7 → 206,7
}
tokenlist;
 
static int32_t getatoken(scriptfile *sf, tokenlist *tl, int32_t ntokens)
static int32_t getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens)
{
char *tok;
int32_t i;
387,7 → 351,7
 
x = (f & 4) ?
(xres>>1)-textsc(newx>>1) :
(widthx>>1)-((o & ROTATESPRITE_MAX)?newx<<15:newx>>1);
(widthx>>1)-((o & ROTATESPRITE_MAX)?newx<<15:newx>>1);
}
 
ox = x;
435,14 → 399,14
 
if (f&4)
rotatesprite(textsc(x<<shift),(origy<<shift)+textsc((y-origy)<<shift),textsc(z),
0,ac,s,p,(8|16|(o&1)|(o&32)),x1,y1,x2,y2);
0,ac,s,p,(8|16|(o&1)|(o&32)),x1,y1,x2,y2);
else if (f&1)
rotatesprite(x<<shift,(y<<shift),z,0,ac,s,p,(8|16|(o&1)|(o&32)),x1,y1,x2,y2);
else rotatesprite(x<<shift,(y<<shift),z,0,ac,s,p,(2|o),x1,y1,x2,y2);
 
x += i = (f & 8) ?
((8 - squishtext) * z)>>16 :
((tilesizx[ac] - squishtext) * z)>>16;
((8 - squishtext) * z)>>16 :
((tilesizx[ac] - squishtext) * z)>>16;
 
if ((*t >= '0' && *t <= '9'))
x -= i - ((8 * z)>>16);
485,7 → 449,7
return (textsc(x));
}
 
static inline int32_t mpgametext(int32_t y,const char *t,int32_t s,int32_t dabits)
inline int32_t mpgametext(int32_t y,const char *t,int32_t s,int32_t dabits)
{
return(G_PrintGameText(4,STARTALPHANUM, 5,y,t,s,0,dabits,0, 0, xdim-1, ydim-1, 65536));
}
593,123 → 557,6
}
}
 
void Net_Connect(const char * srvaddr)
{
ENetAddress address;
ENetEvent event;
char * addrstr = NULL;
int32_t i;
 
Net_Disconnect();
 
g_netClient = enet_host_create(NULL, 1, CHAN_MAX, 0, 0);
 
if (g_netClient == NULL)
{
initprintf("An error occurred while trying to create an ENet client host.\n");
return;
}
 
addrstr = strtok((char *)srvaddr, ":");
enet_address_set_host(&address, addrstr);
address.port = atoi((addrstr = strtok(NULL, ":")) == NULL ? "23513" : addrstr);
 
g_netClientPeer = enet_host_connect(g_netClient, &address, CHAN_MAX, 0);
 
if (g_netClientPeer == NULL)
{
initprintf("No available peers for initiating an ENet connection.\n");
return;
}
 
for (i=4; i>0; i--)
{
/* Wait up to 5 seconds for the connection attempt to succeed. */
if (enet_host_service(g_netClient, & event, 5000) > 0 &&
event.type == ENET_EVENT_TYPE_CONNECT)
{
initprintf("Connection to %s:%d succeeded.\n", (char *)srvaddr, address.port);
return;
}
else
{
/* Either the 5 seconds are up or a disconnect event was */
/* received. Reset the peer in the event the 5 seconds */
/* had run out without any significant event. */
enet_peer_reset(g_netClientPeer);
initprintf("Connection to %s:%d failed.\n",(char *)srvaddr,address.port);
}
initprintf(i ? "Retrying...\n" : "Giving up connection attempt.\n");
}
 
Net_Disconnect();
}
 
void Net_Disconnect(void)
{
if (g_netClient)
{
ENetEvent event;
 
if (g_netClientPeer)
enet_peer_disconnect_later(g_netClientPeer, 0);
 
while (enet_host_service(g_netClient, & event, 3000) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
case ENET_EVENT_TYPE_NONE:
case ENET_EVENT_TYPE_RECEIVE:
if (event.packet)
enet_packet_destroy(event.packet);
break;
 
case ENET_EVENT_TYPE_DISCONNECT:
numplayers = playerswhenstarted = ud.multimode = 1;
myconnectindex = screenpeek = 0;
G_BackToMenu();
break;
}
}
 
enet_peer_reset(g_netClientPeer);
g_netClientPeer = NULL;
enet_host_destroy(g_netClient);
g_netClient = NULL;
return;
}
 
if (g_netServer)
{
ENetPeer * currentPeer;
ENetEvent event;
 
for (currentPeer = g_netServer -> peers;
currentPeer < & g_netServer -> peers [g_netServer -> peerCount];
++ currentPeer)
{
enet_peer_disconnect_later(currentPeer, 0);
}
 
while (enet_host_service(g_netServer, & event, 3000) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
case ENET_EVENT_TYPE_NONE:
case ENET_EVENT_TYPE_RECEIVE:
case ENET_EVENT_TYPE_DISCONNECT:
if (event.packet)
enet_packet_destroy(event.packet);
break;
}
}
enet_host_destroy(g_netServer);
g_netServer = NULL;
}
}
 
void G_GameQuit(void)
{
if (numplayers < 2)
726,1614 → 573,7
G_GameExit("Timed out.");
}
 
static void Net_SendVersion(ENetPeer * client)
{
if (!g_netServer) return;
 
buf[0] = PACKET_VERSION;
buf[1] = BYTEVERSION;
buf[2] = (uint8_t)atoi(s_buildDate);
buf[3] = myconnectindex;
 
enet_peer_send(client, CHAN_GAMESTATE, enet_packet_create(&buf[0], 4, ENET_PACKET_FLAG_RELIABLE));
}
 
void Net_SendClientInfo(void)
{
int32_t i,l;
 
for (l=0; (unsigned)l<sizeof(szPlayerName)-1; l++)
g_player[myconnectindex].user_name[l] = Btoupper(szPlayerName[l]);
 
if (numplayers < 2) return;
 
buf[0] = PACKET_CLIENT_INFO;
l = 1;
 
//null terminated player name to send
for (i=0; szPlayerName[i]; i++) buf[l++] = Btoupper(szPlayerName[i]);
buf[l++] = 0;
 
buf[l++] = g_player[myconnectindex].ps->aim_mode = ud.mouseaiming;
buf[l++] = g_player[myconnectindex].ps->auto_aim = ud.config.AutoAim;
buf[l++] = g_player[myconnectindex].ps->weaponswitch = ud.weaponswitch;
buf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = ud.color;
 
buf[l++] = g_player[myconnectindex].pteam = ud.team;
 
for (i=0; i<10; i++)
{
g_player[myconnectindex].wchoice[i] = g_player[0].wchoice[i];
buf[l++] = (uint8_t)g_player[0].wchoice[i];
}
 
buf[l++] = myconnectindex;
 
if (g_netClient)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
else if (g_netServer)
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
}
 
void Net_SendUserMapName(void)
{
int32_t j;
 
if (numplayers < 2)
return;
 
packbuf[0] = PACKET_USER_MAP;
packbuf[1] = 0;
 
Bcorrectfilename(boardfilename,0);
 
j = Bstrlen(boardfilename);
boardfilename[j++] = 0;
Bstrcat(packbuf+1,boardfilename);
 
packbuf[j++] = myconnectindex;
 
if (g_netClient)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(packbuf, j, ENET_PACKET_FLAG_RELIABLE));
else if (g_netServer)
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, j, ENET_PACKET_FLAG_RELIABLE));
}
 
// FIXME: change all of the game starting support code to be fully server controlled
void Net_NewGame(int32_t volume, int32_t level)
{
packbuf[0] = PACKET_NEW_GAME;
packbuf[1] = ud.m_level_number = level;
packbuf[2] = ud.m_volume_number = volume;
packbuf[3] = ud.m_player_skill+1;
packbuf[4] = ud.m_monsters_off;
packbuf[5] = ud.m_respawn_monsters;
packbuf[6] = ud.m_respawn_items;
packbuf[7] = ud.m_respawn_inventory;
packbuf[8] = ud.m_coop;
packbuf[9] = ud.m_marker;
packbuf[10] = ud.m_ffire;
packbuf[11] = ud.m_noexits;
packbuf[12] = myconnectindex;
 
if (g_netClient)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(packbuf, 13, ENET_PACKET_FLAG_RELIABLE));
else if (g_netServer)
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 13, ENET_PACKET_FLAG_RELIABLE));
}
 
static mapstate_t *g_multiMapState = NULL;
static int32_t spritecrc[MAXSPRITES], lastupdate[MAXSPRITES], sectcrc[MAXSECTORS], lastsectupdate[MAXSECTORS];
static int32_t wallcrc[MAXWALLS], lastwallupdate[MAXWALLS];
 
// sends a simple crc32 of the current password, verified by the server before the connection can continue
static void Net_SendChallenge(void)
{
int32_t l = 1;
uint32_t crc = crc32once((uint8_t *)g_netPassword, Bstrlen(g_netPassword));
 
if (!g_netClientPeer) return;
 
buf[0] = PACKET_AUTH;
*(uint32_t *)&buf[1] = crc;
l += sizeof(int32_t);
 
buf[l++] = myconnectindex;
 
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
}
 
static void P_RemovePlayer(int32_t i)
{
// server obviously can't leave the game, and index 0 shows up for disconnect events from
// players that haven't gotten far enough into the connection process to get a player ID
 
if (i == 0) return;
 
g_player[i].playerquitflag = 0;
 
Bsprintf(buf,"%s^00 is history!",g_player[i].user_name);
G_AddUserQuote(buf);
 
if (numplayers == 1)
S_PlaySound(GENERIC_AMBIENCE17);
 
if (g_player[myconnectindex].ps->gm & MODE_GAME)
{
if (screenpeek == i)
screenpeek = myconnectindex;
 
pub = NUMPAGES;
pus = NUMPAGES;
G_UpdateScreenArea();
 
P_QuickKill(g_player[i].ps);
 
if (voting == i)
{
for (i=0; i<MAXPLAYERS; i++)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
voting = -1;
}
 
Bstrcpy(ScriptQuotes[116],buf);
g_player[myconnectindex].ps->ftq = 116;
g_player[myconnectindex].ps->fta = 180;
}
}
 
// sync a connecting player up with the current game state
void Net_SyncPlayer(ENetEvent * event)
{
int32_t i, j;
 
g_netPlayersWaiting++;
 
S_PlaySound(DUKE_GETWEAPON2);
 
TRAVERSE_CONNECT(i)
if (g_player[i].playerquitflag == 0)
break;
 
// open a new slot if necessary
event->peer->data = (void *)((intptr_t) (i = (i == -1 ? playerswhenstarted++ : i)));
 
g_player[i].netsynctime = totalclock;
g_player[i].playerquitflag = 1;
 
for (j=0; j<playerswhenstarted-1; j++) connectpoint2[j] = j+1;
connectpoint2[playerswhenstarted-1] = -1;
 
TRAVERSE_CONNECT(j)
{
if (!g_player[j].ps) g_player[j].ps = (DukePlayer_t *) Bcalloc(1, sizeof(DukePlayer_t));
if (!g_player[j].sync) g_player[j].sync = (input_t *) Bcalloc(1, sizeof(input_t));
}
 
packbuf[0] = PACKET_NUM_PLAYERS;
packbuf[1] = ++numplayers;
packbuf[2] = playerswhenstarted;
packbuf[3] = ++ud.multimode;
packbuf[4] = i;
packbuf[5] = myconnectindex;
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 6, ENET_PACKET_FLAG_RELIABLE));
 
packbuf[0] = PACKET_PLAYER_INDEX;
packbuf[1] = i;
packbuf[2] = myconnectindex;
enet_peer_send(event->peer, CHAN_GAMESTATE, enet_packet_create(packbuf, 3, ENET_PACKET_FLAG_RELIABLE));
 
Net_SendClientInfo();
Net_SendUserMapName();
 
if (g_player[0].ps->gm & MODE_GAME)
{
if (g_multiMapState == NULL) g_multiMapState = (mapstate_t *)Bcalloc(1, sizeof(mapstate_t));
if (g_multiMapState)
{
char * buf = (char *)Bmalloc(sizeof(mapstate_t)<<1);
 
sprite[g_player[i].ps->i].cstat = 32768;
g_player[i].ps->runspeed = g_playerFriction;
g_player[i].ps->last_extra = sprite[g_player[i].ps->i].extra = g_player[i].ps->max_player_health = g_maxPlayerHealth;
 
G_SaveMapState(g_multiMapState);
j = qlz_compress((char *)g_multiMapState, buf, sizeof(mapstate_t), state_compress);
 
// all of these packets are SYNCPACKETSIZE
while (j >= SYNCPACKETSIZE)
{
enet_peer_send(event->peer, CHAN_SYNC,
enet_packet_create((char *)(buf)+qlz_size_compressed(buf)-j, SYNCPACKETSIZE, ENET_PACKET_FLAG_RELIABLE));
j -= SYNCPACKETSIZE;
}
 
// ...except for this one. A non-SYNCPACKETSIZE packet on CHAN_SYNC doubles as the signal that the transfer is done.
enet_peer_send(event->peer, CHAN_SYNC,
enet_packet_create((char *)(buf)+qlz_size_compressed(buf)-j, j, ENET_PACKET_FLAG_RELIABLE));
 
Bfree(buf);
Bfree(g_multiMapState);
g_multiMapState = NULL;
}
}
}
 
int32_t Net_UnpackSprite(int32_t i, uint8_t *pbuf)
{
int16_t sect, statnum, osect, ostatnum, jj, opicnum, j = 0;
#ifdef POLYMER
int16_t lightid = -1;
_prlight *mylight = NULL;
#endif
 
osect = sprite[i].sectnum;
ostatnum = sprite[i].statnum;
opicnum = sprite[i].picnum;
 
Bmemcpy(&sprite[i], &pbuf[j], sizeof(spritetype));
j += sizeof(spritetype);
 
sect = sprite[i].sectnum;
statnum = sprite[i].statnum;
 
if (sect == MAXSECTORS || statnum == MAXSTATUS)
{
j += sizeof(NetActorData_t);
deletesprite(i);
return j;
}
 
sprite[i].sectnum = osect;
sprite[i].statnum = ostatnum;
 
// doesn't exist on the client yet
if (ostatnum == MAXSTATUS || osect == MAXSECTORS)
{
int16_t sprs[MAXSPRITES], z = 0;
while ((sprs[z++] = insertsprite(sect, statnum)) != i);
z--;
while (z--) deletesprite(sprs[z]);
}
else
{
if (sect != osect) changespritesect(i, sect);
if (statnum != ostatnum) changespritestat(i, statnum);
}
#ifdef POLYMER
if (sprite[i].picnum == opicnum)
{
mylight = actor[i].lightptr;
lightid = actor[i].lightId;
}
else if (getrendermode() == 4 && actor[i].lightptr != NULL)
{
polymer_deletelight(actor[i].lightId);
actor[i].lightId = -1;
actor[i].lightptr = NULL;
}
#endif
 
/*initprintf("updating sprite %d (%d)\n",i,sprite[i].picnum);*/
 
jj = j++;
 
Bmemcpy(&actor[i], &pbuf[j], sizeof(NetActorData_t));
j += sizeof(NetActorData_t);
 
actor[i].projectile = &SpriteProjectile[i];
#ifdef POLYMER
actor[i].lightptr = mylight;
actor[i].lightId = lightid;
#endif
 
actor[i].flags &= ~SPRITE_NULL;
 
if (pbuf[jj] & 1) T2 += (intptr_t)&script[0];
if (pbuf[jj] & 2) T5 += (intptr_t)&script[0];
if (pbuf[jj] & 4) T6 += (intptr_t)&script[0];
 
do
{
int16_t var_id = *(int16_t *)&pbuf[j];
 
j += sizeof(int16_t);
 
if (var_id == MAXGAMEVARS) break;
 
if (aGameVars[var_id].val.plValues)
aGameVars[var_id].val.plValues[i] = *(int32_t *)&pbuf[j];
j += sizeof(int32_t);
}
while (1);
 
return j;
}
 
int32_t Net_PackSprite(int32_t i, uint8_t *pbuf)
{
int32_t j = 0, jj;
 
*(int16_t *)&pbuf[j] = i;
j += sizeof(int16_t);
Bmemcpy(&pbuf[j], &sprite[i], sizeof(spritetype));
j += sizeof(spritetype);
 
pbuf[(jj = j++)] = 0;
 
if (T2 >= (intptr_t)&script[0] && T2 < (intptr_t)(&script[g_scriptSize]))
{
pbuf[jj] |= 1;
T2 -= (intptr_t)&script[0];
}
 
if (T5 >= (intptr_t)&script[0] && T5 < (intptr_t)(&script[g_scriptSize]))
{
pbuf[jj] |= 2;
T5 -= (intptr_t)&script[0];
}
 
if (T6 >= (intptr_t)&script[0] && T6 < (intptr_t)(&script[g_scriptSize]))
{
pbuf[jj] |= 4;
T6 -= (intptr_t)&script[0];
}
 
Bmemcpy(&pbuf[j], &actor[i], sizeof(NetActorData_t));
j += sizeof(NetActorData_t);
 
if (pbuf[jj] & 1) T2 += (intptr_t)&script[0];
if (pbuf[jj] & 2) T5 += (intptr_t)&script[0];
if (pbuf[jj] & 4) T6 += (intptr_t)&script[0];
 
{
int16_t ii=g_gameVarCount-1, kk = 0;
 
for (; ii>=0 && kk <= 64; ii--)
{
if ((aGameVars[ii].dwFlags & (GAMEVAR_PERACTOR|GAMEVAR_NOMULTI)) == GAMEVAR_PERACTOR && aGameVars[ii].val.plValues)
{
if (aGameVars[ii].val.plValues[i] != aGameVars[ii].lDefault)
{
*(int16_t *)&pbuf[j] = ii;
j += sizeof(int16_t);
*(int32_t *)&pbuf[j] = aGameVars[ii].val.plValues[i];
j += sizeof(int32_t);
kk++;
}
}
}
*(int16_t *)&pbuf[j] = MAXGAMEVARS;
j += sizeof(int16_t);
}
 
return j;
}
 
void Net_ParseServerPacket(ENetEvent * event)
{
uint8_t * pbuf = event->packet->data;
int32_t packbufleng = event->packet->dataLength;
int16_t i, j, l;
int32_t other = pbuf[--packbufleng];
input_t *nsyn;
 
#if 0
initprintf("RECEIVED PACKET: type: %d : len %d\n", pbuf[0], packbufleng);
#endif
switch (pbuf[0])
{
case PACKET_MASTER_TO_SLAVE: //[0] (receive master sync buffer)
if (!(g_player[myconnectindex].ps->gm & MODE_GAME) || g_netSync) return;
 
j = 0;
 
packbufleng = qlz_size_decompressed((char *)&pbuf[1]);
pbuf = (uint8_t *)Bcalloc(1, packbufleng+1);
packbufleng = qlz_decompress((char *)&event->packet->data[1], (char *)(pbuf), state_decompress);
 
ticrandomseed = *(int32_t *)&pbuf[j];
j += sizeof(int32_t);
ud.pause_on = pbuf[j++];
 
TRAVERSE_CONNECT(i)
{
g_player[i].ps->dead_flag = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
g_player[i].playerquitflag = pbuf[j++];
 
if (g_player[i].playerquitflag == 0) continue;
 
if (i == myconnectindex && !g_player[i].ps->dead_flag)
{
j += offsetof(input_t, filler) +
(sizeof(vec3_t) * 3) + // position and velocity
(sizeof(int16_t) * 3); // ang and horiz
goto process;
}
 
nsyn = (input_t *)&inputfifo[0][0];
 
Bmemcpy(&nsyn[i], &pbuf[j], offsetof(input_t, filler));
j += offsetof(input_t, filler);
 
// Bmemcpy(&g_player[i].ps->opos.x, &g_player[i].ps->pos.x, sizeof(vec3_t));
 
Bmemcpy(&g_player[i].ps->pos.x, &pbuf[j], sizeof(vec3_t) * 2);
if (g_player[i].ps->cursectnum >= 0 && g_player[i].ps->cursectnum < numsectors)
{
updatesectorz(g_player[i].ps->pos.x, g_player[i].ps->pos.y, g_player[i].ps->pos.z,
&g_player[i].ps->cursectnum);
changespritesect(g_player[i].ps->i, g_player[i].ps->cursectnum);
}
Bmemcpy(&sprite[g_player[i].ps->i], &pbuf[j], sizeof(vec3_t));
sprite[g_player[i].ps->i].z += PHEIGHT;
j += sizeof(vec3_t) * 2;
 
Bmemcpy(&g_player[i].ps->posvel.x, &pbuf[j], sizeof(vec3_t));
j += sizeof(vec3_t);
 
g_player[i].ps->oang = g_player[i].ps->ang;
g_player[i].ps->ang = sprite[g_player[i].ps->i].ang = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
Bmemcpy(&g_player[i].ps->ohoriz, &g_player[i].ps->horiz, sizeof(int16_t) * 2);
Bmemcpy(&g_player[i].ps->horiz, &pbuf[j], sizeof(int16_t) * 2);
j += sizeof(int16_t) * 2;
 
process:
g_player[i].ps->gotweapon = *(uint16_t *)&pbuf[j];
j += sizeof(uint16_t);
 
Bmemcpy(&g_player[i].ps->ammo_amount[0], &pbuf[j], sizeof(g_player[i].ps->ammo_amount));
j += sizeof(g_player[i].ps->ammo_amount);
 
Bmemcpy(&g_player[i].ps->inv_amount[0], &pbuf[j], sizeof(g_player[i].ps->inv_amount));
j += sizeof(g_player[i].ps->inv_amount);
 
Bmemcpy(g_player[i].frags, &pbuf[j], sizeof(g_player[i].frags));
j += sizeof(g_player[i].frags);
 
sprite[g_player[i].ps->i].extra = (uint8_t)pbuf[j++];
 
sprite[g_player[i].ps->i].cstat = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
g_player[i].ps->kickback_pic = (uint8_t)pbuf[j++];
 
actor[g_player[i].ps->i].owner = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
actor[g_player[i].ps->i].picnum = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
g_player[i].ps->curr_weapon = (uint8_t)pbuf[j++];
g_player[i].ps->last_weapon = (int8_t)pbuf[j++];
g_player[i].ps->wantweaponfire = (int8_t)pbuf[j++];
g_player[i].ps->weapon_pos = (int8_t)pbuf[j++];
g_player[i].ps->frag_ps = (uint8_t)pbuf[j++];
 
g_player[i].ps->frag = (uint8_t)pbuf[j++];
 
g_player[i].ps->fraggedself = (uint8_t)pbuf[j++];
 
g_player[i].ps->last_extra = (uint8_t)pbuf[j++];
 
g_player[i].ping = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
sprite[g_player[i].ps->i].pal = (uint8_t)pbuf[j++];
 
l = i;
 
i = g_player[l].ps->i;
 
{
int16_t jj = j++;
int32_t oa = (T5 >= (intptr_t)&script[0] && T5 < (intptr_t)&script[g_scriptSize]) ? T5-(intptr_t)&script[0] : T5;
 
Bmemcpy(&T5, &pbuf[j], sizeof(T5));
j += sizeof(T5);
 
if (oa != T5) T3 = T4 = 0;
if (pbuf[jj] & 2) T5 += (intptr_t)&script[0];
}
 
do
{
int16_t var_id = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
if (var_id == MAXGAMEVARS) break;
 
aGameVars[var_id].val.plValues[i] = *(int32_t *)&pbuf[j];
j += sizeof(int32_t);
}
while (1);
 
i = l;
 
do
{
int16_t var_id = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
if (var_id == MAXGAMEVARS) break;
 
aGameVars[var_id].val.plValues[i] = *(int32_t *)&pbuf[j];
j += sizeof(int32_t);
}
while (1);
}
 
{
// sprite/sector/wall updates tacked on to the end of the packet
 
l = pbuf[j++];
while (l--)
{
int32_t i = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
j += Net_UnpackSprite(i, &pbuf[j]);
}
}
 
Bfree(pbuf);
 
break;
 
case PACKET_MAP_STREAM:
if (!(g_player[myconnectindex].ps->gm & MODE_GAME) || g_netSync) return;
 
j = 0;
 
packbufleng = qlz_size_decompressed((char *)&pbuf[1]);
pbuf = (uint8_t *)Bcalloc(1, packbufleng+1);
packbufleng = qlz_decompress((char *)&event->packet->data[1], (char *)(pbuf), state_decompress);
 
l = pbuf[j++];
while (l--)
{
int32_t i = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
j += Net_UnpackSprite(i, &pbuf[j]);
}
 
l = pbuf[j++];
while (l--)
{
int16_t secid = *(int16_t *)&pbuf[j];
 
Bmemcpy(&sector[secid], &pbuf[j + sizeof(int16_t)], sizeof(sectortype));
j += sizeof(int16_t) + sizeof(sectortype);
}
 
l = pbuf[j++];
while (l--)
{
int16_t wallid = *(int16_t *)&pbuf[j];
 
Bmemcpy(&wall[wallid], &pbuf[j + sizeof(int16_t)], sizeof(walltype));
j += sizeof(int16_t) + sizeof(walltype);
// we call dragpoint() to make sure the nextwall position gets updated too
dragpoint(wallid, wall[wallid].x, wall[wallid].y);
}
 
Bfree(pbuf);
 
break;
 
 
case PACKET_MESSAGE:
Bstrncpy(recbuf, (char *)pbuf+2, packbufleng-2);
recbuf[packbufleng-2] = 0;
 
G_AddUserQuote(recbuf);
S_PlaySound(EXITMENUSOUND);
 
pus = pub = NUMPAGES;
 
break;
 
case PACKET_NEW_GAME:
if ((vote_map + vote_episode + voting) != -3)
G_AddUserQuote("VOTE SUCCEEDED");
 
ud.m_level_number = ud.level_number = pbuf[1];
ud.m_volume_number = ud.volume_number = pbuf[2];
ud.m_player_skill = ud.player_skill = pbuf[3];
ud.m_monsters_off = ud.monsters_off = pbuf[4];
ud.m_respawn_monsters = ud.respawn_monsters = pbuf[5];
ud.m_respawn_items = ud.respawn_items = pbuf[6];
ud.m_respawn_inventory = ud.respawn_inventory = pbuf[7];
ud.m_coop = pbuf[8];
ud.m_marker = ud.marker = pbuf[9];
ud.m_ffire = ud.ffire = pbuf[10];
ud.m_noexits = ud.noexits = pbuf[11];
 
TRAVERSE_CONNECT(i)
{
P_ResetWeapons(i);
P_ResetInventory(i);
}
 
G_NewGame(ud.volume_number,ud.level_number,ud.player_skill);
ud.coop = ud.m_coop;
 
if (G_EnterLevel(MODE_GAME)) G_BackToMenu();
break;
 
case PACKET_VERSION:
if (pbuf[1] != BYTEVERSION || pbuf[2] != (uint8_t)atoi(s_buildDate))
{
Bsprintf(tempbuf, "Server protocol is version %d.%d, expecting %d.%d\n",
pbuf[1], pbuf[2], BYTEVERSION, (uint8_t)atoi(s_buildDate));
initprintf(tempbuf);
initprintf("Server version mismatch! You cannot play Duke with different versions!\n");
g_netDisconnect = 1;
return;
}
Net_SendChallenge();
break;
 
case PACKET_NUM_PLAYERS:
numplayers = pbuf[1];
playerswhenstarted = pbuf[2];
ud.multimode = pbuf[3];
if (pbuf[4]) // ID of new player
{
g_player[pbuf[4]].playerquitflag = 1;
 
if (!g_player[pbuf[4]].ps) g_player[pbuf[4]].ps = (DukePlayer_t *) Bcalloc(1,sizeof(DukePlayer_t));
if (!g_player[pbuf[4]].sync) g_player[pbuf[4]].sync = (input_t *) Bcalloc(1,sizeof(input_t));
}
 
for (i=0; i<playerswhenstarted-1; i++) connectpoint2[i] = i+1;
connectpoint2[playerswhenstarted-1] = -1;
 
S_PlaySound(DUKE_GETWEAPON2);
 
// myconnectindex is 0 until we get PACKET_PLAYER_INDEX
if (myconnectindex != 0)
Net_SendClientInfo();
break;
 
// receive client player index from server
case PACKET_PLAYER_INDEX:
myconnectindex = pbuf[1];
g_player[myconnectindex].playerquitflag = 1;
Net_SendClientInfo();
break;
 
case PACKET_PLAYER_DISCONNECTED:
if ((g_player[myconnectindex].ps->gm & MODE_GAME) && !g_netSync)
P_RemovePlayer(pbuf[1]);
numplayers = pbuf[2];
ud.multimode = pbuf[3];
playerswhenstarted = pbuf[4];
break;
 
case PACKET_PLAYER_SPAWN:
if (!(g_player[myconnectindex].ps->gm & MODE_GAME) || g_netSync) break;
P_ResetPlayer(pbuf[1]);
break;
 
case PACKET_PLAYER_READY:
g_player[0].playerreadyflag++;
return;
 
case PACKET_FRAG:
if (!(g_player[myconnectindex].ps->gm & MODE_GAME) || g_netSync) break;
g_player[pbuf[1]].ps->frag_ps = pbuf[2];
actor[g_player[pbuf[1]].ps->i].picnum = pbuf[3];
ticrandomseed = *(int32_t *)&pbuf[4];
P_FragPlayer(pbuf[1]);
break;
 
case PACKET_CLIENT_INFO:
for (i=1; pbuf[i]; i++)
g_player[other].user_name[i-1] = pbuf[i];
g_player[other].user_name[i-1] = 0;
i++;
 
g_player[other].ps->aim_mode = pbuf[i++];
g_player[other].ps->auto_aim = pbuf[i++];
g_player[other].ps->weaponswitch = pbuf[i++];
g_player[other].ps->palookup = g_player[other].pcolor = pbuf[i++];
g_player[other].pteam = pbuf[i++];
 
j = i;
for (; i-j<10; i++) g_player[other].wchoice[i-j] = pbuf[i];
 
g_player[other].playerquitflag = 1;
 
break;
 
 
case PACKET_RTS:
if (numlumps == 0) break;
 
if (ud.config.SoundToggle == 0 || ud.lockout == 1 || ud.config.FXDevice < 0 || !(ud.config.VoiceToggle & 4))
break;
FX_PlayAuto3D((char *)RTS_GetSound(pbuf[1]-1),RTS_SoundLength(pbuf[1]-1),0,0,0,255,-pbuf[1]);
g_RTSPlaying = 7;
 
break;
 
case PACKET_USER_MAP:
Bstrcpy(boardfilename,(char *)pbuf+1);
boardfilename[packbufleng-1] = 0;
Bcorrectfilename(boardfilename,0);
if (boardfilename[0] != 0)
{
if ((i = kopen4loadfrommod(boardfilename,0)) < 0)
{
Bmemset(boardfilename,0,sizeof(boardfilename));
Net_SendUserMapName();
}
else kclose(i);
}
 
if (ud.m_level_number == 7 && ud.m_volume_number == 0 && boardfilename[0] == 0)
ud.m_level_number = 0;
 
break;
 
case PACKET_MAP_VOTE:
if (voting == myconnectindex && g_player[(uint8_t)pbuf[1]].gotvote == 0)
{
g_player[(uint8_t)pbuf[1]].gotvote = 1;
g_player[(uint8_t)pbuf[1]].vote = pbuf[2];
Bsprintf(tempbuf,"CONFIRMED VOTE FROM %s",g_player[(uint8_t)pbuf[1]].user_name);
G_AddUserQuote(tempbuf);
}
break;
 
case PACKET_MAP_VOTE_INITIATE: // call map vote
voting = pbuf[1];
vote_episode = pbuf[2];
vote_map = pbuf[3];
 
Bsprintf(tempbuf,"%s^00 HAS CALLED A VOTE TO CHANGE MAP TO %s (E%dL%d)",
g_player[(uint8_t)pbuf[1]].user_name,
MapInfo[(uint8_t)(pbuf[2]*MAXLEVELS + pbuf[3])].name,
pbuf[2]+1,pbuf[3]+1);
G_AddUserQuote(tempbuf);
 
Bsprintf(tempbuf,"PRESS F1 TO ACCEPT, F2 TO DECLINE");
G_AddUserQuote(tempbuf);
 
for (i=MAXPLAYERS-1; i>=0; i--)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
g_player[voting].gotvote = g_player[voting].vote = 1;
break;
 
case PACKET_MAP_VOTE_CANCEL: // cancel map vote
if (voting == pbuf[1])
{
voting = -1;
i = 0;
for (j=MAXPLAYERS-1; j>=0; j--)
i += g_player[j].gotvote;
 
if (i != numplayers)
Bsprintf(tempbuf,"%s^00 HAS CANCELED THE VOTE",g_player[(uint8_t)pbuf[1]].user_name);
else Bsprintf(tempbuf,"VOTE FAILED");
for (i=MAXPLAYERS-1; i>=0; i--)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
G_AddUserQuote(tempbuf);
}
break;
 
case PACKET_LOAD_GAME:
multiflag = 2;
multiwhat = 0;
multiwho = pbuf[2]; //other: need to send in m/s mode because of possible re-transmit
multipos = pbuf[1];
G_LoadPlayer(multipos);
multiflag = 0;
break;
}
}
 
void Net_ParseClientPacket(ENetEvent * event)
{
uint8_t * pbuf = event->packet->data;
int32_t packbufleng = event->packet->dataLength;
int16_t i, j;
int32_t other = pbuf[--packbufleng];
input_t *nsyn;
 
#if 0
initprintf("RECEIVED PACKET: type: %d : len %d\n", pbuf[0], packbufleng);
#endif
switch (pbuf[0])
{
case PACKET_SLAVE_TO_MASTER: //[1] (receive slave sync buffer)
j = 0;
 
packbufleng = qlz_size_decompressed((char *)&pbuf[1]);
pbuf = (uint8_t *)Bcalloc(1, packbufleng+1);
packbufleng = qlz_decompress((char *)&event->packet->data[1], (char *)(pbuf), state_decompress);
 
nsyn = (input_t *)&inputfifo[0][0];
 
Bmemcpy(&nsyn[other], &pbuf[j], sizeof(input_t));
 
j += offsetof(input_t, filler);
 
// anyone the server thinks is dead can go fuck themselves
if (g_player[other].ps->dead_flag)
{
Bfree(pbuf);
break;
}
else
g_player[other].playerquitflag = 1;
 
// Bmemcpy(&g_player[other].ps->opos.x, &g_player[other].ps->pos.x, sizeof(vec3_t));
Bmemcpy(&g_player[other].ps->pos.x, &pbuf[j], sizeof(vec3_t) * 2);
updatesectorz(g_player[other].ps->pos.x, g_player[other].ps->pos.y, g_player[other].ps->pos.z,
&g_player[other].ps->cursectnum);
Bmemcpy(&sprite[g_player[other].ps->i], &pbuf[j], sizeof(vec3_t));
sprite[g_player[other].ps->i].z += PHEIGHT;
changespritesect(g_player[other].ps->i, g_player[other].ps->cursectnum);
j += sizeof(vec3_t) * 2;
 
Bmemcpy(&g_player[other].ps->posvel.x, &pbuf[j], sizeof(vec3_t));
j += sizeof(vec3_t);
 
g_player[other].ps->oang = g_player[other].ps->ang;
Bmemcpy(&g_player[other].ps->ang, &pbuf[j], sizeof(int16_t));
Bmemcpy(&sprite[g_player[other].ps->i].ang, &pbuf[j], sizeof(int16_t));
j += sizeof(int16_t);
 
Bmemcpy(&g_player[other].ps->ohoriz, &g_player[other].ps->horiz, sizeof(int16_t) * 2);
Bmemcpy(&g_player[other].ps->horiz, &pbuf[j], sizeof(int16_t) * 2);
j += sizeof(int16_t) * 2;
 
Bfree(pbuf);
break;
 
case PACKET_PLAYER_READY:
if (g_player[myconnectindex].ps->gm & MODE_GAME)
{
packbuf[0] = PACKET_PLAYER_READY;
packbuf[1] = myconnectindex;
enet_peer_send(event->peer, CHAN_GAMESTATE, enet_packet_create(packbuf, 2, ENET_PACKET_FLAG_RELIABLE));
}
g_player[other].playerreadyflag++;
return;
 
case PACKET_MESSAGE:
Bstrncpy(recbuf, (char *)pbuf+2, packbufleng-2);
recbuf[packbufleng-2] = 0;
 
G_AddUserQuote(recbuf);
S_PlaySound(EXITMENUSOUND);
 
pus = pub = NUMPAGES;
break;
 
case PACKET_NEW_GAME:
if ((vote_map + vote_episode + voting) != -3)
G_AddUserQuote("VOTE SUCCEEDED");
 
ud.m_level_number = ud.level_number = pbuf[1];
ud.m_volume_number = ud.volume_number = pbuf[2];
ud.m_player_skill = ud.player_skill = pbuf[3];
ud.m_monsters_off = ud.monsters_off = pbuf[4];
ud.m_respawn_monsters = ud.respawn_monsters = pbuf[5];
ud.m_respawn_items = ud.respawn_items = pbuf[6];
ud.m_respawn_inventory = ud.respawn_inventory = pbuf[7];
ud.m_coop = pbuf[8];
ud.m_marker = ud.marker = pbuf[9];
ud.m_ffire = ud.ffire = pbuf[10];
ud.m_noexits = ud.noexits = pbuf[11];
 
TRAVERSE_CONNECT(i)
{
P_ResetWeapons(i);
P_ResetInventory(i);
}
 
G_NewGame(ud.volume_number,ud.level_number,ud.player_skill);
ud.coop = ud.m_coop;
 
if (G_EnterLevel(MODE_GAME)) G_BackToMenu();
break;
 
case PACKET_AUTH:
{
uint32_t crc = *(uint32_t *)&pbuf[1];
 
if (crc == crc32once((uint8_t *)g_netPassword, Bstrlen(g_netPassword)))
Net_SyncPlayer(event);
else
{
enet_peer_disconnect_later(event->peer, DISC_BAD_PASSWORD);
initprintf("Bad password from client.\n");
}
}
break;
 
case PACKET_CLIENT_INFO:
for (i=1; pbuf[i]; i++)
g_player[other].user_name[i-1] = pbuf[i];
g_player[other].user_name[i-1] = 0;
i++;
 
g_player[other].ps->aim_mode = pbuf[i++];
g_player[other].ps->auto_aim = pbuf[i++];
g_player[other].ps->weaponswitch = pbuf[i++];
g_player[other].ps->palookup = g_player[other].pcolor = pbuf[i++];
g_player[other].pteam = pbuf[i++];
 
for (j=i; i-j<10; i++) g_player[other].wchoice[i-j] = pbuf[i];
break;
 
case PACKET_RTS:
if (numlumps == 0) break;
 
if (ud.config.SoundToggle == 0 || ud.lockout == 1 || ud.config.FXDevice < 0 || !(ud.config.VoiceToggle & 4))
break;
 
FX_PlayAuto3D((char *)RTS_GetSound(pbuf[1]-1),RTS_SoundLength(pbuf[1]-1),0,0,0,255,-pbuf[1]);
g_RTSPlaying = 7;
break;
 
case PACKET_USER_MAP:
Bstrcpy(boardfilename,(char *)pbuf+1);
boardfilename[packbufleng-1] = 0;
Bcorrectfilename(boardfilename,0);
if (boardfilename[0] != 0)
{
if ((i = kopen4loadfrommod(boardfilename,0)) < 0)
{
Bmemset(boardfilename,0,sizeof(boardfilename));
Net_SendUserMapName();
}
else kclose(i);
}
 
if (ud.m_level_number == 7 && ud.m_volume_number == 0 && boardfilename[0] == 0)
ud.m_level_number = 0;
break;
 
case PACKET_MAP_VOTE:
if (voting == myconnectindex && g_player[(uint8_t)pbuf[1]].gotvote == 0)
{
g_player[(uint8_t)pbuf[1]].gotvote = 1;
g_player[(uint8_t)pbuf[1]].vote = pbuf[2];
Bsprintf(tempbuf,"CONFIRMED VOTE FROM %s",g_player[(uint8_t)pbuf[1]].user_name);
G_AddUserQuote(tempbuf);
}
break;
 
case PACKET_MAP_VOTE_INITIATE:
voting = pbuf[1];
vote_episode = pbuf[2];
vote_map = pbuf[3];
 
Bsprintf(tempbuf,"%s^00 HAS CALLED A VOTE TO CHANGE MAP TO %s (E%dL%d)",
g_player[(uint8_t)pbuf[1]].user_name,
MapInfo[(uint8_t)(pbuf[2]*MAXLEVELS + pbuf[3])].name,
pbuf[2]+1,pbuf[3]+1);
G_AddUserQuote(tempbuf);
 
Bsprintf(tempbuf,"PRESS F1 TO ACCEPT, F2 TO DECLINE");
G_AddUserQuote(tempbuf);
 
for (i=MAXPLAYERS-1; i>=0; i--)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
g_player[voting].gotvote = g_player[voting].vote = 1;
break;
 
case PACKET_MAP_VOTE_CANCEL:
if (voting == pbuf[1])
{
voting = -1;
i = 0;
for (j=MAXPLAYERS-1; j>=0; j--)
i += g_player[j].gotvote;
 
if (i != numplayers)
Bsprintf(tempbuf,"%s^00 HAS CANCELED THE VOTE",g_player[(uint8_t)pbuf[1]].user_name);
else Bsprintf(tempbuf,"VOTE FAILED");
for (i=MAXPLAYERS-1; i>=0; i--)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
G_AddUserQuote(tempbuf);
}
break;
 
case PACKET_LOAD_GAME:
multiflag = 2;
multiwhat = 0;
multiwho = pbuf[2]; //other: need to send in m/s mode because of possible re-transmit
multipos = pbuf[1];
G_LoadPlayer(multipos);
multiflag = 0;
break;
 
case PACKET_REQUEST_GAMESTATE:
if (g_netServer && g_player[0].ps->gm & MODE_GAME)
{
packbuf[0] = PACKET_NEW_GAME;
packbuf[1] = ud.level_number;
packbuf[2] = ud.volume_number;
packbuf[3] = ud.player_skill+1;
packbuf[4] = ud.monsters_off;
packbuf[5] = ud.respawn_monsters;
packbuf[6] = ud.respawn_items;
packbuf[7] = ud.respawn_inventory;
packbuf[8] = ud.coop;
packbuf[9] = ud.marker;
packbuf[10] = ud.ffire;
packbuf[11] = ud.noexits;
packbuf[12] = myconnectindex;
 
enet_peer_send(event->peer, CHAN_GAMESTATE, enet_packet_create(packbuf, 13, ENET_PACKET_FLAG_RELIABLE));
 
j = g_player[other].ps->i;
Bmemcpy(g_player[other].ps, g_player[0].ps, sizeof(DukePlayer_t));
 
g_player[other].ps->i = j;
changespritestat(j, STAT_PLAYER);
 
P_ResetStatus(other);
P_ResetWeapons(other);
P_ResetInventory(other);
 
g_player[other].ps->last_extra = sprite[g_player[other].ps->i].extra = g_player[other].ps->max_player_health;
sprite[g_player[other].ps->i].cstat = 1+256;
actor[g_player[other].ps->i].t_data[2] = actor[g_player[other].ps->i].t_data[3] = actor[g_player[other].ps->i].t_data[4] = 0;
 
g_netPlayersWaiting--;
 
// a player connecting is a good time to mark things as needing to be updated
// we invalidate everything that has changed since we started sending the snapshot of the map to the new player
 
{
int32_t zz, i, nexti;
 
for (zz = 0; (unsigned)zz < (sizeof(g_netStatnums)/sizeof(g_netStatnums[0])); zz++)
TRAVERSE_SPRITE_STAT(headspritestat[g_netStatnums[zz]], i, nexti)
{
if (lastupdate[i] >= g_player[other].netsynctime)
spritecrc[i] = 0xdeadbeef;
}
}
 
for (i=numwalls-1; i>=0; i--)
if (lastwallupdate[i] >= g_player[other].netsynctime)
wallcrc[i] = 0xdeadbeef;
 
for (i=numsectors-1; i>=0; i--)
if (lastsectupdate[i] >= g_player[other].netsynctime)
sectcrc[i] = 0xdeadbeef;
}
break;
}
}
 
 
void Net_GetPackets(void)
{
sampletimer();
MUSIC_Update();
S_Update();
 
G_HandleSpecialKeys();
 
if (g_netDisconnect)
{
Net_Disconnect();
g_netDisconnect = 0;
 
if (g_gameQuit)
G_GameExit(" ");
 
return;
}
 
if (g_netServer)
{
ENetEvent event;
 
// pull events from the wire into the packet queue without dispatching them, once per Net_GetPackets() call
enet_host_service(g_netServer, NULL, 0);
 
// dispatch any pending events from the local packet queue
while (enet_host_check_events(g_netServer, &event) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
{
char ipaddr[32];
 
enet_address_get_host_ip(&event.peer->address, ipaddr, sizeof(ipaddr));
 
initprintf("A new client connected from %s:%u.\n",
ipaddr, event.peer -> address.port);
}
Net_SendVersion(event.peer);
break;
 
case ENET_EVENT_TYPE_RECEIVE:
/*
initprintf ("A packet of length %u containing %s was received from player %d on channel %u.\n",
event.packet -> dataLength,
event.packet -> data,
event.peer -> data,
event.channelID);
*/
Net_ParseClientPacket(&event);
// broadcast takes care of enet_packet_destroy itself
// we set the state to disconnected so enet_host_broadcast doesn't send the player back his own packets
if ((event.channelID == CHAN_GAMESTATE && event.packet->data[0] > PACKET_BROADCAST) || event.channelID == CHAN_CHAT)
{
event.peer->state = ENET_PEER_STATE_DISCONNECTED;
enet_host_broadcast(g_netServer, event.channelID,
enet_packet_create(event.packet->data, event.packet->dataLength, event.packet->flags & ENET_PACKET_FLAG_RELIABLE));
event.peer->state = ENET_PEER_STATE_CONNECTED;
}
 
enet_packet_destroy(event.packet);
g_player[(intptr_t)event.peer->data].ping = (event.peer->lastRoundTripTime + event.peer->roundTripTime)/2;
break;
 
case ENET_EVENT_TYPE_DISCONNECT:
numplayers--;
ud.multimode--;
 
P_RemovePlayer((intptr_t)event.peer->data);
 
packbuf[0] = PACKET_PLAYER_DISCONNECTED;
packbuf[1] = (intptr_t)event.peer->data;
packbuf[2] = numplayers;
packbuf[3] = ud.multimode;
packbuf[4] = playerswhenstarted;
packbuf[5] = myconnectindex;
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 6, ENET_PACKET_FLAG_RELIABLE));
 
initprintf("%s disconnected.\n", g_player[(intptr_t)event.peer->data].user_name);
event.peer->data = NULL;
break;
 
default:
break;
}
}
}
else if (g_netClient)
{
ENetEvent event;
 
enet_host_service(g_netClient, NULL, 0);
 
while (enet_host_check_events(g_netClient, &event) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_RECEIVE:
 
/*
initprintf("A packet of length %u was received from player %d on channel %u.\n",
event.packet -> dataLength,
event.peer -> data,
event.channelID);
*/
 
// mapstate transfer from the server... all packets but the last are SYNCPACKETSIZE
if (event.channelID == CHAN_SYNC)
{
static int32_t datasiz = 0;
static uint8_t * buf = NULL;
 
if (buf == NULL)
{
datasiz = 0;
g_netSync = 1;
buf = Bcalloc(1, sizeof(mapstate_t)<<1);
}
 
g_multiMapState = (mapstate_t *)Brealloc(g_multiMapState, sizeof(mapstate_t));
 
if (buf && event.packet->dataLength == SYNCPACKETSIZE)
{
Bmemcpy((uint8_t *)(buf)+datasiz, event.packet->data, event.packet->dataLength);
datasiz += SYNCPACKETSIZE;
}
// last packet of mapstate sequence
else if (buf)
{
Bmemcpy((uint8_t *)(buf)+datasiz, event.packet->data, event.packet->dataLength);
datasiz = 0;
g_netSync = 0;
if (qlz_size_decompressed((const char *)buf) == sizeof(mapstate_t))
{
qlz_decompress((const char *)buf, g_multiMapState, state_decompress);
Bfree(buf);
buf = NULL;
 
packbuf[0] = PACKET_REQUEST_GAMESTATE;
packbuf[1] = myconnectindex;
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&packbuf[0], 2, ENET_PACKET_FLAG_RELIABLE));
}
else
{
initprintf("Invalid map state from server!\n");
Bfree(buf);
buf = NULL;
g_netDisconnect = 1;
}
}
else
{
initprintf("Error allocating buffer for map state!\n");
g_netDisconnect = 1;
}
}
else Net_ParseServerPacket(&event);
 
enet_packet_destroy(event.packet);
break;
 
case ENET_EVENT_TYPE_DISCONNECT:
g_netDisconnect = 1;
numplayers = playerswhenstarted = ud.multimode = 1;
myconnectindex = screenpeek = 0;
G_BackToMenu();
switch (event.data)
{
case DISC_BAD_PASSWORD:
initprintf("Bad password.\n");
return;
case DISC_KICKED:
initprintf("You have been kicked from the server.\n");
return;
case DISC_BANNED:
initprintf("You have been banned from this server.\n");
return;
default:
initprintf("Disconnected.\n");
return;
}
default:
break;
}
}
}
}
 
void Net_UpdateClients(void)
{
input_t * osyn = (input_t *)&inputfifo[1][0];
input_t * nsyn = (input_t *)&inputfifo[0][0];
int16_t i, nexti, k = 0, l;
int32_t j;
 
if (!g_netServer || numplayers < 2)
{
ticrandomseed = randomseed;
if (g_netServer)
Bmemcpy(&osyn[0], &nsyn[0], sizeof(input_t));
return;
}
 
packbuf[0] = PACKET_MASTER_TO_SLAVE;
j = 1;
 
*(int32_t *)&packbuf[j] = ticrandomseed = randomseed;
j += sizeof(int32_t);
packbuf[j++] = ud.pause_on;
 
TRAVERSE_CONNECT(i)
{
Bmemcpy(&osyn[i], &nsyn[i], offsetof(input_t, filler));
 
*(int16_t *)&packbuf[j] = g_player[i].ps->dead_flag;
j += sizeof(int16_t);
 
packbuf[j++] = g_player[i].playerquitflag;
 
if (g_player[i].playerquitflag == 0) continue;
 
Bmemcpy(&packbuf[j], &nsyn[i], offsetof(input_t, filler));
j += offsetof(input_t, filler);
 
Bmemcpy(&packbuf[j], &g_player[i].ps->pos.x, sizeof(vec3_t) * 2);
j += sizeof(vec3_t) * 2;
 
Bmemcpy(&packbuf[j], &g_player[i].ps->posvel.x, sizeof(vec3_t));
j += sizeof(vec3_t);
 
*(int16_t *)&packbuf[j] = g_player[i].ps->ang;
j += sizeof(int16_t);
 
Bmemcpy(&packbuf[j], &g_player[i].ps->horiz, sizeof(int16_t) * 2);
j += sizeof(int16_t) * 2;
 
*(uint16_t *)&packbuf[j] = g_player[i].ps->gotweapon;
j += sizeof(uint16_t);
 
Bmemcpy(&packbuf[j], &g_player[i].ps->ammo_amount[0], sizeof(g_player[i].ps->ammo_amount));
j += sizeof(g_player[i].ps->ammo_amount);
 
Bmemcpy(&packbuf[j], &g_player[i].ps->inv_amount[0], sizeof(g_player[i].ps->inv_amount));
j += sizeof(g_player[i].ps->inv_amount);
 
Bmemcpy(&packbuf[j], g_player[i].frags, sizeof(g_player[i].frags));
j += sizeof(g_player[i].frags);
 
packbuf[j++] = (uint8_t) sprite[g_player[i].ps->i].extra;
 
*(int16_t *)&packbuf[j] = sprite[g_player[i].ps->i].cstat;
j += sizeof(int16_t);
 
packbuf[j++] = (uint8_t) g_player[i].ps->kickback_pic;
 
*(int16_t *)&packbuf[j] = actor[g_player[i].ps->i].owner;
j += sizeof(int16_t);
 
*(int16_t *)&packbuf[j] = actor[g_player[i].ps->i].picnum;
j += sizeof(int16_t);
 
packbuf[j++] = (uint8_t) g_player[i].ps->curr_weapon;
packbuf[j++] = (int8_t) g_player[i].ps->last_weapon;
packbuf[j++] = (int8_t) g_player[i].ps->wantweaponfire;
packbuf[j++] = (int8_t) g_player[i].ps->weapon_pos;
packbuf[j++] = (uint8_t) g_player[i].ps->frag_ps;
 
packbuf[j++] = g_player[i].ps->frag;
packbuf[j++] = g_player[i].ps->fraggedself;
packbuf[j++] = g_player[i].ps->last_extra;
 
*(int16_t *)&packbuf[j] = g_player[i].ping;
j += sizeof(int16_t);
 
packbuf[j++] = sprite[g_player[i].ps->i].pal;
 
l = i;
i = g_player[l].ps->i;
 
{
int32_t jj, oa;
packbuf[(jj = j++)] = 0;
 
if (T5 >= (intptr_t)&script[0] && T5 < (intptr_t)(&script[g_scriptSize]))
{
packbuf[jj] |= 2;
T5 -= (intptr_t)&script[0];
}
 
oa = T5;
 
Bmemcpy(&packbuf[j], &T5, sizeof(T5));
j += sizeof(T5);
 
if (oa != T5) T3 = T4 = 0;
 
if (packbuf[jj] & 2) T5 += (intptr_t)&script[0];
}
 
{
int16_t ii=g_gameVarCount-1, kk = 0;
 
for (; ii>=0 && kk <= 64; ii--)
{
if ((aGameVars[ii].dwFlags & (GAMEVAR_PERACTOR|GAMEVAR_NOMULTI)) == GAMEVAR_PERACTOR && aGameVars[ii].val.plValues)
{
if (aGameVars[ii].val.plValues[i] != aGameVars[ii].lDefault)
{
*(int16_t *)&packbuf[j] = ii;
j += sizeof(int16_t);
*(int32_t *)&packbuf[j] = aGameVars[ii].val.plValues[i];
j += sizeof(int32_t);
kk++;
}
}
}
*(int16_t *)&packbuf[j] = MAXGAMEVARS;
j += sizeof(int16_t);
}
 
i = l;
 
{
int16_t ii=g_gameVarCount-1, kk = 0;
 
for (; ii>=0 && kk <= 64; ii--)
{
if ((aGameVars[ii].dwFlags & (GAMEVAR_PERPLAYER|GAMEVAR_NOMULTI)) == GAMEVAR_PERPLAYER && aGameVars[ii].val.plValues)
{
if (aGameVars[ii].val.plValues[i] != aGameVars[ii].lDefault)
{
*(int16_t *)&packbuf[j] = ii;
j += sizeof(int16_t);
*(int32_t *)&packbuf[j] = aGameVars[ii].val.plValues[i];
j += sizeof(int32_t);
kk++;
}
}
}
*(int16_t *)&packbuf[j] = MAXGAMEVARS;
j += sizeof(int16_t);
}
}
 
k = 0;
 
{
int32_t zz, zj;
 
packbuf[(zj = j++)] = 0;
 
for (zz = 0; (unsigned)zz < (sizeof(g_netStatnums)/sizeof(g_netStatnums[0])) /*&& k <= 3*/; zz++)
TRAVERSE_SPRITE_STAT(headspritestat[g_netStatnums[zz]], i, nexti)
{
// only send newly spawned sprites
if (!lastupdate[i])
{
lastupdate[i] = totalclock;
 
j += Net_PackSprite(i, (uint8_t *)&packbuf[j]);
k++;
}
}
 
packbuf[zj] = k;
j++;
}
 
{
char buf[PACKBUF_SIZE];
 
if (j >= PACKBUF_SIZE) {
initprintf("Global packet buffer overflow! Size of packet: %i\n", j);
}
 
j = qlz_compress((char *)(packbuf)+1, (char *)buf, j, state_compress);
Bmemcpy((char *)(packbuf)+1, (char *)buf, j);
j++;
}
 
packbuf[j++] = myconnectindex;
 
enet_host_broadcast(g_netServer, CHAN_MOVE, enet_packet_create(packbuf, j, 0));
}
 
void Net_StreamLevel(void)
{
int16_t i, nexti, k = 0, l;
int32_t j;
int32_t zz, zj;
 
if (!g_netServer || numplayers < 2)
return;
 
packbuf[0] = PACKET_MAP_STREAM;
j = 1;
 
packbuf[(zj = j++)] = 0;
 
for (zz = 0; (unsigned)zz < (sizeof(g_netStatnums)/sizeof(g_netStatnums[0])) /*&& k <= 3*/; zz++)
TRAVERSE_SPRITE_STAT(headspritestat[g_netStatnums[zz]], i, nexti)
{
// only send STAT_MISC sprites at spawn time and let the client handle it from there
if (totalclock > (lastupdate[i] + TICRATE) && sprite[i].statnum != STAT_MISC)
{
l = crc32once((uint8_t *)&sprite[i], sizeof(spritetype));
 
if (!lastupdate[i] || spritecrc[i] != l)
{
/*initprintf("updating sprite %d (%d)\n",i,sprite[i].picnum);*/
spritecrc[i] = l;
lastupdate[i] = totalclock;
 
j += Net_PackSprite(i, (uint8_t *)&packbuf[j]);
k++;
}
}
}
 
packbuf[zj] = k;
k = 0;
 
packbuf[(zj = j++)] = 0;
for (i = numsectors-1; i >= 0 && k <= 6; i--)
{
if (totalclock > (lastsectupdate[i] + TICRATE))
{
l = crc32once((uint8_t *)&sector[i], sizeof(sectortype));
 
if (sectcrc[i] != l)
{
sectcrc[i] = l;
lastsectupdate[i] = totalclock;
*(int16_t *)&packbuf[j] = i;
j += sizeof(int16_t);
Bmemcpy(&packbuf[j], &sector[i], sizeof(sectortype));
j += sizeof(sectortype);
k++;
}
}
}
packbuf[zj] = k;
k = 0;
 
packbuf[(zj = j++)] = 0;
for (i = numwalls-1; i >= 0 && k <= 6; i--)
{
if (totalclock > (lastwallupdate[i] + TICRATE))
{
l = crc32once((uint8_t *)&wall[i], sizeof(walltype));
 
if (wallcrc[i] != l)
{
wallcrc[i] = l;
lastwallupdate[i] = totalclock;
*(int16_t *)&packbuf[j] = i;
j += sizeof(int16_t);
Bmemcpy(&packbuf[j], &wall[i], sizeof(walltype));
j += sizeof(walltype);
k++;
}
}
}
packbuf[zj] = k;
 
j++;
 
{
char buf[PACKBUF_SIZE];
 
if (j >= PACKBUF_SIZE) {
initprintf("Global packet buffer overflow! Size of packet: %i\n", j);
}
 
j = qlz_compress((char *)(packbuf)+1, (char *)buf, j, state_compress);
Bmemcpy((char *)(packbuf)+1, (char *)buf, j);
j++;
}
 
packbuf[j++] = myconnectindex;
 
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, j, ENET_PACKET_FLAG_RELIABLE));
}
 
 
void faketimerhandler(void)
{
if (g_netServer)
enet_host_service(g_netServer, NULL, 0);
else if (g_netClient)
enet_host_service(g_netClient, NULL, 0);
}
 
extern int32_t cacnum;
typedef struct { intptr_t *hand; int32_t leng; char *lock ; } cactype;
extern cactype cac[];
 
static void G_ShowCacheLocks(void)
2352,7 → 592,7
k += 6;
 
for (i=10; i>=0; i--)
if (lumplockbyte[i] >= 200)
if (rts_lumplockbyte[i] >= 200)
{
Bsprintf(tempbuf,"RTS Locked %d:",i);
printext256(0L,k,31,-1,tempbuf,1);
2385,7 → 625,7
a = 1024;
 
rotatesprite((orientation&ROTATESPRITE_MAX)?x:(x<<16),(orientation&ROTATESPRITE_MAX)?y:(y<<16),
65536L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
65536L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
}
 
void G_DrawTilePal(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p)
2396,7 → 636,7
a = 1024;
 
rotatesprite((orientation&ROTATESPRITE_MAX)?x:(x<<16),(orientation&ROTATESPRITE_MAX)?y:(y<<16),
65536L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
65536L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
}
 
void G_DrawTileSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation)
2407,7 → 647,7
a = 1024;
 
rotatesprite((orientation&ROTATESPRITE_MAX)?x:(x<<16),(orientation&ROTATESPRITE_MAX)?y:(y<<16),
32768L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
32768L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
}
 
void G_DrawTilePalSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p)
2418,7 → 658,7
a = 1024;
 
rotatesprite((orientation&ROTATESPRITE_MAX)?x:(x<<16),(orientation&ROTATESPRITE_MAX)?y:(y<<16),
32768L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
32768L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
}
 
#define POLYMOSTTRANS (1)
2989,6 → 1229,7
minitext(284-30-o+1,180-3+1,"OFF",4,POLYMOSTTRANS+10+16+permbit+256 + ROTATESPRITE_MAX);
minitext(284-30-o,180-3,"OFF",2,10+16+permbit+256 + ROTATESPRITE_MAX);
}
 
if (p->inven_icon >= 6)
{
if (getrendermode() >= 3 && althud_shadows)
2995,7 → 1236,6
minitext(284-35-o+1,180-3+1,"AUTO",4,POLYMOSTTRANS+10+16+permbit+256 + ROTATESPRITE_MAX);
minitext(284-35-o,180-3,"AUTO",2,10+16+permbit+256 + ROTATESPRITE_MAX);
}
 
}
return;
}
3467,7 → 1707,7
// this handles both multiplayer and item pickup message type text
// both are passed on to gametext
 
static void G_PrintGameQuotes(void)
void G_PrintGameQuotes(void)
{
int32_t i, j, k, l;
 
3630,14 → 1870,14
}
}
else for (; start >= end; start += step)
{
if (KB_KeyPressed(sc_Space))
{
KB_ClearKeyDown(sc_Space);
return;
if (KB_KeyPressed(sc_Space))
{
KB_ClearKeyDown(sc_Space);
return;
}
G_FadePalette(r,g,b,start);
}
G_FadePalette(r,g,b,start);
}
}
 
void fadepaltile(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step, int32_t tile)
3656,15 → 1896,15
}
}
else for (; start >= end; start += step)
{
if (KB_KeyPressed(sc_Space))
{
KB_ClearKeyDown(sc_Space);
return;
if (KB_KeyPressed(sc_Space))
{
KB_ClearKeyDown(sc_Space);
return;
}
rotatesprite(0,0,65536L,0,tile,0,0,2+8+16+(ud.bgstretch?1024:0), 0,0,xdim-1,ydim-1);
G_FadePalette(r,g,b,start);
}
rotatesprite(0,0,65536L,0,tile,0,0,2+8+16+(ud.bgstretch?1024:0), 0,0,xdim-1,ydim-1);
G_FadePalette(r,g,b,start);
}
}
 
static void G_DisplayExtraScreens(void)
3684,7 → 1924,7
KB_FlushKeyboardQueue();
rotatesprite(0,0,65536L,0,3291,0,0,2+8+16+64+(ud.bgstretch?1024:0), 0,0,xdim-1,ydim-1);
fadepaltile(0,0,0, 63,0,-7, 3291);
while (!KB_KeyWaiting())
while (!KB_KeyWaiting())
{
handleevents();
Net_GetPackets();
3843,158 → 2083,7
return (0);
}
 
static void Net_EnterMessage(void)
{
int16_t hitstate, i, j, l;
 
if (g_player[myconnectindex].ps->gm&MODE_SENDTOWHOM)
{
if (g_chatPlayer != -1 || ud.multimode < 3)
{
tempbuf[0] = PACKET_MESSAGE;
tempbuf[2] = 0;
recbuf[0] = 0;
 
if (ud.multimode < 3)
g_chatPlayer = 2;
 
if (typebuf[0] == '/' && Btoupper(typebuf[1]) == 'M' && Btoupper(typebuf[2]) == 'E')
{
Bstrcat(recbuf,"* ");
i = 3, j = Bstrlen(typebuf);
Bstrcpy(tempbuf,typebuf);
while (i < j)
{
typebuf[i-3] = tempbuf[i];
i++;
}
typebuf[i-3] = '\0';
Bstrcat(recbuf,g_player[myconnectindex].user_name);
}
else
{
Bstrcat(recbuf,g_player[myconnectindex].user_name);
Bstrcat(recbuf,": ");
}
 
Bstrcat(recbuf,"^00");
Bstrcat(recbuf,typebuf);
j = Bstrlen(recbuf);
recbuf[j] = 0;
Bstrcat(tempbuf+2,recbuf);
 
if (g_chatPlayer >= ud.multimode)
{
tempbuf[1] = 255;
tempbuf[j+2] = myconnectindex;
j++;
if (g_netServer) enet_host_broadcast(g_netServer, CHAN_CHAT, enet_packet_create(tempbuf, j+2, 0));
else if (g_netClient) enet_peer_send(g_netClientPeer, CHAN_CHAT, enet_packet_create(tempbuf, j+2, 0));
G_AddUserQuote(recbuf);
quotebot += 8;
l = G_GameTextLen(USERQUOTE_LEFTOFFSET,OSD_StripColors(tempbuf,recbuf));
while (l > (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET))
{
l -= (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET);
quotebot += 8;
}
quotebotgoal = quotebot;
}
g_chatPlayer = -1;
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
}
else if (g_chatPlayer == -1)
{
j = 50;
gametext(320>>1,j,"SEND MESSAGE TO...",0,2+8+16);
j += 8;
TRAVERSE_CONNECT(i)
{
if (i == myconnectindex)
{
minitextshade((320>>1)-40+1,j+1,"A/ENTER - ALL",26,0,2+8+16);
minitext((320>>1)-40,j,"A/ENTER - ALL",0,2+8+16);
j += 7;
}
else
{
Bsprintf(buf," %d - %s",i+1,g_player[i].user_name);
minitextshade((320>>1)-40-6+1,j+1,buf,26,0,2+8+16);
minitext((320>>1)-40-6,j,buf,0,2+8+16);
j += 7;
}
}
minitextshade((320>>1)-40-4+1,j+1," ESC - Abort",26,0,2+8+16);
minitext((320>>1)-40-4,j," ESC - Abort",0,2+8+16);
j += 7;
 
if (ud.screen_size > 0) j = 200-45;
else j = 200-8;
mpgametext(j,typebuf,0,2+8+16);
 
if (KB_KeyWaiting())
{
i = KB_GetCh();
 
if (i == 'A' || i == 'a' || i == 13)
g_chatPlayer = ud.multimode;
else if (i >= '1' || i <= (ud.multimode + '1'))
g_chatPlayer = i - '1';
else
{
g_chatPlayer = ud.multimode;
if (i == 27)
{
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
g_chatPlayer = -1;
}
else
typebuf[0] = 0;
}
 
KB_ClearKeyDown(sc_1);
KB_ClearKeyDown(sc_2);
KB_ClearKeyDown(sc_3);
KB_ClearKeyDown(sc_4);
KB_ClearKeyDown(sc_5);
KB_ClearKeyDown(sc_6);
KB_ClearKeyDown(sc_7);
KB_ClearKeyDown(sc_8);
KB_ClearKeyDown(sc_A);
KB_ClearKeyDown(sc_Escape);
KB_ClearKeyDown(sc_Enter);
}
}
}
else
{
if (ud.screen_size > 1) j = 200-45;
else j = 200-8;
if (xdim >= 640 && ydim >= 480)
j = scale(j,ydim,200);
hitstate = Net_EnterText(320>>1,j,typebuf,120,1);
 
if (hitstate == 1)
{
KB_ClearKeyDown(sc_Enter);
if (Bstrlen(typebuf) == 0)
{
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
return;
}
if (ud.automsg)
{
if (SHIFTS_IS_PRESSED) g_chatPlayer = -1;
else g_chatPlayer = ud.multimode;
}
g_player[myconnectindex].ps->gm |= MODE_SENDTOWHOM;
}
else if (hitstate == -1)
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
else pub = NUMPAGES;
}
}
 
static inline void G_MoveClouds(void)
{
int32_t i;
4676,7 → 2765,7
VM_OnEvent(EVENT_DISPLAYCROSSHAIR, g_player[screenpeek].ps->i, screenpeek, -1);
if (aGameVars[g_iReturnVarID].val.lValue == 0)
rotatesprite((160L-(g_player[myconnectindex].ps->look_ang>>1))<<16,100L<<16,scale(65536,ud.crosshairscale,100),
0,CROSSHAIR,0,CROSSHAIR_PAL,2+1,windowx1,windowy1,windowx2,windowy2);
0,CROSSHAIR,0,CROSSHAIR_PAL,2+1,windowx1,windowy1,windowx2,windowy2);
}
#if 0
if (GametypeFlags[ud.coop] & GAMETYPE_TDM)
4686,7 → 2775,7
if (g_player[i].ps->team == g_player[myconnectindex].ps->team)
{
j = min(max((G_GetAngleDelta(getangle(g_player[i].ps->pos.x-g_player[myconnectindex].ps->pos.x,
g_player[i].ps->pos.y-g_player[myconnectindex].ps->pos.y),g_player[myconnectindex].ps->ang))>>1,-160),160);
g_player[i].ps->pos.y-g_player[myconnectindex].ps->pos.y),g_player[myconnectindex].ps->ang))>>1,-160),160);
rotatesprite((160-j)<<16,100L<<16,65536L,0,DUKEICON,0,0,2+1,windowx1,windowy1,windowx2,windowy2);
}
}
4740,7 → 2829,7
 
if (ud.player_skill > 3 || ((g_netServer || ud.multimode > 1) && !GTFLAGS(GAMETYPE_PLAYERSFRIENDLY)))
Bsprintf(tempbuf,"K:^15%d",(ud.multimode>1 &&!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY))?
g_player[myconnectindex].ps->frag-g_player[myconnectindex].ps->fraggedself:g_player[myconnectindex].ps->actors_killed);
g_player[myconnectindex].ps->frag-g_player[myconnectindex].ps->fraggedself:g_player[myconnectindex].ps->actors_killed);
else
{
if (g_player[myconnectindex].ps->actors_killed >= g_player[myconnectindex].ps->max_actors_killed)
4796,8 → 2885,9
int32_t bakcstat = sp->cstat;
hitdata_t hitinfo;
vec3_t n = { (sintable[(ang+1536)&2047]>>4),
(sintable[(ang+1024)&2047]>>4),
(horiz-100)*128 };
(sintable[(ang+1024)&2047]>>4),
(horiz-100)*128
};
 
sp->cstat &= (int16_t)~0x101;
 
4863,7 → 2953,7
 
y1 = 0;
y2 = ydim;
if (g_player[myconnectindex].ps->gm & MODE_GAME || ud.recstat == 2)
if (g_player[myconnectindex].ps->gm &MODE_GAME || ud.recstat == 2)
{
if (GametypeFlags[ud.coop] & GAMETYPE_FRAGBAR)
{
5485,7 → 3575,7
Gv_DumpValues();
// fclose(fp);
saveboard("debug.map",&g_player[myconnectindex].ps->pos.x,&g_player[myconnectindex].ps->pos.y,
&g_player[myconnectindex].ps->pos.z,&g_player[myconnectindex].ps->ang,&g_player[myconnectindex].ps->cursectnum);
&g_player[myconnectindex].ps->pos.z,&g_player[myconnectindex].ps->ang,&g_player[myconnectindex].ps->cursectnum);
}
 
int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int32_t s_pn,int32_t s_s,int32_t s_xr,int32_t s_yr,int32_t s_a,int32_t s_ve,int32_t s_zv,int32_t s_ow,int32_t s_ss)
5505,7 → 3595,7
}
 
Bmemcpy(s, &spr_temp, sizeof(spritetype));
Bmemset(&actor[i], 0, sizeof(ActorData_t));
Bmemset(&actor[i], 0, sizeof(actor_t));
Bmemcpy(&actor[i].bposx, s, sizeof(vec3_t)); // update bposx/y/z
 
actor[i].projectile = &SpriteProjectile[i];
5569,7 → 3659,7
{
i = pn;
 
Bmemset(&actor[i], 0, sizeof(ActorData_t));
Bmemset(&actor[i], 0, sizeof(actor_t));
Bmemcpy(&actor[i].bposx, &sprite[i], sizeof(vec3_t));
 
actor[i].picnum = PN;
6899,8 → 4989,8
if (sp->lotag != 23)
{
for (j=0; j<MAXSPRITES; j++)
if (sprite[j].statnum < MAXSTATUS && sprite[j].picnum == SECTOREFFECTOR &&
(sprite[j].lotag == 7 || sprite[j].lotag == 23) && i != j && sprite[j].hitag == SHT)
if (sprite[j].statnum < MAXSTATUS && sprite[j].picnum == SECTOREFFECTOR &&
(sprite[j].lotag == 7 || sprite[j].lotag == 23) && i != j && sprite[j].hitag == SHT)
{
OW = j;
break;
7497,7 → 5587,7
}
 
if (t->picnum < GREENSLIME || t->picnum > GREENSLIME+7)
switch (DynamicTileMap[t->picnum])
switch (DynamicTileMap[t->picnum])
{
case BLOODPOOL__STATIC:
case PUKE__STATIC:
8340,10 → 6430,10
 
actor[i].dispicnum = t->picnum;
// why?
/*
if (sector[t->sectnum].floorpicnum == MIRROR)
t->xrepeat = t->yrepeat = 0;
*/
/*
if (sector[t->sectnum].floorpicnum == MIRROR)
t->xrepeat = t->yrepeat = 0;
*/
}
 
if (apScriptGameEvent[EVENT_ANIMATESPRITES])
8772,7 → 6862,7
levnume--;
 
if ((VOLUMEONE && volnume > 0) || volnume > g_numVolumes-1 ||
levnume >= MAXLEVELS || MapInfo[volnume*MAXLEVELS+levnume].filename == NULL)
levnume >= MAXLEVELS || MapInfo[volnume *MAXLEVELS+levnume].filename == NULL)
{
g_player[myconnectindex].ps->cheat_phase = 0;
KB_FlushKeyBoardQueue();
8974,19 → 7064,8
}
}
 
static void demo_preparewarp()
void G_HandleLocalKeys(void)
{
if (!g_demo_paused)
{
g_demo_soundToggle = ud.config.SoundToggle;
ud.config.SoundToggle = 0;
}
FX_StopAllSounds();
S_ClearSoundLocks();
}
 
GAME_STATIC void G_HandleLocalKeys(void)
{
int32_t i,ch;
int32_t j;
 
9330,29 → 7409,29
screenpeek = myconnectindex;
}
 
/*
KB_ClearKeyDown(sc_Space);
KB_ClearKeyDown(sc_kpad_Enter);
KB_ClearKeyDown(sc_Enter);
MOUSE_ClearButton(LEFT_MOUSE);
ud.show_help ++;
/*
KB_ClearKeyDown(sc_Space);
KB_ClearKeyDown(sc_kpad_Enter);
KB_ClearKeyDown(sc_Enter);
MOUSE_ClearButton(LEFT_MOUSE);
ud.show_help ++;
 
if (ud.show_help > 2)
{
ud.show_help = 0;
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) ready2send = 1;
G_UpdateScreenArea();
}
else
{
setview(0,0,xdim-1,ydim-1);
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2)
{
ready2send = 0;
totalclock = ototalclock;
}
}
*/
if (ud.show_help > 2)
{
ud.show_help = 0;
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) ready2send = 1;
G_UpdateScreenArea();
}
else
{
setview(0,0,xdim-1,ydim-1);
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2)
{
ready2send = 0;
totalclock = ototalclock;
}
}
*/
}
 
// if((!net_server && ud.multimode < 2))
9800,7 → 7879,7
int32_t tokn;
char *cmdtokptr;
 
static tokenlist tokens[] =
static const tokenlist tokens[] =
{
{ "include", T_INCLUDE },
{ "#include", T_INCLUDE },
9811,7 → 7890,7
{ "sound", T_SOUND },
};
 
static tokenlist sound_musictokens[] =
static const tokenlist sound_musictokens[] =
{
{ "id", T_ID },
{ "file", T_FILE },
10176,11 → 8255,11
if (!Bstrcasecmp(c+1,"net"))
{
G_GameExit("EDuke32 no longer supports legacy networking.\n\n"
"If using YANG or other launchers that only support legacy netplay, download an older build of EDuke32. "
"Otherwise, run the following:\n\n"
"eduke32 -server\n\n"
"Other clients can then connect by typing \"connect [host]\" in the console.\n\n"
"EDuke32 will now close.");
"If using YANG or other launchers that only support legacy netplay, download an older build of EDuke32. "
"Otherwise, run the following:\n\n"
"eduke32 -server\n\n"
"Other clients can then connect by typing \"connect [host]\" in the console.\n\n"
"EDuke32 will now close.");
}
if (!Bstrcasecmp(c+1,"port"))
{
10974,7 → 9053,7
 
#ifdef WIN32
Bsprintf(tempbuf, "You have run Duke Nukem 3D shareware %d times. It is now time to upgrade to the complete version!\n\n"
"Purchase Duke Nukem 3D for $5.99 now?\n", ud.executions);
"Purchase Duke Nukem 3D for $5.99 now?\n", ud.executions);
 
if (wm_ynbox("Upgrade to the full version of Duke Nukem 3D",tempbuf))
{
11109,6 → 9188,7
ud.eog = 0;
if ((!g_netServer && ud.multimode < 2))
{
extern int32_t probey;
if (!VOLUMEALL)
G_DoOrderScreen();
g_player[myconnectindex].ps->gm = MODE_MENU;
11198,7 → 9278,7
GAME_getcolumnwidth,
GAME_getrowheight,
GAME_clearbackground,
(int32_t(*)(void))GetTime,
(int32_t( *)(void))GetTime,
GAME_onshowosd
);
Bstrcpy(tempbuf, APPNAME);
11290,8 → 9370,8
for (i=NUMGAMEFUNCTIONS-1; i>=0; i--)
{
char *str = Bstrtolower(Bstrdup(gamefunctions[i]));
hash_add(&h_gamefuncs,gamefunctions[i],i);
hash_add(&h_gamefuncs,str,i);
hash_add(&h_gamefuncs,gamefunctions[i],i,0);
hash_add(&h_gamefuncs,str,i,0);
Bfree(str);
}
 
11407,18 → 9487,9
{
// overwrite the default GRP and CON so that if the user chooses
// something different, they get what they asked for
if (WW2GI)
{
Bsprintf(defaultduke3dgrp,"ww2gi.grp");
Bsprintf(defaultduke3ddef,"ww2gi.def");
Bsprintf(defaultconfilename, "ww2gi.con");
}
else
{
Bsprintf(defaultduke3dgrp,"nam.grp");
Bsprintf(defaultduke3ddef,"nam.def");
Bsprintf(defaultconfilename, "nam.con");
}
Bsprintf(defaultduke3dgrp, WW2GI ? "ww2gi.grp" : "nam.grp");
Bsprintf(defaultduke3ddef, WW2GI ? "ww2gi.def" : "nam.def");
Bsprintf(defaultconfilename, WW2GI ? "ww2gi.con" : "nam.con");
 
Bsprintf(GametypeNames[0],"GRUNTMATCH (SPAWN)");
Bsprintf(GametypeNames[2],"GRUNTMATCH (NO SPAWN)");
11449,7 → 9520,7
}
 
// shitcan the old cache directory
#if defined(POLYMOST) && defined(USE_OPENGL)
#if 0 && defined(POLYMOST) && defined(USE_OPENGL)
{
struct stat st;
char dir[BMAX_PATH];
11528,9 → 9599,7
}
#endif
 
i = initgroupfile(g_grpNamePtr);
 
if (i == -1)
if ((i = initgroupfile(g_grpNamePtr)) == -1)
initprintf("Warning: could not find main data file '%s'!\n",g_grpNamePtr);
else
initprintf("Using '%s' as main game data file.\n", g_grpNamePtr);
11584,8 → 9653,9
while (CommandGrps)
{
s = CommandGrps->next;
j = initgroupfile(CommandGrps->str);
if (j == -1) initprintf("Could not find file '%s'.\n",CommandGrps->str);
 
if ((j = initgroupfile(CommandGrps->str)) == -1)
initprintf("Could not find file '%s'.\n",CommandGrps->str);
else
{
g_groupFileHandle = j;
11697,7 → 9767,7
 
RTS_Init(ud.rtsname);
 
if (numlumps)
if (rts_numlumps)
initprintf("Using .RTS file '%s'\n",ud.rtsname);
 
if (ud.last_level)
11755,14 → 9825,13
while (setgamemode(0,xres[i],yres[i],bpp[j]) < 0)
{
initprintf("Failure setting video mode %dx%dx%d windowed! Attempting safer mode...\n",xres[i],yres[i],bpp[i]);
j++;
if (j == 3)
 
if (++j == 3)
{
i++;
if (++i == 4)
G_GameExit("Unable to set failsafe video mode!");
j = 0;
}
if (i == 4)
G_GameExit("Unable to set failsafe video mode!");
}
}
#else
11878,7 → 9947,7
KB_KeyDown[sc_Escape] = 1;
quitevent = 0;
}
 
sampletimer();
MUSIC_Update();
Net_GetPackets();
11904,21 → 9973,21
Bmemcpy(&inputfifo[0][myconnectindex], &avg, sizeof(input_t));
Bmemset(&avg, 0, sizeof(input_t));
 
/*
if (ud.playerai && (g_netServer || ud.multimode > 1))
{
TRAVERSE_CONNECT(i)
if (i != myconnectindex)
{
//clearbufbyte(&inputfifo[g_player[i].movefifoend&(MOVEFIFOSIZ-1)][i],sizeof(input_t),0L);
computergetinput(i,&inputfifo[0][i]);
}
}
*/
/*
if (ud.playerai && (g_netServer || ud.multimode > 1))
{
TRAVERSE_CONNECT(i)
if (i != myconnectindex)
{
//clearbufbyte(&inputfifo[g_player[i].movefifoend&(MOVEFIFOSIZ-1)][i],sizeof(input_t),0L);
computergetinput(i,&inputfifo[0][i]);
}
}
*/
 
j = 0;
 
do
do
{
sampletimer();
 
11927,7 → 9996,7
ototalclock += TICSPERFRAME;
 
if (((ud.show_help == 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU) || ud.recstat == 2 || (g_netServer || ud.multimode > 1)) &&
(g_player[myconnectindex].ps->gm&MODE_GAME) && G_MoveLoop())
(g_player[myconnectindex].ps->gm&MODE_GAME) && G_MoveLoop())
j++;
}
while (!(g_player[myconnectindex].ps->gm & (MODE_MENU|MODE_DEMO)) && totalclock >= ototalclock+TICSPERFRAME);
11980,7 → 10049,7
nextrender += g_frameDelay;
 
if ((ud.show_help == 0 && (!g_netServer && ud.multimode < 2) && !(g_player[myconnectindex].ps->gm&MODE_MENU)) ||
(g_netServer || ud.multimode > 1) || ud.recstat == 2)
(g_netServer || ud.multimode > 1) || ud.recstat == 2)
i = min(max((totalclock-ototalclock)*(65536L/TICSPERFRAME),0),65536);
else
i = 65536;
12001,643 → 10070,6
G_GameExit(" ");
}
 
extern int32_t sv_loadsnapshot(int32_t fil, int32_t *ret_hasdiffs, int32_t *ret_demoticcnt, int32_t *ret_synccompress);
 
GAME_STATIC int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
{
char d[14];
int32_t i;
 
Bstrcpy(d, "edemo_.edm");
 
if (g_whichDemo == 10)
d[5] = 'x';
else
d[5] = '0' + g_whichDemo;
 
if (g_whichDemo == 1 && firstdemofile[0] != 0)
{
if ((g_demo_recFilePtr = kopen4loadfrommod(firstdemofile,g_loadFromGroupOnly)) == -1) return(0);
}
else if ((g_demo_recFilePtr = kopen4loadfrommod(d,g_loadFromGroupOnly)) == -1) return(0);
 
i=sv_loadsnapshot(g_demo_recFilePtr, &demo_hasdiffs, &g_demo_totalCnt, &demo_synccompress);
if (i==0)
{
demo_hasseeds = demo_synccompress&2;
demo_synccompress &= 1;
 
i = g_demo_totalCnt/(TICRATE/TICSPERFRAME);
OSD_Printf("demo duration: %d min %d sec\n", i/60, i%60);
 
g_demo_cnt=1;
ud.reccnt = 0;
 
ud.god = ud.cashman = ud.eog = ud.showallmap = 0;
ud.clipping = ud.scrollmode = ud.overhead_on = 0; //= ud.pause_on = 0;
 
// G_NewGame(ud.volume_number,ud.level_number,ud.player_skill);
// G_ResetTimers();
totalclock = ototalclock = lockclock = 0;
 
return 1;
}
else
{
OSD_Printf(OSD_ERROR "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
kclose(g_demo_recFilePtr);
return 0;
}
#if 0
corrupt:
OSD_Printf(OSD_ERROR "Demo %d header is corrupt.\n",g_whichDemo);
ud.reccnt = 0;
kclose(g_demo_recFilePtr);
return 0;
#endif
}
 
#if KRANDDEBUG
extern void krd_enable(int32_t which);
extern int32_t krd_print(const char *filename);
#endif
 
void G_OpenDemoWrite(void)
{
char d[14];
int32_t i, demonum=1;
extern int32_t sv_saveandmakesnapshot(FILE* fil, int32_t recdiffs, int32_t diffcompress, int32_t synccompress);
 
if (ud.recstat == 2) kclose(g_demo_recFilePtr);
 
if ((g_player[myconnectindex].ps->gm&MODE_GAME) && g_player[myconnectindex].ps->dead_flag)
{
Bstrcpy(ScriptQuotes[122], "CANNOT START DEMO RECORDING WHEN DEAD!");
P_DoQuote(122, g_player[myconnectindex].ps);
ud.recstat = ud.m_recstat = 0;
return;
}
 
if (demorec_diffs_cvar && !demorec_force_cvar)
for (i=1; i<g_scriptSize-2; i++)
{
intptr_t w=script[i];
if ((w&0x0fff)==CON_RESIZEARRAY && (w>>12) && script[i+1]>=0 && script[i+1]<g_gameArrayCount)
{
OSD_Printf("\nThe CON code possibly contains a RESIZEARRAY command.\n");
OSD_Printf("Gamearrays that change their size during the game are unsupported by\n");
OSD_Printf("the demo recording system. If you are sure that the code doesn't\n");
OSD_Printf("contain a RESIZEARRAY command, you can force recording with the\n");
OSD_Printf("`demorec_force' cvar. Alternatively, you can disable diff recording\n");
OSD_Printf("with the `demorec_diffs' cvar.\n\n");
Bstrcpy(ScriptQuotes[122], "FAILED STARTING DEMO RECORDING. SEE OSD FOR DETAILS.");
P_DoQuote(122, g_player[myconnectindex].ps);
ud.recstat = ud.m_recstat = 0;
return;
}
}
 
while (1)
{
if (demonum == 10000) return;
Bsprintf(d, "edemo%d.edm", demonum++);
g_demo_filePtr = fopen(d, "rb");
if (g_demo_filePtr == NULL) break;
Bfclose(g_demo_filePtr);
}
 
if ((g_demo_filePtr = fopen(d,"wb")) == NULL) return;
 
i=sv_saveandmakesnapshot(g_demo_filePtr, demorec_diffs_cvar, demorec_diffcompress_cvar,
demorec_synccompress_cvar|(demorec_seeds_cvar<<1));
if (i)
{
Bstrcpy(ScriptQuotes[122], "FAILED STARTING DEMO RECORDING. SEE OSD FOR DETAILS.");
P_DoQuote(122, g_player[myconnectindex].ps);
Bfclose(g_demo_filePtr), g_demo_filePtr=NULL;
ud.recstat = ud.m_recstat = 0;
return;
}
demorec_seeds = demorec_seeds_cvar;
demorec_diffs = demorec_diffs_cvar;
demo_synccompress = demorec_synccompress_cvar;
demorec_difftics = demorec_difftics_cvar;
 
Bstrcpy(ScriptQuotes[122], "DEMO RECORDING STARTED");
P_DoQuote(122, g_player[myconnectindex].ps);
 
ud.reccnt = 0;
ud.recstat = ud.m_recstat = 1; //
 
#if KRANDDEBUG
krd_enable(1);
#endif
 
g_demo_cnt = 1;
}
 
 
static uint8_t g_demo_seedbuf[RECSYNCBUFSIZ];
 
static void dowritesync()
{
int16_t tmpreccnt;
 
fwrite("sYnC", 4, 1, g_demo_filePtr);
tmpreccnt = (int16_t)ud.reccnt;
fwrite(&tmpreccnt, sizeof(int16_t), 1, g_demo_filePtr);
if (demorec_seeds)
fwrite(g_demo_seedbuf, 1, ud.reccnt, g_demo_filePtr);
 
if (demo_synccompress)
dfwrite(recsync, sizeof(input_t), ud.reccnt, g_demo_filePtr);
else //if (demo_synccompress==0)
fwrite(recsync, sizeof(input_t), ud.reccnt, g_demo_filePtr);
ud.reccnt = 0;
}
 
static void G_DemoRecord(void)
{
int16_t i;
extern uint32_t sv_writediff(FILE *fil);
 
g_demo_cnt++;
 
if (demorec_diffs && (g_demo_cnt%demorec_difftics == 1))
{
sv_writediff(g_demo_filePtr);
demorec_difftics = demorec_difftics_cvar;
}
 
if (demorec_seeds)
g_demo_seedbuf[ud.reccnt] = (uint8_t)(randomseed>>24);
 
TRAVERSE_CONNECT(i)
{
Bmemcpy(&recsync[ud.reccnt], g_player[i].sync, sizeof(input_t));
ud.reccnt++;
}
 
if (ud.reccnt > RECSYNCBUFSIZ-MAXPLAYERS || (demorec_diffs && (g_demo_cnt%demorec_difftics == 0)))
dowritesync();
}
 
void G_CloseDemoWrite(void)
{
extern void sv_freemem();
 
if (ud.recstat == 1)
{
if (ud.reccnt > 0)
dowritesync();
 
fwrite("EnD!", 4, 1, g_demo_filePtr);
 
if (fseek(g_demo_filePtr, 20, SEEK_SET))
perror("G_CloseDemoWrite: fseek");
else
fwrite(&g_demo_cnt, sizeof(g_demo_cnt), 1, g_demo_filePtr);
 
ud.recstat = ud.m_recstat = 0;
fclose(g_demo_filePtr);
 
sv_freemem();
 
Bstrcpy(ScriptQuotes[122], "DEMO RECORDING STOPPED");
P_DoQuote(122, g_player[myconnectindex].ps);
}
#if KRANDDEBUG
krd_print("krandrec.log");
#endif
}
 
static int32_t g_whichDemo = 1;
extern int32_t sv_updatestate(int32_t frominit);
 
static void dorestoremodes(int32_t menu)
{
if (menu) g_player[myconnectindex].ps->gm |= MODE_MENU;
else g_player[myconnectindex].ps->gm &= ~MODE_MENU;
g_player[myconnectindex].ps->gm &= ~MODE_GAME;
g_player[myconnectindex].ps->gm |= MODE_DEMO;
}
 
static int32_t doupdatestate(int32_t frominit)
{
int32_t j,k;
j = g_player[myconnectindex].ps->gm&MODE_MENU;
k = sv_updatestate(frominit);
// tmpdifftime = g_demo_cnt+12;
dorestoremodes(j);
if (k) OSD_Printf("sv_updatestate() returned %d.\n", k);
return k;
}
 
#define CORRUPT(code) do { corruptcode=code; goto corrupt; } while(0)
 
#define DOREADSYNC(code) do \
{ \
uint16_t si; \
int32_t i; \
if (kread(g_demo_recFilePtr, &si, sizeof(uint16_t)) != (int32_t)sizeof(uint16_t)) CORRUPT(code); \
i = si; \
if (demo_hasseeds) \
{ \
if (kread(g_demo_recFilePtr, g_demo_seedbuf, i) != i) CORRUPT(code); \
} \
if (demo_synccompress) \
{ \
if (kdfread(recsync, sizeof(input_t), i, g_demo_recFilePtr) != i) CORRUPT(code+1); \
} \
else \
if (kread(g_demo_recFilePtr, recsync, sizeof(input_t)*i) != (int32_t)sizeof(input_t)*i) CORRUPT(code+2); \
ud.reccnt = i; \
} while (0)
 
 
GAME_STATIC int32_t G_PlaybackDemo(void)
{
int32_t bigi, j, k, initsyncofs = 0, lastsyncofs = 0, lastsynctic = 0, lastsyncclock = 0;
int32_t foundemo = 0, corruptcode, outofsync=0;
static int32_t in_menu = 0;
// static int32_t tmpdifftime=0;
 
if (ready2send) return 0;
 
RECHECK:
 
#if KRANDDEBUG
if (foundemo)
krd_print("krandplay.log");
#endif
 
in_menu = g_player[myconnectindex].ps->gm&MODE_MENU;
 
pub = NUMPAGES;
pus = NUMPAGES;
 
flushperms();
if ((!g_netServer && ud.multimode < 2)) foundemo = G_OpenDemoRead(g_whichDemo);
if (foundemo == 0)
{
if (g_whichDemo > 1)
{
g_whichDemo = 1;
goto RECHECK;
}
fadepal(0,0,0, 0,63,7);
P_SetGamePalette(g_player[myconnectindex].ps, palette, 1); // JBF 20040308
G_DrawBackground();
M_DisplayMenus();
//g_player[myconnectindex].ps->palette = palette;
nextpage();
fadepal(0,0,0, 63,0,-7);
ud.reccnt = 0;
}
else
{
ud.recstat = 2;
g_whichDemo++;
if (g_whichDemo == 10) g_whichDemo = 1;
 
g_player[myconnectindex].ps->gm &= ~MODE_GAME;
g_player[myconnectindex].ps->gm |= MODE_DEMO;
 
// if (G_EnterLevel(MODE_DEMO))
// {
// OSD_Printf("G_PlaybackDemo: G_EnterLevel\n");
// ud.recstat = foundemo = 0;
// }
//
lastsyncofs = ktell(g_demo_recFilePtr);
initsyncofs = lastsyncofs;
lastsynctic = g_demo_cnt;
lastsyncclock = totalclock;
outofsync = 0;
#if KRANDDEBUG
krd_enable(2);
#endif
}
 
if (foundemo == 0 || in_menu || KB_KeyWaiting() || numplayers > 1)
{
FX_StopAllSounds();
S_ClearSoundLocks();
g_player[myconnectindex].ps->gm |= MODE_MENU;
}
 
ready2send = 0;
bigi = 0;
 
KB_FlushKeyboardQueue();
 
// OSD_Printf("ticcnt=%d, total=%d\n", g_demo_cnt, g_demo_totalCnt);
while (g_demo_cnt < g_demo_totalCnt || foundemo==0)
{
if (foundemo && (!g_demo_paused || g_demo_goalCnt))
{
if (g_demo_goalCnt>0 && g_demo_goalCnt < g_demo_cnt) // rewind
{
k = g_player[myconnectindex].ps->gm&MODE_MENU;
if (g_demo_goalCnt > lastsynctic)
{
if (doupdatestate(0)==0)
{
g_demo_cnt = lastsynctic;
klseek(g_demo_recFilePtr, lastsyncofs, SEEK_SET);
ud.reccnt = 0;
 
totalclock = ototalclock = lockclock = lastsyncclock;
}
else CORRUPT(-1);
}
else
{
//loadfrombeg:
// j = sv_loadsnapshot(g_demo_recFilePtr, &g_demo_totalCnt);
j = doupdatestate(1);
if (!j)
{
klseek(g_demo_recFilePtr, initsyncofs, SEEK_SET);
g_levelTextTime = 0;
 
g_demo_cnt = 1;
ud.reccnt = 0;
 
// ud.god = ud.cashman = ud.eog = ud.showallmap = 0;
// ud.clipping = ud.scrollmode = ud.overhead_on = ud.pause_on = 0;
 
totalclock = ototalclock = lockclock = 0;
}
else CORRUPT(0);
}
dorestoremodes(k);
}
 
while (totalclock >= (lockclock+TICSPERFRAME)
// || (ud.reccnt > (TICRATE/TICSPERFRAME)*2 && ud.pause_on)
|| (g_demo_goalCnt>0 && g_demo_cnt<g_demo_goalCnt))
{
if (ud.reccnt<=0)
{
char tmpbuf[4];
 
if (ud.reccnt<0)
{
OSD_Printf("G_PlaybackDemo: ud.reccnt<0!\n");
CORRUPT(1);
}
 
bigi = 0;
//reread:
if (kread(g_demo_recFilePtr, tmpbuf, 4) != 4) CORRUPT(2);
 
if (Bmemcmp(tmpbuf, "sYnC", 4)==0)
DOREADSYNC(3);
else if (demo_hasdiffs && Bmemcmp(tmpbuf, "dIfF", 4)==0)
{
extern int32_t sv_readdiff(int32_t fil);
 
k=sv_readdiff(g_demo_recFilePtr);
if (k)
{
OSD_Printf("sv_readdiff() returned %d.\n", k);
CORRUPT(6);
}
else
{
lastsyncofs = ktell(g_demo_recFilePtr);
lastsynctic = g_demo_cnt;
lastsyncclock = totalclock;
if (kread(g_demo_recFilePtr, tmpbuf, 4) != 4) CORRUPT(7);
if (Bmemcmp(tmpbuf, "sYnC", 4)) CORRUPT(8);
DOREADSYNC(9);
 
if ((g_demo_goalCnt==0 && demoplay_diffs) ||
(g_demo_goalCnt>0 && ud.reccnt/ud.multimode >= g_demo_goalCnt-g_demo_cnt))
{
doupdatestate(0);
}
}
}
else if (Bmemcmp(tmpbuf, "EnD!", 4)==0)
goto nextdemo;
else CORRUPT(12);
 
if (0)
{
corrupt:
OSD_Printf(OSD_ERROR "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
nextdemo:
foundemo = 0;
ud.reccnt = 0;
kclose(g_demo_recFilePtr);
g_player[myconnectindex].ps->gm |= MODE_MENU;
if (g_demo_goalCnt>0)
{
g_demo_goalCnt=0;
ud.config.SoundToggle = g_demo_soundToggle;
}
goto RECHECK;
}
}
 
if (demo_hasseeds)
outofsync = (uint8_t)(randomseed>>24) != g_demo_seedbuf[bigi];
 
TRAVERSE_CONNECT(j)
{
copybufbyte(&recsync[bigi], &inputfifo[0][j], sizeof(input_t));
bigi++;
ud.reccnt--;
}
g_demo_cnt++;
 
if (!g_demo_paused)
{
// assumption that ud.multimode doesn't change in a demo may not be true
// sometime in the future v v v v v v v v v
if (g_demo_goalCnt==0 || !demo_hasdiffs || ud.reccnt/ud.multimode>=g_demo_goalCnt-g_demo_cnt)
G_DoMoveThings(); // increases lockclock by TICSPERFRAME
else
lockclock += TICSPERFRAME;
}
else
{
k = ud.config.SoundToggle;
ud.config.SoundToggle = 0;
G_DoMoveThings();
ud.config.SoundToggle = k;
}
 
ototalclock += TICSPERFRAME;
 
if (g_demo_goalCnt > 0)
{
totalclock += TICSPERFRAME;
 
// OSD_Printf("t:%d, l+T:%d; cnt:%d, goal:%d%s", totalclock, (lockclock+TICSPERFRAME),
// g_demo_cnt, g_demo_goalCnt, g_demo_cnt>=g_demo_goalCnt?" ":"\n");
if (g_demo_cnt>=g_demo_goalCnt)
{
g_demo_goalCnt = 0;
ud.config.SoundToggle = g_demo_soundToggle;
}
}
}
}
else if (foundemo && g_demo_paused)
{
totalclock = lockclock;
}
 
if (foundemo == 0)
G_DrawBackground();
else
{
G_HandleLocalKeys();
 
// j = min(max((totalclock-lockclock)*(65536/TICSPERFRAME),0),65536);
 
j = min(max((totalclock - ototalclock) * (65536 / 4),0),65536);
if (g_demo_paused && g_demo_rewind)
j = 65536-j;
 
G_DrawRooms(screenpeek,j);
G_DisplayRest(j);
 
if ((g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
{
if (demoplay_showsync && outofsync)
gametext(160,100,"OUT OF SYNC",0,2+8+16);
 
if (g_demo_showStats)
{
// if (g_demo_cnt<tmpdifftime)
// gametext(160,100,"DIFF",0,2+8+16);
// {
// char buf[32];
// Bsprintf(buf, "RC:%4d TC:%5d", ud.reccnt, g_demo_cnt);
// gametext(160,100,buf,0,2+8+16);
// }
 
j=g_demo_cnt/(TICRATE/TICSPERFRAME);
Bsprintf(buf, "%02d:%02d", j/60, j%60);
gametext(18,16,buf,0,2+8+16);
 
rotatesprite(60<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16,0,0,(xdim*95)/320,ydim-1);
rotatesprite(90<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16,(xdim*95)/320,0,(xdim*125)/320,ydim-1);
rotatesprite(120<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16,(xdim*125)/320,0,(xdim*155)/320,ydim-1);
rotatesprite(150<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16,(xdim*155)/320,0,xdim-1,ydim-1);
 
j = (182<<16) - ((((120*(g_demo_totalCnt-g_demo_cnt))<<4)/g_demo_totalCnt)<<12);
rotatesprite(j,(16<<16)+(1<<15),32768,0,SLIDEBAR+1,0,0,2+8+16,0,0,xdim-1,ydim-1);
 
j=(g_demo_totalCnt-g_demo_cnt)/(TICRATE/TICSPERFRAME);
Bsprintf(buf, "-%02d:%02d%s", j/60, j%60, g_demo_paused?" ^15PAUSED":"");
gametext(194,16,buf,0,2+8+16);
}
}
 
if ((g_netServer || ud.multimode > 1) && g_player[myconnectindex].ps->gm)
Net_GetPackets();
 
if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex)
gametext(160,60,"PRESS F1 TO ACCEPT, F2 TO DECLINE",0,2+8+16);
}
 
if ((g_player[myconnectindex].ps->gm&MODE_MENU) && (g_player[myconnectindex].ps->gm&MODE_EOL))
goto RECHECK;
 
if (KB_KeyPressed(sc_Escape) && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0 && (g_player[myconnectindex].ps->gm&MODE_TYPE) == 0)
{
KB_ClearKeyDown(sc_Escape);
FX_StopAllSounds();
S_ClearSoundLocks();
g_player[myconnectindex].ps->gm |= MODE_MENU;
ChangeToMenu(0);
S_MenuSound();
}
 
if (g_player[myconnectindex].ps->gm&MODE_TYPE)
{
Net_EnterMessage();
if ((g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE)
g_player[myconnectindex].ps->gm = MODE_MENU;
}
else
{
if (ud.recstat != 2)
M_DisplayMenus();
if ((g_netServer || ud.multimode > 1) && g_currentMenu != 20003 && g_currentMenu != 20005 && g_currentMenu != 210)
{
ControlInfo noshareinfo;
CONTROL_GetInput(&noshareinfo);
if (BUTTON(gamefunc_SendMessage))
{
KB_FlushKeyboardQueue();
CONTROL_ClearButton(gamefunc_SendMessage);
g_player[myconnectindex].ps->gm = MODE_TYPE;
typebuf[0] = 0;
inputloc = 0;
}
}
}
 
G_PrintGameQuotes();
 
if (ud.last_camsprite != ud.camerasprite)
{
ud.last_camsprite = ud.camerasprite;
ud.camera_time = totalclock+(TICRATE*2);
}
 
if (VOLUMEONE)
{
if (ud.show_help == 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
rotatesprite((320-50)<<16,9<<16,65536L,0,BETAVERSION,0,0,2+8+16+128,0,0,xdim-1,ydim-1);
}
handleevents();
Net_GetPackets();
nextpage();
 
if (g_player[myconnectindex].ps->gm == MODE_GAME)
{
if (foundemo)
{
#if KRANDDEBUG
krd_print("krandplay.log");
#endif
kclose(g_demo_recFilePtr);
}
return 0;
}
}
ud.multimode = numplayers; // fixes 2 infinite loops after watching demo
kclose(g_demo_recFilePtr);
 
#if 0
{
uint32_t crcv;
// sync checker
+ initcrc32table();
crc32init(&crcv);
crc32block(&crcv, (char *)wall, sizeof(wall));
crc32block(&crcv, (char *)sector, sizeof(sector));
crc32block(&crcv, (char *)sprite, sizeof(sprite));
crc32finish(&crcv);
initprintf("Checksum = %08X\n",crcv);
}
#endif
 
if (g_player[myconnectindex].ps->gm&MODE_MENU) goto RECHECK;
#if KRANDDEBUG
if (foundemo)
krd_print("krandplay.log");
#endif
return 1;
}
 
GAME_STATIC GAME_INLINE int32_t G_MoveLoop()
{
Net_GetPackets();
12645,7 → 10077,7
return G_DoMoveThings();
}
 
GAME_STATIC int32_t G_DoMoveThings(void)
int32_t G_DoMoveThings(void)
{
int32_t i, j;
 
12717,21 → 10149,21
 
G_UpdateInterpolations();
 
/*
j = -1;
TRAVERSE_CONNECT(i)
{
if (g_player[i].playerquitflag == 0 || TEST_SYNC_KEY(g_player[i].sync->bits,SK_GAMEQUIT) == 0)
/*
j = -1;
TRAVERSE_CONNECT(i)
{
j = i;
continue;
}
if (g_player[i].playerquitflag == 0 || TEST_SYNC_KEY(g_player[i].sync->bits,SK_GAMEQUIT) == 0)
{
j = i;
continue;
}
 
G_CloseDemoWrite();
G_CloseDemoWrite();
 
g_player[i].playerquitflag = 0;
}
*/
g_player[i].playerquitflag = 0;
}
*/
 
g_moveThingsCount++;
 
13826,14 → 11258,6
CONTROL_DefineFlag(gamefunc_Previous_Weapon,FALSE);
}
 
/*
===================
=
= GetTime
=
===================
*/
 
int32_t GetTime(void)
{
return totalclock;
/polymer/eduke32/source/game.h
0,0 → 1,327
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __game_h__
#define __game_h__
 
#define USERQUOTE_LEFTOFFSET 5
#define USERQUOTE_RIGHTOFFSET 14
 
#define MAXCHEATLEN 20
#define NUMCHEATCODES (int32_t)(sizeof(CheatStrings)/sizeof(CheatStrings[0]))
 
enum GametypeFlags_t {
GAMETYPE_COOP = 0x00000001,
GAMETYPE_WEAPSTAY = 0x00000002,
GAMETYPE_FRAGBAR = 0x00000004,
GAMETYPE_SCORESHEET = 0x00000008,
GAMETYPE_DMSWITCHES = 0x00000010,
GAMETYPE_COOPSPAWN = 0x00000020,
GAMETYPE_ACCESSCARDSPRITES = 0x00000040,
GAMETYPE_COOPVIEW = 0x00000080,
GAMETYPE_COOPSOUND = 0x00000100,
GAMETYPE_OTHERPLAYERSINMAP = 0x00000200,
GAMETYPE_ITEMRESPAWN = 0x00000400,
GAMETYPE_MARKEROPTION = 0x00000800,
GAMETYPE_PLAYERSFRIENDLY = 0x00001000,
GAMETYPE_FIXEDRESPAWN = 0x00002000,
GAMETYPE_ACCESSATSTART = 0x00004000,
GAMETYPE_PRESERVEINVENTORYDEATH = 0x00008000,
GAMETYPE_TDM = 0x00010000,
GAMETYPE_TDMSPAWN = 0x00020000
};
 
// logo control
enum LogoFlags_t {
LOGO_ENABLED = 0x00000001,
LOGO_PLAYANIM = 0x00000002,
LOGO_PLAYMUSIC = 0x00000004,
LOGO_3DRSCREEN = 0x00000008,
LOGO_TITLESCREEN = 0x00000010,
LOGO_DUKENUKEM = 0x00000020,
LOGO_THREEDEE = 0x00000040,
LOGO_PLUTOPAKSPRITE = 0x00000080,
LOGO_SHAREWARESCREENS = 0x00000100,
LOGO_TENSCREEN = 0x00000200
};
 
#define deletesprite A_DeleteSprite
void A_DeleteSprite(int32_t s);
 
typedef struct {
vec3_t camera;
int32_t const_visibility,uw_framerate;
int32_t camera_time,folfvel,folavel,folx,foly,fola;
int32_t reccnt,crosshairscale;
 
int32_t runkey_mode,statusbarscale,mouseaiming,weaponswitch,drawweapon; // JBF 20031125
int32_t democams,color,msgdisptime,statusbarmode;
int32_t m_noexits,noexits,autovote,automsg,idplayers;
int32_t team, viewbob, weaponsway, althud, weaponscale, textscale;
 
int32_t entered_name,screen_tilting,shadows,fta_on,executions,auto_run;
int32_t coords,tickrate,levelstats,m_coop,coop,screen_size,lockout,crosshair;
int32_t playerai,angleinterpolation,obituaries;
 
int32_t respawn_monsters,respawn_items,respawn_inventory,recstat,monsters_off,brightness;
int32_t m_respawn_items,m_respawn_monsters,m_respawn_inventory,m_recstat,m_monsters_off,detail;
int32_t m_ffire,ffire,m_player_skill,m_level_number,m_volume_number,multimode;
int32_t player_skill,level_number,volume_number,m_marker,marker,mouseflip;
 
int32_t configversion;
 
int16_t cameraang, camerasect, camerahoriz;
int16_t pause_on,from_bonus;
int16_t camerasprite,last_camsprite;
int16_t last_level,secretlevel, bgstretch;
 
struct {
int32_t UseJoystick;
int32_t UseMouse;
int32_t AutoAim;
int32_t ShowOpponentWeapons;
int32_t MouseDeadZone,MouseBias;
int32_t SmoothInput;
 
// JBF 20031211: Store the input settings because
// (currently) jmact can't regurgitate them
int32_t MouseFunctions[MAXMOUSEBUTTONS][2];
int32_t MouseDigitalFunctions[MAXMOUSEAXES][2];
int32_t MouseAnalogueAxes[MAXMOUSEAXES];
int32_t MouseAnalogueScale[MAXMOUSEAXES];
int32_t JoystickFunctions[MAXJOYBUTTONS][2];
int32_t JoystickDigitalFunctions[MAXJOYAXES][2];
int32_t JoystickAnalogueAxes[MAXJOYAXES];
int32_t JoystickAnalogueScale[MAXJOYAXES];
int32_t JoystickAnalogueDead[MAXJOYAXES];
int32_t JoystickAnalogueSaturate[MAXJOYAXES];
uint8_t KeyboardKeys[NUMGAMEFUNCTIONS][2];
 
//
// Sound variables
//
int32_t FXDevice;
int32_t MusicDevice;
int32_t FXVolume;
int32_t MusicVolume;
int32_t SoundToggle;
int32_t MusicToggle;
int32_t VoiceToggle;
int32_t AmbienceToggle;
 
int32_t NumVoices;
int32_t NumChannels;
int32_t NumBits;
int32_t MixRate;
 
int32_t ReverseStereo;
 
//
// Screen variables
//
 
int32_t ScreenMode;
 
int32_t ScreenWidth;
int32_t ScreenHeight;
int32_t ScreenBPP;
 
int32_t ForceSetup;
int32_t NoAutoLoad;
 
int32_t scripthandle;
int32_t setupread;
 
int32_t CheckForUpdates;
int32_t LastUpdateCheck;
int32_t useprecache;
} config;
 
char overhead_on,last_overhead,showweapons;
char god,warp_on,cashman,eog,showallmap;
char show_help,scrollmode,clipping;
char ridecule[10][40];
char savegame[10][22];
char pwlockout[128],rtsname[128];
char display_bonus_screen;
char show_level_text;
} user_defs;
 
 
extern cactype cac[];
 
// this is checked against http://eduke32.com/VERSION
extern const char *s_buildDate;
extern char *g_defNamePtr;
extern char *g_gameNamePtr;
extern char *g_gameNamePtr;
extern char *g_grpNamePtr;
extern char *g_grpNamePtr;
extern char *g_scriptNamePtr;
extern char CheatStrings[][MAXCHEATLEN];
extern char boardfilename[BMAX_PATH], currentboardfilename[BMAX_PATH];
extern char boardfilename[BMAX_PATH];
extern char defaultduke3dgrp[BMAX_PATH];
extern char g_modDir[BMAX_PATH];
extern char g_modDir[BMAX_PATH];
extern char inputloc;
extern char ror_protectedsectors[MAXSECTORS];
 
extern float r_ambientlight;
 
extern int32_t althud_flashing;
extern int32_t althud_numberpal;
extern int32_t althud_numbertile;
extern int32_t althud_shadows;
extern int32_t cacnum;
extern int32_t drawing_ror;
extern int32_t g_Shareware;
extern int32_t g_cameraClock;
extern int32_t g_cameraDistance;
extern int32_t g_cameraDistance;
extern int32_t g_crosshairSum;
extern int32_t g_doQuickSave;
extern int32_t g_forceWeaponChoice;
extern int32_t g_gameType;
extern int32_t g_levelTextTime;
extern int32_t g_noSetup;
extern int32_t g_quitDeadline;
extern int32_t g_restorePalette;
extern int32_t g_scriptSanityChecks;
extern int32_t hud_glowingquotes;
extern int32_t hud_showmapname;
extern int32_t lastvisinc;
extern int32_t rts_numlumps;
extern int32_t qsetmode;
extern int32_t quotebot;
extern int32_t quotebotgoal;
extern int32_t r_maxfps;
extern int32_t tempwallptr;
extern int32_t ticrandomseed;
extern int32_t vote_map;
extern int32_t voting;
 
extern int8_t cheatbuf[MAXCHEATLEN],cheatbuflen;
 
extern palette_t CrosshairColors;
extern palette_t DefaultCrosshairColors;
 
extern uint32_t g_frameDelay;
 
extern uint8_t waterpal[768],slimepal[768],titlepal[768],drealms[768],endingpal[768],*animpal;
 
extern user_defs ud;
 
int32_t A_CheckInventorySprite(spritetype *s);
int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int32_t s_pn,int32_t s_s,int32_t s_xr,int32_t s_yr,int32_t s_a,int32_t s_ve,int32_t s_zv,int32_t s_ow,int32_t s_ss);
int32_t A_Spawn(int32_t j,int32_t pn);
int32_t G_DoMoveThings(void);
int32_t G_EndOfLevel(void);
int32_t G_GameTextLen(int32_t x,const char *t);
int32_t G_PrintGameText(int32_t f,int32_t tile,int32_t x,int32_t y,const char *t,int32_t s,int32_t p,int32_t o,int32_t x1,int32_t y1,int32_t x2,int32_t y2,int32_t z);
int32_t GetTime(void);
int32_t _EnterText(int32_t small,int32_t x,int32_t y,char *t,int32_t dalen,int32_t c);
int32_t kopen4loadfrommod(char *filename,char searchfirst);
int32_t minitext_(int32_t x,int32_t y,const char *t,int32_t s,int32_t p,int32_t sb);
extern inline int32_t mpgametext(int32_t y,const char *t,int32_t s,int32_t dabits);
int32_t startwin_run(void);
 
void A_SpawnCeilingGlass(int32_t i,int32_t sectnum,int32_t n);
void A_SpawnGlass(int32_t i,int32_t n);
void A_SpawnRandomGlass(int32_t i,int32_t wallnum,int32_t n);
void A_SpawnWallGlass(int32_t i,int32_t wallnum,int32_t n);
void G_AddUserQuote(const char *daquote);
void G_BackToMenu(void);
void G_BonusScreen(int32_t bonusonly);
void G_CheatGetInv(void);
void G_DisplayRest(int32_t smoothratio);
void G_DoSpriteAnimations(int32_t x,int32_t y,int32_t a,int32_t smoothratio);
void G_DrawBackground(void);
void G_DrawFrags(void);
void G_DrawRooms(int32_t snum,int32_t smoothratio);
void G_DrawTXDigiNumZ(int32_t starttile,int32_t x,int32_t y,int32_t n,int32_t s,int32_t pal,int32_t cs,int32_t x1,int32_t y1,int32_t x2,int32_t y2,int32_t z);
void G_DrawTile(int32_t x,int32_t y,int32_t tilenum,int32_t shade,int32_t orientation);
void G_DrawTilePal(int32_t x,int32_t y,int32_t tilenum,int32_t shade,int32_t orientation,int32_t p);
void G_DrawTilePalSmall(int32_t x,int32_t y,int32_t tilenum,int32_t shade,int32_t orientation,int32_t p);
void G_DrawTileSmall(int32_t x,int32_t y,int32_t tilenum,int32_t shade,int32_t orientation);
void G_FadePalette(int32_t r,int32_t g,int32_t b,int32_t e);
void G_GameExit(const char *t);
void G_GameQuit(void);
void G_GetCrosshairColor(void);
void G_HandleLocalKeys(void);
void G_HandleSpecialKeys(void);
void G_PrintGameQuotes(void);
void G_SE40(int32_t smoothratio);
void G_SetCrosshairColor(int32_t r,int32_t g,int32_t b);
void G_SetStatusBarScale(int32_t sc);
void G_Shutdown(void);
void G_UpdatePlayerFromMenu(void);
void M32RunScript(const char *s);
void P_DoQuote(int32_t q,DukePlayer_t *p);
void P_SetGamePalette(DukePlayer_t *player,uint8_t *pal,int32_t set);
void app_main(int32_t argc,const char **argv);
void computergetinput(int32_t snum,input_t *syn);
void fadepal(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step);
void fadepaltile(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step,int32_t tile);
void sendscore(const char *s);
 
static inline int32_t G_GetTeamPalette(int32_t team)
{
int8_t pal[] = { 3, 10, 11, 12 };
 
if (team > (int32_t)(sizeof(pal)/sizeof(pal[0])) || team < 0)
return 0;
 
return pal[team];
}
 
#if defined(_WIN32)
int32_t G_GetVersionFromWebsite(char *buffer);
#endif
 
#if defined(RENDERTYPEWIN) && defined(USE_OPENGL)
extern char forcegl;
#endif
 
#if defined(RENDERTYPEWIN)
void app_crashhandler(void);
#endif
 
#if KRANDDEBUG
int32_t krd_print(const char *filename);
void krd_enable(int32_t which);
#endif
 
#define minitextshade(x, y, t, s, p, sb) minitext_(x,y,t,s,p,sb)
#define minitext(x, y, t, p, sb) minitext_(x,y,t,0,p,sb)
#define menutext(x,y,s,p,t) menutext_(x,y,s,p,(char *)OSD_StripColors(menutextbuf,t),10+16)
#define gametext(x,y,t,s,dabits) G_PrintGameText(0,STARTALPHANUM, x,y,t,s,0,dabits,0, 0, xdim-1, ydim-1, 65536)
#define gametextscaled(x,y,t,s,dabits) G_PrintGameText(1,STARTALPHANUM, x,y,t,s,0,dabits,0, 0, xdim-1, ydim-1, 65536)
#define gametextpal(x,y,t,s,p) G_PrintGameText(0,STARTALPHANUM, x,y,t,s,p,26,0, 0, xdim-1, ydim-1, 65536)
#define gametextpalbits(x,y,t,s,p,dabits) G_PrintGameText(0,STARTALPHANUM, x,y,t,s,p,dabits,0, 0, xdim-1, ydim-1, 65536)
#define A_CheckSpriteFlags(iActor, iType) (((SpriteFlags[sprite[iActor].picnum]^actor[iActor].flags) & iType) != 0)
#define A_CheckSpriteTileFlags(iPicnum, iType) ((SpriteFlags[iPicnum] & iType) != 0)
#define G_EnterText(x, y, t, dalen, c) _EnterText(0,x,y,t,dalen,c)
#define Net_EnterText(x, y, t, dalen, c) _EnterText(1,x,y,t,dalen,c)
#define S_StopSound(num) S_StopEnvSound(num, -1)
 
#endif
/polymer/eduke32/source/gamedef.c
22,6 → 22,7
 
#include "duke3d.h"
#include "gamedef.h"
#include "gameexec.h"
 
#include "osd.h"
 
996,15 → 997,15
hash_init(&actorH);
hash_init(&tspriteH);
 
for (i=NUMKEYWORDS-1; i>=0; i--) hash_add(&h_keywords,keyw[i],i);
for (i=0; SectorLabels[i].lId >= 0; i++) hash_add(&sectorH,SectorLabels[i].name,i);
for (i=0; WallLabels[i].lId >= 0; i++) hash_add(&wallH,WallLabels[i].name,i);
for (i=0; UserdefsLabels[i].lId >= 0; i++) hash_add(&userdefH,UserdefsLabels[i].name,i);
for (i=0; ProjectileLabels[i].lId >= 0; i++) hash_add(&projectileH,ProjectileLabels[i].name,i);
for (i=0; PlayerLabels[i].lId >= 0; i++) hash_add(&playerH,PlayerLabels[i].name,i);
for (i=0; InputLabels[i].lId >= 0; i++) hash_add(&inputH,InputLabels[i].name,i);
for (i=0; ActorLabels[i].lId >= 0; i++) hash_add(&actorH,ActorLabels[i].name,i);
for (i=0; TsprLabels[i].lId >= 0; i++) hash_add(&tspriteH,TsprLabels[i].name,i);
for (i=NUMKEYWORDS-1; i>=0; i--) hash_add(&h_keywords,keyw[i],i,0);
for (i=0; SectorLabels[i].lId >= 0; i++) hash_add(&sectorH,SectorLabels[i].name,i,0);
for (i=0; WallLabels[i].lId >= 0; i++) hash_add(&wallH,WallLabels[i].name,i,0);
for (i=0; UserdefsLabels[i].lId >= 0; i++) hash_add(&userdefH,UserdefsLabels[i].name,i,0);
for (i=0; ProjectileLabels[i].lId >= 0; i++) hash_add(&projectileH,ProjectileLabels[i].name,i,0);
for (i=0; PlayerLabels[i].lId >= 0; i++) hash_add(&playerH,PlayerLabels[i].name,i,0);
for (i=0; InputLabels[i].lId >= 0; i++) hash_add(&inputH,InputLabels[i].name,i,0);
for (i=0; ActorLabels[i].lId >= 0; i++) hash_add(&actorH,ActorLabels[i].name,i,0);
for (i=0; TsprLabels[i].lId >= 0; i++) hash_add(&tspriteH,TsprLabels[i].name,i,0);
}
 
// "magic" number for { and }, overrides line number in compiled code for later detection
1221,7 → 1222,7
initprintf("%s:%d: debug: EOF in comment!\n",g_szScriptFileName,g_lineNumber);
C_ReportError(-1);
initprintf("%s:%d: error: found `/*' with no `*/'.\n",g_szScriptFileName,g_lineNumber);
g_parsingActorPtr = 0;g_processingState = g_numBraces = 0;
g_parsingActorPtr = 0; g_processingState = g_numBraces = 0;
g_numCompilerErrors++;
continue;
}
2034,7 → 2035,7
 
g_processingState = 1;
Bsprintf(g_szCurrentBlockName,"%s",label+(g_numLabels<<6));
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels);
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels,0);
g_numLabels++;
return 0;
}
2323,7 → 2324,7
if (i == -1)
{
// printf("Defining Definition '%s' to be '%d'\n",label+(g_numLabels<<6),*(g_scriptPtr-1));
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels);
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels,0);
labeltype[g_numLabels] = LABEL_DEFINE;
labelcode[g_numLabels++] = *(g_scriptPtr-1);
if (*(g_scriptPtr-1) >= 0 && *(g_scriptPtr-1) < MAXTILES && g_dynamicTileMapping)
2407,7 → 2408,7
 
if (i == -1)
{
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels);
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels,0);
labeltype[g_numLabels] = LABEL_MOVE;
labelcode[g_numLabels++] = (intptr_t) g_scriptPtr;
}
2603,7 → 2604,7
if (i == -1)
{
labeltype[g_numLabels] = LABEL_AI;
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels);
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels,0);
labelcode[g_numLabels++] = (intptr_t) g_scriptPtr;
}
 
2685,7 → 2686,7
{
labeltype[g_numLabels] = LABEL_ACTION;
labelcode[g_numLabels] = (intptr_t) g_scriptPtr;
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels);
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels,0);
g_numLabels++;
}
 
4668,7 → 4669,7
}
//AddLog("Adding value to script");
g_caseScriptPtr[g_numCases++]=j; // save value
g_caseScriptPtr[g_numCases]=(intptr_t)((intptr_t*)g_scriptPtr-&script[0]); // save offset
g_caseScriptPtr[g_numCases]=(intptr_t)((intptr_t *)g_scriptPtr-&script[0]); // save offset
}
// j = C_GetKeyword();
//Bsprintf(g_szBuf,"case3: %.12s",textptr);
5112,10 → 5113,10
}
gamefunctions[j][i] = '\0';
keydefaults[j*3][i] = '\0';
hash_add(&h_gamefuncs,gamefunctions[j],j);
hash_add(&h_gamefuncs,gamefunctions[j],j,0);
{
char *str = Bstrtolower(Bstrdup(gamefunctions[j]));
hash_add(&h_gamefuncs,str,j);
hash_add(&h_gamefuncs,str,j,0);
Bfree(str);
}
 
5357,16 → 5358,16
 
Bcorrectfilename(tempbuf,0);
 
if (MapInfo[j*MAXLEVELS+k].filename == NULL)
MapInfo[j*MAXLEVELS+k].filename = Bcalloc(Bstrlen(tempbuf)+1,sizeof(uint8_t));
if (MapInfo[j *MAXLEVELS+k].filename == NULL)
MapInfo[j *MAXLEVELS+k].filename = Bcalloc(Bstrlen(tempbuf)+1,sizeof(uint8_t));
else if ((Bstrlen(tempbuf)+1) > sizeof(MapInfo[j*MAXLEVELS+k].filename))
MapInfo[j*MAXLEVELS+k].filename = Brealloc(MapInfo[j*MAXLEVELS+k].filename,(Bstrlen(tempbuf)+1));
MapInfo[j *MAXLEVELS+k].filename = Brealloc(MapInfo[j*MAXLEVELS+k].filename,(Bstrlen(tempbuf)+1));
 
Bstrcpy(MapInfo[j*MAXLEVELS+k].filename,tempbuf);
 
C_SkipComments();
 
MapInfo[j*MAXLEVELS+k].partime =
MapInfo[j *MAXLEVELS+k].partime =
(((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+
(((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC);
 
5373,7 → 5374,7
textptr += 5;
while (*textptr == ' ' || *textptr == '\t') textptr++;
 
MapInfo[j*MAXLEVELS+k].designertime =
MapInfo[j *MAXLEVELS+k].designertime =
(((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+
(((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC);
 
5398,10 → 5399,10
 
tempbuf[i] = '\0';
 
if (MapInfo[j*MAXLEVELS+k].name == NULL)
MapInfo[j*MAXLEVELS+k].name = Bcalloc(Bstrlen(tempbuf)+1,sizeof(uint8_t));
if (MapInfo[j *MAXLEVELS+k].name == NULL)
MapInfo[j *MAXLEVELS+k].name = Bcalloc(Bstrlen(tempbuf)+1,sizeof(uint8_t));
else if ((Bstrlen(tempbuf)+1) > sizeof(MapInfo[j*MAXLEVELS+k].name))
MapInfo[j*MAXLEVELS+k].name = Brealloc(MapInfo[j*MAXLEVELS+k].name,(Bstrlen(tempbuf)+1));
MapInfo[j *MAXLEVELS+k].name = Brealloc(MapInfo[j*MAXLEVELS+k].name,(Bstrlen(tempbuf)+1));
 
/* initprintf("level name string len: %d\n",Bstrlen(tempbuf)); */
 
5818,7 → 5819,7
{
Bstrcpy(label+(g_numLabels<<6),lLabel);
labeltype[g_numLabels] = lType;
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels);
hash_add(&h_labels,label+(g_numLabels<<6),g_numLabels,0);
labelcode[g_numLabels++] = lValue;
g_numDefaultLabels++;
}
5973,8 → 5974,8
int8_t velmult; // 1b
uint8_t clipdist; // 1b
} defaultprojectile_t;
defaultprojectile_t DefaultProjectile =
 
defaultprojectile_t DefaultProjectile =
{
1, -1, 2048, 0, 0, SMALLSMOKE, -1, -1, 600, BULLETHOLE, -1, 0, 0, 448, g_numFreezeBounces, PIPEBOMB_BOUNCE, 1,
100, -1, -1, -1, -1, -1, -96, 18, 18, 0, 1, 32
6171,7 → 6172,7
C_SetScriptSize(g_scriptPtr-script+8);
 
initprintf("Script compiled in %dms, %ld*%db, version %s\n", getticks() - startcompiletime,
(unsigned)(g_scriptPtr-script), sizeof(intptr_t), (g_scriptVersion == 14?"1.4+":"1.3D"));
(unsigned)(g_scriptPtr-script), sizeof(intptr_t), (g_scriptVersion == 14?"1.4+":"1.3D"));
 
initprintf("%ld/%ld labels, %d/%d variables\n", g_numLabels,
min((MAXSECTORS * sizeof(sectortype)/sizeof(int32_t)),
6277,10 → 6278,10
g_numObituaries = (sizeof(PlayerObituaries)/sizeof(PlayerObituaries[0]));
for (i=g_numObituaries-1; i>=0; i--)
{
if (ScriptQuotes[i+FIRST_OBITUARY_QUOTE] == NULL)
if (ScriptQuotes[i+OBITQUOTEINDEX] == NULL)
{
ScriptQuotes[i+FIRST_OBITUARY_QUOTE] = Bcalloc(MAXQUOTELEN,sizeof(uint8_t));
Bstrcpy(ScriptQuotes[i+FIRST_OBITUARY_QUOTE],PlayerObituaries[i]);
ScriptQuotes[i+OBITQUOTEINDEX] = Bcalloc(MAXQUOTELEN,sizeof(uint8_t));
Bstrcpy(ScriptQuotes[i+OBITQUOTEINDEX],PlayerObituaries[i]);
}
}
 
6287,10 → 6288,10
g_numSelfObituaries = (sizeof(PlayerSelfObituaries)/sizeof(PlayerSelfObituaries[0]));
for (i=g_numSelfObituaries-1; i>=0; i--)
{
if (ScriptQuotes[i+FIRST_SUICIDE_QUOTE] == NULL)
if (ScriptQuotes[i+SUICIDEQUOTEINDEX] == NULL)
{
ScriptQuotes[i+FIRST_SUICIDE_QUOTE] = Bcalloc(MAXQUOTELEN,sizeof(uint8_t));
Bstrcpy(ScriptQuotes[i+FIRST_SUICIDE_QUOTE],PlayerSelfObituaries[i]);
ScriptQuotes[i+SUICIDEQUOTEINDEX] = Bcalloc(MAXQUOTELEN,sizeof(uint8_t));
Bstrcpy(ScriptQuotes[i+SUICIDEQUOTEINDEX],PlayerSelfObituaries[i]);
}
}
}
/polymer/eduke32/source/gamedef.h
27,6 → 27,13
#define LABEL_HASPARM2 1
#define LABEL_ISSTRING 2
 
extern hashtable_t h_gamevars;
extern hashtable_t h_arrays;
extern hashtable_t h_keywords;
extern hashtable_t h_gamefuncs;
extern hashtable_t h_labels;
 
 
extern int32_t g_iReturnVarID; // var ID of "RETURN"
extern int32_t g_iWeaponVarID; // var ID of "WEAPON"
extern int32_t g_iWorksLikeVarID; // var ID of "WORKSLIKE"
60,7 → 67,9
extern char CheatStrings[][MAXCHEATLEN];
extern char g_szScriptFileName[BMAX_PATH];
extern int32_t g_totalLines,g_lineNumber;
extern int32_t g_numCompilerErrors,g_numCompilerWarnings;
extern int32_t g_numCompilerErrors,g_numCompilerWarnings,g_numQuoteRedefinitions;
extern int32_t g_scriptVersion;
extern char g_szBuf[1024];
 
extern intptr_t *g_scriptPtr;
 
81,6 → 90,9
extern const memberlabel_t InputLabels[];
extern const memberlabel_t TsprLabels[];
 
void C_ReportError(int32_t iError);
void C_Compile(const char *filenam);
 
/*
extern void VM_AccessUserdef(int32_t iSet, int32_t lLabelID, int32_t lVar2);
extern void VM_AccessActiveProjectile(int32_t iSet, int32_t lVar1, int32_t lLabelID, int32_t lVar2);
/polymer/eduke32/source/gameexec.c
25,10 → 25,13
 
#include "duke3d.h"
#include "gamedef.h"
#include "gameexec.h"
#include "scriplib.h"
 
#include "savegame.h"
#include "premap.h"
#include "osdcmds.h"
#include "osd.h"
#include "menus.h"
 
#if KRANDDEBUG
# define GAMEEXEC_INLINE
86,7 → 89,8
intptr_t *oinsptr=insptr;
vmstate_t vm_backup;
vmstate_t tempvm = { iActor, iPlayer, lDist, &actor[iActor].t_data[0],
&sprite[iActor], 0};
&sprite[iActor], 0
};
 
Bmemcpy(&vm_backup, &vm, sizeof(vmstate_t));
Bmemcpy(&vm, &tempvm, sizeof(vmstate_t));
171,7 → 175,7
bxvect = sintable[(SA+512)&2047];
byvect = sintable[SA&2047];
 
if (mxvect*bx + myvect*by >= 0)
if (mxvect *bx + myvect *by >= 0)
if (bxvect*bx + byvect*by < 0)
{
d = bxvect*by - byvect*bx;
262,7 → 266,7
{
spritetype *s = &sprite[iActor];
 
if (s->statnum == STAT_PLAYER || s->statnum == STAT_STANDABLE || s->statnum == STAT_ZOMBIEACTOR || s->statnum == STAT_ACTOR || s->statnum == STAT_PROJECTILE)
// if (s->statnum == STAT_PLAYER || s->statnum == STAT_STANDABLE || s->statnum == STAT_ZOMBIEACTOR || s->statnum == STAT_ACTOR || s->statnum == STAT_PROJECTILE)
{
int32_t hz,lz,zr = 127L;
int32_t cstat = s->cstat;
272,9 → 276,9
if (s->statnum == STAT_PROJECTILE)
zr = 4L;
 
s->z -= FOURSLEIGHT;
s->z -= ZOFFSET;
getzrange((vec3_t *)s,s->sectnum,&actor[iActor].ceilingz,&hz,&actor[iActor].floorz,&lz,zr,CLIPMASK0);
s->z += FOURSLEIGHT;
s->z += ZOFFSET;
 
s->cstat = cstat;
 
304,11 → 308,13
}
}
}
else
{
actor[iActor].ceilingz = sector[s->sectnum].ceilingz;
actor[iActor].floorz = sector[s->sectnum].floorz;
}
/*
else
{
actor[iActor].ceilingz = sector[s->sectnum].ceilingz;
actor[iActor].floorz = sector[s->sectnum].floorz;
}
*/
}
 
void A_Fall(int32_t iActor)
328,9 → 334,9
{
int32_t cstat = s->cstat;
s->cstat = 0;
s->z -= FOURSLEIGHT;
s->z -= ZOFFSET;
getzrange((vec3_t *)s,s->sectnum,&actor[iActor].ceilingz,&hz,&actor[iActor].floorz,&lz,127L,CLIPMASK0);
s->z += FOURSLEIGHT;
s->z += ZOFFSET;
s->cstat = cstat;
}
else
339,15 → 345,15
actor[iActor].floorz = sector[s->sectnum].floorz;
}
 
if (s->z < actor[iActor].floorz-(FOURSLEIGHT))
if (s->z < actor[iActor].floorz-(ZOFFSET))
{
if (sector[s->sectnum].lotag == 2 && s->zvel > 3122)
s->zvel = 3144;
s->z += s->zvel = min(6144, s->zvel+c);
}
if (s->z >= actor[iActor].floorz-(FOURSLEIGHT))
if (s->z >= actor[iActor].floorz-(ZOFFSET))
{
s->z = actor[iActor].floorz - FOURSLEIGHT;
s->z = actor[iActor].floorz - ZOFFSET;
s->zvel = 0;
}
}
617,8 → 623,9
}
 
{
vec3_t tmpvect = { (daxvel*(sintable[(angdif+512)&2047]))>>14,
(daxvel*(sintable[angdif&2047]))>>14, vm.g_sp->zvel };
vec3_t tmpvect = { (daxvel*(sintable[(angdif+512)&2047]))>>14,
(daxvel*(sintable[angdif&2047]))>>14, vm.g_sp->zvel
};
 
actor[vm.g_i].movflag = A_MoveSprite(vm.g_i,&tmpvect,CLIPMASK0);
}
631,15 → 638,15
else vm.g_sp->shade += (sector[vm.g_sp->sectnum].floorshade-vm.g_sp->shade)>>1;
 
// wtf?
/*
if (sector[vm.g_sp->sectnum].floorpicnum == MIRROR)
deletesprite(vm.g_i);
*/
/*
if (sector[vm.g_sp->sectnum].floorpicnum == MIRROR)
deletesprite(vm.g_i);
*/
}
 
GAMEEXEC_STATIC GAMEEXEC_INLINE void __fastcall VM_DoConditional(register int32_t condition)
{
if (condition || ((insptr = (intptr_t *)*(insptr+1)) && (((*insptr)&0xFFF) == CON_ELSE)))
if (condition || ((insptr = (intptr_t *)*(insptr+1)) && (((*insptr) & 0xfff) == CON_ELSE)))
{
// skip 'else' pointer.. and...
insptr += 2;
964,8 → 971,8
int32_t j = (*insptr++ - vm.g_sp->xrepeat)<<1;
vm.g_sp->xrepeat += ksgn(j);
 
if ((vm.g_sp->picnum == APLAYER && vm.g_sp->yrepeat < 36) || *insptr < vm.g_sp->yrepeat ||
((vm.g_sp->yrepeat*(tilesizy[vm.g_sp->picnum]+8))<<2) < (actor[vm.g_i].floorz - actor[vm.g_i].ceilingz))
if ((vm.g_sp->picnum == APLAYER && vm.g_sp->yrepeat < 36) || *insptr < vm.g_sp->yrepeat ||
((vm.g_sp->yrepeat*(tilesizy[vm.g_sp->picnum]+8))<<2) < (actor[vm.g_i].floorz - actor[vm.g_i].ceilingz))
{
j = ((*insptr)-vm.g_sp->yrepeat)<<1;
if (klabs(j)) vm.g_sp->yrepeat += ksgn(j);
1102,15 → 1109,15
actor[vm.g_i].cgg = 3;
}
 
if (vm.g_sp->z < (actor[vm.g_i].floorz-FOURSLEIGHT))
if (vm.g_sp->z < (actor[vm.g_i].floorz-ZOFFSET))
{
vm.g_sp->z += vm.g_sp->zvel = min(6144, vm.g_sp->zvel+j);
 
if (vm.g_sp->z > (actor[vm.g_i].floorz - FOURSLEIGHT))
vm.g_sp->z = (actor[vm.g_i].floorz - FOURSLEIGHT);
if (vm.g_sp->z > (actor[vm.g_i].floorz - ZOFFSET))
vm.g_sp->z = (actor[vm.g_i].floorz - ZOFFSET);
continue;
}
vm.g_sp->z = actor[vm.g_i].floorz - FOURSLEIGHT;
vm.g_sp->z = actor[vm.g_i].floorz - ZOFFSET;
 
if (A_CheckEnemySprite(vm.g_sp) || (vm.g_sp->picnum == APLAYER && vm.g_sp->owner >= 0))
{
1131,7 → 1138,7
else if (vm.g_sp->zvel > 2048 && sector[vm.g_sp->sectnum].lotag != 1)
{
j = vm.g_sp->sectnum;
pushmove((vec3_t *)vm.g_sp,(int16_t*)&j,128L,(4L<<8),(4L<<8),CLIPMASK0);
pushmove((vec3_t *)vm.g_sp,(int16_t *)&j,128L,(4L<<8),(4L<<8),CLIPMASK0);
if (j != vm.g_sp->sectnum && j >= 0 && j < MAXSECTORS)
changespritesect(vm.g_i,j);
A_PlaySound(THUD,vm.g_i);
1139,11 → 1146,11
}
}
 
if (vm.g_sp->z > (actor[vm.g_i].floorz - FOURSLEIGHT))
if (vm.g_sp->z > (actor[vm.g_i].floorz - ZOFFSET))
{
A_GetZLimits(vm.g_i);
if (actor[vm.g_i].floorz != sector[vm.g_sp->sectnum].floorz)
vm.g_sp->z = (actor[vm.g_i].floorz - FOURSLEIGHT);
vm.g_sp->z = (actor[vm.g_i].floorz - ZOFFSET);
continue;
}
else if (sector[vm.g_sp->sectnum].lotag == 1)
1152,17 → 1159,17
{
default:
// fix for flying/jumping monsters getting stuck in water
{
intptr_t *moveptr = (intptr_t *)vm.g_t[1];
if (vm.g_sp->hitag & jumptoplayer || (actorscrptr[vm.g_sp->picnum] &&
moveptr >= &script[0] && moveptr <= (&script[0]+g_scriptSize) && *(moveptr+1)))
{
intptr_t *moveptr = (intptr_t *)vm.g_t[1];
if (vm.g_sp->hitag & jumptoplayer || (actorscrptr[vm.g_sp->picnum] &&
moveptr >= &script[0] && moveptr <= (&script[0]+g_scriptSize) && *(moveptr+1)))
{
// OSD_Printf("%d\n",*(moveptr+1));
break;
}
// OSD_Printf("%d\n",*(moveptr+1));
break;
}
// OSD_Printf("hitag: %d\n",vm.g_sp->hitag);
vm.g_sp->z += (24<<8);
}
// OSD_Printf("hitag: %d\n",vm.g_sp->hitag);
vm.g_sp->z += (24<<8);
case OCTABRAIN__STATIC:
case COMMANDER__STATIC:
case DRONE__STATIC:
1892,7 → 1899,7
// (int32_t)insptr,(int32_t)lCheckCase,lpCases[lCheckCase*2+1],(int32_t)&script[0]);
//AddLog(g_szBuf);
// fake a 2-d Array
insptr=(intptr_t*)(lpCases[lCheckCase*2+1] + &script[0]);
insptr=(intptr_t *)(lpCases[lCheckCase*2+1] + &script[0]);
//Bsprintf(g_szBuf,"insptr=%d. ", (int32_t)insptr);
//AddLog(g_szBuf);
VM_Execute(0);
1907,7 → 1914,7
if (*lpDefault)
{
//AddLog("No Matching Case: Using Default");
insptr=(intptr_t*)(*lpDefault + &script[0]);
insptr=(intptr_t *)(*lpDefault + &script[0]);
VM_Execute(0);
}
else
2281,8 → 2288,8
setview(x1,y1,x2,y2);
 
#if 0
if (!ud.pause_on && ((ud.show_help == 0 && (!net_server && ud.multimode < 2) && !(g_player[myconnectindex].ps->gm&MODE_MENU))
|| (net_server || ud.multimode > 1) || ud.recstat == 2))
if (!ud.pause_on && ((ud.show_help == 0 && (!net_server && ud.multimode < 2) && !(g_player[myconnectindex].ps->gm&MODE_MENU))
|| (net_server || ud.multimode > 1) || ud.recstat == 2))
smoothratio = min(max((totalclock-ototalclock)*(65536L/TICSPERFRAME),0),65536);
#endif
G_DoInterpolations(smoothratio);
2557,7 → 2564,7
{
int32_t v1=*insptr++,v2=*insptr++,v3=*insptr++,v4=*insptr++,v5=*insptr++,v6=*insptr++,v7=*insptr++,v8=*insptr++;
time_t rawtime;
struct tm * ti;
struct tm *ti;
 
time(&rawtime);
ti=localtime(&rawtime);
3001,8 → 3008,8
continue;
 
case CON_SAVEMAPSTATE:
if (MapInfo[ud.volume_number*MAXLEVELS+ud.level_number].savedstate == NULL)
MapInfo[ud.volume_number*MAXLEVELS+ud.level_number].savedstate = Bcalloc(1,sizeof(mapstate_t));
if (MapInfo[ud.volume_number *MAXLEVELS+ud.level_number].savedstate == NULL)
MapInfo[ud.volume_number *MAXLEVELS+ud.level_number].savedstate = Bcalloc(1,sizeof(mapstate_t));
G_SaveMapState(MapInfo[ud.volume_number*MAXLEVELS+ud.level_number].savedstate);
insptr++;
continue;
4475,7 → 4482,7
insptr++;
if (g_player[vm.g_p].ps->knee_incs == 0 && sprite[g_player[vm.g_p].ps->i].xrepeat >= 40)
if (cansee(vm.g_sp->x,vm.g_sp->y,vm.g_sp->z-(4<<8),vm.g_sp->sectnum,g_player[vm.g_p].ps->pos.x,
g_player[vm.g_p].ps->pos.y,g_player[vm.g_p].ps->pos.z+(16<<8),sprite[g_player[vm.g_p].ps->i].sectnum))
g_player[vm.g_p].ps->pos.y,g_player[vm.g_p].ps->pos.z+(16<<8),sprite[g_player[vm.g_p].ps->i].sectnum))
{
int32_t j = playerswhenstarted-1;
for (; j>=0; j--)
4604,7 → 4611,7
{
int32_t k = 0;
 
for (;k<MAXSOUNDINSTANCES;k++)
for (; k<MAXSOUNDINSTANCES; k++)
{
if (g_sounds[j].SoundOwner[k].i == vm.g_i)
break;
4694,7 → 4701,8
void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist)
{
vmstate_t tempvm = { iActor, iPlayer, lDist, &actor[iActor].t_data[0],
&sprite[iActor], 0};
&sprite[iActor], 0
};
 
if (g_netClient && A_CheckSpriteFlags(iActor, SPRITE_NULL))
{
4706,7 → 4714,7
randomseed = ticrandomseed;
 
Bmemcpy(&vm, &tempvm, sizeof(vmstate_t));
 
insptr = 4 + (actorscrptr[vm.g_sp->picnum]);
 
if (vm.g_sp->sectnum < 0 || vm.g_sp->sectnum >= MAXSECTORS)
4849,7 → 4857,7
}
}
 
Bmemcpy(&save->actor[0],&actor[0],sizeof(ActorData_t)*MAXSPRITES);
Bmemcpy(&save->actor[0],&actor[0],sizeof(actor_t)*MAXSPRITES);
 
for (i=MAXSPRITES-1; i>=0; i--)
{
4947,7 → 4955,7
Bmemcpy(&headspritestat[0],&save->headspritestat[0],sizeof(headspritestat));
Bmemcpy(&prevspritestat[0],&save->prevspritestat[0],sizeof(prevspritestat));
Bmemcpy(&nextspritestat[0],&save->nextspritestat[0],sizeof(nextspritestat));
Bmemcpy(&actor[0],&save->actor[0],sizeof(ActorData_t)*MAXSPRITES);
Bmemcpy(&actor[0],&save->actor[0],sizeof(actor_t)*MAXSPRITES);
 
for (i=MAXSPRITES-1; i>=0; i--)
{
/polymer/eduke32/source/gameexec.h
0,0 → 1,139
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __gameexec_h__
#define __gameexec_h__
 
// the order of these can't be changed or else compatibility with EDuke 2.0 mods will break
enum GameEvent_t {
EVENT_INIT,
EVENT_ENTERLEVEL,
EVENT_RESETWEAPONS,
EVENT_RESETINVENTORY,
EVENT_HOLSTER,
EVENT_LOOKLEFT,
EVENT_LOOKRIGHT,
EVENT_SOARUP,
EVENT_SOARDOWN,
EVENT_CROUCH,
EVENT_JUMP,
EVENT_RETURNTOCENTER,
EVENT_LOOKUP,
EVENT_LOOKDOWN,
EVENT_AIMUP,
EVENT_FIRE,
EVENT_CHANGEWEAPON,
EVENT_GETSHOTRANGE,
EVENT_GETAUTOAIMANGLE,
EVENT_GETLOADTILE,
EVENT_CHEATGETSTEROIDS,
EVENT_CHEATGETHEAT,
EVENT_CHEATGETBOOT,
EVENT_CHEATGETSHIELD,
EVENT_CHEATGETSCUBA,
EVENT_CHEATGETHOLODUKE,
EVENT_CHEATGETJETPACK,
EVENT_CHEATGETFIRSTAID,
EVENT_QUICKKICK,
EVENT_INVENTORY,
EVENT_USENIGHTVISION,
EVENT_USESTEROIDS,
EVENT_INVENTORYLEFT,
EVENT_INVENTORYRIGHT,
EVENT_HOLODUKEON,
EVENT_HOLODUKEOFF,
EVENT_USEMEDKIT,
EVENT_USEJETPACK,
EVENT_TURNAROUND,
EVENT_DISPLAYWEAPON,
EVENT_FIREWEAPON,
EVENT_SELECTWEAPON,
EVENT_MOVEFORWARD,
EVENT_MOVEBACKWARD,
EVENT_TURNLEFT,
EVENT_TURNRIGHT,
EVENT_STRAFELEFT,
EVENT_STRAFERIGHT,
EVENT_WEAPKEY1,
EVENT_WEAPKEY2,
EVENT_WEAPKEY3,
EVENT_WEAPKEY4,
EVENT_WEAPKEY5,
EVENT_WEAPKEY6,
EVENT_WEAPKEY7,
EVENT_WEAPKEY8,
EVENT_WEAPKEY9,
EVENT_WEAPKEY10,
EVENT_DRAWWEAPON,
EVENT_DISPLAYCROSSHAIR,
EVENT_DISPLAYREST,
EVENT_DISPLAYSBAR,
EVENT_RESETPLAYER,
EVENT_INCURDAMAGE,
EVENT_AIMDOWN,
EVENT_GAME,
EVENT_PREVIOUSWEAPON,
EVENT_NEXTWEAPON,
EVENT_SWIMUP,
EVENT_SWIMDOWN,
EVENT_GETMENUTILE,
EVENT_SPAWN,
EVENT_LOGO,
EVENT_EGS,
EVENT_DOFIRE,
EVENT_PRESSEDFIRE,
EVENT_USE,
EVENT_PROCESSINPUT,
EVENT_FAKEDOMOVETHINGS,
EVENT_DISPLAYROOMS,
EVENT_KILLIT,
EVENT_LOADACTOR,
EVENT_DISPLAYBONUSSCREEN,
EVENT_DISPLAYMENU,
EVENT_DISPLAYMENUREST,
EVENT_DISPLAYLOADINGSCREEN,
EVENT_ANIMATESPRITES,
EVENT_NEWGAME,
MAXEVENTS
};
 
extern int32_t g_errorLineNum;
extern int32_t g_tw;
extern int32_t ticrandomseed;
extern vmstate_t vm;
 
void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist);
void A_Fall(int32_t iActor);
int32_t A_FurthestVisiblePoint(int32_t iActor,spritetype *ts,int32_t *dax,int32_t *day);
int32_t A_GetFurthestAngle(int32_t iActor,int32_t angs);
void A_GetZLimits(int32_t iActor);
void A_LoadActor(int32_t iActor);
int32_t G_GetAngleDelta(int32_t a,int32_t na);
void G_RestoreMapState(mapstate_t *save);
void G_RestoreMapState(mapstate_t *save);
void G_SaveMapState(mapstate_t *save);
void G_SaveMapState(mapstate_t *save);
void Gv_RefreshPointers(void);
void VM_OnEvent(register int32_t iEventID,register int32_t iActor,register int32_t iPlayer,register int32_t lDist);
void VM_ScriptInfo(void);
 
#endif
/polymer/eduke32/source/gamestructures.c
1208,7 → 1208,7
if ((iPlayer<0 || iPlayer >= playerswhenstarted) /* && g_scriptSanityChecks */)
goto badplayer;
 
if ((PlayerLabels[lLabelID].flags & LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= PlayerLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
if ((PlayerLabels[lLabelID].flags &LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= PlayerLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
goto badpos;
 
switch (lLabelID)
1539,7 → 1539,7
if ((iPlayer<0 || iPlayer >= playerswhenstarted) /* && g_scriptSanityChecks */)
goto badplayer;
 
if ((PlayerLabels[lLabelID].flags & LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= PlayerLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
if ((PlayerLabels[lLabelID].flags &LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= PlayerLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
goto badpos;
 
lVar1=Gv_GetVar(lVar2, vm.g_i, vm.g_p);
2372,7 → 2372,7
if ((iActor < 0 || iActor >= MAXSPRITES) /* && g_scriptSanityChecks */)
goto badactor;
 
if ((ActorLabels[lLabelID].flags & LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= ActorLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
if ((ActorLabels[lLabelID].flags &LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= ActorLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
goto badpos;
 
lVar1=Gv_GetVar(lVar2, vm.g_i, vm.g_p);
2616,7 → 2616,7
if ((iActor < 0 || iActor >= MAXSPRITES) /* && g_scriptSanityChecks */)
goto badactor;
 
if ((ActorLabels[lLabelID].flags & LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= ActorLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
if ((ActorLabels[lLabelID].flags &LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= ActorLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
goto badpos;
 
switch (lLabelID)
3366,7 → 3366,7
#else
static int32_t __fastcall VM_AccessSpriteX(int32_t iActor, int32_t lLabelID, int32_t lParm2)
{
if ((ActorLabels[lLabelID].flags & LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= ActorLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
if ((ActorLabels[lLabelID].flags &LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= ActorLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
goto badpos;
 
switch (lLabelID)
3465,7 → 3465,7
 
static int32_t __fastcall VM_AccessPlayerX(int32_t iPlayer, int32_t lLabelID, int32_t lParm2)
{
if ((PlayerLabels[lLabelID].flags & LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= PlayerLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
if ((PlayerLabels[lLabelID].flags &LABEL_HASPARM2 && (lParm2 < 0 || lParm2 >= PlayerLabels[lLabelID].maxParm2)) /* && g_scriptSanityChecks */)
goto badpos;
 
switch (lLabelID)
/polymer/eduke32/source/gamevars.c
21,6 → 21,7
//-------------------------------------------------------------------------
 
#include "duke3d.h"
#include "gamevars.h"
#include "gamedef.h"
#include "osd.h"
 
127,7 → 128,7
if (kdfread(&(aGameVars[i]),sizeof(gamevar_t),1,fil) != 1) goto corrupt;
aGameVars[i].szLabel=Bcalloc(MAXVARLABEL,sizeof(uint8_t));
if (kdfread(aGameVars[i].szLabel,sizeof(uint8_t) * MAXVARLABEL, 1, fil) != 1) goto corrupt;
hash_replace(&h_gamevars,aGameVars[i].szLabel,i);
hash_add(&h_gamevars, aGameVars[i].szLabel,i, 1);
 
if (aGameVars[i].dwFlags & GAMEVAR_PERPLAYER)
{
155,7 → 156,7
if (kdfread(&(aGameArrays[i]),sizeof(gamearray_t),1,fil) != 1) goto corrupt;
aGameArrays[i].szLabel=Bcalloc(MAXARRAYLABEL,sizeof(uint8_t));
if (kdfread(aGameArrays[i].szLabel,sizeof(uint8_t) * MAXARRAYLABEL, 1, fil) != 1) goto corrupt;
hash_replace(&h_arrays,aGameArrays[i].szLabel,i);
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
 
aGameArrays[i].plValues=Bcalloc(aGameArrays[i].size,sizeof(intptr_t));
if (kdfread(aGameArrays[i].plValues,sizeof(intptr_t) * aGameArrays[i].size, 1, fil) < 1) goto corrupt;
342,11 → 343,11
OSD_Printf("gamevar %s ",aGameVars[i].szLabel);
 
if (aGameVars[i].dwFlags & (GAMEVAR_INTPTR))
OSD_Printf("%d",*((int32_t*)aGameVars[i].val.lValue));
OSD_Printf("%d",*((int32_t *)aGameVars[i].val.lValue));
else if (aGameVars[i].dwFlags & (GAMEVAR_SHORTPTR))
OSD_Printf("%d",*((int16_t*)aGameVars[i].val.lValue));
OSD_Printf("%d",*((int16_t *)aGameVars[i].val.lValue));
else if (aGameVars[i].dwFlags & (GAMEVAR_CHARPTR))
OSD_Printf("%d",*((char*)aGameVars[i].val.lValue));
OSD_Printf("%d",*((char *)aGameVars[i].val.lValue));
else
OSD_Printf("%" PRIdPTR "",aGameVars[i].val.lValue);
 
382,8 → 383,8
{
if (aGameVars[i].szLabel != NULL)
Gv_NewVar(aGameVars[i].szLabel,
aGameVars[i].dwFlags & GAMEVAR_NODEFAULT ? aGameVars[i].val.lValue : aGameVars[i].lDefault,
aGameVars[i].dwFlags);
aGameVars[i].dwFlags & GAMEVAR_NODEFAULT ? aGameVars[i].val.lValue : aGameVars[i].lDefault,
aGameVars[i].dwFlags);
}
 
for (i=0; i<MAXGAMEARRAYS; i++)
431,7 → 432,7
aGameArrays[i].size=asize;
aGameArrays[i].bReset=0;
g_gameArrayCount++;
hash_replace(&h_arrays,aGameArrays[i].szLabel,i);
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
return 1;
}
 
508,7 → 509,7
if (i == g_gameVarCount)
{
// we're adding a new one.
hash_add(&h_gamevars, aGameVars[i].szLabel, g_gameVarCount++);
hash_add(&h_gamevars, aGameVars[i].szLabel, g_gameVarCount++, 0);
}
 
if (aGameVars[i].dwFlags & GAMEVAR_PERPLAYER)
640,11 → 641,11
if (iActor < 0 || iActor >= MAXSPRITES) goto bad_id;
return ((aGameVars[id].val.plValues[iActor] ^ -negateResult) + negateResult);
case GAMEVAR_INTPTR:
return (((*((int32_t*)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
return (((*((int32_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
case GAMEVAR_SHORTPTR:
return (((*((int16_t*)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
return (((*((int16_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
case GAMEVAR_CHARPTR:
return (((*((char*)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
return (((*((char *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
}
}
bad_id:
675,29 → 676,29
aGameVars[id].val.plValues[iActor]=lValue;
return;
case GAMEVAR_INTPTR:
*((int32_t*)aGameVars[id].val.lValue)=(int32_t)lValue;
*((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
return;
case GAMEVAR_SHORTPTR:
*((int16_t*)aGameVars[id].val.lValue)=(int16_t)lValue;
*((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
return;
case GAMEVAR_CHARPTR:
*((uint8_t*)aGameVars[id].val.lValue)=(uint8_t)lValue;
*((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
return;
}
 
badvarid:
OSD_Printf(CON_ERROR "Gv_SetVar(): invalid gamevar (%d) from sprite %d (%d), player %d\n",
g_errorLineNum,keyw[g_tw],id,vm.g_i,sprite[vm.g_i].picnum,vm.g_p);
g_errorLineNum,keyw[g_tw],id,vm.g_i,sprite[vm.g_i].picnum,vm.g_p);
return;
 
badplayer:
OSD_Printf(CON_ERROR "Gv_SetVar(): invalid player (%d) for gamevar %s from sprite %d, player %d\n",
g_errorLineNum,keyw[g_tw],iPlayer,aGameVars[id].szLabel,vm.g_i,vm.g_p);
g_errorLineNum,keyw[g_tw],iPlayer,aGameVars[id].szLabel,vm.g_i,vm.g_p);
return;
 
badactor:
OSD_Printf(CON_ERROR "Gv_SetVar(): invalid actor (%d) for gamevar %s from sprite %d (%d), player %d\n",
g_errorLineNum,keyw[g_tw],iActor,aGameVars[id].szLabel,vm.g_i,sprite[vm.g_i].picnum,vm.g_p);
g_errorLineNum,keyw[g_tw],iActor,aGameVars[id].szLabel,vm.g_i,sprite[vm.g_i].picnum,vm.g_p);
return;
}
 
786,11 → 787,11
case GAMEVAR_PERACTOR:
return ((aGameVars[id].val.plValues[vm.g_i] ^ -negateResult) + negateResult);
case GAMEVAR_INTPTR:
return (((*((int32_t*)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
return (((*((int32_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
case GAMEVAR_SHORTPTR:
return (((*((int16_t*)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
return (((*((int16_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
case GAMEVAR_CHARPTR:
return (((*((uint8_t*)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
return (((*((uint8_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
}
}
}
812,24 → 813,24
aGameVars[id].val.plValues[vm.g_i]=lValue;
return;
case GAMEVAR_INTPTR:
*((int32_t*)aGameVars[id].val.lValue)=(int32_t)lValue;
*((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
return;
case GAMEVAR_SHORTPTR:
*((int16_t*)aGameVars[id].val.lValue)=(int16_t)lValue;
*((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
return;
case GAMEVAR_CHARPTR:
*((uint8_t*)aGameVars[id].val.lValue)=(uint8_t)lValue;
*((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
return;
}
 
badplayer:
OSD_Printf(CON_ERROR "Gv_SetVar(): invalid player (%d) for gamevar %s\n",
g_errorLineNum,keyw[g_tw],vm.g_p,aGameVars[id].szLabel);
g_errorLineNum,keyw[g_tw],vm.g_p,aGameVars[id].szLabel);
return;
 
badactor:
OSD_Printf(CON_ERROR "Gv_SetVar(): invalid actor (%d) for gamevar %s\n",
g_errorLineNum,keyw[g_tw],vm.g_i,aGameVars[id].szLabel);
g_errorLineNum,keyw[g_tw],vm.g_i,aGameVars[id].szLabel);
return;
}
 
/polymer/eduke32/source/gamevars.h
0,0 → 1,97
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __gamevars_h__
#define __gamevars_h__
 
// store global game definitions
enum GamevarFlags_t {
MAXGAMEVARS = 2048, // must be a power of two
MAXVARLABEL = 26,
GAMEVAR_PERPLAYER = 0x00000001, // per-player variable
GAMEVAR_PERACTOR = 0x00000002, // per-actor variable
GAMEVAR_USER_MASK = (0x00000001|0x00000002),
GAMEVAR_RESET = 0x00000008, // marks var for to default
GAMEVAR_DEFAULT = 0x00000100, // allow override
GAMEVAR_SECRET = 0x00000200, // don't dump...
GAMEVAR_NODEFAULT = 0x00000400, // don't reset on actor spawn
GAMEVAR_SYSTEM = 0x00000800, // cannot change mode flags...(only default value)
GAMEVAR_READONLY = 0x00001000, // values are read-only (no setvar allowed)
GAMEVAR_INTPTR = 0x00002000, // plValues is a pointer to an int32_t
GAMEVAR_SYNCCHECK = 0x00004000, // throw warnings during compile if used in local event
GAMEVAR_SHORTPTR = 0x00008000, // plValues is a pointer to a short
GAMEVAR_CHARPTR = 0x00010000, // plValues is a pointer to a char
GAMEVAR_NORESET = 0x00020000, // var values are not reset when restoring map state
GAMEVAR_SPECIAL = 0x00040000, // flag for structure member shortcut vars
GAMEVAR_NOMULTI = 0x00080000, // don't attach to multiplayer packets
};
 
enum GamearrayFlags_t {
MAXGAMEARRAYS = (MAXGAMEVARS>>2), // must be lower than MAXGAMEVARS
MAXARRAYLABEL = MAXVARLABEL,
GAMEARRAY_NORMAL = 0,
GAMEARRAY_NORESET = 0x00000001,
};
 
#pragma pack(push,1)
typedef struct {
union {
intptr_t lValue;
intptr_t *plValues; // array of values when 'per-player', or 'per-actor'
} val;
intptr_t lDefault;
uintptr_t dwFlags;
char *szLabel;
} gamevar_t;
 
typedef struct {
char *szLabel;
int32_t *plValues; // array of values
intptr_t size;
intptr_t bReset;
} gamearray_t;
#pragma pack(pop)
 
extern gamevar_t aGameVars[MAXGAMEVARS];
extern gamearray_t aGameArrays[MAXGAMEARRAYS];
extern int32_t g_gameVarCount;
extern int32_t g_gameArrayCount;
 
int32_t __fastcall Gv_GetVar(register int32_t id,register int32_t iActor,register int32_t iPlayer);
int32_t __fastcall Gv_GetVarX(register int32_t id);
int32_t Gv_GetVarByLabel(const char *szGameLabel,int32_t lDefault,int32_t iActor,int32_t iPlayer);
int32_t Gv_NewArray(const char *pszLabel,int32_t asize);
int32_t Gv_NewVar(const char *pszLabel,int32_t lValue,uint32_t dwFlags);
int32_t Gv_ReadSave(int32_t fil,int32_t newbehav);
void __fastcall A_ResetVars(register int32_t iActor);
void __fastcall Gv_SetVar(register int32_t id,register int32_t lValue,register int32_t iActor,register int32_t iPlayer);
void __fastcall Gv_SetVarX(register int32_t id,register int32_t lValue);
void G_FreeMapState(int32_t mapnum);
void Gv_DumpValues(void);
void Gv_Init(void);
void Gv_InitWeaponPointers(void);
void Gv_RefreshPointers(void);
void Gv_RefreshPointers(void);
void Gv_ResetSystemDefaults(void);
void Gv_ResetVars(void);
void Gv_WriteSave(FILE *fil,int32_t newbehav);
#endif
/polymer/eduke32/source/global.c
20,9 → 20,12
*/
//-------------------------------------------------------------------------
 
#define __global_c__
#include "global.h"
#include "duke3d.h"
 
const char *s_buildDate = "20100714";
 
const char *s_buildDate = "20100727";
char *MusicPtr = NULL;
int32_t g_musicSize;
 
34,7 → 37,7
int32_t g_spriteGravity=176;
 
// int32_t temp_data[MAXSPRITES][6];
ActorData_t actor[MAXSPRITES];
actor_t actor[MAXSPRITES];
 
int16_t SpriteDeletionQueue[1024],g_spriteDeleteQueuePos,g_spriteDeleteQueueSize=64;
animwalltype animwall[MAXANIMWALLS];
86,9 → 89,11
int32_t playerswhenstarted;
 
int32_t fricxv,fricyv;
#pragma pack(push,1)
playerdata_t g_player[MAXPLAYERS];
input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
PlayerSpawn_t g_playerSpawnPoints[MAXPLAYERS];
playerspawn_t g_playerSpawnPoints[MAXPLAYERS];
#pragma pack(pop)
user_defs ud;
 
char pus, pub;
158,7 → 163,8
int16_t myangbak[MOVEFIFOSIZ];
char szPlayerName[32];
int32_t g_damageCameras,g_freezerSelfDamage=0,g_tripbombLaserMode=0;
int32_t g_gameQuit = 0,everyothertime;
int32_t g_gameQuit = 0;
uint32_t everyothertime;
int32_t g_numFreezeBounces=3,g_rpgBlastRadius,g_pipebombBlastRadius,g_tripbombBlastRadius,
g_shrinkerBlastRadius,g_morterBlastRadius,g_bouncemineBlastRadius,g_seenineBlastRadius;
DukeStatus_t sbar;
183,3 → 189,4
int32_t g_doQuickSave = 0;
uint32_t g_moveThingsCount = 0;
 
int32_t g_restorePalette = 0, g_screenCapture = 0, g_noEnemies = 0;
/polymer/eduke32/source/global.h
0,0 → 1,144
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __global_h__
#define __global_h__
 
#include "duke3d.h"
#include "sector.h"
 
#ifdef __global_c__
#define G_EXTERN
#else
#define G_EXTERN extern
#endif
 
// duke3d global soup :(
 
#define MAXINTERPOLATIONS MAXSPRITES
 
G_EXTERN DukeStatus_t sbar;
G_EXTERN actor_t actor[MAXSPRITES];
G_EXTERN animwalltype animwall[MAXANIMWALLS];
G_EXTERN char *ScriptQuotes[MAXQUOTES],*ScriptQuoteRedefinitions[MAXQUOTES];
G_EXTERN char *label;
G_EXTERN char ActorType[MAXTILES];
G_EXTERN char CheatKeys[2];
G_EXTERN char EnvMusicFilename[MAXVOLUMES+1][BMAX_PATH];
G_EXTERN char EpisodeNames[MAXVOLUMES][33];
G_EXTERN char GametypeNames[MAXGAMETYPES][33];
G_EXTERN char SkillNames[5][33];
G_EXTERN char g_RTSPlaying;
G_EXTERN char g_musicIndex;
G_EXTERN char g_numGametypes;
G_EXTERN char g_numPlayerSprites,g_loadFromGroupOnly;
G_EXTERN char g_numVolumes;
G_EXTERN char myjumpingtoggle,myonground,myhardlanding,myreturntocenter;
G_EXTERN char pus,pub;
G_EXTERN char ready2send;
G_EXTERN char setupfilename[BMAX_PATH];
G_EXTERN char szPlayerName[32];
G_EXTERN char tempbuf[2048],packbuf[PACKBUF_SIZE],menutextbuf[128],buf[1024];
G_EXTERN char typebuflen,typebuf[141];
G_EXTERN const char *s_buildDate;
G_EXTERN input_t avg;
G_EXTERN input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
G_EXTERN input_t loc;
G_EXTERN input_t recsync[RECSYNCBUFSIZ];
G_EXTERN int16_t BlimpSpawnSprites[15];
G_EXTERN int16_t SpriteDeletionQueue[1024],g_spriteDeleteQueuePos,g_spriteDeleteQueueSize;
G_EXTERN int16_t animatesect[MAXANIMATES];
G_EXTERN int16_t camsprite;
G_EXTERN int16_t cyclers[MAXCYCLERS][6],g_numCyclers;
G_EXTERN int16_t g_globalRandom;
G_EXTERN int16_t g_mirrorWall[64],g_mirrorSector[64],g_mirrorCount;
G_EXTERN int16_t g_numAnimWalls;
G_EXTERN int16_t g_numClouds,clouds[128],cloudx[128],cloudy[128];
G_EXTERN int16_t myang,omyang,mycursectnum,myjumpingcounter;
G_EXTERN int16_t myangbak[MOVEFIFOSIZ];
G_EXTERN int16_t myhoriz,omyhoriz,myhorizoff,omyhorizoff;
G_EXTERN int16_t neartagsector,neartagwall,neartagsprite;
G_EXTERN int32_t *animateptr[MAXANIMATES];
G_EXTERN int32_t *curipos[MAXINTERPOLATIONS];
G_EXTERN int32_t GametypeFlags[MAXGAMETYPES];
G_EXTERN int32_t SpriteFlags[MAXTILES];
G_EXTERN int32_t animategoal[MAXANIMATES],animatevel[MAXANIMATES],g_animateCount;
G_EXTERN int32_t bakipos[MAXINTERPOLATIONS];
G_EXTERN int32_t cloudtotalclock;
G_EXTERN int32_t fricxv,fricyv;
G_EXTERN int32_t g_currentFrameRate;
G_EXTERN int32_t g_currentMenu;
G_EXTERN int32_t g_damageCameras,g_freezerSelfDamage;
G_EXTERN int32_t g_doQuickSave;
G_EXTERN char g_earthquakeTime;
G_EXTERN int32_t g_gameQuit;
G_EXTERN int32_t g_groupFileHandle;
G_EXTERN int32_t g_impactDamage,g_maxPlayerHealth;
G_EXTERN int32_t g_interpolationLock;
G_EXTERN int32_t g_lastSaveSlot;
G_EXTERN int32_t g_musicSize;
G_EXTERN int32_t g_numFreezeBounces;
G_EXTERN int32_t g_numInterpolations;
G_EXTERN int32_t g_numLabels,g_numDefaultLabels;
G_EXTERN int32_t g_numRealPalettes;
G_EXTERN int32_t g_playerFriction;
G_EXTERN int32_t g_scriptDebug;
G_EXTERN int32_t g_scriptSize;
G_EXTERN int32_t g_showShareware;
G_EXTERN int32_t g_spriteGravity;
G_EXTERN int32_t g_timerTicsPerSecond;
G_EXTERN int32_t g_tripbombLaserMode;
G_EXTERN int32_t movefifosendplc;
G_EXTERN int32_t msx[2048],msy[2048];
G_EXTERN int32_t neartaghitdist,lockclock,g_startArmorAmount;
G_EXTERN int32_t nextvoxid;
G_EXTERN int32_t oldipos[MAXINTERPOLATIONS];
G_EXTERN int32_t playerswhenstarted;
G_EXTERN int32_t screenpeek;
G_EXTERN int32_t startofdynamicinterpolations;
G_EXTERN int32_t vel,svel,angvel,horiz,ototalclock,g_actorRespawnTime;
G_EXTERN int8_t multiwho,multipos,multiwhat,multiflag;
G_EXTERN intptr_t *actorscrptr[MAXTILES],*g_parsingActorPtr;
G_EXTERN intptr_t *g_scriptPtr,*insptr,*labelcode,*labeltype;
G_EXTERN intptr_t *script;
G_EXTERN map_t MapInfo[(MAXVOLUMES+1)*MAXLEVELS];
G_EXTERN playerdata_t g_player[MAXPLAYERS];
G_EXTERN playerspawn_t g_playerSpawnPoints[MAXPLAYERS];
G_EXTERN projectile_t ProjectileData[MAXTILES],DefaultProjectileData[MAXTILES],SpriteProjectile[MAXSPRITES];
G_EXTERN sound_t g_sounds[MAXSOUNDS];
G_EXTERN uint32_t everyothertime;
G_EXTERN uint32_t g_moveThingsCount;
G_EXTERN vec3_t my,omy,myvel;
G_EXTERN volatile char g_soundlocks[MAXSOUNDS];
G_EXTERN int32_t g_rpgBlastRadius;
G_EXTERN int32_t g_pipebombBlastRadius;
G_EXTERN int32_t g_tripbombBlastRadius;
G_EXTERN int32_t g_shrinkerBlastRadius;
G_EXTERN int32_t g_morterBlastRadius;
G_EXTERN int32_t g_bouncemineBlastRadius;
G_EXTERN int32_t g_seenineBlastRadius;
G_EXTERN int32_t g_itemRespawnTime;
G_EXTERN int32_t g_restorePalette;
G_EXTERN int32_t g_screenCapture;
G_EXTERN int32_t g_noEnemies;
 
#endif
/polymer/eduke32/source/grpscan.c
234,7 → 234,7
while (foundgrps)
{
fg = foundgrps->next;
Bfree((char*)foundgrps->name);
Bfree((char *)foundgrps->name);
Bfree(foundgrps);
foundgrps = fg;
}
/polymer/eduke32/source/m32def.c
121,7 → 121,7
char x[64];
 
x[0] = 0;
for (i=0; i<sizeof(LabelTypeText)/sizeof(char*); i++)
for (i=0; i<sizeof(LabelTypeText)/sizeof(char *); i++)
{
if (!(type & (1<<i))) continue;
if (x[0]) Bstrcat(x, " or ");
525,27 → 525,27
 
hash_init(&h_keywords);
for (i=NUMKEYWORDS-1; i>=0; i--)
hash_add(&h_keywords, keyw[i], i);
hash_add(&h_keywords, keyw[i], i, 0);
for (i=0; i<NUMALTKEYWORDS; i++)
hash_add(&h_keywords, altkeyw[i].token, altkeyw[i].val);
hash_add(&h_keywords, altkeyw[i].token, altkeyw[i].val, 0);
 
hash_init(&h_sector);
for (i=0; SectorLabels[i].lId >=0; i++)
hash_add(&h_sector,SectorLabels[i].name,i);
hash_add(&h_sector,"filler", SECTOR_ALIGNTO);
hash_add(&h_sector,SectorLabels[i].name,i, 0);
hash_add(&h_sector,"filler", SECTOR_ALIGNTO, 0);
 
hash_init(&h_wall);
for (i=0; WallLabels[i].lId >=0; i++)
hash_add(&h_wall,WallLabels[i].name,i);
hash_add(&h_wall,WallLabels[i].name,i, 0);
 
hash_init(&h_sprite);
for (i=0; SpriteLabels[i].lId >=0; i++)
hash_add(&h_sprite,SpriteLabels[i].name,i);
hash_add(&h_sprite,"filler", SPRITE_DETAIL);
hash_add(&h_sprite,SpriteLabels[i].name,i, 0);
hash_add(&h_sprite,"filler", SPRITE_DETAIL, 0);
 
hash_init(&h_iter);
for (i=0; iter_tokens[i].val >=0; i++)
hash_add(&h_iter, iter_tokens[i].token, iter_tokens[i].val);
hash_add(&h_iter, iter_tokens[i].token, iter_tokens[i].val, 0);
}
 
static int32_t C_SetScriptSize(int32_t size)
603,7 → 603,7
static inline int32_t isaltok(char c)
{
return isalnum(c) || c == '#' || c == '{' || c == '}' || c == '/' || c == '\\' ||
c == '*' || c == '-' || c == '_' || c == '.';
c == '*' || c == '-' || c == '_' || c == '.';
}
 
static int32_t C_SkipComments(void)
924,7 → 924,7
}
}
else if (type != GAMEVAR_SPECIAL &&
(textptr[0]=='.' || (textptr[0]=='-' && textptr[1]=='.')))
(textptr[0]=='.' || (textptr[0]=='-' && textptr[1]=='.')))
{
int32_t lLabelID = -1, aridx = M32_THISACTOR_VAR_ID;
 
1430,7 → 1430,7
// printf("Defining Definition '%s' to be '%d'\n",label+(g_numLabels*MAXLABELLEN),*(g_scriptPtr-1));
// Bmemcpy(label+(g_numLabels*MAXLABELLEN), tlabel, MAXLABELLEN);
C_CopyLabel();
hash_add(&h_labels, label+(g_numLabels*MAXLABELLEN), g_numLabels);
hash_add(&h_labels, label+(g_numLabels*MAXLABELLEN), g_numLabels, 0);
labeltype[g_numLabels] = LABEL_DEFINE;
labelval[g_numLabels++] = *(g_scriptPtr-1);
}
1576,7 → 1576,7
 
Bmemcpy(statesinfo[j].name, tlabel, MAXLABELLEN);
Bsprintf(g_szCurrentBlockName, "%s", tlabel);
hash_add(&h_states, tlabel, j);
hash_add(&h_states, tlabel, j, 0);
}
 
return 0;
3162,7 → 3162,7
static void C_AddDefinition(const char *lLabel,int32_t lValue, uint8_t lType)
{
Bstrcpy(label+(g_numLabels*MAXLABELLEN), lLabel);
hash_add(&h_labels, label+(g_numLabels*MAXLABELLEN), g_numLabels);
hash_add(&h_labels, label+(g_numLabels*MAXLABELLEN), g_numLabels, 0);
labeltype[g_numLabels] = lType;
labelval[g_numLabels++] = lValue;
g_numDefaultLabels++;
3333,7 → 3333,7
int32_t i,j;
int32_t fs,fp;
int32_t startcompiletime;
instype* oscriptPtr;
instype *oscriptPtr;
int32_t ostateCount = g_stateCount;
 
interactive_compilation = !isfilename;
/polymer/eduke32/source/m32exec.c
602,7 → 602,7
{
case 0:
case GAMEARRAY_OFINT:
Bmemcpy((int32_t*)aGameArrays[di].vals + didx, (int32_t *)aGameArrays[si].vals + sidx, numelts * sizeof(int32_t));
Bmemcpy((int32_t *)aGameArrays[di].vals + didx, (int32_t *)aGameArrays[si].vals + sidx, numelts * sizeof(int32_t));
break;
case GAMEARRAY_OFSHORT:
for (; numelts>0; numelts--)
832,7 → 832,7
insptr++;
{
int32_t bits=Gv_GetVarX(*insptr), scale=*(insptr+1);
float fval = *((float*)&bits);
float fval = *((float *)&bits);
 
Gv_SetVarX(*insptr, (int32_t)(fval * scale));
}
1141,13 → 1141,13
 
if (state < 0)
{
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t(*)(const void*,const void*))X_DoSortDefault);
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t( *)(const void *,const void *))X_DoSortDefault);
}
else
{
x_sortingstateptr = script + statesinfo[state].ofs;
vm.g_st = 1+MAXEVENTS+state;
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t(*)(const void*,const void*))X_DoSort);
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t( *)(const void *,const void *))X_DoSort);
vm.g_st = o_g_st;
insptr = end;
}
1972,7 → 1972,7
{
int32_t v1=*insptr++,v2=*insptr++,v3=*insptr++,v4=*insptr++,v5=*insptr++,v6=*insptr++,v7=*insptr++,v8=*insptr++;
time_t rawtime;
struct tm * ti;
struct tm *ti;
 
time(&rawtime);
ti = localtime(&rawtime);
/polymer/eduke32/source/m32vars.c
120,7 → 120,7
aGameArrays[i].dwFlags = dwFlags & ~GAMEARRAY_RESET;
 
g_gameArrayCount++;
hash_replace(&h_arrays, aGameArrays[i].szLabel, i);
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
return 1;
}
 
191,7 → 191,7
if (i == g_gameVarCount)
{
// we're adding a new one.
hash_add(&h_gamevars, aGameVars[i].szLabel, g_gameVarCount++);
hash_add(&h_gamevars, aGameVars[i].szLabel, g_gameVarCount++, 0);
}
 
if (aGameVars[i].dwFlags & GAMEVAR_PERBLOCK)
229,11 → 229,11
return aGameVars[id].val.plValues[vm.g_st];
case GAMEVAR_FLOATPTR:
case GAMEVAR_INTPTR:
return *((int32_t*)aGameVars[id].val.lValue);
return *((int32_t *)aGameVars[id].val.lValue);
case GAMEVAR_SHORTPTR:
return *((int16_t*)aGameVars[id].val.lValue);
return *((int16_t *)aGameVars[id].val.lValue);
case GAMEVAR_CHARPTR:
return *((uint8_t*)aGameVars[id].val.lValue);
return *((uint8_t *)aGameVars[id].val.lValue);
default:
M32_PRINTERROR("Gv_GetVarN(): WTF??");
vm.flags |= VMFLAG_ERROR;
353,15 → 353,15
case GAMEVAR_FLOATPTR:
if (negateResult)
{
float fval = -(*(float*)aGameVars[id].val.lValue);
float fval = -(*(float *)aGameVars[id].val.lValue);
return *(int32_t *)&fval;
}
case GAMEVAR_INTPTR:
return ((*((int32_t*)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
return ((*((int32_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
case GAMEVAR_SHORTPTR:
return ((*((int16_t*)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
return ((*((int16_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
case GAMEVAR_CHARPTR:
return ((*((uint8_t*)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
return ((*((uint8_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
default:
M32_PRINTERROR("Gv_GetVarX(): WTF??");
vm.flags |= VMFLAG_ERROR;
473,13 → 473,13
}
}
case GAMEVAR_INTPTR:
*((int32_t*)aGameVars[id].val.lValue)=(int32_t)lValue;
*((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
return;
case GAMEVAR_SHORTPTR:
*((int16_t*)aGameVars[id].val.lValue)=(int16_t)lValue;
*((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
return;
case GAMEVAR_CHARPTR:
*((uint8_t*)aGameVars[id].val.lValue)=(uint8_t)lValue;
*((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
return;
default:
M32_PRINTERROR("Gv_SetVarX(): WTF??");
/polymer/eduke32/source/macros.h
22,6 → 22,11
 
// Macros, some from SW source
 
#define ALT_IS_PRESSED ( KB_KeyPressed( sc_RightAlt ) || KB_KeyPressed( sc_LeftAlt ) )
#define SHIFTS_IS_PRESSED ( KB_KeyPressed( sc_RightShift ) || KB_KeyPressed( sc_LeftShift ) )
#define RANDOMSCRAP A_InsertSprite(s->sectnum,s->x+(krand()&255)-128,s->y+(krand()&255)-128,s->z-(8<<8)-(krand()&8191),\
SCRAP6+(krand()&15),-8,48,48,krand()&2047,(krand()&63)+64,-512-(krand()&2047),i,5)
 
#define GTFLAGS(x) (GametypeFlags[ud.coop] & x)
 
#define TRAVERSE_SPRITE_SECT(l, o, n) for ((o) = (l); ((o) != -1) && ((n) = nextspritesect[o]); (o) = (n))
/polymer/eduke32/source/menus.c
25,11 → 25,13
#include "osd.h"
#include "osdcmds.h"
#include "gamedef.h"
#include "gameexec.h"
#include "savegame.h"
#include "premap.h"
#include <sys/stat.h>
 
extern char inputloc;
extern int32_t g_demo_recFilePtr;
//extern char vgacompatible;
int16_t g_skillSoundID=-1;
int32_t probey=0;
static int32_t lastsavehead=0,last_menu_pos=0,last_menu,sh,onbar,buttonstat;
469,7 → 471,10
 
extern int32_t G_LoadSaveHeader(char spot,struct savehead *saveh);
 
#pragma pack(push,1)
static struct savehead savehead;
#pragma pack(pop)
 
//static int32_t volnum,levnum,plrskl,numplr;
//static char brdfn[BMAX_PATH];
int32_t g_lastSaveSlot = -1;
1464,38 → 1469,10
totalclock = ototalclock;
}
 
if ((g_netServer || ud.multimode > 1))
{
if (g_player[myconnectindex].ps->gm&MODE_GAME)
{
G_LoadPlayer(-1-g_lastSaveSlot);
g_player[myconnectindex].ps->gm = MODE_GAME;
}
else
{
tempbuf[0] = PACKET_LOAD_GAME;
tempbuf[1] = g_lastSaveSlot;
tempbuf[2] = myconnectindex;
c = G_LoadPlayer(g_lastSaveSlot);
if (c == 0)
g_player[myconnectindex].ps->gm = MODE_GAME;
 
if (g_netClient)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(tempbuf, 3, ENET_PACKET_FLAG_RELIABLE));
else if (g_netServer)
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(tempbuf, 3, ENET_PACKET_FLAG_RELIABLE));
 
Net_GetPackets();
 
G_LoadPlayer(g_lastSaveSlot);
 
multiflag = 0;
}
}
else
{
c = G_LoadPlayer(g_lastSaveSlot);
if (c == 0)
g_player[myconnectindex].ps->gm = MODE_GAME;
}
 
break;
}
 
1874,8 → 1851,8
for (m=0,i=(totalclock/104)%numlines; m<6; m++,i++)
{
if (i==numlines) i=0;
minitext(161-(Bstrlen(scroller[i])<<1), 101+10+10+8+4+(m*7)-l, (char*)scroller[i], 4, 10+16+128);
minitext(160-(Bstrlen(scroller[i])<<1), 100+10+10+8+4+(m*7)-l, (char*)scroller[i], 8, 10+16+128);
minitext(161-(Bstrlen(scroller[i])<<1), 101+10+10+8+4+(m*7)-l, (char *)scroller[i], 4, 10+16+128);
minitext(160-(Bstrlen(scroller[i])<<1), 100+10+10+8+4+(m*7)-l, (char *)scroller[i], 8, 10+16+128);
}
}
 
1929,7 → 1906,7
 
if (KB_KeyPressed(sc_Q)) ChangeToMenu(500);
 
if (x == -1 && (g_player[myconnectindex].ps->gm&MODE_GAME || ud.recstat == 2))
if (x == -1 && (g_player[myconnectindex].ps->gm &MODE_GAME || ud.recstat == 2))
{
g_player[myconnectindex].ps->gm &= ~MODE_MENU;
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2)
2592,7 → 2569,7
 
if (x == -1)
{
if (g_player[myconnectindex].ps->gm&MODE_GAME && g_currentMenu == 232)
if (g_player[myconnectindex].ps->gm &MODE_GAME && g_currentMenu == 232)
{
g_player[myconnectindex].ps->gm &= ~MODE_MENU;
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2)
4448,7 → 4425,7
ud.config.NumVoices = soundvoices;
ud.config.NumBits = soundbits;
 
if (g_player[myconnectindex].ps->gm&MODE_GAME && g_currentMenu == 701)
if (g_player[myconnectindex].ps->gm &MODE_GAME && g_currentMenu == 701)
{
g_player[myconnectindex].ps->gm &= ~MODE_MENU;
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2)
5008,7 → 4985,7
{
KB_ClearKeyDown(sc_N);
g_quitDeadline = 0;
if (g_player[myconnectindex].ps->gm&MODE_DEMO && ud.recstat == 2)
if (g_player[myconnectindex].ps->gm &MODE_DEMO && ud.recstat == 2)
g_player[myconnectindex].ps->gm = MODE_DEMO;
else
{
5017,7 → 4994,7
ChangeToMenu(last_menu);
probey = last_menu_pos;
}
else if (!(g_player[myconnectindex].ps->gm & MODE_GAME || ud.recstat == 2))
else if (!(g_player[myconnectindex].ps->gm &MODE_GAME || ud.recstat == 2))
ChangeToMenu(0);
else g_player[myconnectindex].ps->gm &= ~MODE_MENU;
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2)
/polymer/eduke32/source/menus.h
0,0 → 1,40
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __menus_h__
#define __menus_h__
 
#include "savegame.h"
 
extern char inputloc;
extern int16_t g_skillSoundID;
extern int32_t g_demo_recFilePtr;
extern int32_t g_lastSaveSlot;
extern int32_t g_quitDeadline;
extern int32_t probey;
extern int32_t voting;
int32_t G_LoadSaveHeader(char spot,struct savehead *saveh);
int32_t menutext_(int32_t x,int32_t y,int32_t s,int32_t p,char *t,int32_t bits);
void ChangeToMenu(int32_t cm);
void G_CheckPlayerColor(int32_t *color,int32_t prev_color);
void M_DisplayMenus(void);
#endif
/polymer/eduke32/source/mpu401.c
124,7 → 124,7
switch (uMsg)
{
case MOM_DONE:
midiOutUnprepareHeader((HMIDIOUT)handle, (MIDIHDR*)dwParam1, sizeof(MIDIHDR));
midiOutUnprepareHeader((HMIDIOUT)handle, (MIDIHDR *)dwParam1, sizeof(MIDIHDR));
for (i=0; i<NUMBUFFERS; i++)
{
if (dwParam1 == (uint32_t)&bufferheaders[i])
181,9 → 181,9
}
 
p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer];
((int32_t*)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent;
((int32_t*)p)[1] = 0;
((int32_t*)p)[2] = (MEVT_SHORTMSG << 24) | ((*((int32_t*)data)) & masks[count-1]);
((int32_t *)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent;
((int32_t *)p)[1] = 0;
((int32_t *)p)[2] = (MEVT_SHORTMSG << 24) | ((*((int32_t *)data)) & masks[count-1]);
eventcnt[_MPU_CurrentBuffer] += 12;
}
else
203,9 → 203,9
}
 
p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer];
((int32_t*)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent;
((int32_t*)p)[1] = 0;
((int32_t*)p)[2] = (MEVT_LONGMSG<<24) | (count & 0xffffffl);
((int32_t *)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent;
((int32_t *)p)[1] = 0;
((int32_t *)p)[2] = (MEVT_LONGMSG<<24) | (count & 0xffffffl);
p+=12; eventcnt[_MPU_CurrentBuffer] += 12;
for (; count>0; count--, padded--, eventcnt[_MPU_CurrentBuffer]++)
*(p++) = *(data++);
227,7 → 227,7
static int32_t masks[3] = { 0x00ffffffl, 0x0000ffffl, 0x000000ffl };
 
if (!count) return;
if (count<=3) midiOutShortMsg((HMIDIOUT)hmido, (*((int32_t*)data)) & masks[count-1]);
if (count<=3) midiOutShortMsg((HMIDIOUT)hmido, (*((int32_t *)data)) & masks[count-1]);
else
{
ZeroMemory(&mhdr, sizeof(mhdr));
/polymer/eduke32/source/namesdyn.c
1532,7 → 1532,7
int32_t i;
hash_init(&h_names);
for (i=0; list[i].val; i++)
hash_add(&h_names,list[i].s,i);
hash_add(&h_names,list[i].s,i,0);
}
 
void freehashnames()
/polymer/eduke32/source/namesdyn.h
20,6 → 20,9
*/
//-------------------------------------------------------------------------
 
void G_InitDynamicTiles(void);
void G_ProcessDynamicTileMapping(const char *szLabel, int32_t lValue);
 
extern int32_t SECTOREFFECTOR;
#define SECTOREFFECTOR__STATIC 1
extern int32_t ACTIVATOR;
/polymer/eduke32/source/net.c
0,0 → 1,1982
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#include "duke3d.h"
#include "game.h"
#include "gamedef.h"
#include "net.h"
#include "premap.h"
 
#include "enet/enet.h"
#include "quicklz.h"
#include "crc32.h"
 
/*
this should be lower than the MTU size by at least the size of the UDP and ENet headers
or else fragmentation will occur
*/
#define SYNCPACKETSIZE 1366
 
ENetHost *g_netServer = NULL;
ENetHost *g_netClient = NULL;
ENetPeer *g_netClientPeer = NULL;
int32_t g_netPort = 23513;
int32_t g_netDisconnect = 0;
char g_netPassword[32];
int32_t g_netSync = 0;
int32_t g_netPlayersWaiting = 0;
int32_t g_netServerMode = 0;
 
static char recbuf[180];
static int32_t g_chatPlayer = -1;
 
// sprites of these statnums are synced to clients by the server
int8_t g_netStatnums[8] = { STAT_PROJECTILE, STAT_STANDABLE, STAT_ACTIVATOR, STAT_TRANSPORT,
STAT_EFFECTOR, STAT_ACTOR, STAT_ZOMBIEACTOR, STAT_MISC
};
 
int32_t lastupdate[MAXSPRITES];
int32_t lastsectupdate[MAXSECTORS];
int32_t lastwallupdate[MAXWALLS];
mapstate_t *g_multiMapState = NULL;
static int32_t spritecrc[MAXSPRITES];
static int32_t sectcrc[MAXSECTORS];
static int32_t wallcrc[MAXWALLS];
 
void Net_Connect(const char *srvaddr)
{
ENetAddress address;
ENetEvent event;
char *addrstr = NULL;
int32_t i;
 
Net_Disconnect();
 
g_netClient = enet_host_create(NULL, 1, CHAN_MAX, 0, 0);
 
if (g_netClient == NULL)
{
initprintf("An error occurred while trying to create an ENet client host.\n");
return;
}
 
addrstr = strtok((char *)srvaddr, ":");
enet_address_set_host(&address, addrstr);
address.port = atoi((addrstr = strtok(NULL, ":")) == NULL ? "23513" : addrstr);
 
g_netClientPeer = enet_host_connect(g_netClient, &address, CHAN_MAX, 0);
 
if (g_netClientPeer == NULL)
{
initprintf("No available peers for initiating an ENet connection.\n");
return;
}
 
for (i=4; i>0; i--)
{
/* Wait up to 5 seconds for the connection attempt to succeed. */
if (enet_host_service(g_netClient, & event, 5000) > 0 &&
event.type == ENET_EVENT_TYPE_CONNECT)
{
initprintf("Connection to %s:%d succeeded.\n", (char *)srvaddr, address.port);
return;
}
else
{
/* Either the 5 seconds are up or a disconnect event was */
/* received. Reset the peer in the event the 5 seconds */
/* had run out without any significant event. */
enet_peer_reset(g_netClientPeer);
initprintf("Connection to %s:%d failed.\n",(char *)srvaddr,address.port);
}
initprintf(i ? "Retrying...\n" : "Giving up connection attempt.\n");
}
 
Net_Disconnect();
}
 
void Net_Disconnect(void)
{
if (g_netClient)
{
ENetEvent event;
 
if (g_netClientPeer)
enet_peer_disconnect_later(g_netClientPeer, 0);
 
while (enet_host_service(g_netClient, & event, 3000) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
case ENET_EVENT_TYPE_NONE:
case ENET_EVENT_TYPE_RECEIVE:
if (event.packet)
enet_packet_destroy(event.packet);
break;
 
case ENET_EVENT_TYPE_DISCONNECT:
numplayers = playerswhenstarted = ud.multimode = 1;
myconnectindex = screenpeek = 0;
G_BackToMenu();
break;
}
}
 
enet_peer_reset(g_netClientPeer);
g_netClientPeer = NULL;
enet_host_destroy(g_netClient);
g_netClient = NULL;
return;
}
 
if (g_netServer)
{
ENetPeer *currentPeer;
ENetEvent event;
 
for (currentPeer = g_netServer -> peers;
currentPeer < & g_netServer -> peers [g_netServer -> peerCount];
++ currentPeer)
{
enet_peer_disconnect_later(currentPeer, 0);
}
 
while (enet_host_service(g_netServer, & event, 3000) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
case ENET_EVENT_TYPE_NONE:
case ENET_EVENT_TYPE_RECEIVE:
case ENET_EVENT_TYPE_DISCONNECT:
if (event.packet)
enet_packet_destroy(event.packet);
break;
}
}
enet_host_destroy(g_netServer);
g_netServer = NULL;
}
}
 
static void Net_SendVersion(ENetPeer *client)
{
if (!g_netServer) return;
 
buf[0] = PACKET_VERSION;
buf[1] = BYTEVERSION;
buf[2] = (uint8_t)atoi(s_buildDate);
buf[3] = myconnectindex;
 
enet_peer_send(client, CHAN_GAMESTATE, enet_packet_create(&buf[0], 4, ENET_PACKET_FLAG_RELIABLE));
}
 
void Net_SendClientInfo(void)
{
int32_t i,l;
 
for (l=0; (unsigned)l<sizeof(szPlayerName)-1; l++)
g_player[myconnectindex].user_name[l] = Btoupper(szPlayerName[l]);
 
if (numplayers < 2) return;
 
buf[0] = PACKET_CLIENT_INFO;
l = 1;
 
//null terminated player name to send
for (i=0; szPlayerName[i]; i++) buf[l++] = Btoupper(szPlayerName[i]);
buf[l++] = 0;
 
buf[l++] = g_player[myconnectindex].ps->aim_mode = ud.mouseaiming;
buf[l++] = g_player[myconnectindex].ps->auto_aim = ud.config.AutoAim;
buf[l++] = g_player[myconnectindex].ps->weaponswitch = ud.weaponswitch;
buf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = ud.color;
 
buf[l++] = g_player[myconnectindex].pteam = ud.team;
 
for (i=0; i<10; i++)
{
g_player[myconnectindex].wchoice[i] = g_player[0].wchoice[i];
buf[l++] = (uint8_t)g_player[0].wchoice[i];
}
 
buf[l++] = myconnectindex;
 
if (g_netClient)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
else if (g_netServer)
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
}
 
void Net_SendUserMapName(void)
{
int32_t j;
 
if (numplayers < 2)
return;
 
packbuf[0] = PACKET_USER_MAP;
packbuf[1] = 0;
 
Bcorrectfilename(boardfilename,0);
 
j = Bstrlen(boardfilename);
boardfilename[j++] = 0;
Bstrcat(packbuf+1,boardfilename);
 
packbuf[j++] = myconnectindex;
 
if (g_netClient)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(packbuf, j, ENET_PACKET_FLAG_RELIABLE));
else if (g_netServer)
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, j, ENET_PACKET_FLAG_RELIABLE));
}
 
// FIXME: change all of the game starting support code to be fully server controlled
void Net_NewGame(int32_t volume, int32_t level)
{
packbuf[0] = PACKET_NEW_GAME;
packbuf[1] = ud.m_level_number = level;
packbuf[2] = ud.m_volume_number = volume;
packbuf[3] = ud.m_player_skill+1;
packbuf[4] = ud.m_monsters_off;
packbuf[5] = ud.m_respawn_monsters;
packbuf[6] = ud.m_respawn_items;
packbuf[7] = ud.m_respawn_inventory;
packbuf[8] = ud.m_coop;
packbuf[9] = ud.m_marker;
packbuf[10] = ud.m_ffire;
packbuf[11] = ud.m_noexits;
packbuf[12] = myconnectindex;
 
if (g_netClient)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(packbuf, 13, ENET_PACKET_FLAG_RELIABLE));
else if (g_netServer)
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 13, ENET_PACKET_FLAG_RELIABLE));
}
 
// sends a simple crc32 of the current password, verified by the server before the connection can continue
static void Net_SendChallenge(void)
{
int32_t l = 1;
uint32_t crc = crc32once((uint8_t *)g_netPassword, Bstrlen(g_netPassword));
 
if (!g_netClientPeer) return;
 
buf[0] = PACKET_AUTH;
*(uint32_t *)&buf[1] = crc;
l += sizeof(int32_t);
 
buf[l++] = myconnectindex;
 
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&buf[0], l, ENET_PACKET_FLAG_RELIABLE));
}
 
static void P_RemovePlayer(int32_t i)
{
// server obviously can't leave the game, and index 0 shows up for disconnect events from
// players that haven't gotten far enough into the connection process to get a player ID
 
if (i == 0) return;
 
g_player[i].playerquitflag = 0;
 
Bsprintf(buf,"%s^00 is history!",g_player[i].user_name);
G_AddUserQuote(buf);
 
if (numplayers == 1)
S_PlaySound(GENERIC_AMBIENCE17);
 
if (g_player[myconnectindex].ps->gm & MODE_GAME)
{
if (screenpeek == i)
screenpeek = myconnectindex;
 
pub = NUMPAGES;
pus = NUMPAGES;
G_UpdateScreenArea();
 
P_QuickKill(g_player[i].ps);
 
if (voting == i)
{
for (i=0; i<MAXPLAYERS; i++)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
voting = -1;
}
 
Bstrcpy(ScriptQuotes[116],buf);
g_player[myconnectindex].ps->ftq = 116;
g_player[myconnectindex].ps->fta = 180;
}
}
 
// sync a connecting player up with the current game state
void Net_SyncPlayer(ENetEvent *event)
{
int32_t i, j;
 
g_netPlayersWaiting++;
 
S_PlaySound(DUKE_GETWEAPON2);
 
TRAVERSE_CONNECT(i)
if (g_player[i].playerquitflag == 0)
break;
 
// open a new slot if necessary
event->peer->data = (void *)((intptr_t)(i = (i == -1 ? playerswhenstarted++ : i)));
 
g_player[i].netsynctime = totalclock;
g_player[i].playerquitflag = 1;
 
for (j=0; j<playerswhenstarted-1; j++) connectpoint2[j] = j+1;
connectpoint2[playerswhenstarted-1] = -1;
 
TRAVERSE_CONNECT(j)
{
if (!g_player[j].ps) g_player[j].ps = (DukePlayer_t *) Bcalloc(1, sizeof(DukePlayer_t));
if (!g_player[j].sync) g_player[j].sync = (input_t *) Bcalloc(1, sizeof(input_t));
}
 
packbuf[0] = PACKET_NUM_PLAYERS;
packbuf[1] = ++numplayers;
packbuf[2] = playerswhenstarted;
packbuf[3] = ++ud.multimode;
packbuf[4] = i;
packbuf[5] = myconnectindex;
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 6, ENET_PACKET_FLAG_RELIABLE));
 
packbuf[0] = PACKET_PLAYER_INDEX;
packbuf[1] = i;
packbuf[2] = myconnectindex;
enet_peer_send(event->peer, CHAN_GAMESTATE, enet_packet_create(packbuf, 3, ENET_PACKET_FLAG_RELIABLE));
 
Net_SendClientInfo();
Net_SendUserMapName();
 
if (g_player[0].ps->gm & MODE_GAME)
{
if (g_multiMapState == NULL) g_multiMapState = (mapstate_t *)Bcalloc(1, sizeof(mapstate_t));
if (g_multiMapState)
{
char *buf = (char *)Bmalloc(sizeof(mapstate_t)<<1);
 
sprite[g_player[i].ps->i].cstat = 32768;
g_player[i].ps->runspeed = g_playerFriction;
g_player[i].ps->last_extra = sprite[g_player[i].ps->i].extra = g_player[i].ps->max_player_health = g_maxPlayerHealth;
 
G_SaveMapState(g_multiMapState);
if ((j = qlz_compress((char *)g_multiMapState, buf, sizeof(mapstate_t), state_compress)))
{
// all of these packets are SYNCPACKETSIZE
do
{
enet_peer_send(event->peer, CHAN_SYNC,
enet_packet_create((char *)(buf)+qlz_size_compressed(buf)-j, SYNCPACKETSIZE, ENET_PACKET_FLAG_RELIABLE));
j -= SYNCPACKETSIZE;
}
while (j >= SYNCPACKETSIZE);
 
// ...except for this one. A non-SYNCPACKETSIZE packet on CHAN_SYNC doubles as the signal that the transfer is done.
enet_peer_send(event->peer, CHAN_SYNC,
enet_packet_create((char *)(buf)+qlz_size_compressed(buf)-j, j, ENET_PACKET_FLAG_RELIABLE));
}
else
initprintf("Error compressing map state for transfer!\n");
 
Bfree(buf);
Bfree(g_multiMapState);
g_multiMapState = NULL;
}
}
}
 
int32_t Net_UnpackSprite(int32_t i, uint8_t *pbuf)
{
int16_t sect, statnum, osect, ostatnum, jj, opicnum, j = 0;
#ifdef POLYMER
int16_t lightid = -1;
_prlight *mylight = NULL;
#endif
 
osect = sprite[i].sectnum;
ostatnum = sprite[i].statnum;
opicnum = sprite[i].picnum;
 
Bmemcpy(&sprite[i], &pbuf[j], sizeof(spritetype));
j += sizeof(spritetype);
 
sect = sprite[i].sectnum;
statnum = sprite[i].statnum;
 
if (sect == MAXSECTORS || statnum == MAXSTATUS)
{
j += sizeof(netactor_t);
deletesprite(i);
return j;
}
 
sprite[i].sectnum = osect;
sprite[i].statnum = ostatnum;
 
// doesn't exist on the client yet
if (ostatnum == MAXSTATUS || osect == MAXSECTORS)
{
int16_t sprs[MAXSPRITES], z = 0;
while ((sprs[z++] = insertsprite(sect, statnum)) != i);
z--;
while (z--) deletesprite(sprs[z]);
}
else
{
if (sect != osect) changespritesect(i, sect);
if (statnum != ostatnum) changespritestat(i, statnum);
}
#ifdef POLYMER
if (sprite[i].picnum == opicnum)
{
mylight = actor[i].lightptr;
lightid = actor[i].lightId;
}
else if (getrendermode() == 4 && actor[i].lightptr != NULL)
{
polymer_deletelight(actor[i].lightId);
actor[i].lightId = -1;
actor[i].lightptr = NULL;
}
#endif
 
/*initprintf("updating sprite %d (%d)\n",i,sprite[i].picnum);*/
 
jj = j++;
 
Bmemcpy(&actor[i], &pbuf[j], sizeof(netactor_t));
j += sizeof(netactor_t);
 
actor[i].projectile = &SpriteProjectile[i];
#ifdef POLYMER
actor[i].lightptr = mylight;
actor[i].lightId = lightid;
#endif
 
actor[i].flags &= ~SPRITE_NULL;
 
if (pbuf[jj] & 1) T2 += (intptr_t)&script[0];
if (pbuf[jj] & 2) T5 += (intptr_t)&script[0];
if (pbuf[jj] & 4) T6 += (intptr_t)&script[0];
 
do
{
int16_t var_id = *(int16_t *)&pbuf[j];
 
j += sizeof(int16_t);
 
if (var_id == MAXGAMEVARS) break;
 
if (aGameVars[var_id].val.plValues)
aGameVars[var_id].val.plValues[i] = *(int32_t *)&pbuf[j];
j += sizeof(int32_t);
}
while (1);
 
return j;
}
 
int32_t Net_PackSprite(int32_t i, uint8_t *pbuf)
{
int32_t j = 0, jj;
 
*(int16_t *)&pbuf[j] = i;
j += sizeof(int16_t);
Bmemcpy(&pbuf[j], &sprite[i], sizeof(spritetype));
j += sizeof(spritetype);
 
pbuf[(jj = j++)] = 0;
 
if (T2 >= (intptr_t)&script[0] && T2 < (intptr_t)(&script[g_scriptSize]))
{
pbuf[jj] |= 1;
T2 -= (intptr_t)&script[0];
}
 
if (T5 >= (intptr_t)&script[0] && T5 < (intptr_t)(&script[g_scriptSize]))
{
pbuf[jj] |= 2;
T5 -= (intptr_t)&script[0];
}
 
if (T6 >= (intptr_t)&script[0] && T6 < (intptr_t)(&script[g_scriptSize]))
{
pbuf[jj] |= 4;
T6 -= (intptr_t)&script[0];
}
 
Bmemcpy(&pbuf[j], &actor[i], sizeof(netactor_t));
j += sizeof(netactor_t);
 
if (pbuf[jj] & 1) T2 += (intptr_t)&script[0];
if (pbuf[jj] & 2) T5 += (intptr_t)&script[0];
if (pbuf[jj] & 4) T6 += (intptr_t)&script[0];
 
{
int16_t ii=g_gameVarCount-1, kk = 0;
 
for (; ii>=0 && kk <= 64; ii--)
{
if ((aGameVars[ii].dwFlags & (GAMEVAR_PERACTOR|GAMEVAR_NOMULTI)) == GAMEVAR_PERACTOR && aGameVars[ii].val.plValues)
{
if (aGameVars[ii].val.plValues[i] != aGameVars[ii].lDefault)
{
*(int16_t *)&pbuf[j] = ii;
j += sizeof(int16_t);
*(int32_t *)&pbuf[j] = aGameVars[ii].val.plValues[i];
j += sizeof(int32_t);
kk++;
}
}
}
*(int16_t *)&pbuf[j] = MAXGAMEVARS;
j += sizeof(int16_t);
}
 
return j;
}
 
void Net_ParseServerPacket(ENetEvent *event)
{
uint8_t *pbuf = event->packet->data;
int32_t packbufleng = event->packet->dataLength;
int16_t i, j, l;
int32_t other = pbuf[--packbufleng];
input_t *nsyn;
 
#if 0
initprintf("RECEIVED PACKET: type: %d : len %d\n", pbuf[0], packbufleng);
#endif
switch (pbuf[0])
{
case PACKET_MASTER_TO_SLAVE: //[0] (receive master sync buffer)
if (!(g_player[myconnectindex].ps->gm & MODE_GAME) || g_netSync) return;
 
j = 0;
 
packbufleng = qlz_size_decompressed((char *)&pbuf[1]);
pbuf = (uint8_t *)Bcalloc(1, packbufleng+1);
packbufleng = qlz_decompress((char *)&event->packet->data[1], (char *)(pbuf), state_decompress);
 
ticrandomseed = *(int32_t *)&pbuf[j];
j += sizeof(int32_t);
ud.pause_on = pbuf[j++];
 
TRAVERSE_CONNECT(i)
{
g_player[i].ps->dead_flag = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
g_player[i].playerquitflag = pbuf[j++];
 
if (g_player[i].playerquitflag == 0) continue;
 
if (i == myconnectindex && !g_player[i].ps->dead_flag)
{
j += offsetof(input_t, filler) +
(sizeof(vec3_t) * 3) + // position and velocity
(sizeof(int16_t) * 3); // ang and horiz
goto process;
}
 
nsyn = (input_t *)&inputfifo[0][0];
 
Bmemcpy(&nsyn[i], &pbuf[j], offsetof(input_t, filler));
j += offsetof(input_t, filler);
 
// Bmemcpy(&g_player[i].ps->opos.x, &g_player[i].ps->pos.x, sizeof(vec3_t));
 
Bmemcpy(&g_player[i].ps->pos.x, &pbuf[j], sizeof(vec3_t) * 2);
if (g_player[i].ps->cursectnum >= 0 && g_player[i].ps->cursectnum < numsectors)
{
updatesectorz(g_player[i].ps->pos.x, g_player[i].ps->pos.y, g_player[i].ps->pos.z,
&g_player[i].ps->cursectnum);
changespritesect(g_player[i].ps->i, g_player[i].ps->cursectnum);
}
Bmemcpy(&sprite[g_player[i].ps->i], &pbuf[j], sizeof(vec3_t));
sprite[g_player[i].ps->i].z += PHEIGHT;
j += sizeof(vec3_t) * 2;
 
Bmemcpy(&g_player[i].ps->posvel.x, &pbuf[j], sizeof(vec3_t));
j += sizeof(vec3_t);
 
g_player[i].ps->oang = g_player[i].ps->ang;
g_player[i].ps->ang = sprite[g_player[i].ps->i].ang = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
Bmemcpy(&g_player[i].ps->ohoriz, &g_player[i].ps->horiz, sizeof(int16_t) * 2);
Bmemcpy(&g_player[i].ps->horiz, &pbuf[j], sizeof(int16_t) * 2);
j += sizeof(int16_t) * 2;
 
process:
g_player[i].ps->gotweapon = *(uint16_t *)&pbuf[j];
j += sizeof(uint16_t);
 
Bmemcpy(&g_player[i].ps->ammo_amount[0], &pbuf[j], sizeof(g_player[i].ps->ammo_amount));
j += sizeof(g_player[i].ps->ammo_amount);
 
Bmemcpy(&g_player[i].ps->inv_amount[0], &pbuf[j], sizeof(g_player[i].ps->inv_amount));
j += sizeof(g_player[i].ps->inv_amount);
 
Bmemcpy(g_player[i].frags, &pbuf[j], sizeof(g_player[i].frags));
j += sizeof(g_player[i].frags);
 
sprite[g_player[i].ps->i].extra = (uint8_t)pbuf[j++];
 
sprite[g_player[i].ps->i].cstat = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
g_player[i].ps->kickback_pic = (uint8_t)pbuf[j++];
 
actor[g_player[i].ps->i].owner = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
actor[g_player[i].ps->i].picnum = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
g_player[i].ps->curr_weapon = (uint8_t)pbuf[j++];
g_player[i].ps->last_weapon = (int8_t)pbuf[j++];
g_player[i].ps->wantweaponfire = (int8_t)pbuf[j++];
g_player[i].ps->weapon_pos = (int8_t)pbuf[j++];
g_player[i].ps->frag_ps = (uint8_t)pbuf[j++];
 
g_player[i].ps->frag = (uint8_t)pbuf[j++];
 
g_player[i].ps->fraggedself = (uint8_t)pbuf[j++];
 
g_player[i].ps->last_extra = (uint8_t)pbuf[j++];
 
g_player[i].ping = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
sprite[g_player[i].ps->i].pal = (uint8_t)pbuf[j++];
 
l = i;
 
i = g_player[l].ps->i;
 
{
int16_t jj = j++;
int32_t oa = (T5 >= (intptr_t)&script[0] && T5 < (intptr_t)&script[g_scriptSize]) ? T5-(intptr_t)&script[0] : T5;
 
Bmemcpy(&T5, &pbuf[j], sizeof(T5));
j += sizeof(T5);
 
if (oa != T5) T3 = T4 = 0;
if (pbuf[jj] & 2) T5 += (intptr_t)&script[0];
}
 
do
{
int16_t var_id = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
if (var_id == MAXGAMEVARS) break;
 
aGameVars[var_id].val.plValues[i] = *(int32_t *)&pbuf[j];
j += sizeof(int32_t);
}
while (1);
 
i = l;
 
do
{
int16_t var_id = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
if (var_id == MAXGAMEVARS) break;
 
aGameVars[var_id].val.plValues[i] = *(int32_t *)&pbuf[j];
j += sizeof(int32_t);
}
while (1);
}
 
{
// sprite/sector/wall updates tacked on to the end of the packet
 
l = pbuf[j++];
while (l--)
{
int32_t i = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
j += Net_UnpackSprite(i, &pbuf[j]);
}
}
 
Bfree(pbuf);
 
break;
 
case PACKET_MAP_STREAM:
if (!(g_player[myconnectindex].ps->gm & MODE_GAME) || g_netSync) return;
 
j = 0;
 
packbufleng = qlz_size_decompressed((char *)&pbuf[1]);
pbuf = (uint8_t *)Bcalloc(1, packbufleng+1);
packbufleng = qlz_decompress((char *)&event->packet->data[1], (char *)(pbuf), state_decompress);
 
l = pbuf[j++];
while (l--)
{
int32_t i = *(int16_t *)&pbuf[j];
j += sizeof(int16_t);
 
j += Net_UnpackSprite(i, &pbuf[j]);
}
 
l = pbuf[j++];
while (l--)
{
int16_t secid = *(int16_t *)&pbuf[j];
 
Bmemcpy(&sector[secid], &pbuf[j + sizeof(int16_t)], sizeof(sectortype));
j += sizeof(int16_t) + sizeof(sectortype);
}
 
l = pbuf[j++];
while (l--)
{
int16_t wallid = *(int16_t *)&pbuf[j];
 
Bmemcpy(&wall[wallid], &pbuf[j + sizeof(int16_t)], sizeof(walltype));
j += sizeof(int16_t) + sizeof(walltype);
// we call dragpoint() to make sure the nextwall position gets updated too
dragpoint(wallid, wall[wallid].x, wall[wallid].y);
}
 
Bfree(pbuf);
 
break;
 
 
case PACKET_MESSAGE:
Bstrncpy(recbuf, (char *)pbuf+2, packbufleng-2);
recbuf[packbufleng-2] = 0;
 
G_AddUserQuote(recbuf);
S_PlaySound(EXITMENUSOUND);
 
pus = pub = NUMPAGES;
 
break;
 
case PACKET_NEW_GAME:
if ((vote_map + vote_episode + voting) != -3)
G_AddUserQuote("VOTE SUCCEEDED");
 
ud.m_level_number = ud.level_number = pbuf[1];
ud.m_volume_number = ud.volume_number = pbuf[2];
ud.m_player_skill = ud.player_skill = pbuf[3];
ud.m_monsters_off = ud.monsters_off = pbuf[4];
ud.m_respawn_monsters = ud.respawn_monsters = pbuf[5];
ud.m_respawn_items = ud.respawn_items = pbuf[6];
ud.m_respawn_inventory = ud.respawn_inventory = pbuf[7];
ud.m_coop = pbuf[8];
ud.m_marker = ud.marker = pbuf[9];
ud.m_ffire = ud.ffire = pbuf[10];
ud.m_noexits = ud.noexits = pbuf[11];
 
TRAVERSE_CONNECT(i)
{
P_ResetWeapons(i);
P_ResetInventory(i);
}
 
G_NewGame(ud.volume_number,ud.level_number,ud.player_skill);
ud.coop = ud.m_coop;
 
if (G_EnterLevel(MODE_GAME)) G_BackToMenu();
break;
 
case PACKET_VERSION:
if (pbuf[1] != BYTEVERSION || pbuf[2] != (uint8_t)atoi(s_buildDate))
{
Bsprintf(tempbuf, "Server protocol is version %d.%d, expecting %d.%d\n",
pbuf[1], pbuf[2], BYTEVERSION, (uint8_t)atoi(s_buildDate));
initprintf(tempbuf);
initprintf("Server version mismatch! You cannot play Duke with different versions!\n");
g_netDisconnect = 1;
return;
}
Net_SendChallenge();
break;
 
case PACKET_NUM_PLAYERS:
numplayers = pbuf[1];
playerswhenstarted = pbuf[2];
ud.multimode = pbuf[3];
if (pbuf[4]) // ID of new player
{
g_player[pbuf[4]].playerquitflag = 1;
 
if (!g_player[pbuf[4]].ps) g_player[pbuf[4]].ps = (DukePlayer_t *) Bcalloc(1,sizeof(DukePlayer_t));
if (!g_player[pbuf[4]].sync) g_player[pbuf[4]].sync = (input_t *) Bcalloc(1,sizeof(input_t));
}
 
for (i=0; i<playerswhenstarted-1; i++) connectpoint2[i] = i+1;
connectpoint2[playerswhenstarted-1] = -1;
 
S_PlaySound(DUKE_GETWEAPON2);
 
// myconnectindex is 0 until we get PACKET_PLAYER_INDEX
if (myconnectindex != 0)
Net_SendClientInfo();
break;
 
// receive client player index from server
case PACKET_PLAYER_INDEX:
myconnectindex = pbuf[1];
g_player[myconnectindex].playerquitflag = 1;
Net_SendClientInfo();
break;
 
case PACKET_PLAYER_DISCONNECTED:
if ((g_player[myconnectindex].ps->gm & MODE_GAME) && !g_netSync)
P_RemovePlayer(pbuf[1]);
numplayers = pbuf[2];
ud.multimode = pbuf[3];
playerswhenstarted = pbuf[4];
break;
 
case PACKET_PLAYER_SPAWN:
if (!(g_player[myconnectindex].ps->gm & MODE_GAME) || g_netSync) break;
P_ResetPlayer(pbuf[1]);
break;
 
case PACKET_PLAYER_READY:
g_player[0].playerreadyflag++;
return;
 
case PACKET_FRAG:
if (!(g_player[myconnectindex].ps->gm & MODE_GAME) || g_netSync) break;
g_player[pbuf[1]].ps->frag_ps = pbuf[2];
actor[g_player[pbuf[1]].ps->i].picnum = pbuf[3];
ticrandomseed = *(int32_t *)&pbuf[4];
P_FragPlayer(pbuf[1]);
break;
 
case PACKET_CLIENT_INFO:
for (i=1; pbuf[i]; i++)
g_player[other].user_name[i-1] = pbuf[i];
g_player[other].user_name[i-1] = 0;
i++;
 
g_player[other].ps->aim_mode = pbuf[i++];
g_player[other].ps->auto_aim = pbuf[i++];
g_player[other].ps->weaponswitch = pbuf[i++];
g_player[other].ps->palookup = g_player[other].pcolor = pbuf[i++];
g_player[other].pteam = pbuf[i++];
 
j = i;
for (; i-j<10; i++) g_player[other].wchoice[i-j] = pbuf[i];
 
g_player[other].playerquitflag = 1;
 
break;
 
 
case PACKET_RTS:
if (rts_numlumps == 0) break;
 
if (ud.config.SoundToggle == 0 || ud.lockout == 1 || ud.config.FXDevice < 0 || !(ud.config.VoiceToggle & 4))
break;
FX_PlayAuto3D((char *)RTS_GetSound(pbuf[1]-1),RTS_SoundLength(pbuf[1]-1),0,0,0,255,-pbuf[1]);
g_RTSPlaying = 7;
 
break;
 
case PACKET_USER_MAP:
Bstrcpy(boardfilename,(char *)pbuf+1);
boardfilename[packbufleng-1] = 0;
Bcorrectfilename(boardfilename,0);
if (boardfilename[0] != 0)
{
if ((i = kopen4loadfrommod(boardfilename,0)) < 0)
{
Bmemset(boardfilename,0,sizeof(boardfilename));
Net_SendUserMapName();
}
else kclose(i);
}
 
if (ud.m_level_number == 7 && ud.m_volume_number == 0 && boardfilename[0] == 0)
ud.m_level_number = 0;
 
break;
 
case PACKET_MAP_VOTE:
if (voting == myconnectindex && g_player[(uint8_t)pbuf[1]].gotvote == 0)
{
g_player[(uint8_t)pbuf[1]].gotvote = 1;
g_player[(uint8_t)pbuf[1]].vote = pbuf[2];
Bsprintf(tempbuf,"CONFIRMED VOTE FROM %s",g_player[(uint8_t)pbuf[1]].user_name);
G_AddUserQuote(tempbuf);
}
break;
 
case PACKET_MAP_VOTE_INITIATE: // call map vote
voting = pbuf[1];
vote_episode = pbuf[2];
vote_map = pbuf[3];
 
Bsprintf(tempbuf,"%s^00 HAS CALLED A VOTE TO CHANGE MAP TO %s (E%dL%d)",
g_player[(uint8_t)pbuf[1]].user_name,
MapInfo[(uint8_t)(pbuf[2]*MAXLEVELS + pbuf[3])].name,
pbuf[2]+1,pbuf[3]+1);
G_AddUserQuote(tempbuf);
 
Bsprintf(tempbuf,"PRESS F1 TO ACCEPT, F2 TO DECLINE");
G_AddUserQuote(tempbuf);
 
for (i=MAXPLAYERS-1; i>=0; i--)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
g_player[voting].gotvote = g_player[voting].vote = 1;
break;
 
case PACKET_MAP_VOTE_CANCEL: // cancel map vote
if (voting == pbuf[1])
{
voting = -1;
i = 0;
for (j=MAXPLAYERS-1; j>=0; j--)
i += g_player[j].gotvote;
 
if (i != numplayers)
Bsprintf(tempbuf,"%s^00 HAS CANCELED THE VOTE",g_player[(uint8_t)pbuf[1]].user_name);
else Bsprintf(tempbuf,"VOTE FAILED");
for (i=MAXPLAYERS-1; i>=0; i--)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
G_AddUserQuote(tempbuf);
}
break;
}
}
 
void Net_ParseClientPacket(ENetEvent *event)
{
uint8_t *pbuf = event->packet->data;
int32_t packbufleng = event->packet->dataLength;
int16_t i, j;
int32_t other = pbuf[--packbufleng];
input_t *nsyn;
 
#if 0
initprintf("RECEIVED PACKET: type: %d : len %d\n", pbuf[0], packbufleng);
#endif
switch (pbuf[0])
{
case PACKET_SLAVE_TO_MASTER: //[1] (receive slave sync buffer)
j = 0;
 
packbufleng = qlz_size_decompressed((char *)&pbuf[1]);
pbuf = (uint8_t *)Bcalloc(1, packbufleng+1);
packbufleng = qlz_decompress((char *)&event->packet->data[1], (char *)(pbuf), state_decompress);
 
nsyn = (input_t *)&inputfifo[0][0];
 
Bmemcpy(&nsyn[other], &pbuf[j], sizeof(input_t));
 
j += offsetof(input_t, filler);
 
// anyone the server thinks is dead can go fuck themselves
if (g_player[other].ps->dead_flag)
{
Bfree(pbuf);
break;
}
else
g_player[other].playerquitflag = 1;
 
// Bmemcpy(&g_player[other].ps->opos.x, &g_player[other].ps->pos.x, sizeof(vec3_t));
Bmemcpy(&g_player[other].ps->pos.x, &pbuf[j], sizeof(vec3_t) * 2);
updatesectorz(g_player[other].ps->pos.x, g_player[other].ps->pos.y, g_player[other].ps->pos.z,
&g_player[other].ps->cursectnum);
Bmemcpy(&sprite[g_player[other].ps->i], &pbuf[j], sizeof(vec3_t));
sprite[g_player[other].ps->i].z += PHEIGHT;
changespritesect(g_player[other].ps->i, g_player[other].ps->cursectnum);
j += sizeof(vec3_t) * 2;
 
Bmemcpy(&g_player[other].ps->posvel.x, &pbuf[j], sizeof(vec3_t));
j += sizeof(vec3_t);
 
g_player[other].ps->oang = g_player[other].ps->ang;
Bmemcpy(&g_player[other].ps->ang, &pbuf[j], sizeof(int16_t));
Bmemcpy(&sprite[g_player[other].ps->i].ang, &pbuf[j], sizeof(int16_t));
j += sizeof(int16_t);
 
Bmemcpy(&g_player[other].ps->ohoriz, &g_player[other].ps->horiz, sizeof(int16_t) * 2);
Bmemcpy(&g_player[other].ps->horiz, &pbuf[j], sizeof(int16_t) * 2);
j += sizeof(int16_t) * 2;
 
Bfree(pbuf);
break;
 
case PACKET_PLAYER_READY:
if (g_player[myconnectindex].ps->gm & MODE_GAME)
{
packbuf[0] = PACKET_PLAYER_READY;
packbuf[1] = myconnectindex;
enet_peer_send(event->peer, CHAN_GAMESTATE, enet_packet_create(packbuf, 2, ENET_PACKET_FLAG_RELIABLE));
}
g_player[other].playerreadyflag++;
return;
 
case PACKET_MESSAGE:
Bstrncpy(recbuf, (char *)pbuf+2, packbufleng-2);
recbuf[packbufleng-2] = 0;
 
G_AddUserQuote(recbuf);
S_PlaySound(EXITMENUSOUND);
 
pus = pub = NUMPAGES;
break;
 
case PACKET_NEW_GAME:
if ((vote_map + vote_episode + voting) != -3)
G_AddUserQuote("VOTE SUCCEEDED");
 
ud.m_level_number = ud.level_number = pbuf[1];
ud.m_volume_number = ud.volume_number = pbuf[2];
ud.m_player_skill = ud.player_skill = pbuf[3];
ud.m_monsters_off = ud.monsters_off = pbuf[4];
ud.m_respawn_monsters = ud.respawn_monsters = pbuf[5];
ud.m_respawn_items = ud.respawn_items = pbuf[6];
ud.m_respawn_inventory = ud.respawn_inventory = pbuf[7];
ud.m_coop = pbuf[8];
ud.m_marker = ud.marker = pbuf[9];
ud.m_ffire = ud.ffire = pbuf[10];
ud.m_noexits = ud.noexits = pbuf[11];
 
TRAVERSE_CONNECT(i)
{
P_ResetWeapons(i);
P_ResetInventory(i);
}
 
G_NewGame(ud.volume_number,ud.level_number,ud.player_skill);
ud.coop = ud.m_coop;
 
if (G_EnterLevel(MODE_GAME)) G_BackToMenu();
break;
 
case PACKET_AUTH:
{
uint32_t crc = *(uint32_t *)&pbuf[1];
 
if (crc == crc32once((uint8_t *)g_netPassword, Bstrlen(g_netPassword)))
Net_SyncPlayer(event);
else
{
enet_peer_disconnect_later(event->peer, DISC_BAD_PASSWORD);
initprintf("Bad password from client.\n");
}
}
break;
 
case PACKET_CLIENT_INFO:
for (i=1; pbuf[i]; i++)
g_player[other].user_name[i-1] = pbuf[i];
g_player[other].user_name[i-1] = 0;
i++;
 
g_player[other].ps->aim_mode = pbuf[i++];
g_player[other].ps->auto_aim = pbuf[i++];
g_player[other].ps->weaponswitch = pbuf[i++];
g_player[other].ps->palookup = g_player[other].pcolor = pbuf[i++];
g_player[other].pteam = pbuf[i++];
 
for (j=i; i-j<10; i++) g_player[other].wchoice[i-j] = pbuf[i];
break;
 
case PACKET_RTS:
if (rts_numlumps == 0) break;
 
if (ud.config.SoundToggle == 0 || ud.lockout == 1 || ud.config.FXDevice < 0 || !(ud.config.VoiceToggle & 4))
break;
 
FX_PlayAuto3D((char *)RTS_GetSound(pbuf[1]-1),RTS_SoundLength(pbuf[1]-1),0,0,0,255,-pbuf[1]);
g_RTSPlaying = 7;
break;
 
case PACKET_USER_MAP:
Bstrcpy(boardfilename,(char *)pbuf+1);
boardfilename[packbufleng-1] = 0;
Bcorrectfilename(boardfilename,0);
if (boardfilename[0] != 0)
{
if ((i = kopen4loadfrommod(boardfilename,0)) < 0)
{
Bmemset(boardfilename,0,sizeof(boardfilename));
Net_SendUserMapName();
}
else kclose(i);
}
 
if (ud.m_level_number == 7 && ud.m_volume_number == 0 && boardfilename[0] == 0)
ud.m_level_number = 0;
break;
 
case PACKET_MAP_VOTE:
if (voting == myconnectindex && g_player[(uint8_t)pbuf[1]].gotvote == 0)
{
g_player[(uint8_t)pbuf[1]].gotvote = 1;
g_player[(uint8_t)pbuf[1]].vote = pbuf[2];
Bsprintf(tempbuf,"CONFIRMED VOTE FROM %s",g_player[(uint8_t)pbuf[1]].user_name);
G_AddUserQuote(tempbuf);
}
break;
 
case PACKET_MAP_VOTE_INITIATE:
voting = pbuf[1];
vote_episode = pbuf[2];
vote_map = pbuf[3];
 
Bsprintf(tempbuf,"%s^00 HAS CALLED A VOTE TO CHANGE MAP TO %s (E%dL%d)",
g_player[(uint8_t)pbuf[1]].user_name,
MapInfo[(uint8_t)(pbuf[2]*MAXLEVELS + pbuf[3])].name,
pbuf[2]+1,pbuf[3]+1);
G_AddUserQuote(tempbuf);
 
Bsprintf(tempbuf,"PRESS F1 TO ACCEPT, F2 TO DECLINE");
G_AddUserQuote(tempbuf);
 
for (i=MAXPLAYERS-1; i>=0; i--)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
g_player[voting].gotvote = g_player[voting].vote = 1;
break;
 
case PACKET_MAP_VOTE_CANCEL:
if (voting == pbuf[1])
{
voting = -1;
i = 0;
for (j=MAXPLAYERS-1; j>=0; j--)
i += g_player[j].gotvote;
 
if (i != numplayers)
Bsprintf(tempbuf,"%s^00 HAS CANCELED THE VOTE",g_player[(uint8_t)pbuf[1]].user_name);
else Bsprintf(tempbuf,"VOTE FAILED");
for (i=MAXPLAYERS-1; i>=0; i--)
{
g_player[i].vote = 0;
g_player[i].gotvote = 0;
}
G_AddUserQuote(tempbuf);
}
break;
 
case PACKET_REQUEST_GAMESTATE:
if (g_netServer && g_player[0].ps->gm & MODE_GAME)
{
packbuf[0] = PACKET_NEW_GAME;
packbuf[1] = ud.level_number;
packbuf[2] = ud.volume_number;
packbuf[3] = ud.player_skill+1;
packbuf[4] = ud.monsters_off;
packbuf[5] = ud.respawn_monsters;
packbuf[6] = ud.respawn_items;
packbuf[7] = ud.respawn_inventory;
packbuf[8] = ud.coop;
packbuf[9] = ud.marker;
packbuf[10] = ud.ffire;
packbuf[11] = ud.noexits;
packbuf[12] = myconnectindex;
 
enet_peer_send(event->peer, CHAN_GAMESTATE, enet_packet_create(packbuf, 13, ENET_PACKET_FLAG_RELIABLE));
 
j = g_player[other].ps->i;
Bmemcpy(g_player[other].ps, g_player[0].ps, sizeof(DukePlayer_t));
 
g_player[other].ps->i = j;
changespritestat(j, STAT_PLAYER);
 
P_ResetStatus(other);
P_ResetWeapons(other);
P_ResetInventory(other);
 
g_player[other].ps->last_extra = sprite[g_player[other].ps->i].extra = g_player[other].ps->max_player_health;
sprite[g_player[other].ps->i].cstat = 1+256;
actor[g_player[other].ps->i].t_data[2] = actor[g_player[other].ps->i].t_data[3] = actor[g_player[other].ps->i].t_data[4] = 0;
 
g_netPlayersWaiting--;
 
// a player connecting is a good time to mark things as needing to be updated
// we invalidate everything that has changed since we started sending the snapshot of the map to the new player
 
{
int32_t zz, i, nexti;
 
for (zz = 0; (unsigned)zz < (sizeof(g_netStatnums)/sizeof(g_netStatnums[0])); zz++)
TRAVERSE_SPRITE_STAT(headspritestat[g_netStatnums[zz]], i, nexti)
{
if (lastupdate[i] >= g_player[other].netsynctime)
spritecrc[i] = 0xdeadbeef;
}
}
 
for (i=numwalls-1; i>=0; i--)
if (lastwallupdate[i] >= g_player[other].netsynctime)
wallcrc[i] = 0xdeadbeef;
 
for (i=numsectors-1; i>=0; i--)
if (lastsectupdate[i] >= g_player[other].netsynctime)
sectcrc[i] = 0xdeadbeef;
}
break;
}
}
 
 
void Net_GetPackets(void)
{
sampletimer();
MUSIC_Update();
S_Update();
 
G_HandleSpecialKeys();
 
if (g_netDisconnect)
{
Net_Disconnect();
g_netDisconnect = 0;
 
if (g_gameQuit)
G_GameExit(" ");
 
return;
}
 
if (g_netServer)
{
ENetEvent event;
 
// pull events from the wire into the packet queue without dispatching them, once per Net_GetPackets() call
enet_host_service(g_netServer, NULL, 0);
 
// dispatch any pending events from the local packet queue
while (enet_host_check_events(g_netServer, &event) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
{
char ipaddr[32];
 
enet_address_get_host_ip(&event.peer->address, ipaddr, sizeof(ipaddr));
 
initprintf("A new client connected from %s:%u.\n",
ipaddr, event.peer -> address.port);
}
Net_SendVersion(event.peer);
break;
 
case ENET_EVENT_TYPE_RECEIVE:
/*
initprintf ("A packet of length %u containing %s was received from player %d on channel %u.\n",
event.packet -> dataLength,
event.packet -> data,
event.peer -> data,
event.channelID);
*/
Net_ParseClientPacket(&event);
// broadcast takes care of enet_packet_destroy itself
// we set the state to disconnected so enet_host_broadcast doesn't send the player back his own packets
if ((event.channelID == CHAN_GAMESTATE && event.packet->data[0] > PACKET_BROADCAST) || event.channelID == CHAN_CHAT)
{
event.peer->state = ENET_PEER_STATE_DISCONNECTED;
enet_host_broadcast(g_netServer, event.channelID,
enet_packet_create(event.packet->data, event.packet->dataLength, event.packet->flags & ENET_PACKET_FLAG_RELIABLE));
event.peer->state = ENET_PEER_STATE_CONNECTED;
}
 
enet_packet_destroy(event.packet);
g_player[(intptr_t)event.peer->data].ping = (event.peer->lastRoundTripTime + event.peer->roundTripTime)/2;
break;
 
case ENET_EVENT_TYPE_DISCONNECT:
numplayers--;
ud.multimode--;
 
P_RemovePlayer((intptr_t)event.peer->data);
 
packbuf[0] = PACKET_PLAYER_DISCONNECTED;
packbuf[1] = (intptr_t)event.peer->data;
packbuf[2] = numplayers;
packbuf[3] = ud.multimode;
packbuf[4] = playerswhenstarted;
packbuf[5] = myconnectindex;
 
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 6, ENET_PACKET_FLAG_RELIABLE));
 
initprintf("%s disconnected.\n", g_player[(intptr_t)event.peer->data].user_name);
event.peer->data = NULL;
break;
 
default:
break;
}
}
}
else if (g_netClient)
{
ENetEvent event;
 
enet_host_service(g_netClient, NULL, 0);
 
while (enet_host_check_events(g_netClient, &event) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_RECEIVE:
 
/*
initprintf("A packet of length %u was received from player %d on channel %u.\n",
event.packet -> dataLength,
event.peer -> data,
event.channelID);
*/
 
// mapstate transfer from the server... all packets but the last are SYNCPACKETSIZE
if (event.channelID == CHAN_SYNC)
{
static int32_t datasiz = 0;
static uint8_t *buf = NULL;
 
if (buf == NULL)
{
datasiz = 0;
g_netSync = 1;
buf = (uint8_t *)Bcalloc(1, sizeof(mapstate_t)<<1);
}
 
g_multiMapState = (mapstate_t *)Brealloc(g_multiMapState, sizeof(mapstate_t));
 
if (buf && event.packet->dataLength == SYNCPACKETSIZE)
{
Bmemcpy((uint8_t *)(buf)+datasiz, event.packet->data, event.packet->dataLength);
datasiz += SYNCPACKETSIZE;
}
// last packet of mapstate sequence
else if (buf)
{
Bmemcpy((uint8_t *)(buf)+datasiz, event.packet->data, event.packet->dataLength);
datasiz = 0;
g_netSync = 0;
 
if (qlz_size_decompressed((const char *)buf) == sizeof(mapstate_t))
{
qlz_decompress((const char *)buf, g_multiMapState, state_decompress);
Bfree(buf);
buf = NULL;
 
packbuf[0] = PACKET_REQUEST_GAMESTATE;
packbuf[1] = myconnectindex;
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(&packbuf[0], 2, ENET_PACKET_FLAG_RELIABLE));
}
else
{
initprintf("Invalid map state from server!\n");
Bfree(buf);
buf = NULL;
g_netDisconnect = 1;
}
}
else
{
initprintf("Error allocating buffer for map state!\n");
g_netDisconnect = 1;
}
}
else Net_ParseServerPacket(&event);
 
enet_packet_destroy(event.packet);
break;
 
case ENET_EVENT_TYPE_DISCONNECT:
g_netDisconnect = 1;
numplayers = playerswhenstarted = ud.multimode = 1;
myconnectindex = screenpeek = 0;
G_BackToMenu();
switch (event.data)
{
case DISC_BAD_PASSWORD:
initprintf("Bad password.\n");
return;
case DISC_KICKED:
initprintf("You have been kicked from the server.\n");
return;
case DISC_BANNED:
initprintf("You have been banned from this server.\n");
return;
default:
initprintf("Disconnected.\n");
return;
}
default:
break;
}
}
}
}
 
void Net_UpdateClients(void)
{
input_t *osyn = (input_t *)&inputfifo[1][0];
input_t *nsyn = (input_t *)&inputfifo[0][0];
int16_t i, nexti, k = 0, l;
int32_t j;
 
if (!g_netServer || numplayers < 2)
{
ticrandomseed = randomseed;
if (g_netServer)
Bmemcpy(&osyn[0], &nsyn[0], sizeof(input_t));
return;
}
 
packbuf[0] = PACKET_MASTER_TO_SLAVE;
j = 1;
 
*(int32_t *)&packbuf[j] = ticrandomseed = randomseed;
j += sizeof(int32_t);
packbuf[j++] = ud.pause_on;
 
TRAVERSE_CONNECT(i)
{
Bmemcpy(&osyn[i], &nsyn[i], offsetof(input_t, filler));
 
*(int16_t *)&packbuf[j] = g_player[i].ps->dead_flag;
j += sizeof(int16_t);
 
packbuf[j++] = g_player[i].playerquitflag;
 
if (g_player[i].playerquitflag == 0) continue;
 
Bmemcpy(&packbuf[j], &nsyn[i], offsetof(input_t, filler));
j += offsetof(input_t, filler);
 
Bmemcpy(&packbuf[j], &g_player[i].ps->pos.x, sizeof(vec3_t) * 2);
j += sizeof(vec3_t) * 2;
 
Bmemcpy(&packbuf[j], &g_player[i].ps->posvel.x, sizeof(vec3_t));
j += sizeof(vec3_t);
 
*(int16_t *)&packbuf[j] = g_player[i].ps->ang;
j += sizeof(int16_t);
 
Bmemcpy(&packbuf[j], &g_player[i].ps->horiz, sizeof(int16_t) * 2);
j += sizeof(int16_t) * 2;
 
*(uint16_t *)&packbuf[j] = g_player[i].ps->gotweapon;
j += sizeof(uint16_t);
 
Bmemcpy(&packbuf[j], &g_player[i].ps->ammo_amount[0], sizeof(g_player[i].ps->ammo_amount));
j += sizeof(g_player[i].ps->ammo_amount);
 
Bmemcpy(&packbuf[j], &g_player[i].ps->inv_amount[0], sizeof(g_player[i].ps->inv_amount));
j += sizeof(g_player[i].ps->inv_amount);
 
Bmemcpy(&packbuf[j], g_player[i].frags, sizeof(g_player[i].frags));
j += sizeof(g_player[i].frags);
 
packbuf[j++] = (uint8_t) sprite[g_player[i].ps->i].extra;
 
*(int16_t *)&packbuf[j] = sprite[g_player[i].ps->i].cstat;
j += sizeof(int16_t);
 
packbuf[j++] = (uint8_t) g_player[i].ps->kickback_pic;
 
*(int16_t *)&packbuf[j] = actor[g_player[i].ps->i].owner;
j += sizeof(int16_t);
 
*(int16_t *)&packbuf[j] = actor[g_player[i].ps->i].picnum;
j += sizeof(int16_t);
 
packbuf[j++] = (uint8_t) g_player[i].ps->curr_weapon;
packbuf[j++] = (int8_t) g_player[i].ps->last_weapon;
packbuf[j++] = (int8_t) g_player[i].ps->wantweaponfire;
packbuf[j++] = (int8_t) g_player[i].ps->weapon_pos;
packbuf[j++] = (uint8_t) g_player[i].ps->frag_ps;
 
packbuf[j++] = g_player[i].ps->frag;
packbuf[j++] = g_player[i].ps->fraggedself;
packbuf[j++] = g_player[i].ps->last_extra;
 
*(int16_t *)&packbuf[j] = g_player[i].ping;
j += sizeof(int16_t);
 
packbuf[j++] = sprite[g_player[i].ps->i].pal;
 
l = i;
i = g_player[l].ps->i;
 
{
int32_t jj, oa;
 
packbuf[(jj = j++)] = 0;
 
if (T5 >= (intptr_t)&script[0] && T5 < (intptr_t)(&script[g_scriptSize]))
{
packbuf[jj] |= 2;
T5 -= (intptr_t)&script[0];
}
 
oa = T5;
 
Bmemcpy(&packbuf[j], &T5, sizeof(T5));
j += sizeof(T5);
 
if (oa != T5) T3 = T4 = 0;
 
if (packbuf[jj] & 2) T5 += (intptr_t)&script[0];
}
 
{
int16_t ii=g_gameVarCount-1, kk = 0;
 
for (; ii>=0 && kk <= 64; ii--)
{
if ((aGameVars[ii].dwFlags & (GAMEVAR_PERACTOR|GAMEVAR_NOMULTI)) == GAMEVAR_PERACTOR && aGameVars[ii].val.plValues)
{
if (aGameVars[ii].val.plValues[i] != aGameVars[ii].lDefault)
{
*(int16_t *)&packbuf[j] = ii;
j += sizeof(int16_t);
*(int32_t *)&packbuf[j] = aGameVars[ii].val.plValues[i];
j += sizeof(int32_t);
kk++;
}
}
}
*(int16_t *)&packbuf[j] = MAXGAMEVARS;
j += sizeof(int16_t);
}
 
i = l;
 
{
int16_t ii=g_gameVarCount-1, kk = 0;
 
for (; ii>=0 && kk <= 64; ii--)
{
if ((aGameVars[ii].dwFlags & (GAMEVAR_PERPLAYER|GAMEVAR_NOMULTI)) == GAMEVAR_PERPLAYER && aGameVars[ii].val.plValues)
{
if (aGameVars[ii].val.plValues[i] != aGameVars[ii].lDefault)
{
*(int16_t *)&packbuf[j] = ii;
j += sizeof(int16_t);
*(int32_t *)&packbuf[j] = aGameVars[ii].val.plValues[i];
j += sizeof(int32_t);
kk++;
}
}
}
*(int16_t *)&packbuf[j] = MAXGAMEVARS;
j += sizeof(int16_t);
}
}
 
k = 0;
 
{
int32_t zz, zj;
 
packbuf[(zj = j++)] = 0;
 
for (zz = 0; (unsigned)zz < (sizeof(g_netStatnums)/sizeof(g_netStatnums[0])) /*&& k <= 3*/; zz++)
TRAVERSE_SPRITE_STAT(headspritestat[g_netStatnums[zz]], i, nexti)
{
// only send newly spawned sprites
if (!lastupdate[i])
{
lastupdate[i] = totalclock;
 
j += Net_PackSprite(i, (uint8_t *)&packbuf[j]);
k++;
}
}
 
packbuf[zj] = k;
j++;
}
 
{
char buf[PACKBUF_SIZE];
 
if (j >= PACKBUF_SIZE)
{
initprintf("Global packet buffer overflow! Size of packet: %i\n", j);
}
 
j = qlz_compress((char *)(packbuf)+1, (char *)buf, j, state_compress);
Bmemcpy((char *)(packbuf)+1, (char *)buf, j);
j++;
}
 
packbuf[j++] = myconnectindex;
 
enet_host_broadcast(g_netServer, CHAN_MOVE, enet_packet_create(packbuf, j, 0));
}
 
void Net_StreamLevel(void)
{
int16_t i, nexti, k = 0, l;
int32_t j;
int32_t zz, zj;
 
if (!g_netServer || numplayers < 2)
return;
 
packbuf[0] = PACKET_MAP_STREAM;
j = 1;
 
packbuf[(zj = j++)] = 0;
 
for (zz = 0; (unsigned)zz < (sizeof(g_netStatnums)/sizeof(g_netStatnums[0])) /*&& k <= 3*/; zz++)
TRAVERSE_SPRITE_STAT(headspritestat[g_netStatnums[zz]], i, nexti)
{
// only send STAT_MISC sprites at spawn time and let the client handle it from there
if (totalclock > (lastupdate[i] + TICRATE) && sprite[i].statnum != STAT_MISC)
{
l = crc32once((uint8_t *)&sprite[i], sizeof(spritetype));
 
if (!lastupdate[i] || spritecrc[i] != l)
{
/*initprintf("updating sprite %d (%d)\n",i,sprite[i].picnum);*/
spritecrc[i] = l;
lastupdate[i] = totalclock;
 
j += Net_PackSprite(i, (uint8_t *)&packbuf[j]);
k++;
}
}
}
 
packbuf[zj] = k;
k = 0;
 
packbuf[(zj = j++)] = 0;
for (i = numsectors-1; i >= 0 && k <= 6; i--)
{
if (totalclock > (lastsectupdate[i] + TICRATE))
{
l = crc32once((uint8_t *)&sector[i], sizeof(sectortype));
 
if (sectcrc[i] != l)
{
sectcrc[i] = l;
lastsectupdate[i] = totalclock;
*(int16_t *)&packbuf[j] = i;
j += sizeof(int16_t);
Bmemcpy(&packbuf[j], &sector[i], sizeof(sectortype));
j += sizeof(sectortype);
k++;
}
}
}
packbuf[zj] = k;
k = 0;
 
packbuf[(zj = j++)] = 0;
for (i = numwalls-1; i >= 0 && k <= 6; i--)
{
if (totalclock > (lastwallupdate[i] + TICRATE))
{
l = crc32once((uint8_t *)&wall[i], sizeof(walltype));
 
if (wallcrc[i] != l)
{
wallcrc[i] = l;
lastwallupdate[i] = totalclock;
*(int16_t *)&packbuf[j] = i;
j += sizeof(int16_t);
Bmemcpy(&packbuf[j], &wall[i], sizeof(walltype));
j += sizeof(walltype);
k++;
}
}
}
packbuf[zj] = k;
 
j++;
 
{
char buf[PACKBUF_SIZE];
 
if (j >= PACKBUF_SIZE)
{
initprintf("Global packet buffer overflow! Size of packet: %i\n", j);
}
 
j = qlz_compress((char *)(packbuf)+1, (char *)buf, j, state_compress);
Bmemcpy((char *)(packbuf)+1, (char *)buf, j);
j++;
}
 
packbuf[j++] = myconnectindex;
 
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, j, ENET_PACKET_FLAG_RELIABLE));
}
 
void faketimerhandler(void)
{
if (g_netServer)
enet_host_service(g_netServer, NULL, 0);
else if (g_netClient)
enet_host_service(g_netClient, NULL, 0);
}
 
void Net_EnterMessage(void)
{
int16_t hitstate, i, j, l;
 
if (g_player[myconnectindex].ps->gm&MODE_SENDTOWHOM)
{
if (g_chatPlayer != -1 || ud.multimode < 3)
{
tempbuf[0] = PACKET_MESSAGE;
tempbuf[2] = 0;
recbuf[0] = 0;
 
if (ud.multimode < 3)
g_chatPlayer = 2;
 
if (typebuf[0] == '/' && Btoupper(typebuf[1]) == 'M' && Btoupper(typebuf[2]) == 'E')
{
Bstrcat(recbuf,"* ");
i = 3, j = Bstrlen(typebuf);
Bstrcpy(tempbuf,typebuf);
while (i < j)
{
typebuf[i-3] = tempbuf[i];
i++;
}
typebuf[i-3] = '\0';
Bstrcat(recbuf,g_player[myconnectindex].user_name);
}
else
{
Bstrcat(recbuf,g_player[myconnectindex].user_name);
Bstrcat(recbuf,": ");
}
 
Bstrcat(recbuf,"^00");
Bstrcat(recbuf,typebuf);
j = Bstrlen(recbuf);
recbuf[j] = 0;
Bstrcat(tempbuf+2,recbuf);
 
if (g_chatPlayer >= ud.multimode)
{
tempbuf[1] = 255;
tempbuf[j+2] = myconnectindex;
j++;
if (g_netServer) enet_host_broadcast(g_netServer, CHAN_CHAT, enet_packet_create(tempbuf, j+2, 0));
else if (g_netClient) enet_peer_send(g_netClientPeer, CHAN_CHAT, enet_packet_create(tempbuf, j+2, 0));
G_AddUserQuote(recbuf);
quotebot += 8;
l = G_GameTextLen(USERQUOTE_LEFTOFFSET,OSD_StripColors(tempbuf,recbuf));
while (l > (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET))
{
l -= (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET);
quotebot += 8;
}
quotebotgoal = quotebot;
}
g_chatPlayer = -1;
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
}
else if (g_chatPlayer == -1)
{
j = 50;
gametext(320>>1,j,"SEND MESSAGE TO...",0,2+8+16);
j += 8;
TRAVERSE_CONNECT(i)
{
if (i == myconnectindex)
{
minitextshade((320>>1)-40+1,j+1,"A/ENTER - ALL",26,0,2+8+16);
minitext((320>>1)-40,j,"A/ENTER - ALL",0,2+8+16);
j += 7;
}
else
{
Bsprintf(buf," %d - %s",i+1,g_player[i].user_name);
minitextshade((320>>1)-40-6+1,j+1,buf,26,0,2+8+16);
minitext((320>>1)-40-6,j,buf,0,2+8+16);
j += 7;
}
}
minitextshade((320>>1)-40-4+1,j+1," ESC - Abort",26,0,2+8+16);
minitext((320>>1)-40-4,j," ESC - Abort",0,2+8+16);
j += 7;
 
if (ud.screen_size > 0) j = 200-45;
else j = 200-8;
mpgametext(j,typebuf,0,2+8+16);
 
if (KB_KeyWaiting())
{
i = KB_GetCh();
 
if (i == 'A' || i == 'a' || i == 13)
g_chatPlayer = ud.multimode;
else if (i >= '1' || i <= (ud.multimode + '1'))
g_chatPlayer = i - '1';
else
{
g_chatPlayer = ud.multimode;
if (i == 27)
{
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
g_chatPlayer = -1;
}
else
typebuf[0] = 0;
}
 
KB_ClearKeyDown(sc_1);
KB_ClearKeyDown(sc_2);
KB_ClearKeyDown(sc_3);
KB_ClearKeyDown(sc_4);
KB_ClearKeyDown(sc_5);
KB_ClearKeyDown(sc_6);
KB_ClearKeyDown(sc_7);
KB_ClearKeyDown(sc_8);
KB_ClearKeyDown(sc_A);
KB_ClearKeyDown(sc_Escape);
KB_ClearKeyDown(sc_Enter);
}
}
}
else
{
if (ud.screen_size > 1) j = 200-45;
else j = 200-8;
if (xdim >= 640 && ydim >= 480)
j = scale(j,ydim,200);
hitstate = Net_EnterText(320>>1,j,typebuf,120,1);
 
if (hitstate == 1)
{
KB_ClearKeyDown(sc_Enter);
if (Bstrlen(typebuf) == 0)
{
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
return;
}
if (ud.automsg)
{
if (SHIFTS_IS_PRESSED) g_chatPlayer = -1;
else g_chatPlayer = ud.multimode;
}
g_player[myconnectindex].ps->gm |= MODE_SENDTOWHOM;
}
else if (hitstate == -1)
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
else pub = NUMPAGES;
}
}
 
void Net_WaitForServer(void)
{
int32_t server_ready = g_player[0].playerreadyflag;
 
if (numplayers < 2 || g_netServer) return;
 
if ((g_netServer || ud.multimode > 1))
{
P_SetGamePalette(g_player[myconnectindex].ps, titlepal, 11);
rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1);
 
rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1);
rotatesprite(160<<16,(129)<<16,30<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1);
if (PLUTOPAK) // JBF 20030804
rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1);
 
gametext(160,190,"WAITING FOR SERVER",14,2);
nextpage();
}
 
do
{
if (quitevent || keystatus[1]) G_GameExit("");
 
packbuf[0] = PACKET_PLAYER_READY;
packbuf[1] = myconnectindex;
 
if (g_netClientPeer)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(packbuf, 2, ENET_PACKET_FLAG_RELIABLE));
 
handleevents();
Net_GetPackets();
 
if (g_player[0].playerreadyflag > server_ready)
{
P_SetGamePalette(g_player[myconnectindex].ps, palette, 11);
return;
}
}
while (1);
}
 
void Net_ResetPrediction(void)
{
Bmemcpy(&my, &g_player[myconnectindex].ps, sizeof(vec3_t));
Bmemcpy(&omy, &g_player[myconnectindex].ps, sizeof(vec3_t));
Bmemset(&myvel, 0, sizeof(vec3_t));
 
myang = omyang = g_player[myconnectindex].ps->ang;
myhoriz = omyhoriz = g_player[myconnectindex].ps->horiz;
myhorizoff = omyhorizoff = g_player[myconnectindex].ps->horizoff;
mycursectnum = g_player[myconnectindex].ps->cursectnum;
myjumpingcounter = g_player[myconnectindex].ps->jumping_counter;
myjumpingtoggle = g_player[myconnectindex].ps->jumping_toggle;
myonground = g_player[myconnectindex].ps->on_ground;
myhardlanding = g_player[myconnectindex].ps->hard_landing;
myreturntocenter = g_player[myconnectindex].ps->return_to_center;
}
 
/polymer/eduke32/source/net.h
0,0 → 1,111
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __netplay_h__
#define __netplay_h__
 
#include "enet/enet.h"
 
enum netchan_t
{
CHAN_MOVE, // unreliable movement packets
CHAN_GAMESTATE, // gamestate changes... frags, respawns, player names, etc
CHAN_SYNC, // client join sync packets
CHAN_CHAT, // chat and RTS
CHAN_MISC, // whatever else
CHAN_MAX
};
 
enum DukePacket_t
{
PACKET_MASTER_TO_SLAVE,
PACKET_SLAVE_TO_MASTER,
 
PACKET_NUM_PLAYERS,
PACKET_PLAYER_INDEX,
PACKET_PLAYER_DISCONNECTED,
PACKET_PLAYER_SPAWN,
PACKET_FRAG,
PACKET_REQUEST_GAMESTATE,
PACKET_VERSION,
PACKET_AUTH,
PACKET_PLAYER_READY,
PACKET_MAP_STREAM,
 
// any packet with an ID higher than PACKET_BROADCAST is rebroadcast by server
// so hacked clients can't create fake server packets and get the server to
// send them to everyone
// newer versions of the netcode also make this determination based on which
// channel the packet was broadcast on
 
PACKET_BROADCAST,
PACKET_NEW_GAME,
PACKET_RTS,
PACKET_CLIENT_INFO,
PACKET_MESSAGE,
PACKET_USER_MAP,
 
PACKET_MAP_VOTE,
PACKET_MAP_VOTE_INITIATE,
PACKET_MAP_VOTE_CANCEL,
};
 
enum NetDisconnect_t
{
DISC_BAD_PASSWORD = 1,
DISC_KICKED,
DISC_BANNED
};
 
extern ENetHost *g_netClient;
extern ENetHost *g_netServer;
extern ENetPeer *g_netClientPeer;
extern char g_netPassword[32];
extern int32_t g_netDisconnect;
extern int32_t g_netPlayersWaiting;
extern int32_t g_netPort;
extern int32_t g_netServerMode;
extern int32_t g_netSync;
extern int32_t lastsectupdate[MAXSECTORS];
extern int32_t lastupdate[MAXSPRITES];
extern int32_t lastwallupdate[MAXWALLS];
extern int8_t g_netStatnums[8];
extern mapstate_t *g_multiMapState;
 
int32_t Net_PackSprite(int32_t i,uint8_t *pbuf);
int32_t Net_UnpackSprite(int32_t i,uint8_t *pbuf);
void Net_Connect(const char *srvaddr);
void Net_Disconnect(void);
void Net_EnterMessage(void);
void Net_GetPackets(void);
void Net_NewGame(int32_t volume,int32_t level);
void Net_ParseClientPacket(ENetEvent *event);
void Net_ParseServerPacket(ENetEvent *event);
void Net_ResetPrediction(void);
void Net_SendClientInfo(void);
void Net_SendUserMapName(void);
void Net_StreamLevel(void);
void Net_SyncPlayer(ENetEvent *event);
void Net_UpdateClients(void);
void Net_WaitForServer(void);
void faketimerhandler(void);
#endif
/polymer/eduke32/source/osdcmds.c
24,8 → 24,12
#include "osdcmds.h"
#include "baselayer.h"
#include "duke3d.h"
#include "premap.h"
#include "menus.h"
#include "osd.h"
#include "osdfuncs.h"
#include "gamedef.h"
 
#include <ctype.h>
#include <limits.h>
#include "enet/enet.h"
82,7 → 86,7
}
}
 
if (level > MAXLEVELS || MapInfo[volume*MAXLEVELS+level].filename == NULL)
if (level > MAXLEVELS || MapInfo[volume *MAXLEVELS+level].filename == NULL)
{
OSD_Printf("changelevel: invalid level number\n");
return OSDCMD_SHOWHELP;
1168,7 → 1172,7
 
static int32_t osdcmd_listplayers(const osdfuncparm_t *parm)
{
ENetPeer * currentPeer;
ENetPeer *currentPeer;
char ipaddr[32];
 
if (parm->numparms != 0)
1197,7 → 1201,7
 
static int32_t osdcmd_kick(const osdfuncparm_t *parm)
{
ENetPeer * currentPeer;
ENetPeer *currentPeer;
uint32_t hexaddr;
 
if (parm->numparms != 1)
1233,7 → 1237,7
 
static int32_t osdcmd_kickban(const osdfuncparm_t *parm)
{
ENetPeer * currentPeer;
ENetPeer *currentPeer;
uint32_t hexaddr;
 
if (parm->numparms != 1)
1253,7 → 1257,7
continue;
 
sscanf(parm->parms[0],"%" PRIxPTR "", &hexaddr);
 
// TODO: implement banning logic
 
if (currentPeer->address.host == hexaddr)
1369,97 → 1373,101
 
cvar_t cvars_game[] =
{
{ "crosshair", "crosshair: enable/disable crosshair", (void*)&ud.crosshair, CVAR_BOOL, 0, 1 },
{ "crosshair", "crosshair: enable/disable crosshair", (void *)&ud.crosshair, CVAR_BOOL, 0, 1 },
 
{ "cl_autoaim", "cl_autoaim: enable/disable weapon autoaim", (void*)&ud.config.AutoAim, CVAR_INT|CVAR_MULTI, 0, 2 },
{ "cl_automsg", "cl_automsg: enable/disable automatically sending messages to all players", (void*)&ud.automsg, CVAR_BOOL, 0, 1 },
{ "cl_autorun", "cl_autorun", (void*)&ud.auto_run, CVAR_BOOL, 0, 1 },
{ "cl_autovote", "cl_autovote: enable/disable automatic voting", (void*)&ud.autovote, CVAR_INT, 0, 2 },
{ "cl_autoaim", "cl_autoaim: enable/disable weapon autoaim", (void *)&ud.config.AutoAim, CVAR_INT|CVAR_MULTI, 0, 2 },
{ "cl_automsg", "cl_automsg: enable/disable automatically sending messages to all players", (void *)&ud.automsg, CVAR_BOOL, 0, 1 },
{ "cl_autorun", "cl_autorun", (void *)&ud.auto_run, CVAR_BOOL, 0, 1 },
{ "cl_autovote", "cl_autovote: enable/disable automatic voting", (void *)&ud.autovote, CVAR_INT, 0, 2 },
 
{ "cl_obituaries", "cl_obituaries: enable/disable multiplayer death messages", (void*)&ud.obituaries, CVAR_BOOL, 0, 1 },
{ "cl_democams", "cl_democams: enable/disable demo playback cameras", (void*)&ud.democams, CVAR_BOOL, 0, 1 },
{ "cl_obituaries", "cl_obituaries: enable/disable multiplayer death messages", (void *)&ud.obituaries, CVAR_BOOL, 0, 1 },
{ "cl_democams", "cl_democams: enable/disable demo playback cameras", (void *)&ud.democams, CVAR_BOOL, 0, 1 },
 
{ "cl_idplayers", "cl_idplayers: enable/disable name display when aiming at opponents", (void*)&ud.idplayers, CVAR_BOOL, 0, 1 },
{ "cl_idplayers", "cl_idplayers: enable/disable name display when aiming at opponents", (void *)&ud.idplayers, CVAR_BOOL, 0, 1 },
 
{ "cl_showcoords", "cl_showcoords: show your position in the game world", (void*)&ud.coords, CVAR_BOOL, 0, 1 },
{ "cl_showcoords", "cl_showcoords: show your position in the game world", (void *)&ud.coords, CVAR_BOOL, 0, 1 },
 
{ "cl_viewbob", "cl_viewbob: enable/disable player head bobbing", (void*)&ud.viewbob, CVAR_BOOL, 0, 1 },
{ "cl_viewbob", "cl_viewbob: enable/disable player head bobbing", (void *)&ud.viewbob, CVAR_BOOL, 0, 1 },
 
{ "cl_weaponsway", "cl_weaponsway: enable/disable player weapon swaying", (void*)&ud.weaponsway, CVAR_BOOL, 0, 1 },
{ "cl_weaponswitch", "cl_weaponswitch: enable/disable auto weapon switching", (void*)&ud.weaponswitch, CVAR_INT|CVAR_MULTI, 0, 3 },
{ "cl_angleinterpolation", "cl_angleinterpolation: enable/disable angle interpolation", (void*)&ud.angleinterpolation, CVAR_INT, 0, 256 },
{ "cl_weaponsway", "cl_weaponsway: enable/disable player weapon swaying", (void *)&ud.weaponsway, CVAR_BOOL, 0, 1 },
{ "cl_weaponswitch", "cl_weaponswitch: enable/disable auto weapon switching", (void *)&ud.weaponswitch, CVAR_INT|CVAR_MULTI, 0, 3 },
{ "cl_angleinterpolation", "cl_angleinterpolation: enable/disable angle interpolation", (void *)&ud.angleinterpolation, CVAR_INT, 0, 256 },
 
{ "color", "color: changes player palette", (void*)&ud.color, CVAR_INT|CVAR_MULTI, 0, g_numRealPalettes },
{ "color", "color: changes player palette", (void *)&ud.color, CVAR_INT|CVAR_MULTI, 0, g_numRealPalettes },
 
{ "crosshairscale","crosshairscale: changes the size of the crosshair", (void*)&ud.crosshairscale, CVAR_INT, 10, 100 },
{ "crosshairscale","crosshairscale: changes the size of the crosshair", (void *)&ud.crosshairscale, CVAR_INT, 10, 100 },
 
{ "demorec_diffs","demorec_diffs: enable/disable diff recording in demos",(void*)&demorec_diffs_cvar, CVAR_BOOL, 0, 1 },
{ "demorec_force","demorec_force: enable/disable forced demo recording",(void*)&demorec_force_cvar, CVAR_BOOL|CVAR_NOSAVE, 0, 1 },
{ "demorec_difftics","demorec_difftics <number>: sets game tic interval after which a diff is recorded",
(void*)&demorec_difftics_cvar, CVAR_INT, 2, 60*(TICRATE/TICSPERFRAME) },
{ "demorec_diffcompress","demorec_diffcompress <number>: Compression method for diffs. (0: none, 1: KSLZW)",(void*)&demorec_diffcompress_cvar, CVAR_INT, 0, 1 },
{ "demorec_synccompress","demorec_synccompress <number>: Compression method for input. (0: none, 1: KSLZW)",(void*)&demorec_synccompress_cvar, CVAR_INT, 0, 1 },
{ "demorec_seeds","demorec_seeds: enable/disable recording of random seed for later sync checking",(void*)&demorec_seeds_cvar, CVAR_BOOL, 0, 1 },
{ "demoplay_diffs","demoplay_diffs: enable/disable application of diffs in demo playback",(void*)&demoplay_diffs, CVAR_BOOL, 0, 1 },
{ "demoplay_showsync","demoplay_showsync: enable/disable display of sync status",(void*)&demoplay_showsync, CVAR_BOOL, 0, 1 },
{ "demorec_diffs","demorec_diffs: enable/disable diff recording in demos",(void *)&demorec_diffs_cvar, CVAR_BOOL, 0, 1 },
{ "demorec_force","demorec_force: enable/disable forced demo recording",(void *)&demorec_force_cvar, CVAR_BOOL|CVAR_NOSAVE, 0, 1 },
{
"demorec_difftics","demorec_difftics <number>: sets game tic interval after which a diff is recorded",
(void *)&demorec_difftics_cvar, CVAR_INT, 2, 60*(TICRATE/TICSPERFRAME)
},
{ "demorec_diffcompress","demorec_diffcompress <number>: Compression method for diffs. (0: none, 1: KSLZW)",(void *)&demorec_diffcompress_cvar, CVAR_INT, 0, 1 },
{ "demorec_synccompress","demorec_synccompress <number>: Compression method for input. (0: none, 1: KSLZW)",(void *)&demorec_synccompress_cvar, CVAR_INT, 0, 1 },
{ "demorec_seeds","demorec_seeds: enable/disable recording of random seed for later sync checking",(void *)&demorec_seeds_cvar, CVAR_BOOL, 0, 1 },
{ "demoplay_diffs","demoplay_diffs: enable/disable application of diffs in demo playback",(void *)&demoplay_diffs, CVAR_BOOL, 0, 1 },
{ "demoplay_showsync","demoplay_showsync: enable/disable display of sync status",(void *)&demoplay_showsync, CVAR_BOOL, 0, 1 },
 
{ "hud_althud", "hud_althud: enable/disable alternate mini-hud", (void*)&ud.althud, CVAR_BOOL, 0, 1 },
{ "hud_bgstretch", "hud_bgstretch: enable/disable background image stretching in wide resolutions", (void*)&ud.bgstretch, CVAR_BOOL, 0, 1 },
{ "hud_messagetime", "hud_messagetime: length of time to display multiplayer chat messages", (void*)&ud.msgdisptime, CVAR_INT, 0, 3600 },
{ "hud_numbertile", "hud_numbertile: first tile in alt hud number set", (void*)&althud_numbertile, CVAR_INT, 0, MAXTILES-10 },
{ "hud_numberpal", "hud_numberpal: pal for alt hud numbers", (void*)&althud_numberpal, CVAR_INT, 0, MAXPALOOKUPS },
{ "hud_shadows", "hud_shadows: enable/disable althud shadows", (void*)&althud_shadows, CVAR_BOOL, 0, 1 },
{ "hud_flashing", "hud_flashing: enable/disable althud flashing", (void*)&althud_flashing, CVAR_BOOL, 0, 1 },
{ "hud_glowingquotes", "hud_glowingquotes: enable/disable \"glowing\" quote text", (void*)&hud_glowingquotes, CVAR_BOOL, 0, 1 },
{ "hud_scale","hud_scale: changes the hud scale", (void*)&ud.statusbarscale, CVAR_INT|CVAR_FUNCPTR, 10, 100 },
{ "hud_showmapname", "hud_showmapname: enable/disable map name display on load", (void*)&hud_showmapname, CVAR_BOOL, 0, 1 },
{ "hud_stats", "hud_stats: enable/disable level statistics display", (void*)&ud.levelstats, CVAR_BOOL, 0, 1 },
{ "hud_textscale", "hud_textscale: sets multiplayer chat message size", (void*)&ud.textscale, CVAR_INT, 100, 400 },
{ "hud_weaponscale","hud_weaponscale: changes the weapon scale", (void*)&ud.weaponscale, CVAR_INT, 10, 100 },
{ "hud_althud", "hud_althud: enable/disable alternate mini-hud", (void *)&ud.althud, CVAR_BOOL, 0, 1 },
{ "hud_bgstretch", "hud_bgstretch: enable/disable background image stretching in wide resolutions", (void *)&ud.bgstretch, CVAR_BOOL, 0, 1 },
{ "hud_messagetime", "hud_messagetime: length of time to display multiplayer chat messages", (void *)&ud.msgdisptime, CVAR_INT, 0, 3600 },
{ "hud_numbertile", "hud_numbertile: first tile in alt hud number set", (void *)&althud_numbertile, CVAR_INT, 0, MAXTILES-10 },
{ "hud_numberpal", "hud_numberpal: pal for alt hud numbers", (void *)&althud_numberpal, CVAR_INT, 0, MAXPALOOKUPS },
{ "hud_shadows", "hud_shadows: enable/disable althud shadows", (void *)&althud_shadows, CVAR_BOOL, 0, 1 },
{ "hud_flashing", "hud_flashing: enable/disable althud flashing", (void *)&althud_flashing, CVAR_BOOL, 0, 1 },
{ "hud_glowingquotes", "hud_glowingquotes: enable/disable \"glowing\" quote text", (void *)&hud_glowingquotes, CVAR_BOOL, 0, 1 },
{ "hud_scale","hud_scale: changes the hud scale", (void *)&ud.statusbarscale, CVAR_INT|CVAR_FUNCPTR, 10, 100 },
{ "hud_showmapname", "hud_showmapname: enable/disable map name display on load", (void *)&hud_showmapname, CVAR_BOOL, 0, 1 },
{ "hud_stats", "hud_stats: enable/disable level statistics display", (void *)&ud.levelstats, CVAR_BOOL, 0, 1 },
{ "hud_textscale", "hud_textscale: sets multiplayer chat message size", (void *)&ud.textscale, CVAR_INT, 100, 400 },
{ "hud_weaponscale","hud_weaponscale: changes the weapon scale", (void *)&ud.weaponscale, CVAR_INT, 10, 100 },
 
{ "in_joystick","in_joystick: enables input from the joystick if it is present",(void*)&ud.config.UseJoystick, CVAR_BOOL|CVAR_FUNCPTR, 0, 1 },
{ "in_mouse","in_mouse: enables input from the mouse if it is present",(void*)&ud.config.UseMouse, CVAR_BOOL|CVAR_FUNCPTR, 0, 1 },
{ "in_joystick","in_joystick: enables input from the joystick if it is present",(void *)&ud.config.UseJoystick, CVAR_BOOL|CVAR_FUNCPTR, 0, 1 },
{ "in_mouse","in_mouse: enables input from the mouse if it is present",(void *)&ud.config.UseMouse, CVAR_BOOL|CVAR_FUNCPTR, 0, 1 },
 
{ "in_aimmode", "in_aimmode: 0:toggle, 1:hold to aim", (void*)&ud.mouseaiming, CVAR_BOOL, 0, 1 },
{ "in_mousebias", "in_mousebias: emulates the original mouse code's weighting of input towards whichever axis is moving the most at any given time",
(void*)&ud.config.MouseBias, CVAR_INT, 0, 32 },
{ "in_mousedeadzone", "in_mousedeadzone: amount of mouse movement to filter out", (void*)&ud.config.MouseDeadZone, CVAR_INT, 0, 512 },
{ "in_mouseflip", "in_mouseflip: invert vertical mouse movement", (void*)&ud.mouseflip, CVAR_BOOL, 0, 1 },
{ "in_mousemode", "in_mousemode: like pressing U.", (void*)&g_myAimMode, CVAR_BOOL, 0, 1 },
{ "in_mousesmoothing", "in_mousesmoothing: enable/disable mouse input smoothing", (void*)&ud.config.SmoothInput, CVAR_BOOL, 0, 1 },
{ "in_aimmode", "in_aimmode: 0:toggle, 1:hold to aim", (void *)&ud.mouseaiming, CVAR_BOOL, 0, 1 },
{
"in_mousebias", "in_mousebias: emulates the original mouse code's weighting of input towards whichever axis is moving the most at any given time",
(void *)&ud.config.MouseBias, CVAR_INT, 0, 32
},
{ "in_mousedeadzone", "in_mousedeadzone: amount of mouse movement to filter out", (void *)&ud.config.MouseDeadZone, CVAR_INT, 0, 512 },
{ "in_mouseflip", "in_mouseflip: invert vertical mouse movement", (void *)&ud.mouseflip, CVAR_BOOL, 0, 1 },
{ "in_mousemode", "in_mousemode: like pressing U.", (void *)&g_myAimMode, CVAR_BOOL, 0, 1 },
{ "in_mousesmoothing", "in_mousesmoothing: enable/disable mouse input smoothing", (void *)&ud.config.SmoothInput, CVAR_BOOL, 0, 1 },
 
{ "mus_enabled", "mus_enabled: enables/disables music", (void*)&ud.config.MusicToggle, CVAR_BOOL, 0, 1 },
{ "mus_volume", "mus_musvolume: controls volume of midi music", (void*)&ud.config.MusicVolume, CVAR_INT, 0, 255 },
{ "mus_enabled", "mus_enabled: enables/disables music", (void *)&ud.config.MusicToggle, CVAR_BOOL, 0, 1 },
{ "mus_volume", "mus_musvolume: controls volume of midi music", (void *)&ud.config.MusicVolume, CVAR_INT, 0, 255 },
 
{ "osdhightile", "osdhightile: enable/disable hires art replacements for console text", (void*)&osdhightile, CVAR_BOOL, 0, 1 },
{ "osdhightile", "osdhightile: enable/disable hires art replacements for console text", (void *)&osdhightile, CVAR_BOOL, 0, 1 },
 
{ "r_drawweapon", "r_drawweapon: enable/disable weapon drawing", (void*)&ud.drawweapon, CVAR_INT, 0, 2 },
{ "r_showfps", "r_showfps: show the frame rate counter", (void*)&ud.tickrate, CVAR_BOOL, 0, 1 },
{ "r_shadows", "r_shadows: enable/disable sprite and model shadows", (void*)&ud.shadows, CVAR_BOOL, 0, 1 },
{ "r_precache", "r_precache: enable/disable the pre-level caching routine", (void*)&ud.config.useprecache, CVAR_BOOL, 0, 1 },
{ "r_drawweapon", "r_drawweapon: enable/disable weapon drawing", (void *)&ud.drawweapon, CVAR_INT, 0, 2 },
{ "r_showfps", "r_showfps: show the frame rate counter", (void *)&ud.tickrate, CVAR_BOOL, 0, 1 },
{ "r_shadows", "r_shadows: enable/disable sprite and model shadows", (void *)&ud.shadows, CVAR_BOOL, 0, 1 },
{ "r_precache", "r_precache: enable/disable the pre-level caching routine", (void *)&ud.config.useprecache, CVAR_BOOL, 0, 1 },
 
{ "r_ambientlight", "r_ambientlight: sets the global map light level",(void*)&r_ambientlight, CVAR_FLOAT|CVAR_FUNCPTR, 0, 10 },
{ "r_ambientlight", "r_ambientlight: sets the global map light level",(void *)&r_ambientlight, CVAR_FLOAT|CVAR_FUNCPTR, 0, 10 },
{ "r_maxfps", "r_maxfps: sets a framerate cap",(void *)&r_maxfps, CVAR_INT|CVAR_FUNCPTR, 0, 1000 },
 
{ "sensitivity","sensitivity <value>: changes the mouse sensitivity", (void*)&CONTROL_MouseSensitivity, CVAR_FLOAT|CVAR_FUNCPTR, 0, 25 },
{ "sensitivity","sensitivity <value>: changes the mouse sensitivity", (void *)&CONTROL_MouseSensitivity, CVAR_FLOAT|CVAR_FUNCPTR, 0, 25 },
 
{ "skill","skill <value>: changes the game skill setting", (void*)&ud.player_skill, CVAR_INT|CVAR_FUNCPTR|CVAR_NOMULTI, 0, 5 },
{ "skill","skill <value>: changes the game skill setting", (void *)&ud.player_skill, CVAR_INT|CVAR_FUNCPTR|CVAR_NOMULTI, 0, 5 },
 
{ "snd_ambience", "snd_ambience: enables/disables ambient sounds", (void*)&ud.config.AmbienceToggle, CVAR_BOOL, 0, 1 },
{ "snd_duketalk", "snd_duketalk: enables/disables Duke's speech", (void*)&ud.config.VoiceToggle, CVAR_INT, 0, 5 },
{ "snd_enabled", "snd_enabled: enables/disables sound effects", (void*)&ud.config.SoundToggle, CVAR_BOOL, 0, 1 },
{ "snd_fxvolume", "snd_fxvolume: volume of sound effects", (void*)&ud.config.FXVolume, CVAR_INT, 0, 255 },
{ "snd_mixrate", "snd_mixrate: sound mixing rate", (void*)&ud.config.MixRate, CVAR_INT, 0, 48000 },
{ "snd_numbits", "snd_numbits: sound bits", (void*)&ud.config.NumBits, CVAR_INT, 8, 16 },
{ "snd_numchannels", "snd_numchannels: the number of sound channels", (void*)&ud.config.NumChannels, CVAR_INT, 0, 2 },
{ "snd_numvoices", "snd_numvoices: the number of concurrent sounds", (void*)&ud.config.NumVoices, CVAR_INT, 0, 96 },
{ "snd_reversestereo", "snd_reversestereo: reverses the stereo channels", (void*)&ud.config.ReverseStereo, CVAR_BOOL, 0, 16 },
{ "snd_ambience", "snd_ambience: enables/disables ambient sounds", (void *)&ud.config.AmbienceToggle, CVAR_BOOL, 0, 1 },
{ "snd_duketalk", "snd_duketalk: enables/disables Duke's speech", (void *)&ud.config.VoiceToggle, CVAR_INT, 0, 5 },
{ "snd_enabled", "snd_enabled: enables/disables sound effects", (void *)&ud.config.SoundToggle, CVAR_BOOL, 0, 1 },
{ "snd_fxvolume", "snd_fxvolume: volume of sound effects", (void *)&ud.config.FXVolume, CVAR_INT, 0, 255 },
{ "snd_mixrate", "snd_mixrate: sound mixing rate", (void *)&ud.config.MixRate, CVAR_INT, 0, 48000 },
{ "snd_numbits", "snd_numbits: sound bits", (void *)&ud.config.NumBits, CVAR_INT, 8, 16 },
{ "snd_numchannels", "snd_numchannels: the number of sound channels", (void *)&ud.config.NumChannels, CVAR_INT, 0, 2 },
{ "snd_numvoices", "snd_numvoices: the number of concurrent sounds", (void *)&ud.config.NumVoices, CVAR_INT, 0, 96 },
{ "snd_reversestereo", "snd_reversestereo: reverses the stereo channels", (void *)&ud.config.ReverseStereo, CVAR_BOOL, 0, 16 },
 
{ "team","team <value>: change team in multiplayer", (void*)&ud.team, CVAR_INT|CVAR_MULTI, 0, 3 },
{ "team","team <value>: change team in multiplayer", (void *)&ud.team, CVAR_INT|CVAR_MULTI, 0, 3 },
 
{ "vid_gamma","vid_gamma <gamma>: adjusts gamma ramp",(void*)&vid_gamma, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },
{ "vid_contrast","vid_contrast <gamma>: adjusts gamma ramp",(void*)&vid_contrast, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },
{ "vid_brightness","vid_brightness <gamma>: adjusts gamma ramp",(void*)&vid_brightness, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },
{ "vid_gamma","vid_gamma <gamma>: adjusts gamma ramp",(void *)&vid_gamma, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },
{ "vid_contrast","vid_contrast <gamma>: adjusts gamma ramp",(void *)&vid_contrast, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },
{ "vid_brightness","vid_brightness <gamma>: adjusts gamma ramp",(void *)&vid_brightness, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },
};
 
osdcmd_cheatsinfo_stat.cheatnum = -1;
/polymer/eduke32/source/osdcmds.h
31,8 → 31,20
extern struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat;
 
int32_t registerosdcommands(void);
void onvideomodechange(int32_t newmode);
 
extern float r_ambientlight,r_ambientlightrecip;
 
#pragma pack(push,1)
// key bindings stuff
typedef struct {
char *name;
int32_t id;
} keydef_t;
 
extern keydef_t ConsoleKeys[];
extern char *ConsoleButtons[];
#pragma pack(pop)
 
#endif // __osdcmds_h__
 
/polymer/eduke32/source/osdfuncs.c
24,6 → 24,7
#include "build.h"
#include "namesdyn.h"
#include "osdfuncs.h"
#include "premap.h"
 
int32_t osdhightile = 0;
 
/polymer/eduke32/source/player.c
23,6 → 23,8
#include "duke3d.h"
#include "osd.h"
#include "gamedef.h"
#include "player.h"
#include "gameexec.h"
#include "enet/enet.h"
 
int32_t g_currentweapon;
172,7 → 174,7
if (srcvect.z > j || srcvect.z < n)
break;
j = A_InsertSprite(sect,srcvect.x,srcvect.y,srcvect.z,ProjectileData[atwith].trail,-32,
ProjectileData[atwith].txrepeat,ProjectileData[atwith].tyrepeat,ang,0,0,g_player[0].ps->i,0);
ProjectileData[atwith].txrepeat,ProjectileData[atwith].tyrepeat,ang,0,0,g_player[0].ps->i,0);
changespritestat(j,1);
}
}
255,7 → 257,7
if (PN == APLAYER &&
// ud.ffire == 0 &&
(GTFLAGS(GAMETYPE_PLAYERSFRIENDLY) || (GTFLAGS(GAMETYPE_TDM) &&
g_player[sprite[i].yvel].ps->team == g_player[s->yvel].ps->team)) &&
g_player[sprite[i].yvel].ps->team == g_player[s->yvel].ps->team)) &&
s->picnum == APLAYER &&
s != &sprite[i])
continue;
422,14 → 424,14
ProjectileData[atwith].range = 1024;
 
if (FindDistance2D(srcvect.x-hitinfo.pos.x,srcvect.y-hitinfo.pos.y) < ProjectileData[atwith].range)
if (FindDistance2D(wall[hitinfo.hitwall].x-wall[wall[hitinfo.hitwall].point2].x,wall[hitinfo.hitwall].y-wall[wall[hitinfo.hitwall].point2].y) >
(mulscale(ProjectileData[atwith].xrepeat+8,tilesizx[ProjectileData[atwith].decal],3)))
if (FindDistance2D(wall[hitinfo.hitwall].x-wall[wall[hitinfo.hitwall].point2].x,wall[hitinfo.hitwall].y-wall[wall[hitinfo.hitwall].point2].y) >
(mulscale(ProjectileData[atwith].xrepeat+8,tilesizx[ProjectileData[atwith].decal],3)))
if (hitinfo.hitwall >= 0 && wall[hitinfo.hitwall].overpicnum != BIGFORCE)
if ((wall[hitinfo.hitwall].nextsector >= 0 && hitinfo.hitsect >= 0 &&
sector[wall[hitinfo.hitwall].nextsector].lotag == 0 &&
sector[hitinfo.hitsect].lotag == 0 &&
sector[wall[hitinfo.hitwall].nextsector].lotag == 0 &&
(sector[hitinfo.hitsect].floorz-sector[wall[hitinfo.hitwall].nextsector].floorz) >
(sector[hitinfo.hitsect].floorz-sector[wall[hitinfo.hitwall].nextsector].floorz) >
(mulscale(ProjectileData[atwith].yrepeat,tilesizy[ProjectileData[atwith].decal],3)<<8)) ||
(wall[hitinfo.hitwall].nextsector == -1 && sector[hitinfo.hitsect].lotag == 0))
if ((wall[hitinfo.hitwall].cstat&16) == 0)
749,9 → 751,9
if (hitinfo.hitsprite >= 0)
{
A_DamageObject(hitinfo.hitsprite,k);
if (sprite[hitinfo.hitsprite].picnum == APLAYER &&
(ud.ffire == 1 || (!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY) && GTFLAGS(GAMETYPE_TDM) &&
g_player[sprite[hitinfo.hitsprite].yvel].ps->team != g_player[sprite[i].yvel].ps->team)))
if (sprite[hitinfo.hitsprite].picnum == APLAYER &&
(ud.ffire == 1 || (!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY) && GTFLAGS(GAMETYPE_TDM) &&
g_player[sprite[hitinfo.hitsprite].yvel].ps->team != g_player[sprite[i].yvel].ps->team)))
{
l = A_Spawn(k,JIBS6);
sprite[k].xrepeat = sprite[k].yrepeat = 0;
1227,7 → 1229,7
if (hitinfo.hitsprite != -1)
{
if (sprite[hitinfo.hitsprite].statnum == STAT_ACTOR || sprite[hitinfo.hitsprite].statnum == STAT_ZOMBIEACTOR ||
sprite[hitinfo.hitsprite].statnum == STAT_PLAYER || sprite[hitinfo.hitsprite].statnum == STAT_DUMMYPLAYER)
sprite[hitinfo.hitsprite].statnum == STAT_PLAYER || sprite[hitinfo.hitsprite].statnum == STAT_DUMMYPLAYER)
j = hitinfo.hitsprite;
}
}
1320,7 → 1322,7
{
A_DamageObject(hitinfo.hitsprite,k);
if (sprite[hitinfo.hitsprite].picnum == APLAYER && (ud.ffire == 1 || (!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY) &&
GTFLAGS(GAMETYPE_TDM) && g_player[sprite[hitinfo.hitsprite].yvel].ps->team != g_player[sprite[i].yvel].ps->team)))
GTFLAGS(GAMETYPE_TDM) && g_player[sprite[hitinfo.hitsprite].yvel].ps->team != g_player[sprite[i].yvel].ps->team)))
{
l = A_Spawn(k,JIBS6);
sprite[k].xrepeat = sprite[k].yrepeat = 0;
1538,7 → 1540,7
}
 
j = A_InsertSprite(sect,srcvect.x,srcvect.y,srcvect.z,
atwith,-127,sizx,sizy,sa,vel,zvel,i,4);
atwith,-127,sizx,sizy,sa,vel,zvel,i,4);
sprite[j].extra += (krand()&7);
 
if (atwith == COOLEXPLOSION1)
1743,8 → 1745,8
int32_t lLifetimeVar=Gv_GetVarByLabel("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, g_player[p].ps->i, p);
// set timer. blows up when at zero....
actor[k].t_data[7]=lLifetime
+ mulscale(krand(),lLifetimeVar, 14)
- lLifetimeVar;
+ mulscale(krand(),lLifetimeVar, 14)
- lLifetimeVar;
actor[k].t_data[6]=1;
}
else
2058,8 → 2060,8
case HANDBOMB_WEAPON:
case SHOTGUN_WEAPON:
rotatesprite(160<<16,(180+(g_player[screenpeek].ps->weapon_pos*g_player[screenpeek].ps->weapon_pos))<<16,
scale(65536,ud.statusbarscale,100),0,g_currentweapon==GROW_WEAPON?GROWSPRITEICON:WeaponPickupSprites[g_currentweapon],
0,0,2,windowx1,windowy1,windowx2,windowy2);
scale(65536,ud.statusbarscale,100),0,g_currentweapon==GROW_WEAPON?GROWSPRITEICON:WeaponPickupSprites[g_currentweapon],
0,0,2,windowx1,windowy1,windowx2,windowy2);
return;
default:
return;
2088,7 → 2090,7
}
 
G_DrawTileScaled(105+(g_player[snum].sync->avel>>4)-(g_player[snum].ps->look_ang>>1)+(knee_y[g_player[snum].ps->knee_incs]>>2),
looking_arc+280-((g_player[snum].ps->horiz-g_player[snum].ps->horizoff)>>4),KNEE,gs,4+262144,pal);
looking_arc+280-((g_player[snum].ps->horiz-g_player[snum].ps->horizoff)>>4),KNEE,gs,4+262144,pal);
 
return 1;
}
2110,8 → 2112,8
pal = sector[g_player[snum].ps->cursectnum].floorpal;
 
G_DrawTileScaled(160+(g_player[snum].sync->avel>>4)-(g_player[snum].ps->look_ang>>1),
looking_arc+180-((g_player[snum].ps->horiz-g_player[snum].ps->horizoff)>>4),
CRACKKNUCKLES+knuckle_frames[g_player[snum].ps->knuckle_incs>>1],gs,4+262144,pal);
looking_arc+180-((g_player[snum].ps->horiz-g_player[snum].ps->horizoff)>>4),
CRACKKNUCKLES+knuckle_frames[g_player[snum].ps->knuckle_incs>>1],gs,4+262144,pal);
 
return 1;
}
2152,7 → 2154,7
else
{
if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_AMMOPERSHOT &&
aplWeaponWorksLike[p->curr_weapon][snum] != KNEE_WEAPON)
aplWeaponWorksLike[p->curr_weapon][snum] != KNEE_WEAPON)
{
if (p->ammo_amount[p->curr_weapon] > 0)
p->ammo_amount[p->curr_weapon]--;
2254,7 → 2256,7
if (g_player[snum].ps->access_incs == 0 || sprite[g_player[snum].ps->i].extra <= 0) return 0;
 
looking_arc = access_y[g_player[snum].ps->access_incs] + klabs(g_player[snum].ps->look_ang)/9 -
(g_player[snum].ps->hard_landing<<3);
(g_player[snum].ps->hard_landing<<3);
 
if (g_player[snum].ps->access_spritenum >= 0)
p = sprite[g_player[snum].ps->access_spritenum].pal;
2264,11 → 2266,11
 
if ((g_player[snum].ps->access_incs-3) > 0 && (g_player[snum].ps->access_incs-3)>>3)
G_DrawTileScaled(170+(g_player[snum].sync->avel>>4)-(g_player[snum].ps->look_ang>>1)+(access_y[g_player[snum].ps->access_incs]>>2),
looking_arc+266-((g_player[snum].ps->horiz-g_player[snum].ps->horizoff)>>4),HANDHOLDINGLASER+(g_player[snum].ps->access_incs>>3),
gs,262144,p);
looking_arc+266-((g_player[snum].ps->horiz-g_player[snum].ps->horizoff)>>4),HANDHOLDINGLASER+(g_player[snum].ps->access_incs>>3),
gs,262144,p);
else
G_DrawTileScaled(170+(g_player[snum].sync->avel>>4)-(g_player[snum].ps->look_ang>>1)+(access_y[g_player[snum].ps->access_incs]>>2),
looking_arc+266-((g_player[snum].ps->horiz-g_player[snum].ps->horizoff)>>4),HANDHOLDINGACCESS,gs,4+262144,p);
looking_arc+266-((g_player[snum].ps->horiz-g_player[snum].ps->horizoff)>>4),HANDHOLDINGACCESS,gs,4+262144,p);
 
return 1;
}
2291,7 → 2293,7
if (gs > 24) gs = 24;
 
if (p->newowner >= 0 || ud.camerasprite >= 0 || p->over_shoulder_on > 0 || (sprite[p->i].pal != 1 && sprite[p->i].extra <= 0) ||
P_DisplayFist(gs,snum) || P_DisplayKnuckles(gs,snum) || P_DisplayTip(gs,snum) || P_DisplayAccess(gs,snum))
P_DisplayFist(gs,snum) || P_DisplayKnuckles(gs,snum) || P_DisplayTip(gs,snum) || P_DisplayAccess(gs,snum))
return;
 
P_DisplayKnee(gs,snum);
3048,16 → 3050,6
tics = totalclock-lastcontroltime;
lastcontroltime = totalclock;
 
if (multiflag == 1)
{
loc.bits = 1<<SK_MULTIFLAG;
loc.bits |= multiwhat<<(SK_MULTIFLAG+1);
loc.bits |= multipos<<(SK_MULTIFLAG+2);
multiflag = 0;
return;
}
 
 
// running = BUTTON(gamefunc_Run)|ud.auto_run;
// JBF: Run key behaviour is selectable
if (ud.runkey_mode)
3184,8 → 3176,8
 
loc.bits |= BUTTON(gamefunc_Crouch)<<SK_CROUCH;
loc.bits |= BUTTON(gamefunc_Fire)<<SK_FIRE;
loc.bits |= (BUTTON(gamefunc_Aim_Up) || (BUTTON(gamefunc_Dpad_Aiming) && vel > 0))<<SK_AIM_UP;
loc.bits |= (BUTTON(gamefunc_Aim_Down) || (BUTTON(gamefunc_Dpad_Aiming) && vel < 0))<<SK_AIM_DOWN;
loc.bits |= (BUTTON(gamefunc_Aim_Up) || (BUTTON(gamefunc_Dpad_Aiming) && vel > 0))<<SK_AIM_UP;
loc.bits |= (BUTTON(gamefunc_Aim_Down) || (BUTTON(gamefunc_Dpad_Aiming) && vel < 0))<<SK_AIM_DOWN;
if (ud.runkey_mode) loc.bits |= (ud.auto_run | BUTTON(gamefunc_Run))<<SK_RUN;
else loc.bits |= (BUTTON(gamefunc_Run) ^ ud.auto_run)<<SK_RUN;
loc.bits |= BUTTON(gamefunc_Look_Left)<<SK_LOOK_LEFT;
3198,7 → 3190,7
loc.bits |= BUTTON(gamefunc_MedKit)<<SK_MEDKIT;
loc.bits |= BUTTON(gamefunc_Center_View)<<SK_CENTER_VIEW;
loc.bits |= BUTTON(gamefunc_Holster_Weapon)<<SK_HOLSTER;
loc.bits |= (BUTTON(gamefunc_Inventory_Left) || (BUTTON(gamefunc_Dpad_Select) && (svel > 0 || angvel < 0))) <<SK_INV_LEFT;
loc.bits |= (BUTTON(gamefunc_Inventory_Left) || (BUTTON(gamefunc_Dpad_Select) && (svel > 0 || angvel < 0))) <<SK_INV_LEFT;
loc.bits |= KB_KeyPressed(sc_Pause)<<SK_PAUSE;
loc.bits |= BUTTON(gamefunc_Quick_Kick)<<SK_QUICK_KICK;
loc.bits |= g_myAimMode<<SK_AIMMODE;
3205,7 → 3197,7
loc.bits |= BUTTON(gamefunc_Holo_Duke)<<SK_HOLODUKE;
loc.bits |= BUTTON(gamefunc_Jetpack)<<SK_JETPACK;
loc.bits |= (((int32_t)g_gameQuit)<<SK_GAMEQUIT);
loc.bits |= (BUTTON(gamefunc_Inventory_Right) || (BUTTON(gamefunc_Dpad_Select) && (svel < 0 || angvel > 0))) <<SK_INV_RIGHT;
loc.bits |= (BUTTON(gamefunc_Inventory_Right) || (BUTTON(gamefunc_Dpad_Select) && (svel < 0 || angvel > 0))) <<SK_INV_RIGHT;
loc.bits |= BUTTON(gamefunc_TurnAround)<<SK_TURNAROUND;
loc.bits |= BUTTON(gamefunc_Open)<<SK_OPEN;
loc.bits |= BUTTON(gamefunc_Inventory)<<SK_INVENTORY;
3544,8 → 3536,8
 
Gv_SetVar(g_iWeaponVarID,p->curr_weapon, p->i, snum);
Gv_SetVar(g_iWorksLikeVarID,
(p->curr_weapon>=0) ? aplWeaponWorksLike[p->curr_weapon][snum] : -1,
p->i, snum);
(p->curr_weapon>=0) ? aplWeaponWorksLike[p->curr_weapon][snum] : -1,
p->i, snum);
}
 
void P_SelectNextInvItem(DukePlayer_t *p)
3614,14 → 3606,8
p->random_club_frame = 0;
p->curr_weapon = weap;
Gv_SetVar(g_iWeaponVarID,p->curr_weapon, p->i, snum);
if (p->curr_weapon>=0)
{
Gv_SetVar(g_iWorksLikeVarID,aplWeaponWorksLike[p->curr_weapon][snum], p->i, snum);
}
else
{
Gv_SetVar(g_iWorksLikeVarID,-1, p->i, snum);
}
Gv_SetVar(g_iWorksLikeVarID, p->curr_weapon >= 0 ? aplWeaponWorksLike[p->curr_weapon][snum] : -1, p->i, snum);
 
if (apScriptGameEvent[EVENT_CHANGEWEAPON])
VM_OnEvent(EVENT_CHANGEWEAPON,p->i, snum, -1);
p->kickback_pic = 0;
3784,8 → 3770,8
TRAVERSE_CONNECT(j)
if (p != j && sprite[g_player[j].ps->i].extra > 0)
{
x = klabs(g_player[j].ps->opos.x-g_player[p].ps->pos.x) +
klabs(g_player[j].ps->opos.y-g_player[p].ps->pos.y) +
x = klabs(g_player[j].ps->opos.x-g_player[p].ps->pos.x) +
klabs(g_player[j].ps->opos.y-g_player[p].ps->pos.y) +
(klabs(g_player[j].ps->opos.z-g_player[p].ps->pos.z)>>4);
 
if (x < closest)
3873,7 → 3859,7
 
if (ud.obituaries)
{
Bsprintf(tempbuf,ScriptQuotes[FIRST_OBITUARY_QUOTE+(krand()%g_numObituaries)],
Bsprintf(tempbuf,ScriptQuotes[OBITQUOTEINDEX+(krand()%g_numObituaries)],
&g_player[p->frag_ps].user_name[0],
&g_player[snum].user_name[0]);
G_AddUserQuote(tempbuf);
3886,13 → 3872,13
{
p->fraggedself++;
if (A_CheckEnemyTile(sprite[p->wackedbyactor].picnum))
Bsprintf(tempbuf,ScriptQuotes[FIRST_OBITUARY_QUOTE+(krand()%g_numObituaries)],"A monster",&g_player[snum].user_name[0]);
Bsprintf(tempbuf,ScriptQuotes[OBITQUOTEINDEX+(krand()%g_numObituaries)],"A monster",&g_player[snum].user_name[0]);
else if (actor[p->i].picnum == NUKEBUTTON)
Bsprintf(tempbuf,"^02%s^02 tried to leave",&g_player[snum].user_name[0]);
else
{
// random suicide death string
Bsprintf(tempbuf,ScriptQuotes[FIRST_SUICIDE_QUOTE+(krand()%g_numSelfObituaries)],&g_player[snum].user_name[0]);
Bsprintf(tempbuf,ScriptQuotes[SUICIDEQUOTEINDEX+(krand()%g_numSelfObituaries)],&g_player[snum].user_name[0]);
}
}
else Bsprintf(tempbuf,"^02%s^02 switched to team %d",&g_player[snum].user_name[0],p->team+1);
3968,7 → 3954,7
if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_HOLSTER_CLEARS_CLIP)
{
if (p->ammo_amount[p->curr_weapon] > aplWeaponClip[p->curr_weapon][snum]
&& (p->ammo_amount[p->curr_weapon] % aplWeaponClip[p->curr_weapon][snum]) != 0)
&& (p->ammo_amount[p->curr_weapon] % aplWeaponClip[p->curr_weapon][snum]) != 0)
{
p->ammo_amount[p->curr_weapon]-=
p->ammo_amount[p->curr_weapon] % aplWeaponClip[p->curr_weapon][snum] ;
4031,7 → 4017,7
if (shrunk || p->tipincs || p->access_incs)
sb_snum &= ~BIT(SK_FIRE);
else if (shrunk == 0 && (sb_snum&(1<<2)) && (*kb) == 0 && p->fist_incs == 0 &&
p->last_weapon == -1 && (p->weapon_pos == 0 || p->holster_weapon == 1))
p->last_weapon == -1 && (p->weapon_pos == 0 || p->holster_weapon == 1))
{
p->crack_time = 777;
 
4091,9 → 4077,9
{
hitdata_t hitinfo;
hitscan((const vec3_t *)p,
p->cursectnum, sintable[(p->ang+512)&2047],
sintable[p->ang&2047], (100-p->horiz-p->horizoff)*32,
&hitinfo,CLIPMASK1);
p->cursectnum, sintable[(p->ang+512)&2047],
sintable[p->ang&2047], (100-p->horiz-p->horizoff)*32,
&hitinfo,CLIPMASK1);
 
if (hitinfo.hitsect < 0 || hitinfo.hitsprite >= 0)
break;
4109,9 → 4095,9
while (j >= 0)
{
if (sprite[j].picnum == TRIPBOMB &&
klabs(sprite[j].z-hitinfo.pos.z) < (12<<8) &&
((sprite[j].x-hitinfo.pos.x)*(sprite[j].x-hitinfo.pos.x)+
(sprite[j].y-hitinfo.pos.y)*(sprite[j].y-hitinfo.pos.y)) < (290*290))
klabs(sprite[j].z-hitinfo.pos.z) < (12<<8) &&
((sprite[j].x-hitinfo.pos.x)*(sprite[j].x-hitinfo.pos.x)+
(sprite[j].y-hitinfo.pos.y)*(sprite[j].y-hitinfo.pos.y)) < (290*290))
break;
j = nextspritesect[j];
}
4118,10 → 4104,10
 
if (j == -1 && hitinfo.hitwall >= 0 && (wall[hitinfo.hitwall].cstat&16) == 0)
if ((wall[hitinfo.hitwall].nextsector >= 0 &&
sector[wall[hitinfo.hitwall].nextsector].lotag <= 2) ||
(wall[hitinfo.hitwall].nextsector == -1 && sector[hitinfo.hitsect].lotag <= 2))
sector[wall[hitinfo.hitwall].nextsector].lotag <= 2) ||
(wall[hitinfo.hitwall].nextsector == -1 && sector[hitinfo.hitsect].lotag <= 2))
if (((hitinfo.pos.x-p->pos.x)*(hitinfo.pos.x-p->pos.x) +
(hitinfo.pos.y-p->pos.y)*(hitinfo.pos.y-p->pos.y)) < (290*290))
(hitinfo.pos.y-p->pos.y)*(hitinfo.pos.y-p->pos.y)) < (290*290))
{
p->pos.z = p->opos.z;
p->posvel.z = 0;
4200,10 → 4186,10
}
 
j = A_InsertSprite(p->cursectnum,
p->pos.x+(sintable[(p->ang+512)&2047]>>6),
p->pos.y+(sintable[p->ang&2047]>>6),
p->pos.z,aplWeaponShoots[p->curr_weapon][snum],-16,9,9,
p->ang,(k+(p->hbomb_hold_delay<<5)),i,p->i,1);
p->pos.x+(sintable[(p->ang+512)&2047]>>6),
p->pos.y+(sintable[p->ang&2047]>>6),
p->pos.z,aplWeaponShoots[p->curr_weapon][snum],-16,9,9,
p->ang,(k+(p->hbomb_hold_delay<<5)),i,p->i,1);
 
lPipeBombControl=Gv_GetVarByLabel("PIPEBOMB_CONTROL", PIPEBOMB_REMOTE, -1, snum);
 
4212,8 → 4198,8
int32_t lv=Gv_GetVarByLabel("GRENADE_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, -1, snum);
 
actor[j].t_data[7]= Gv_GetVarByLabel("GRENADE_LIFETIME", NAM_GRENADE_LIFETIME, -1, snum)
+ mulscale(krand(),lv, 14)
- lv;
+ mulscale(krand(),lv, 14)
- lv;
actor[j].t_data[6]=1;
}
else actor[j].t_data[6]=2;
4273,7 → 4259,7
{
(*kb) = 0;
if ((p->ammo_amount[HANDBOMB_WEAPON] > 0) &&
Gv_GetVarByLabel("PIPEBOMB_CONTROL", PIPEBOMB_REMOTE, -1, snum) == PIPEBOMB_REMOTE)
Gv_GetVarByLabel("PIPEBOMB_CONTROL", PIPEBOMB_REMOTE, -1, snum) == PIPEBOMB_REMOTE)
P_AddWeapon(p,HANDBOMB_WEAPON);
else P_CheckWeapon(p);
}
4301,7 → 4287,7
P_CheckWeapon(p);
 
if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_STANDSTILL
&& *kb < (aplWeaponFireDelay[p->curr_weapon][snum]+1))
&& *kb < (aplWeaponFireDelay[p->curr_weapon][snum]+1))
{
p->pos.z = p->opos.z;
p->posvel.z = 0;
4319,8 → 4305,8
if ((*kb) >= aplWeaponTotalTime[p->curr_weapon][snum])
{
if (/*!(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_CHECKATRELOAD) && */ p->reloading == 1 ||
(aplWeaponReload[p->curr_weapon][snum] > aplWeaponTotalTime[p->curr_weapon][snum] && p->ammo_amount[p->curr_weapon] > 0
&& (aplWeaponClip[p->curr_weapon][snum]) && (((p->ammo_amount[p->curr_weapon]%(aplWeaponClip[p->curr_weapon][snum]))==0))))
(aplWeaponReload[p->curr_weapon][snum] > aplWeaponTotalTime[p->curr_weapon][snum] && p->ammo_amount[p->curr_weapon] > 0
&& (aplWeaponClip[p->curr_weapon][snum]) && (((p->ammo_amount[p->curr_weapon]%(aplWeaponClip[p->curr_weapon][snum]))==0))))
{
int32_t i = aplWeaponReload[p->curr_weapon][snum] - aplWeaponTotalTime[p->curr_weapon][snum];
 
4333,11 → 4319,11
if (aplWeaponReloadSound1[p->curr_weapon][snum])
A_PlaySound(aplWeaponReloadSound1[p->curr_weapon][snum],p->i);
}
else if (((*kb) == (aplWeaponReload[p->curr_weapon][snum] - (i/3)) &&
!(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_RELOAD_TIMING)) ||
else if (((*kb) == (aplWeaponReload[p->curr_weapon][snum] - (i/3)) &&
!(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_RELOAD_TIMING)) ||
 
((*kb) == (aplWeaponReload[p->curr_weapon][snum] - i+4) &&
(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_RELOAD_TIMING)))
((*kb) == (aplWeaponReload[p->curr_weapon][snum] - i+4) &&
(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_RELOAD_TIMING)))
{
if (aplWeaponReloadSound2[p->curr_weapon][snum])
A_PlaySound(aplWeaponReloadSound2[p->curr_weapon][snum],p->i);
4352,7 → 4338,7
else
{
if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_AUTOMATIC &&
(aplWeaponWorksLike[p->curr_weapon][snum]==KNEE_WEAPON?1:p->ammo_amount[p->curr_weapon] > 0))
(aplWeaponWorksLike[p->curr_weapon][snum]==KNEE_WEAPON?1:p->ammo_amount[p->curr_weapon] > 0))
{
if (TEST_SYNC_KEY(sb_snum, SK_FIRE))
{
4365,7 → 4351,7
else *kb = 0;
 
if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_RESET &&
((aplWeaponWorksLike[p->curr_weapon][snum] == KNEE_WEAPON)?1:p->ammo_amount[p->curr_weapon] > 0))
((aplWeaponWorksLike[p->curr_weapon][snum] == KNEE_WEAPON)?1:p->ammo_amount[p->curr_weapon] > 0))
{
if (TEST_SYNC_KEY(sb_snum, SK_FIRE)) *kb = 1;
else *kb = 0;
4373,7 → 4359,7
}
}
else if (*kb >= aplWeaponFireDelay[p->curr_weapon][snum] && (*kb) < aplWeaponTotalTime[p->curr_weapon][snum]
&& ((aplWeaponWorksLike[p->curr_weapon][snum] == KNEE_WEAPON)?1:p->ammo_amount[p->curr_weapon] > 0))
&& ((aplWeaponWorksLike[p->curr_weapon][snum] == KNEE_WEAPON)?1:p->ammo_amount[p->curr_weapon] > 0))
{
if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_AUTOMATIC)
{
4403,8 → 4389,8
}
}
if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_RESET &&
(*kb) > aplWeaponTotalTime[p->curr_weapon][snum]-aplWeaponHoldDelay[p->curr_weapon][snum] &&
((aplWeaponWorksLike[p->curr_weapon][snum] == KNEE_WEAPON) || p->ammo_amount[p->curr_weapon] > 0))
(*kb) > aplWeaponTotalTime[p->curr_weapon][snum]-aplWeaponHoldDelay[p->curr_weapon][snum] &&
((aplWeaponWorksLike[p->curr_weapon][snum] == KNEE_WEAPON) || p->ammo_amount[p->curr_weapon] > 0))
{
if (TEST_SYNC_KEY(sb_snum, SK_FIRE)) *kb = 1;
else *kb = 0;
4453,7 → 4439,7
int32_t i;
 
TRAVERSE_CONNECT(i)
g_player[i].ps->gm = MODE_EOL;
g_player[i].ps->gm = MODE_EOL;
 
if (p->buttonpalette && ud.from_bonus == 0)
{
4619,7 → 4605,7
else if (p->timebeforeexit == 1)
{
TRAVERSE_CONNECT(i)
g_player[i].ps->gm = MODE_EOL;
g_player[i].ps->gm = MODE_EOL;
 
ud.m_level_number = ud.level_number++;
 
4979,9 → 4965,9
{
for (j=headspritesect[p->cursectnum]; j>=0; j=nextspritesect[j])
if (sprite[j].picnum == FOOTPRINTS || sprite[j].picnum == FOOTPRINTS2 ||
sprite[j].picnum == FOOTPRINTS3 || sprite[j].picnum == FOOTPRINTS4)
sprite[j].picnum == FOOTPRINTS3 || sprite[j].picnum == FOOTPRINTS4)
if (klabs(sprite[j].x-p->pos.x) < 384 && klabs(sprite[j].y-p->pos.y) < 384)
break;
break;
 
if (j < 0)
{
5174,7 → 5160,7
 
if (p->fist_incs || p->transporter_hold > 2 || p->hard_landing || p->access_incs > 0 || p->knee_incs > 0 ||
(*aplWeaponWorksLike[p->curr_weapon] == TRIPBOMB_WEAPON &&
*kb > 1 && *kb < *aplWeaponFireDelay[p->curr_weapon]))
*kb > 1 && *kb < *aplWeaponFireDelay[p->curr_weapon]))
{
doubvel = 0;
p->posvel.x = 0;
5315,7 → 5301,6
}
 
HORIZONLY:
 
if (psectlotag == 1 || p->spritebridge == 1) i = (4L<<8);
else i = (20L<<8);
 
5403,9 → 5388,7
aGameVars[g_iReturnVarID].val.lValue = 0;
VM_OnEvent(EVENT_RETURNTOCENTER,p->i,snum, -1);
if (aGameVars[g_iReturnVarID].val.lValue == 0)
{
p->return_to_center = 9;
}
}
 
if (TEST_SYNC_KEY(sb_snum, SK_LOOK_UP))
5500,15 → 5483,13
 
if (p->knee_incs > 0)
{
p->knee_incs++;
p->horiz -= 48;
p->return_to_center = 9;
 
if (p->knee_incs > 15)
if (++p->knee_incs > 15)
{
p->knee_incs = 0;
p->holster_weapon = 0;
 
p->weapon_pos = klabs(p->weapon_pos);
 
if (p->actorsqu >= 0 && sprite[p->actorsqu].statnum != MAXSTATUS && dist(&sprite[p->i],&sprite[p->actorsqu]) < 1400)
/polymer/eduke32/source/player.h
0,0 → 1,294
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
 
This file is part of EDuke32.
 
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
 
#ifndef __player_h__
#define __player_h__
 
#define MOVEFIFOSIZ 2
 
#define NAM_GRENADE_LIFETIME 120
#define NAM_GRENADE_LIFETIME_VAR 30
 
#define HORIZ_MIN -99
#define HORIZ_MAX 299
#define AUTO_AIM_ANGLE 48
#define PHEIGHT (38<<8)
 
enum dukeinv_t {
GET_STEROIDS,
GET_SHIELD,
GET_SCUBA,
GET_HOLODUKE,
GET_JETPACK,
GET_DUMMY1,
GET_ACCESS,
GET_HEATS,
GET_DUMMY2,
GET_FIRSTAID,
GET_BOOTS,
GET_MAX
};
 
enum dukeweapon_t {
KNEE_WEAPON,
PISTOL_WEAPON,
SHOTGUN_WEAPON,
CHAINGUN_WEAPON,
RPG_WEAPON,
HANDBOMB_WEAPON,
SHRINKER_WEAPON,
DEVISTATOR_WEAPON,
TRIPBOMB_WEAPON,
FREEZE_WEAPON,
HANDREMOTE_WEAPON,
GROW_WEAPON,
MAX_WEAPONS
};
 
enum weaponflags_t {
WEAPON_SPAWNTYPE1 = 0x00000000, // just spawn
WEAPON_HOLSTER_CLEARS_CLIP = 0x00000001, // 'holstering' clears the current clip
WEAPON_GLOWS = 0x00000002, // weapon 'glows' (shrinker and grower)
WEAPON_AUTOMATIC = 0x00000004, // automatic fire (continues while 'fire' is held down
WEAPON_FIREEVERYOTHER = 0x00000008, // during 'hold time' fire every frame
WEAPON_FIREEVERYTHIRD = 0x00000010, // during 'hold time' fire every third frame
WEAPON_RANDOMRESTART = 0x00000020, // restart for automatic is 'randomized' by RND 3
WEAPON_AMMOPERSHOT = 0x00000040, // uses ammo for each shot (for automatic)
WEAPON_BOMB_TRIGGER = 0x00000080, // weapon is the 'bomb' trigger
WEAPON_NOVISIBLE = 0x00000100, // weapon use does not cause user to become 'visible'
WEAPON_THROWIT = 0x00000200, // weapon 'throws' the 'shoots' item...
WEAPON_CHECKATRELOAD = 0x00000400, // check weapon availability at 'reload' time
WEAPON_STANDSTILL = 0x00000800, // player stops jumping before actual fire (like tripbomb in duke)
WEAPON_SPAWNTYPE2 = 0x00001000, // spawn like shotgun shells
WEAPON_SPAWNTYPE3 = 0x00002000, // spawn like chaingun shells
WEAPON_SEMIAUTO = 0x00004000, // cancel button press after each shot
WEAPON_RELOAD_TIMING = 0x00008000, // special casing for pistol reload sounds
WEAPON_RESET = 0x00010000 // cycle weapon back to frame 1 if fire is held, 0 if not
};
 
enum gamemode_t {
MODE_MENU = 0x00000001,
MODE_DEMO = 0x00000002,
MODE_GAME = 0x00000004,
MODE_EOL = 0x00000008,
MODE_TYPE = 0x00000010,
MODE_RESTART = 0x00000020,
MODE_SENDTOWHOM = 0x00000040,
};
 
// Player Actions.
enum playeraction_t {
pstanding = 0x00000001,
pwalking = 0x00000002,
prunning = 0x00000004,
pducking = 0x00000008,
pfalling = 0x00000010,
pjumping = 0x00000020,
phigher = 0x00000040,
pwalkingback = 0x00000080,
prunningback = 0x00000100,
pkicking = 0x00000200,
pshrunk = 0x00000400,
pjetpack = 0x00000800,
ponsteroids = 0x00001000,
ponground = 0x00002000,
palive = 0x00004000,
pdead = 0x00008000,
pfacing = 0x00010000
};
 
#define TRIPBOMB_TRIPWIRE 0x00000001
#define TRIPBOMB_TIMER 0x00000002
 
#define PIPEBOMB_REMOTE 0x00000001
#define PIPEBOMB_TIMER 0x00000002
 
#pragma pack(push,1)
typedef struct {
int32_t ox,oy,oz;
int16_t oa,os;
} playerspawn_t;
 
typedef struct {
int16_t got_access, last_extra, inv_amount[GET_MAX], curr_weapon, holoduke_on;
int16_t last_weapon, weapon_pos, kickback_pic;
int16_t ammo_amount[MAX_WEAPONS], frag[MAXPLAYERS];
uint16_t gotweapon;
char inven_icon, jetpack_on, heat_on;
} DukeStatus_t;
 
typedef struct {
vec3_t pos, opos, posvel;
int32_t bobposx, bobposy;
int32_t truefz, truecz, player_par;
int32_t randomflamex, exitx, exity;
int32_t runspeed, max_player_health, max_shield_amount;
 
uint32_t interface_toggle_flag;
 
uint8_t *palette;
 
uint16_t max_actors_killed, actors_killed;
uint16_t gotweapon, zoom;
 
int16_t loogiex[64], loogiey[64], sbs, sound_pitch;
 
int16_t ang, oang, angvel, cursectnum, look_ang, last_extra, subweapon;
int16_t max_ammo_amount[MAX_WEAPONS], ammo_amount[MAX_WEAPONS], inv_amount[GET_MAX];
int16_t wackedbyactor, pyoff, opyoff;
 
int16_t horiz, horizoff, ohoriz, ohorizoff;
int16_t newowner, jumping_counter, airleft;
int16_t fta, ftq, access_wallnum, access_spritenum;
int16_t got_access, weapon_ang, visibility;
int16_t somethingonplayer, on_crane, i, one_parallax_sectnum;
int16_t random_club_frame, one_eighty_count;
int16_t dummyplayersprite, extra_extra8;
int16_t actorsqu, timebeforeexit, customexitsound, last_pissed_time;
 
int16_t weaprecs[MAX_WEAPONS], weapon_sway, crack_time, bobcounter;
 
int16_t orotscrnang, rotscrnang, dead_flag; // JBF 20031220: added orotscrnang
int16_t holoduke_on, pycount;
 
uint8_t max_secret_rooms, secret_rooms;
uint8_t frag, fraggedself, quick_kick, last_quick_kick;
uint8_t return_to_center, reloading, weapreccnt;
uint8_t aim_mode, auto_aim, weaponswitch, movement_lock, team;
uint8_t tipincs, hbomb_hold_delay, frag_ps, kickback_pic;
 
uint8_t gm, on_warping_sector, footprintcount, hurt_delay;
uint8_t hbomb_on, jumping_toggle, rapid_fire_hold, on_ground;
uint8_t inven_icon, buttonpalette, over_shoulder_on, show_empty_weapon;
 
uint8_t jetpack_on, spritebridge, lastrandomspot;
uint8_t scuba_on, footprintpal, heat_on, invdisptime;
 
uint8_t holster_weapon, falling_counter, footprintshade;
uint8_t refresh_inventory, last_full_weapon;
 
uint8_t toggle_key_flag, knuckle_incs, knee_incs, access_incs;
uint8_t walking_snd_toggle, palookup, hard_landing, fist_incs;
 
int8_t numloogs, loogcnt, scream_voice, transporter_hold;
int8_t last_weapon, cheat_phase, weapon_pos, wantweaponfire, curr_weapon;
 
palette_t pals;
 
char name[32];
} DukePlayer_t;
 
typedef struct {
uint32_t bits; // 4b
int16_t fvel, svel; // 4b
int8_t avel, horz; // 2b
int8_t extbits, filler; // 2b
} input_t;
 
typedef struct {
DukePlayer_t *ps;
input_t *sync;
 
int32_t netsynctime;
int16_t ping, filler;
int32_t pcolor, pteam;
uint8_t frags[MAXPLAYERS], wchoice[MAX_WEAPONS];
 
char vote, gotvote, playerreadyflag, playerquitflag;
char user_name[32];
} playerdata_t;
#pragma pack(pop)
 
extern char g_numPlayerSprites;
extern int32_t fricxv,fricyv;
 
extern intptr_t *aplWeaponClip[MAX_WEAPONS]; // number of items in clip
extern intptr_t *aplWeaponReload[MAX_WEAPONS]; // delay to reload (include fire)
extern intptr_t *aplWeaponFireDelay[MAX_WEAPONS]; // delay to fire
extern intptr_t *aplWeaponHoldDelay[MAX_WEAPONS]; // delay after release fire button to fire (0 for none)
extern intptr_t *aplWeaponTotalTime[MAX_WEAPONS]; // The total time the weapon is cycling before next fire.
extern intptr_t *aplWeaponFlags[MAX_WEAPONS]; // Flags for weapon
extern intptr_t *aplWeaponShoots[MAX_WEAPONS]; // what the weapon shoots
extern intptr_t *aplWeaponSpawnTime[MAX_WEAPONS]; // the frame at which to spawn an item
extern intptr_t *aplWeaponSpawn[MAX_WEAPONS]; // the item to spawn
extern intptr_t *aplWeaponShotsPerBurst[MAX_WEAPONS]; // number of shots per 'burst' (one ammo per 'burst'
extern intptr_t *aplWeaponWorksLike[MAX_WEAPONS]; // What original the weapon works like
extern intptr_t *aplWeaponInitialSound[MAX_WEAPONS]; // Sound made when initialy firing. zero for no sound
extern intptr_t *aplWeaponFireSound[MAX_WEAPONS]; // Sound made when firing (each time for automatic)
extern intptr_t *aplWeaponSound2Time[MAX_WEAPONS]; // Alternate sound time
extern intptr_t *aplWeaponSound2Sound[MAX_WEAPONS]; // Alternate sound sound ID
extern intptr_t *aplWeaponReloadSound1[MAX_WEAPONS]; // Sound of magazine being removed
extern intptr_t *aplWeaponReloadSound2[MAX_WEAPONS]; // Sound of magazine being inserted
extern intptr_t *aplWeaponSelectSound[MAX_WEAPONS]; // Sound for weapon selection
extern intptr_t *aplWeaponFlashColor[MAX_WEAPONS]; // Color for polymer muzzle flash
 
#pragma pack(push,1)
extern input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
extern playerspawn_t g_playerSpawnPoints[MAXPLAYERS];
extern playerdata_t g_player[MAXPLAYERS];
#pragma pack(pop)
extern char dashow2dsector[(MAXSECTORS+7)>>3];
extern int16_t searchsect[MAXSECTORS],searchparent[MAXSECTORS];
extern int16_t WeaponPickupSprites[MAX_WEAPONS];
extern int32_t g_currentweapon;
extern int32_t g_gs;
extern int32_t g_gun_pos;
extern int32_t g_kb;
extern int32_t g_levelTextTime;
extern int32_t g_looking_angSR1;
extern int32_t g_looking_arc;
extern int32_t g_myAimMode;
extern int32_t g_numObituaries;
extern int32_t g_numSelfObituaries;
extern int32_t g_weapon_offset;
extern int32_t g_weapon_xoffset;
extern int32_t jump_timer;
extern int32_t lastvisinc;
extern int32_t mouseyaxismode;
extern int32_t ticrandomseed;
 
int32_t A_GetHitscanRange(int32_t i);
int32_t A_Shoot(int32_t i,int32_t atwith);
void computergetinput(int32_t snum,input_t *syn);
void getinput(int32_t snum);
int32_t getspritescore(int32_t snum,int32_t dapicnum);
void P_AddAmmo(int32_t weapon,DukePlayer_t *p,int32_t amount);
void P_AddWeapon(DukePlayer_t *p,int32_t weapon);
void P_AddWeaponNoSwitch(DukePlayer_t *p,int32_t weapon);
int32_t P_CheckFloorDamage(DukePlayer_t *p,int32_t j);
void P_CheckTouchDamage(DukePlayer_t *p,int32_t j);
void P_CheckWeapon(DukePlayer_t *p);
void P_DisplayScuba(int32_t snum);
void P_DisplayWeapon(int32_t snum);
int32_t P_DoFist(DukePlayer_t *p);
void P_DoWeaponSpawn(DukePlayer_t *p);
void P_DropWeapon(DukePlayer_t *p);
int32_t P_FindOtherPlayer(int32_t p,int32_t *d);
void P_FireWeapon(DukePlayer_t *p);
void P_FragPlayer(int32_t snum);
void P_ProcessInput(int32_t snum);
void P_ProcessWeapon(int32_t snum);
void P_QuickKill(DukePlayer_t *p);
void P_SelectNextInvItem(DukePlayer_t *p);
void P_UpdateScreenPal(DukePlayer_t *p);
#endif
 
/polymer/eduke32/source/premap.c
23,6 → 23,11
#include "duke3d.h"
#include "osd.h"
#include "gamedef.h"
#include "premap.h"
#include "sounds.h"
#include "gameexec.h"
#include "anim.h"
#include "menus.h"
 
#ifdef RENDERTYPEWIN
#define WIN32_LEAN_AND_MEAN
31,7 → 36,6
 
extern char pow2char[];
 
extern int32_t everyothertime;
static int32_t g_whichPalForPlayer = 9;
int32_t g_numRealPalettes;
int16_t SpriteCacheList[MAXTILES][3];
335,7 → 339,7
 
if (ud.recstat != 2)
{
/*Gv_SetVar(g_iReturnVarID,LOADSCREEN, -1, -1);*/
/*Gv_SetVar(g_iReturnVarID,LOADSCREEN, -1, -1);*/
aGameVars[g_iReturnVarID].val.lValue = LOADSCREEN;
VM_OnEvent(EVENT_GETLOADTILE, -1, myconnectindex, -1);
j = aGameVars[g_iReturnVarID].val.lValue;
868,7 → 872,7
p->weapon_pos = 6;
 
if ((aplWeaponWorksLike[p->curr_weapon][snum] == PISTOL_WEAPON) &&
(aplWeaponReload[p->curr_weapon][snum] > aplWeaponTotalTime[p->curr_weapon][snum]))
(aplWeaponReload[p->curr_weapon][snum] > aplWeaponTotalTime[p->curr_weapon][snum]))
p->kickback_pic = aplWeaponTotalTime[p->curr_weapon][snum];
else p->kickback_pic = 0;
 
899,7 → 903,7
startofdynamicinterpolations = 0;
 
if (((g&MODE_EOL) != MODE_EOL && numplayers < 2 && !g_netServer) ||
(!(GametypeFlags[ud.coop]&GAMETYPE_PRESERVEINVENTORYDEATH) && numplayers > 1))
(!(GametypeFlags[ud.coop]&GAMETYPE_PRESERVEINVENTORYDEATH) && numplayers > 1))
{
P_ResetWeapons(snum);
P_ResetInventory(snum);
1551,47 → 1555,6
g_moveThingsCount = 0;
}
 
void Net_WaitForServer(void)
{
int32_t server_ready = g_player[0].playerreadyflag;
 
if (numplayers < 2 || g_netServer) return;
 
if ((g_netServer || ud.multimode > 1))
{
P_SetGamePalette(g_player[myconnectindex].ps, titlepal, 11);
rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1);
 
rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1);
rotatesprite(160<<16,(129)<<16,30<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1);
if (PLUTOPAK) // JBF 20030804
rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1);
 
gametext(160,190,"WAITING FOR SERVER",14,2);
nextpage();
}
 
while (1)
{
if (quitevent || keystatus[1]) G_GameExit("");
 
packbuf[0] = PACKET_PLAYER_READY;
packbuf[1] = myconnectindex;
 
if (g_netClientPeer)
enet_peer_send(g_netClientPeer, CHAN_GAMESTATE, enet_packet_create(packbuf, 2, ENET_PACKET_FLAG_RELIABLE));
 
handleevents();
Net_GetPackets();
 
if (g_player[0].playerreadyflag > server_ready)
{
P_SetGamePalette(g_player[myconnectindex].ps, palette, 11);
return;
}
}
}
 
void clearfifo(void)
{
int32_t i = 0;
1614,23 → 1577,6
// clearbufbyte(playerquitflag,MAXPLAYERS,0x01);
}
 
void Net_ResetPrediction(void)
{