Subversion Repositories eduke32

Rev

Rev 8519 | Rev 8596 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8519 Rev 8576
1
// Ken Silverman's official web site: "http://www.advsys.net/ken"
1
// Ken Silverman's official web site: "http://www.advsys.net/ken"
2
// See the included license file "BUILDLIC.TXT" for license info.
2
// See the included license file "BUILDLIC.TXT" for license info.
3
//
3
//
4
// This file has been modified from Ken Silverman's original release
4
// This file has been modified from Ken Silverman's original release
5
// by Jonathon Fowler (jf@jonof.id.au)
5
// by Jonathon Fowler (jf@jonof.id.au)
6
6
7
#include "compat.h"
7
#include "compat.h"
8
#include "build.h"
8
#include "build.h"
9
#include "names.h"
9
#include "names.h"
10
#include "pragmas.h"
10
#include "pragmas.h"
11
#include "cache1d.h"
11
#include "cache1d.h"
12
#include "game.h"
12
#include "game.h"
13
#include "osd.h"
13
#include "osd.h"
14
#include "mmulti.h"
14
#include "mmulti.h"
15
#include "common.h"
15
#include "common.h"
16
16
17
#include "renderlayer.h"
17
#include "renderlayer.h"
18
18
19
#include "common_game.h"
19
#include "common_game.h"
20
20
21
const char *AppProperName = "EKenBuild";
21
const char *AppProperName = "EKenBuild";
22
const char *AppTechnicalName = "ekenbuild";
22
const char *AppTechnicalName = "ekenbuild";
23
23
24
#define SETUPFILENAME "ekenbuild.cfg"
24
#define SETUPFILENAME "ekenbuild.cfg"
25
char setupfilename[BMAX_PATH] = SETUPFILENAME;
25
char setupfilename[BMAX_PATH] = SETUPFILENAME;
26
26
27
#define TIMERINTSPERSECOND 140 //280
27
#define TIMERINTSPERSECOND 140 //280
28
#define MOVESPERSECOND 40
28
#define MOVESPERSECOND 40
29
#define TICSPERFRAME 3
29
#define TICSPERFRAME 3
30
#define MOVEFIFOSIZ 256
30
#define MOVEFIFOSIZ 256
31
#define EYEHEIGHT (32<<8)   //Normally (32<<8), (51<<8) to make mirrors happy
31
#define EYEHEIGHT (32<<8)   //Normally (32<<8), (51<<8) to make mirrors happy
32
32
33
#define TILE_TILT           (MAXTILES-2)
33
#define TILE_TILT           (MAXTILES-2)
34
34
35
35
36
static int32_t setsprite_eyeheight(int16_t spritenum, const vec3_t *pos) ATTRIBUTE((nonnull(2)));
36
static int32_t setsprite_eyeheight(int16_t spritenum, const vec3_t *pos) ATTRIBUTE((nonnull(2)));
37
static int32_t setsprite_eyeheight(int16_t spritenum, const vec3_t *pos)
37
static int32_t setsprite_eyeheight(int16_t spritenum, const vec3_t *pos)
38
{
38
{
39
    vec3_t eyepos = *pos;
39
    vec3_t eyepos = *pos;
40
    eyepos.z += EYEHEIGHT;
40
    eyepos.z += EYEHEIGHT;
41
    return setsprite(spritenum, &eyepos);
41
    return setsprite(spritenum, &eyepos);
42
}
42
}
43
43
44
int ksqr(int eax)
44
int ksqr(int eax)
45
{
45
{
46
    return eax*eax;
46
    return eax*eax;
47
}
47
}
48
48
49
// declared in sound.c
49
// declared in sound.c
50
void initsb(char,char,int,char,char,char,char);
50
void initsb(char,char,int,char,char,char,char);
51
void uninitsb(void);
51
void uninitsb(void);
52
void setears(int,int,int,int);
52
void setears(int,int,int,int);
53
void wsayfollow(char const *,int,int,int *,int *,char);
53
void wsayfollow(char const *,int,int,int *,int *,char);
54
void wsay(char const *,int,int,int);
54
void wsay(char const *,int,int,int);
55
void loadwaves(char const *);
55
void loadwaves(char const *);
56
int loadsong(char const *);
56
int loadsong(char const *);
57
void musicon(void);
57
void musicon(void);
58
void musicoff(void);
58
void musicoff(void);
59
void refreshaudio(void);
59
void refreshaudio(void);
60
60
61
// declared in config.c
61
// declared in config.c
62
int Ken_loadsetup(const char *);
62
int Ken_loadsetup(const char *);
63
int Ken_writesetup(const char *);
63
int Ken_writesetup(const char *);
64
64
65
/***************************************************************************
65
/***************************************************************************
66
    KEN'S TAG DEFINITIONS:      (Please define your own tags for your games)
66
    KEN'S TAG DEFINITIONS:      (Please define your own tags for your games)
67

67

68
 sector[?].lotag = 0   Normal sector
68
 sector[?].lotag = 0   Normal sector
69
 sector[?].lotag = 1   If you are on a sector with this tag, then all sectors
69
 sector[?].lotag = 1   If you are on a sector with this tag, then all sectors
70
                       with same hi tag as this are operated.  Once.
70
                       with same hi tag as this are operated.  Once.
71
 sector[?].lotag = 2   Same as sector[?].tag = 1 but this is retriggable.
71
 sector[?].lotag = 2   Same as sector[?].tag = 1 but this is retriggable.
72
 sector[?].lotag = 3   A really stupid sector that really does nothing now.
72
 sector[?].lotag = 3   A really stupid sector that really does nothing now.
73
 sector[?].lotag = 4   A sector where you are put closer to the floor
73
 sector[?].lotag = 4   A sector where you are put closer to the floor
74
                       (such as the slime in DOOM1.DAT)
74
                       (such as the slime in DOOM1.DAT)
75
 sector[?].lotag = 5   A really stupid sector that really does nothing now.
75
 sector[?].lotag = 5   A really stupid sector that really does nothing now.
76
 sector[?].lotag = 6   A normal door - instead of pressing D, you tag the
76
 sector[?].lotag = 6   A normal door - instead of pressing D, you tag the
77
                       sector with a 6.  The reason I make you edit doors
77
                       sector with a 6.  The reason I make you edit doors
78
                       this way is so that can program the doors
78
                       this way is so that can program the doors
79
                       yourself.
79
                       yourself.
80
 sector[?].lotag = 7   A door the goes down to open.
80
 sector[?].lotag = 7   A door the goes down to open.
81
 sector[?].lotag = 8   A door that opens horizontally in the middle.
81
 sector[?].lotag = 8   A door that opens horizontally in the middle.
82
 sector[?].lotag = 9   A sliding door that opens vertically in the middle.
82
 sector[?].lotag = 9   A sliding door that opens vertically in the middle.
83
                       -Example of the advantages of not using BSP tree.
83
                       -Example of the advantages of not using BSP tree.
84
 sector[?].lotag = 10  A warping sector with floor and walls that shade.
84
 sector[?].lotag = 10  A warping sector with floor and walls that shade.
85
 sector[?].lotag = 11  A sector with all walls that do X-panning.
85
 sector[?].lotag = 11  A sector with all walls that do X-panning.
86
 sector[?].lotag = 12  A sector with walls using the dragging function.
86
 sector[?].lotag = 12  A sector with walls using the dragging function.
87
 sector[?].lotag = 13  A sector with some swinging doors in it.
87
 sector[?].lotag = 13  A sector with some swinging doors in it.
88
 sector[?].lotag = 14  A revolving door sector.
88
 sector[?].lotag = 14  A revolving door sector.
89
 sector[?].lotag = 15  A subway track.
89
 sector[?].lotag = 15  A subway track.
90
 sector[?].lotag = 16  A true double-sliding door.
90
 sector[?].lotag = 16  A true double-sliding door.
91

91

92
    wall[?].lotag = 0   Normal wall
92
    wall[?].lotag = 0   Normal wall
93
    wall[?].lotag = 1   Y-panning wall
93
    wall[?].lotag = 1   Y-panning wall
94
    wall[?].lotag = 2   Switch - If you flip it, then all sectors with same hi
94
    wall[?].lotag = 2   Switch - If you flip it, then all sectors with same hi
95
                        tag as this are operated.
95
                        tag as this are operated.
96
    wall[?].lotag = 3   Marked wall to detemine starting dir. (sector tag 12)
96
    wall[?].lotag = 3   Marked wall to detemine starting dir. (sector tag 12)
97
    wall[?].lotag = 4   Mark on the shorter wall closest to the pivot point
97
    wall[?].lotag = 4   Mark on the shorter wall closest to the pivot point
98
                        of a swinging door. (sector tag 13)
98
                        of a swinging door. (sector tag 13)
99
    wall[?].lotag = 5   Mark where a subway should stop. (sector tag 15)
99
    wall[?].lotag = 5   Mark where a subway should stop. (sector tag 15)
100
    wall[?].lotag = 6   Mark for true double-sliding doors (sector tag 16)
100
    wall[?].lotag = 6   Mark for true double-sliding doors (sector tag 16)
101
    wall[?].lotag = 7   Water fountain
101
    wall[?].lotag = 7   Water fountain
102
    wall[?].lotag = 8   Bouncy wall!
102
    wall[?].lotag = 8   Bouncy wall!
103

103

104
 sprite[?].lotag = 0   Normal sprite
104
 sprite[?].lotag = 0   Normal sprite
105
 sprite[?].lotag = 1   If you press space bar on an AL, and the AL is tagged
105
 sprite[?].lotag = 1   If you press space bar on an AL, and the AL is tagged
106
                       with a 1, he will turn evil.
106
                       with a 1, he will turn evil.
107
 sprite[?].lotag = 2   When this sprite is operated, a bomb is shot at its
107
 sprite[?].lotag = 2   When this sprite is operated, a bomb is shot at its
108
                       position.
108
                       position.
109
 sprite[?].lotag = 3   Rotating sprite.
109
 sprite[?].lotag = 3   Rotating sprite.
110
 sprite[?].lotag = 4   Sprite switch.
110
 sprite[?].lotag = 4   Sprite switch.
111
 sprite[?].lotag = 5   Basketball hoop score.
111
 sprite[?].lotag = 5   Basketball hoop score.
112

112

113
    KEN'S STATUS DEFINITIONS:  (Please define your own statuses for your games)
113
    KEN'S STATUS DEFINITIONS:  (Please define your own statuses for your games)
114
 status = 0            Inactive sprite
114
 status = 0            Inactive sprite
115
 status = 1            Active monster sprite
115
 status = 1            Active monster sprite
116
 status = 2            Monster that becomes active only when it sees you
116
 status = 2            Monster that becomes active only when it sees you
117
 status = 3            Smoke on the wall for chainguns
117
 status = 3            Smoke on the wall for chainguns
118
 status = 4            Splashing sprites (When you shoot slime)
118
 status = 4            Splashing sprites (When you shoot slime)
119
 status = 5            Explosion!
119
 status = 5            Explosion!
120
 status = 6            Travelling bullet
120
 status = 6            Travelling bullet
121
 status = 7            Bomb sprial-out explosion
121
 status = 7            Bomb sprial-out explosion
122
 status = 8            Player!
122
 status = 8            Player!
123
 status = 9            EVILALGRAVE shrinking list
123
 status = 9            EVILALGRAVE shrinking list
124
 status = 10           EVILAL list
124
 status = 10           EVILAL list
125
 status = 11           Sprite respawning list
125
 status = 11           Sprite respawning list
126
 status = 12           Sprite which does not respawn (Andy's addition)
126
 status = 12           Sprite which does not respawn (Andy's addition)
127
 status = MAXSTATUS    Non-existent sprite (this will be true for your
127
 status = MAXSTATUS    Non-existent sprite (this will be true for your
128
                       code also)
128
                       code also)
129
**************************************************************************/
129
**************************************************************************/
130
130
131
typedef struct
131
typedef struct
132
{
132
{
133
    signed char fvel, svel, avel;
133
    signed char fvel, svel, avel;
134
    short bits;
134
    short bits;
135
} input;
135
} input;
136
136
137
static int screentilt = 0, oscreentilt = 0;
137
static int screentilt = 0, oscreentilt = 0;
138
138
139
139
140
static int fvel, svel, avel;
140
static int fvel, svel, avel;
141
static int fvel2, svel2, avel2;
141
static int fvel2, svel2, avel2;
142
142
143
unsigned char option[NUMOPTIONS] = {0,0,1,1,0,0,1,1+4+(6<<4)};
143
unsigned char option[NUMOPTIONS] = {0,0,1,1,0,0,1,1+4+(6<<4)};
144
unsigned char keys[NUMGAMEKEYS] =
144
unsigned char keys[NUMGAMEKEYS] =
145
{
145
{
146
    0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39,
146
    0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39,
147
    0x1e,0x2c,0xd1,0xc9,0x33,0x34,
147
    0x1e,0x2c,0xd1,0xc9,0x33,0x34,
148
    0x9c,0x1c,0xd,0xc,0xf
148
    0x9c,0x1c,0xd,0xc,0xf
149
};
149
};
150
150
151
extern "C" {
151
extern "C" {
152
int xdimgame = 320, ydimgame = 200, bppgame = 8, xdim2d = 640, ydim2d = 480;    // JBF 20050318: config.c expects to find these
152
int xdimgame = 320, ydimgame = 200, bppgame = 8, xdim2d = 640, ydim2d = 480;    // JBF 20050318: config.c expects to find these
153
int forcesetup = 1;
153
int forcesetup = 1;
154
}
154
}
155
155
156
static int digihz[8] = {6000,8000,11025,16000,22050,32000,44100,48000};
156
static int digihz[8] = {6000,8000,11025,16000,22050,32000,44100,48000};
157
157
158
static char frame2draw[MAXPLAYERS];
158
static char frame2draw[MAXPLAYERS];
159
static int frameskipcnt[MAXPLAYERS];
159
static int frameskipcnt[MAXPLAYERS];
160
160
161
#define LAVASIZ 128
161
#define LAVASIZ 128
162
#define LAVALOGSIZ 7
162
#define LAVALOGSIZ 7
163
#define LAVAMAXDROPS 32
163
#define LAVAMAXDROPS 32
164
static char lavabakpic[(LAVASIZ+4)*(LAVASIZ+4)], lavainc[LAVASIZ];
164
static char lavabakpic[(LAVASIZ+4)*(LAVASIZ+4)], lavainc[LAVASIZ];
165
static int lavanumdrops, lavanumframes;
165
static int lavanumdrops, lavanumframes;
166
static int lavadropx[LAVAMAXDROPS], lavadropy[LAVAMAXDROPS];
166
static int lavadropx[LAVAMAXDROPS], lavadropy[LAVAMAXDROPS];
167
static int lavadropsiz[LAVAMAXDROPS], lavadropsizlookup[LAVAMAXDROPS];
167
static int lavadropsiz[LAVAMAXDROPS], lavadropsizlookup[LAVAMAXDROPS];
168
static int lavaradx[24][96], lavarady[24][96], lavaradcnt[32];
168
static int lavaradx[24][96], lavarady[24][96], lavaradcnt[32];
169
169
170
//Shared player variables
170
//Shared player variables
171
static vec3_t pos[MAXPLAYERS];
171
static vec3_t pos[MAXPLAYERS];
172
static int horiz[MAXPLAYERS], zoom[MAXPLAYERS], hvel[MAXPLAYERS];
172
static int horiz[MAXPLAYERS], zoom[MAXPLAYERS], hvel[MAXPLAYERS];
173
static short ang[MAXPLAYERS], cursectnum[MAXPLAYERS], ocursectnum[MAXPLAYERS];
173
static short ang[MAXPLAYERS], cursectnum[MAXPLAYERS], ocursectnum[MAXPLAYERS];
174
static short playersprite[MAXPLAYERS], deaths[MAXPLAYERS];
174
static short playersprite[MAXPLAYERS], deaths[MAXPLAYERS];
175
static int lastchaingun[MAXPLAYERS];
175
static int lastchaingun[MAXPLAYERS];
176
static int health[MAXPLAYERS], flytime[MAXPLAYERS];
176
static int health[MAXPLAYERS], flytime[MAXPLAYERS];
177
static short oflags[MAXPLAYERS];
177
static short oflags[MAXPLAYERS];
178
static short numbombs[MAXPLAYERS];
178
static short numbombs[MAXPLAYERS];
179
static short numgrabbers[MAXPLAYERS];   // Andy did this
179
static short numgrabbers[MAXPLAYERS];   // Andy did this
180
static short nummissiles[MAXPLAYERS];   // Andy did this
180
static short nummissiles[MAXPLAYERS];   // Andy did this
181
static char dimensionmode[MAXPLAYERS];
181
static char dimensionmode[MAXPLAYERS];
182
static char revolvedoorstat[MAXPLAYERS];
182
static char revolvedoorstat[MAXPLAYERS];
183
static short revolvedoorang[MAXPLAYERS], revolvedoorrotang[MAXPLAYERS];
183
static short revolvedoorang[MAXPLAYERS], revolvedoorrotang[MAXPLAYERS];
184
static int revolvedoorx[MAXPLAYERS], revolvedoory[MAXPLAYERS];
184
static int revolvedoorx[MAXPLAYERS], revolvedoory[MAXPLAYERS];
185
185
186
static int nummoves;
186
static int nummoves;
187
// Bug: NUMSTATS used to be equal to the greatest tag number,
187
// Bug: NUMSTATS used to be equal to the greatest tag number,
188
// so that the last statrate[] entry was random memory junk
188
// so that the last statrate[] entry was random memory junk
189
// because stats 0-NUMSTATS required NUMSTATS+1 bytes.   -Andy
189
// because stats 0-NUMSTATS required NUMSTATS+1 bytes.   -Andy
190
#define NUMSTATS 13
190
#define NUMSTATS 13
191
static signed char statrate[NUMSTATS] = {-1,0,-1,0,0,0,1,3,0,3,15,-1,-1};
191
static signed char statrate[NUMSTATS] = {-1,0,-1,0,0,0,1,3,0,3,15,-1,-1};
192
192
193
//Input structures
193
//Input structures
194
static char networkmode;     //0 is 2(n-1) mode, 1 is n(n-1) mode
194
static char networkmode;     //0 is 2(n-1) mode, 1 is n(n-1) mode
195
static int locselectedgun, locselectedgun2;
195
static int locselectedgun, locselectedgun2;
196
static input loc, oloc, loc2;
196
static input loc, oloc, loc2;
197
static input ffsync[MAXPLAYERS], osync[MAXPLAYERS], ssync[MAXPLAYERS];
197
static input ffsync[MAXPLAYERS], osync[MAXPLAYERS], ssync[MAXPLAYERS];
198
//Input faketimerhandler -> movethings fifo
198
//Input faketimerhandler -> movethings fifo
199
static int movefifoplc, movefifoend[MAXPLAYERS];
199
static int movefifoplc, movefifoend[MAXPLAYERS];
200
static input baksync[MOVEFIFOSIZ][MAXPLAYERS];
200
static input baksync[MOVEFIFOSIZ][MAXPLAYERS];
201
//Game recording variables
201
//Game recording variables
202
static int reccnt, recstat = 1;
202
static int reccnt, recstat = 1;
203
static input recsync[16384][2];
203
static input recsync[16384][2];
204
204
205
//static int myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1;
205
//static int myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1;
206
static signed char otherlag[MAXPLAYERS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
206
static signed char otherlag[MAXPLAYERS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
207
static int averagelag[MAXPLAYERS] = {512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512};
207
static int averagelag[MAXPLAYERS] = {512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512};
208
208
209
static int fakemovefifoplc;
209
static int fakemovefifoplc;
210
static vec3_t my, omy;
210
static vec3_t my, omy;
211
static int myzvel;
211
static int myzvel;
212
static int myhoriz, omyhoriz;
212
static int myhoriz, omyhoriz;
213
static short myang, omyang, mycursectnum;
213
static short myang, omyang, mycursectnum;
214
static vec3_t mybak[MOVEFIFOSIZ];
214
static vec3_t mybak[MOVEFIFOSIZ];
215
static int myhorizbak[MOVEFIFOSIZ];
215
static int myhorizbak[MOVEFIFOSIZ];
216
static short myangbak[MOVEFIFOSIZ];
216
static short myangbak[MOVEFIFOSIZ];
217
217
218
//GAME.C sync state variables
218
//GAME.C sync state variables
219
static char syncstat, syncval[MOVEFIFOSIZ], othersyncval[MOVEFIFOSIZ];
219
static char syncstat, syncval[MOVEFIFOSIZ], othersyncval[MOVEFIFOSIZ];
220
static int syncvaltottail, syncvalhead, othersyncvalhead, syncvaltail;
220
static int syncvaltottail, syncvalhead, othersyncvalhead, syncvaltail;
221
221
222
static char detailmode = 0, ready2send = 0;
222
static char detailmode = 0, ready2send = 0;
223
static int ototalclock = 0, gotlastpacketclock = 0, smoothratio;
223
static int ototalclock = 0, gotlastpacketclock = 0, smoothratio;
224
static vec3_t opos[MAXPLAYERS];
224
static vec3_t opos[MAXPLAYERS];
225
static int ohoriz[MAXPLAYERS], ozoom[MAXPLAYERS];
225
static int ohoriz[MAXPLAYERS], ozoom[MAXPLAYERS];
226
static short oang[MAXPLAYERS];
226
static short oang[MAXPLAYERS];
227
227
228
static vec3_t osprite[MAXSPRITES];
228
static vec3_t osprite[MAXSPRITES];
229
229
230
#define MAXINTERPOLATIONS 1024
230
#define MAXINTERPOLATIONS 1024
231
static int numinterpolations = 0, startofdynamicinterpolations = 0;
231
static int numinterpolations = 0, startofdynamicinterpolations = 0;
232
static int oldipos[MAXINTERPOLATIONS];
232
static int oldipos[MAXINTERPOLATIONS];
233
static int bakipos[MAXINTERPOLATIONS];
233
static int bakipos[MAXINTERPOLATIONS];
234
static int *curipos[MAXINTERPOLATIONS];
234
static int *curipos[MAXINTERPOLATIONS];
235
235
236
// extern int cachecount;
236
// extern int cachecount;
237
237
238
static char playerreadyflag[MAXPLAYERS];
238
static char playerreadyflag[MAXPLAYERS];
239
239
240
//Miscellaneous variables
240
//Miscellaneous variables
241
static unsigned char packbuf[MAXXDIM];
241
static unsigned char packbuf[MAXXDIM];
242
static char tempbuf[MAXXDIM];
242
static char tempbuf[MAXXDIM];
243
static char boardfilename[BMAX_PATH];
243
static char boardfilename[BMAX_PATH];
244
static short tempshort[MAXSECTORS];
244
static short tempshort[MAXSECTORS];
245
static short screenpeek = 0, oldmousebstatus = 0;
245
static short screenpeek = 0, oldmousebstatus = 0;
246
short brightness = 0;
246
short brightness = 0;
247
static short screensize, screensizeflag = 0;
247
static short screensize, screensizeflag = 0;
248
static short neartagsector, neartagwall, neartagsprite;
248
static short neartagsector, neartagwall, neartagsprite;
249
static int lockclock, neartagdist, neartaghitdist;
249
static int lockclock, neartagdist, neartaghitdist;
250
extern int pageoffset, ydim16;
250
extern int pageoffset, ydim16;
251
static int globhiz, globloz, globhihit, globlohit;
251
static int globhiz, globloz, globhihit, globlohit;
252
252
253
//Over the shoulder mode variables
253
//Over the shoulder mode variables
254
static int cameradist = -1, cameraang = 0, cameraclock = 0;
254
static int cameradist = -1, cameraang = 0, cameraclock = 0;
255
255
256
//Board animation variables
256
//Board animation variables
257
#define MAXMIRRORS 64
257
#define MAXMIRRORS 64
258
static short mirrorwall[MAXMIRRORS], mirrorsector[MAXMIRRORS], mirrorcnt;
258
static short mirrorwall[MAXMIRRORS], mirrorsector[MAXMIRRORS], mirrorcnt;
259
static short floormirrorsector[64], floormirrorcnt;
259
static short floormirrorsector[64], floormirrorcnt;
260
static short turnspritelist[16], turnspritecnt;
260
static short turnspritelist[16], turnspritecnt;
261
static short warpsectorlist[64], warpsectorcnt;
261
static short warpsectorlist[64], warpsectorcnt;
262
static short xpanningsectorlist[16], xpanningsectorcnt;
262
static short xpanningsectorlist[16], xpanningsectorcnt;
263
static short ypanningwalllist[64], ypanningwallcnt;
263
static short ypanningwalllist[64], ypanningwallcnt;
264
static short floorpanninglist[64], floorpanningcnt;
264
static short floorpanninglist[64], floorpanningcnt;
265
static short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt;
265
static short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt;
266
static int dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16];
266
static int dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16];
267
static short swingcnt, swingwall[32][5], swingsector[32];
267
static short swingcnt, swingwall[32][5], swingsector[32];
268
static short swingangopen[32], swingangclosed[32], swingangopendir[32];
268
static short swingangopen[32], swingangclosed[32], swingangopendir[32];
269
static short swingang[32], swinganginc[32];
269
static short swingang[32], swinganginc[32];
270
static int swingx[32][8], swingy[32][8];
270
static int swingx[32][8], swingy[32][8];
271
static short revolvesector[4], revolveang[4], revolvecnt;
271
static short revolvesector[4], revolveang[4], revolvecnt;
272
static int revolvex[4][16], revolvey[4][16];
272
static int revolvex[4][16], revolvey[4][16];
273
static int revolvepivotx[4], revolvepivoty[4];
273
static int revolvepivotx[4], revolvepivoty[4];
274
static short subwaytracksector[4][128], subwaynumsectors[4], subwaytrackcnt;
274
static short subwaytracksector[4][128], subwaynumsectors[4], subwaytrackcnt;
275
static int subwaystop[4][8], subwaystopcnt[4];
275
static int subwaystop[4][8], subwaystopcnt[4];
276
static int subwaytrackx1[4], subwaytracky1[4];
276
static int subwaytrackx1[4], subwaytracky1[4];
277
static int subwaytrackx2[4], subwaytracky2[4];
277
static int subwaytrackx2[4], subwaytracky2[4];
278
static int subwayx[4], subwaygoalstop[4], subwayvel[4], subwaypausetime[4];
278
static int subwayx[4], subwaygoalstop[4], subwayvel[4], subwaypausetime[4];
279
static short waterfountainwall[MAXPLAYERS], waterfountaincnt[MAXPLAYERS];
279
static short waterfountainwall[MAXPLAYERS], waterfountaincnt[MAXPLAYERS];
280
static short slimesoundcnt[MAXPLAYERS];
280
static short slimesoundcnt[MAXPLAYERS];
281
281
282
//Variables that let you type messages to other player
282
//Variables that let you type messages to other player
283
static char getmessage[162], getmessageleng;
283
static char getmessage[162], getmessageleng;
284
static int getmessagetimeoff;
284
static int getmessagetimeoff;
285
static char typemessage[162], typemessageleng = 0, typemode = 0;
285
static char typemessage[162], typemessageleng = 0, typemode = 0;
286
#if 0
286
#if 0
287
static char scantoasc[128] =
287
static char scantoasc[128] =
288
{
288
{
289
    0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,0,
289
    0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,0,
290
    'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'a','s',
290
    'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'a','s',
291
    'd','f','g','h','j','k','l',';',39,'`',0,92,'z','x','c','v',
291
    'd','f','g','h','j','k','l',';',39,'`',0,92,'z','x','c','v',
292
    'b','n','m',',','.','/',0,'*',0,32,0,0,0,0,0,0,
292
    'b','n','m',',','.','/',0,'*',0,32,0,0,0,0,0,0,
293
    0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1',
293
    0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1',
294
    '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0,
294
    '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0,
295
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
295
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
296
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
296
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
297
};
297
};
298
static char scantoascwithshift[128] =
298
static char scantoascwithshift[128] =
299
{
299
{
300
    0,0,'!','@','#','$','%','^','&','*','(',')','_','+',0,0,
300
    0,0,'!','@','#','$','%','^','&','*','(',')','_','+',0,0,
301
    'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,'A','S',
301
    'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,'A','S',
302
    'D','F','G','H','J','K','L',':',34,'~',0,'|','Z','X','C','V',
302
    'D','F','G','H','J','K','L',':',34,'~',0,'|','Z','X','C','V',
303
    'B','N','M','<','>','?',0,'*',0,32,0,0,0,0,0,0,
303
    'B','N','M','<','>','?',0,'*',0,32,0,0,0,0,0,0,
304
    0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1',
304
    0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1',
305
    '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0,
305
    '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0,
306
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
306
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
307
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
307
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
308
};
308
};
309
#endif
309
#endif
310
310
311
//These variables are for animating x, y, or z-coordinates of sectors,
311
//These variables are for animating x, y, or z-coordinates of sectors,
312
//walls, or sprites (They are NOT to be used for changing the [].picnum's)
312
//walls, or sprites (They are NOT to be used for changing the [].picnum's)
313
//See the setanimation(), and getanimategoal() functions for more details.
313
//See the setanimation(), and getanimategoal() functions for more details.
314
#define MAXANIMATES 512
314
#define MAXANIMATES 512
315
static int *animateptr[MAXANIMATES], animategoal[MAXANIMATES];
315
static int *animateptr[MAXANIMATES], animategoal[MAXANIMATES];
316
static int animatevel[MAXANIMATES], animateacc[MAXANIMATES], animatecnt = 0;
316
static int animatevel[MAXANIMATES], animateacc[MAXANIMATES], animatecnt = 0;
317
317
318
#if defined USE_OPENGL
318
#if defined USE_OPENGL
319
//These parameters are in exact order of sprite structure in BUILD.H
319
//These parameters are in exact order of sprite structure in BUILD.H
320
#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2,        \
320
#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2,        \
321
                    clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2,     \
321
                    clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2,     \
322
                    xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \
322
                    xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \
323
    {                                                                       \
323
    {                                                                       \
324
        spritetype *spr2;                                                   \
324
        spritetype *spr2;                                                   \
325
        newspriteindex2 = insertsprite(sectnum2,statnum2);                  \
325
        newspriteindex2 = insertsprite(sectnum2,statnum2);                  \
326
        spr2 = &sprite[newspriteindex2];                                    \
326
        spr2 = &sprite[newspriteindex2];                                    \
327
        spr2->x = x2; spr2->y = y2; spr2->z = z2;                           \
327
        spr2->x = x2; spr2->y = y2; spr2->z = z2;                           \
328
        spr2->cstat = cstat2; spr2->shade = shade2;                         \
328
        spr2->cstat = cstat2; spr2->shade = shade2;                         \
329
        spr2->pal = pal2; spr2->clipdist = clipdist2;                       \
329
        spr2->pal = pal2; spr2->clipdist = clipdist2;                       \
330
        spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2;                 \
330
        spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2;                 \
331
        spr2->xoffset = xoffset2; spr2->yoffset = yoffset2;                 \
331
        spr2->xoffset = xoffset2; spr2->yoffset = yoffset2;                 \
332
        spr2->picnum = picnum2; spr2->ang = ang2;                           \
332
        spr2->picnum = picnum2; spr2->ang = ang2;                           \
333
        spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2;         \
333
        spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2;         \
334
        spr2->owner = owner2;                                               \
334
        spr2->owner = owner2;                                               \
335
        spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2;   \
335
        spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2;   \
336
        copybuf(&spr2->x,&osprite[newspriteindex2].x,3);                    \
336
        copybuf(&spr2->x,&osprite[newspriteindex2].x,3);                    \
337
        show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7));      \
337
        show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7));      \
338
        if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7)))                    \
338
        if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7)))                    \
339
            show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7));   \
339
            show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7));   \
340
        clearbufbyte(&spriteext[newspriteindex2], sizeof(spriteext_t), 0);  \
340
        clearbufbyte(&spriteext[newspriteindex2], sizeof(spriteext_t), 0);  \
341
    }
341
    }
342
#else
342
#else
343
#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2,        \
343
#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2,        \
344
                    clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2,     \
344
                    clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2,     \
345
                    xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \
345
                    xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \
346
    {                                                                       \
346
    {                                                                       \
347
        spritetype *spr2;                                                   \
347
        spritetype *spr2;                                                   \
348
        newspriteindex2 = insertsprite(sectnum2,statnum2);                  \
348
        newspriteindex2 = insertsprite(sectnum2,statnum2);                  \
349
        spr2 = &sprite[newspriteindex2];                                    \
349
        spr2 = &sprite[newspriteindex2];                                    \
350
        spr2->x = x2; spr2->y = y2; spr2->z = z2;                           \
350
        spr2->x = x2; spr2->y = y2; spr2->z = z2;                           \
351
        spr2->cstat = cstat2; spr2->shade = shade2;                         \
351
        spr2->cstat = cstat2; spr2->shade = shade2;                         \
352
        spr2->pal = pal2; spr2->clipdist = clipdist2;                       \
352
        spr2->pal = pal2; spr2->clipdist = clipdist2;                       \
353
        spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2;                 \
353
        spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2;                 \
354
        spr2->xoffset = xoffset2; spr2->yoffset = yoffset2;                 \
354
        spr2->xoffset = xoffset2; spr2->yoffset = yoffset2;                 \
355
        spr2->picnum = picnum2; spr2->ang = ang2;                           \
355
        spr2->picnum = picnum2; spr2->ang = ang2;                           \
356
        spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2;         \
356
        spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2;         \
357
        spr2->owner = owner2;                                               \
357
        spr2->owner = owner2;                                               \
358
        spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2;   \
358
        spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2;   \
359
        copybuf(&spr2->x,&osprite[newspriteindex2].x,3);                    \
359
        copybuf(&spr2->x,&osprite[newspriteindex2].x,3);                    \
360
        show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7));      \
360
        show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7));      \
361
        if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7)))                    \
361
        if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7)))                    \
362
            show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7));   \
362
            show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7));   \
363
    }
363
    }
364
#endif
364
#endif
365
365
366
int osdcmd_restartvid(const osdfuncparm_t *parm)
366
int osdcmd_restartvid(const osdfuncparm_t *parm)
367
{
367
{
368
    UNREFERENCED_PARAMETER(parm);
368
    UNREFERENCED_PARAMETER(parm);
369
369
370
    videoResetMode();
370
    videoResetMode();
371
    if (videoSetGameMode(fullscreen, xdim, ydim, bpp, upscalefactor))
371
    if (videoSetGameMode(fullscreen, xdim, ydim, bpp, upscalefactor))
372
        buildputs("restartvid: Reset failed...\n");
372
        buildputs("restartvid: Reset failed...\n");
373
373
374
    return OSDCMD_OK;
374
    return OSDCMD_OK;
375
}
375
}
376
376
377
static int osdcmd_vidmode(const osdfuncparm_t *parm)
377
static int osdcmd_vidmode(const osdfuncparm_t *parm)
378
{
378
{
379
    int newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen;
379
    int newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen;
380
380
381
    if (parm->numparms < 1 || parm->numparms > 4) return OSDCMD_SHOWHELP;
381
    if (parm->numparms < 1 || parm->numparms > 4) return OSDCMD_SHOWHELP;
382
382
383
    switch (parm->numparms)
383
    switch (parm->numparms)
384
    {
384
    {
385
    case 1:   // bpp switch
385
    case 1:   // bpp switch
386
        newbpp = Batol(parm->parms[0]);
386
        newbpp = Batol(parm->parms[0]);
387
        break;
387
        break;
388
    case 2: // res switch
388
    case 2: // res switch
389
        newx = Batol(parm->parms[0]);
389
        newx = Batol(parm->parms[0]);
390
        newy = Batol(parm->parms[1]);
390
        newy = Batol(parm->parms[1]);
391
        break;
391
        break;
392
    case 3:   // res & bpp switch
392
    case 3:   // res & bpp switch
393
    case 4:
393
    case 4:
394
        newx = Batol(parm->parms[0]);
394
        newx = Batol(parm->parms[0]);
395
        newy = Batol(parm->parms[1]);
395
        newy = Batol(parm->parms[1]);
396
        newbpp = Batol(parm->parms[2]);
396
        newbpp = Batol(parm->parms[2]);
397
        if (parm->numparms == 4)
397
        if (parm->numparms == 4)
398
            newfullscreen = (Batol(parm->parms[3]) != 0);
398
            newfullscreen = (Batol(parm->parms[3]) != 0);
399
        break;
399
        break;
400
    }
400
    }
401
401
402
    if (videoSetGameMode(newfullscreen, newx, newy, newbpp, upscalefactor))
402
    if (videoSetGameMode(newfullscreen, newx, newy, newbpp, upscalefactor))
403
        buildputs("vidmode: Mode change failed!\n");
403
        buildputs("vidmode: Mode change failed!\n");
404
    screensize = xdim+1;
404
    screensize = xdim+1;
405
    return OSDCMD_OK;
405
    return OSDCMD_OK;
406
}
406
}
407
407
408
static int osdcmd_map(const osdfuncparm_t *parm)
408
static int osdcmd_map(const osdfuncparm_t *parm)
409
{
409
{
410
    int i;
410
    int i;
411
    char *dot, namebuf[BMAX_PATH+1];
411
    char *dot, namebuf[BMAX_PATH+1];
412
412
413
    if (parm->numparms != 1) return OSDCMD_SHOWHELP;
413
    if (parm->numparms != 1) return OSDCMD_SHOWHELP;
414
414
415
    strncpy(namebuf, parm->parms[0], BMAX_PATH);
415
    strncpy(namebuf, parm->parms[0], BMAX_PATH);
416
    namebuf[BMAX_PATH] = 0;
416
    namebuf[BMAX_PATH] = 0;
417
    dot = strrchr(namebuf, '.');
417
    dot = strrchr(namebuf, '.');
418
    if ((!dot || Bstrcasecmp(dot, ".map")) && strlen(namebuf) <= BMAX_PATH-4)
418
    if ((!dot || Bstrcasecmp(dot, ".map")) && strlen(namebuf) <= BMAX_PATH-4)
419
    {
419
    {
420
        strcat(namebuf, ".map");
420
        strcat(namebuf, ".map");
421
    }
421
    }
422
422
423
    prepareboard(namebuf);
423
    prepareboard(namebuf);
424
424
425
    screenpeek = myconnectindex;
425
    screenpeek = myconnectindex;
426
    reccnt = 0;
426
    reccnt = 0;
427
    for (i=connecthead; i>=0; i=connectpoint2[i]) initplayersprite((short)i);
427
    for (i=connecthead; i>=0; i=connectpoint2[i]) initplayersprite((short)i);
428
428
429
    waitforeverybody();
429
    waitforeverybody();
430
    totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0;
430
    totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0;
431
431
432
    ready2send = 1;
432
    ready2send = 1;
433
    drawscreen(screenpeek,65536L);
433
    drawscreen(screenpeek,65536L);
434
434
435
    return OSDCMD_OK;
435
    return OSDCMD_OK;
436
}
436
}
437
437
438
static void Ken_UninitAll(void)
438
static void Ken_UninitAll(void)
439
{
439
{
440
    sendlogoff();         //Signing off
440
    sendlogoff();         //Signing off
441
    musicoff();
441
    musicoff();
442
    uninitmultiplayers();
442
    uninitmultiplayers();
443
    timerUninit();
443
    timerUninit();
444
    uninitinput();
444
    uninitinput();
445
    uninitsb();
445
    uninitsb();
446
    engineUnInit();
446
    engineUnInit();
447
    uninitgroupfile();
447
    uninitgroupfile();
448
}
448
}
449
449
450
static void Ken_FatalEngineError(void)
450
static void Ken_FatalEngineError(void)
451
{
451
{
452
    buildprintf("There was a problem initialising the engine: %s.\n", engineerrstr);
452
    buildprintf("There was a problem initialising the engine: %s.\n", engineerrstr);
453
}
453
}
454
454
455
int32_t app_main(int32_t argc, char const * const * argv)
455
int32_t app_main(int32_t argc, char const * const * argv)
456
{
456
{
457
#if defined STARTUP_SETUP_WINDOW
457
#if defined STARTUP_SETUP_WINDOW
458
    int cmdsetup = 0;
458
    int cmdsetup = 0;
459
#endif
459
#endif
460
    int i, j, k /*, l, fil, waitplayers, x1, y1, x2, y2*/;
460
    int i, j, k /*, l, fil, waitplayers, x1, y1, x2, y2*/;
461
    int /*other, packleng,*/ netparm;
461
    int /*other, packleng,*/ netparm;
462
462
463
    OSD_SetLogFile("ekenbuild.log");
463
    OSD_SetLogFile("ekenbuild.log");
464
464
465
    initprintf("%s %s\n", AppProperName, s_buildRev);
465
    initprintf("%s %s\n", AppProperName, s_buildRev);
466
    PrintBuildInfo();
466
    PrintBuildInfo();
467
467
468
    if (enginePreInit())
468
    if (enginePreInit())
469
    {
469
    {
470
        wm_msgbox("Build Engine Initialisation Error",
470
        wm_msgbox("Build Engine Initialisation Error",
471
                  "There was a problem initialising the Build engine: %s", engineerrstr);
471
                  "There was a problem initialising the Build engine: %s", engineerrstr);
472
        exit(1);
472
        exit(1);
473
    }
473
    }
474
474
475
#ifdef USE_OPENGL
475
#ifdef USE_OPENGL
476
    OSD_RegisterFunction("restartvid","restartvid: reinitialise the video mode",osdcmd_restartvid);
476
    OSD_RegisterFunction("restartvid","restartvid: reinitialise the video mode",osdcmd_restartvid);
477
    OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode);
477
    OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode);
478
    OSD_RegisterFunction("map", "map [filename]: load a map", osdcmd_map);
478
    OSD_RegisterFunction("map", "map [filename]: load a map", osdcmd_map);
479
#endif
479
#endif
480
480
481
    wm_setapptitle(AppProperName);
481
    wm_setapptitle(AppProperName);
482
482
483
    Bstrcpy(boardfilename, "nukeland.map");
483
    Bstrcpy(boardfilename, "nukeland.map");
484
    j = 0; netparm = argc;
484
    j = 0; netparm = argc;
485
    for (i=1; i<argc; i++)
485
    for (i=1; i<argc; i++)
486
    {
486
    {
487
        if ((!Bstrcasecmp("-net",argv[i])) || (!Bstrcasecmp("/net",argv[i]))) { j = 1; netparm = i; continue; }
487
        if ((!Bstrcasecmp("-net",argv[i])) || (!Bstrcasecmp("/net",argv[i]))) { j = 1; netparm = i; continue; }
488
        if (j)
488
        if (j)
489
        {
489
        {
490
            if (argv[i][0] == '-' || argv[i][0] == '/')
490
            if (argv[i][0] == '-' || argv[i][0] == '/')
491
            {
491
            {
492
                if (((argv[i][1] == 'n') || (argv[i][1] == 'N')) && (argv[i][2] == '0')) { networkmode = 0; continue; }
492
                if (((argv[i][1] == 'n') || (argv[i][1] == 'N')) && (argv[i][2] == '0')) { networkmode = 0; continue; }
493
                if (((argv[i][1] == 'n') || (argv[i][1] == 'N')) && (argv[i][2] == '1')) { networkmode = 1; continue; }
493
                if (((argv[i][1] == 'n') || (argv[i][1] == 'N')) && (argv[i][2] == '1')) { networkmode = 1; continue; }
494
            }
494
            }
495
            if (isvalidipaddress(argv[i])) continue;
495
            if (isvalidipaddress(argv[i])) continue;
496
        }
496
        }
497
        else
497
        else
498
        {
498
        {
499
            if (!Bstrcasecmp(argv[i], "-setup"))
499
            if (!Bstrcasecmp(argv[i], "-setup"))
500
            {
500
            {
501
#if defined STARTUP_SETUP_WINDOW
501
#if defined STARTUP_SETUP_WINDOW
502
                cmdsetup = 1;
502
                cmdsetup = 1;
503
#endif
503
#endif
504
            }
504
            }
505
            else
505
            else
506
            {
506
            {
507
                Bstrcpy(boardfilename, argv[i]);
507
                Bstrcpy(boardfilename, argv[i]);
508
                if (!Bstrrchr(boardfilename,'.')) Bstrcat(boardfilename,".map");
508
                if (!Bstrrchr(boardfilename,'.')) Bstrcat(boardfilename,".map");
509
            }
509
            }
510
        }
510
        }
511
    }
511
    }
512
512
513
    if ((i = Ken_loadsetup(setupfilename)) < 0)
513
    if ((i = Ken_loadsetup(setupfilename)) < 0)
514
        buildputs("Configuration file not found, using defaults.\n");
514
        buildputs("Configuration file not found, using defaults.\n");
515
515
516
    wm_msgbox("Pre-Release Software Warning", "%s is not ready for public use. Proceed with caution!", AppProperName);
516
    wm_msgbox("Pre-Release Software Warning", "%s is not ready for public use. Proceed with caution!", AppProperName);
517
517
518
#if defined STARTUP_SETUP_WINDOW
518
#if defined STARTUP_SETUP_WINDOW
519
    if (i || forcesetup || cmdsetup)
519
    if (i || forcesetup || cmdsetup)
520
    {
520
    {
521
        if (quitevent || !startwin_run()) return -1;
521
        if (quitevent || !startwin_run()) return -1;
522
    }
522
    }
523
#endif
523
#endif
524
    Ken_writesetup(setupfilename);
524
    Ken_writesetup(setupfilename);
525
525
526
    initgroupfile(G_GrpFile());
526
    initgroupfile(G_GrpFile());
527
    if (engineInit())
527
    if (engineInit())
528
    {
528
    {
529
        Ken_FatalEngineError();
529
        Ken_FatalEngineError();
530
        return -1;
530
        return -1;
531
    }
531
    }
532
532
533
    Ken_PostStartupWindow();
533
    Ken_PostStartupWindow();
534
534
535
    initinput();
535
    initinput();
536
    if (option[3] != 0) mouseInit();
536
    if (option[3] != 0) mouseInit();
537
    timerInit(TIMERINTSPERSECOND);
537
    timerInit(TIMERINTSPERSECOND);
538
538
539
    //initmultiplayers(argc-netparm,&argv[netparm],option[4],option[5],0);
539
    //initmultiplayers(argc-netparm,&argv[netparm],option[4],option[5],0);
540
    if (initmultiplayersparms(argc-netparm,&argv[netparm]))
540
    if (initmultiplayersparms(argc-netparm,&argv[netparm]))
541
    {
541
    {
542
        buildputs("Waiting for players...\n");
542
        buildputs("Waiting for players...\n");
543
        while (initmultiplayerscycle())
543
        while (initmultiplayerscycle())
544
        {
544
        {
545
            handleevents();
545
            handleevents();
546
            if (quitevent)
546
            if (quitevent)
547
            {
547
            {
548
                Ken_UninitAll();
548
                Ken_UninitAll();
549
                return 0;
549
                return 0;
550
            }
550
            }
551
        }
551
        }
552
    }
552
    }
553
    option[4] = (numplayers >= 2);
553
    option[4] = (numplayers >= 2);
554
554
555
    artLoadFiles("tiles000.art",1048576);                      //Load artwork
555
    artLoadFiles("tiles000.art",1048576);                      //Load artwork
556
    Ken_LoadVoxels();
556
    Ken_LoadVoxels();
557
    if (!loaddefinitionsfile(G_DefFile())) buildputs("Definitions file loaded.\n");
557
    if (!loaddefinitionsfile(G_DefFile())) buildputs("Definitions file loaded.\n");
558
558
559
    if (enginePostInit())
559
    if (enginePostInit())
560
    {
560
    {
561
        Ken_UninitAll();
561
        Ken_UninitAll();
562
        Ken_FatalEngineError();
562
        Ken_FatalEngineError();
563
        return -1;
563
        return -1;
564
    }
564
    }
565
565
566
    OSD_SetFunctions(
566
    OSD_SetFunctions(
567
        NULL, NULL, NULL, NULL, NULL,
567
        NULL, NULL, NULL, NULL, NULL,
568
        COMMON_clearbackground,
568
        COMMON_clearbackground,
569
        BGetTime,
569
        BGetTime,
570
        NULL
570
        NULL
571
        );
571
        );
572
572
573
    {
573
    {
574
        char tempbuf[256];
574
        char tempbuf[256];
575
        snprintf(tempbuf, ARRAY_SIZE(tempbuf), "%s %s", AppProperName, s_buildRev);
575
        snprintf(tempbuf, ARRAY_SIZE(tempbuf), "%s %s", AppProperName, s_buildRev);
576
        OSD_SetVersion(tempbuf, 10,0);
576
        OSD_SetVersion(tempbuf, 10,0);
577
    }
577
    }
578
    OSD_SetParameters(0,2, 0,0, 4,0, 0, 0, 0); // TODO: Add error and red palookup IDs.
578
    OSD_SetParameters(0,2, 0,0, 4,0, 0, 0, 0); // TODO: Add error and red palookup IDs.
579
579
580
    //Here's an example of TRUE ornamented walls
580
    //Here's an example of TRUE ornamented walls
581
    //The tileCreate should be called right after artLoadFiles
581
    //The tileCreate should be called right after artLoadFiles
582
    //Since it resets the tile cache for each call.
582
    //Since it resets the tile cache for each call.
583
    if (tileCreate(SLIME,128,128) == 0)    //If enough memory
583
    if (tileCreate(SLIME,128,128) == 0)    //If enough memory
584
    {
584
    {
585
        buildputs("Not enough memory for slime!\n");
585
        buildputs("Not enough memory for slime!\n");
586
        exit(0);
586
        exit(0);
587
    }
587
    }
588
    if (tileCreate(MAXTILES-1,64,64) != 0)    //If enough memory
588
    if (tileCreate(MAXTILES-1,64,64) != 0)    //If enough memory
589
    {
589
    {
590
        //My face with an explosion written over it
590
        //My face with an explosion written over it
591
        tileCopySection(KENPICTURE,0,0,64,64,MAXTILES-1,0,0);
591
        tileCopySection(KENPICTURE,0,0,64,64,MAXTILES-1,0,0);
592
        tileCopySection(EXPLOSION,0,0,64,64,MAXTILES-1,0,0);
592
        tileCopySection(EXPLOSION,0,0,64,64,MAXTILES-1,0,0);
593
    }
593
    }
594
594
595
    initlava();
595
    initlava();
596
596
597
    palettePostLoadLookups();
597
    palettePostLoadLookups();
598
598
599
    prepareboard(boardfilename);                   //Load board
599
    prepareboard(boardfilename);                   //Load board
600
600
601
    initsb(option[1],option[2],digihz[option[7]>>4],((option[7]&4)>0)+1,((option[7]&2)>0)+1,60,option[7]&1);
601
    initsb(option[1],option[2],digihz[option[7]>>4],((option[7]&4)>0)+1,((option[7]&2)>0)+1,60,option[7]&1);
602
    //if (Bstrcmp(boardfilename,"klab.map") == 0)
602
    //if (Bstrcmp(boardfilename,"klab.map") == 0)
603
    //   loadsong("klabsong.kdm");
603
    //   loadsong("klabsong.kdm");
604
    //else
604
    //else
605
    loadsong("neatsong.kdm");
605
    loadsong("neatsong.kdm");
606
    musicon();
606
    musicon();
607
607
608
#if 0
608
#if 0
609
    if (option[4] > 0)
609
    if (option[4] > 0)
610
    {
610
    {
611
        x1 = ((xdim-screensize)>>1);
611
        x1 = ((xdim-screensize)>>1);
612
        x2 = x1+screensize-1;
612
        x2 = x1+screensize-1;
613
        y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1);
613
        y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1);
614
        y2 = y1 + scale(screensize,ydim-32,xdim)-1;
614
        y2 = y1 + scale(screensize,ydim-32,xdim)-1;
615
615
616
        drawtilebackground(/*0L,0L,*/ BACKGROUND,8,x1,y1,x2,y2,0);
616
        drawtilebackground(/*0L,0L,*/ BACKGROUND,8,x1,y1,x2,y2,0);
617
617
618
        sendlogon();
618
        sendlogon();
619
619
620
        if (option[4] < 5) waitplayers = 2; else waitplayers = option[4]-3;
620
        if (option[4] < 5) waitplayers = 2; else waitplayers = option[4]-3;
621
        while (numplayers < waitplayers)
621
        while (numplayers < waitplayers)
622
        {
622
        {
623
            sprintf(tempbuf,"%ld of %ld players in...",numplayers,waitplayers);
623
            sprintf(tempbuf,"%ld of %ld players in...",numplayers,waitplayers);
624
            printext256(68L,84L,31,0,tempbuf,0);
624
            printext256(68L,84L,31,0,tempbuf,0);
625
            videoNextPage();
625
            videoNextPage();
626
626
627
            if (getpacket(&other,packbuf) > 0)
627
            if (getpacket(&other,packbuf) > 0)
628
                if (packbuf[0] == 255)
628
                if (packbuf[0] == 255)
629
                    keystatus[1] = 1;
629
                    keystatus[1] = 1;
630
630
631
            if (handleevents())
631
            if (handleevents())
632
            {
632
            {
633
                if (quitevent)
633
                if (quitevent)
634
                {
634
                {
635
                    keystatus[1] = 1;
635
                    keystatus[1] = 1;
636
                    quitevent = 0;
636
                    quitevent = 0;
637
                }
637
                }
638
            }
638
            }
639
639
640
            if (keystatus[1])
640
            if (keystatus[1])
641
            {
641
            {
642
                Ken_UninitAll();
642
                Ken_UninitAll();
643
                return 0;
643
                return 0;
644
            }
644
            }
645
        }
645
        }
646
        screenpeek = myconnectindex;
646
        screenpeek = myconnectindex;
647
647
648
        if (numplayers <= 3)
648
        if (numplayers <= 3)
649
            networkmode = 1;
649
            networkmode = 1;
650
        else
650
        else
651
            networkmode = 0;
651
            networkmode = 0;
652
652
653
        j = 1;
653
        j = 1;
654
        for (i=connecthead; i>=0; i=connectpoint2[i])
654
        for (i=connecthead; i>=0; i=connectpoint2[i])
655
        {
655
        {
656
            if (myconnectindex == i) break;
656
            if (myconnectindex == i) break;
657
            j++;
657
            j++;
658
        }
658
        }
659
        sprintf(getmessage,"Player %ld",j);
659
        sprintf(getmessage,"Player %ld",j);
660
        if (networkmode == 0)
660
        if (networkmode == 0)
661
        {
661
        {
662
            if (j == 1) Bstrcat(getmessage," (Master)");
662
            if (j == 1) Bstrcat(getmessage," (Master)");
663
            else Bstrcat(getmessage," (Slave)");
663
            else Bstrcat(getmessage," (Slave)");
664
        }
664
        }
665
        else
665
        else
666
            Bstrcat(getmessage," (Even)");
666
            Bstrcat(getmessage," (Even)");
667
        getmessageleng = Bstrlen(getmessage);
667
        getmessageleng = Bstrlen(getmessage);
668
        getmessagetimeoff = totalclock+120;
668
        getmessagetimeoff = totalclock+120;
669
    }
669
    }
670
#endif
670
#endif
671
    screenpeek = myconnectindex;
671
    screenpeek = myconnectindex;
672
    reccnt = 0;
672
    reccnt = 0;
673
    for (i=connecthead; i>=0; i=connectpoint2[i]) initplayersprite((short)i);
673
    for (i=connecthead; i>=0; i=connectpoint2[i]) initplayersprite((short)i);
674
674
675
    waitforeverybody();
675
    waitforeverybody();
676
    totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0;
676
    totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0;
677
677
678
    ready2send = 1;
678
    ready2send = 1;
679
    drawscreen(screenpeek,65536L);
679
    drawscreen(screenpeek,65536L);
680
680
681
    while (!keystatus[1])       //Main loop starts here
681
    while (!keystatus[1])       //Main loop starts here
682
    {
682
    {
683
        if (handleevents())
683
        if (handleevents())
684
        {
684
        {
685
            if (quitevent)
685
            if (quitevent)
686
            {
686
            {
687
                keystatus[1] = 1;
687
                keystatus[1] = 1;
688
                quitevent = 0;
688
                quitevent = 0;
689
            }
689
            }
690
        }
690
        }
691
691
692
        refreshaudio();
692
        refreshaudio();
693
        OSD_DispatchQueued();
693
        OSD_DispatchQueued();
694
694
695
        // backslash (useful only with KDM)
695
        // backslash (useful only with KDM)
696
//      if (keystatus[0x2b]) { keystatus[0x2b] = 0; preparesndbuf(); }
696
//      if (keystatus[0x2b]) { keystatus[0x2b] = 0; preparesndbuf(); }
697
697
698
        if ((networkmode == 1) || (myconnectindex != connecthead))
698
        if ((networkmode == 1) || (myconnectindex != connecthead))
699
            while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings();
699
            while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings();
700
700
701
        getpackets();
701
        getpackets();
702
702
703
        if (typemode == 0)           //if normal game keys active
703
        if (typemode == 0)           //if normal game keys active
704
        {
704
        {
705
            if ((keystatus[0x2a]&keystatus[0x36]&keystatus[0x13]) > 0)   //Sh.Sh.R (replay)
705
            if ((keystatus[0x2a]&keystatus[0x36]&keystatus[0x13]) > 0)   //Sh.Sh.R (replay)
706
            {
706
            {
707
                keystatus[0x13] = 0;
707
                keystatus[0x13] = 0;
708
                playback();
708
                playback();
709
            }
709
            }
710
710
711
            if (keystatus[0x26]&(keystatus[0x1d]|keystatus[0x9d])) //Load game
711
            if (keystatus[0x26]&(keystatus[0x1d]|keystatus[0x9d])) //Load game
712
            {
712
            {
713
                keystatus[0x26] = 0;
713
                keystatus[0x26] = 0;
714
                loadgame();
714
                loadgame();
715
                drawstatusbar(screenpeek);   // Andy did this
715
                drawstatusbar(screenpeek);   // Andy did this
716
            }
716
            }
717
717
718
            if (keystatus[0x1f]&(keystatus[0x1d]|keystatus[0x9d])) //Save game
718
            if (keystatus[0x1f]&(keystatus[0x1d]|keystatus[0x9d])) //Save game
719
            {
719
            {
720
                keystatus[0x1f] = 0;
720
                keystatus[0x1f] = 0;
721
                savegame();
721
                savegame();
722
            }
722
            }
723
        }
723
        }
724
724
725
        if ((networkmode == 0) || (option[4] == 0))
725
        if ((networkmode == 0) || (option[4] == 0))
726
        {
726
        {
727
            while (movefifoplc != movefifoend[0]) domovethings();
727
            while (movefifoplc != movefifoend[0]) domovethings();
728
        }
728
        }
729
        else
729
        else
730
        {
730
        {
731
            j = connecthead;
731
            j = connecthead;
732
            if (j == myconnectindex) j = connectpoint2[j];
732
            if (j == myconnectindex) j = connectpoint2[j];
733
            averagelag[j] = ((averagelag[j]*7+(((movefifoend[myconnectindex]-movefifoend[j]+otherlag[j]+2)&255)<<8))>>3);
733
            averagelag[j] = ((averagelag[j]*7+(((movefifoend[myconnectindex]-movefifoend[j]+otherlag[j]+2)&255)<<8))>>3);
734
            j = max(averagelag[j]>>9,1);
734
            j = max(averagelag[j]>>9,1);
735
            while (((movefifoend[myconnectindex]-movefifoplc)&(MOVEFIFOSIZ-1)) > j)
735
            while (((movefifoend[myconnectindex]-movefifoplc)&(MOVEFIFOSIZ-1)) > j)
736
            {
736
            {
737
                for (i=connecthead; i>=0; i=connectpoint2[i])
737
                for (i=connecthead; i>=0; i=connectpoint2[i])
738
                    if (movefifoplc == movefifoend[i]) break;
738
                    if (movefifoplc == movefifoend[i]) break;
739
                if (i >= 0) break;
739
                if (i >= 0) break;
740
                if (myconnectindex != connecthead)
740
                if (myconnectindex != connecthead)
741
                {
741
                {
742
                    k = ((movefifoend[myconnectindex]-movefifoend[connecthead]-otherlag[connecthead]+128)&255);
742
                    k = ((movefifoend[myconnectindex]-movefifoend[connecthead]-otherlag[connecthead]+128)&255);
743
                    if (k > 128+1) ototalclock++;
743
                    if (k > 128+1) ototalclock++;
744
                    if (k < 128-1) ototalclock--;
744
                    if (k < 128-1) ototalclock--;
745
                }
745
                }
746
                domovethings();
746
                domovethings();
747
            }
747
            }
748
        }
748
        }
749
        i = ((int32_t) totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND));
749
        i = ((int32_t) totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND));
750
750
751
        drawscreen(screenpeek,i);
751
        drawscreen(screenpeek,i);
752
    }
752
    }
753
753
754
    Ken_UninitAll();
754
    Ken_UninitAll();
755
755
756
    return 0;
756
    return 0;
757
}
757
}
758
758
759
void operatesector(short dasector)
759
void operatesector(short dasector)
760
{
760
{
761
    //Door code
761
    //Door code
762
    int i, j, /*k, s, nexti, good, cnt,*/ datag;
762
    int i, j, /*k, s, nexti, good, cnt,*/ datag;
763
    int /*dax, day,*/ daz, dax2, day2, /*daz2,*/ centx, centy;
763
    int /*dax, day,*/ daz, dax2, day2, /*daz2,*/ centx, centy;
764
    short startwall, endwall, wallfind[2];
764
    short startwall, endwall, wallfind[2];
765
765
766
    datag = sector[dasector].lotag;
766
    datag = sector[dasector].lotag;
767
767
768
    startwall = sector[dasector].wallptr;
768
    startwall = sector[dasector].wallptr;
769
    endwall = startwall + sector[dasector].wallnum;
769
    endwall = startwall + sector[dasector].wallnum;
770
    centx = 0L, centy = 0L;
770
    centx = 0L, centy = 0L;
771
    for (i=startwall; i<endwall; i++)
771
    for (i=startwall; i<endwall; i++)
772
    {
772
    {
773
        centx += wall[i].x;
773
        centx += wall[i].x;
774
        centy += wall[i].y;
774
        centy += wall[i].y;
775
    }
775
    }
776
    centx /= (endwall-startwall);
776
    centx /= (endwall-startwall);
777
    centy /= (endwall-startwall);
777
    centy /= (endwall-startwall);
778
778
779
    //Simple door that moves up  (tag 8 is a combination of tags 6 & 7)
779
    //Simple door that moves up  (tag 8 is a combination of tags 6 & 7)
780
    if ((datag == 6) || (datag == 8))    //If the sector in front is a door
780
    if ((datag == 6) || (datag == 8))    //If the sector in front is a door
781
    {
781
    {
782
        i = getanimationgoal(&sector[dasector].ceilingz);
782
        i = getanimationgoal(&sector[dasector].ceilingz);
783
        if (i >= 0)      //If door already moving, reverse its direction
783
        if (i >= 0)      //If door already moving, reverse its direction
784
        {
784
        {
785
            if (datag == 8)
785
            if (datag == 8)
786
                daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
786
                daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
787
            else
787
            else
788
                daz = sector[dasector].floorz;
788
                daz = sector[dasector].floorz;
789
789
790
            if (animategoal[i] == daz)
790
            if (animategoal[i] == daz)
791
                animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz;
791
                animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz;
792
            else
792
            else
793
                animategoal[i] = daz;
793
                animategoal[i] = daz;
794
            animatevel[i] = 0;
794
            animatevel[i] = 0;
795
        }
795
        }
796
        else      //else insert the door's ceiling on the animation list
796
        else      //else insert the door's ceiling on the animation list
797
        {
797
        {
798
            if (sector[dasector].ceilingz == sector[dasector].floorz)
798
            if (sector[dasector].ceilingz == sector[dasector].floorz)
799
                daz = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz;
799
                daz = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz;
800
            else
800
            else
801
            {
801
            {
802
                if (datag == 8)
802
                if (datag == 8)
803
                    daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
803
                    daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
804
                else
804
                else
805
                    daz = sector[dasector].floorz;
805
                    daz = sector[dasector].floorz;
806
            }
806
            }
807
            if ((j = setanimation(&sector[dasector].ceilingz,daz,6L,6L)) >= 0)
807
            if ((j = setanimation(&sector[dasector].ceilingz,daz,6L,6L)) >= 0)
808
                wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,&centx,&centy,0);
808
                wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,&centx,&centy,0);
809
        }
809
        }
810
    }
810
    }
811
    //Simple door that moves down
811
    //Simple door that moves down
812
    if ((datag == 7) || (datag == 8)) //If the sector in front's elevator
812
    if ((datag == 7) || (datag == 8)) //If the sector in front's elevator
813
    {
813
    {
814
        i = getanimationgoal(&sector[dasector].floorz);
814
        i = getanimationgoal(&sector[dasector].floorz);
815
        if (i >= 0)      //If elevator already moving, reverse its direction
815
        if (i >= 0)      //If elevator already moving, reverse its direction
816
        {
816
        {
817
            if (datag == 8)
817
            if (datag == 8)
818
                daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
818
                daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
819
            else
819
            else
820
                daz = sector[dasector].ceilingz;
820
                daz = sector[dasector].ceilingz;
821
821
822
            if (animategoal[i] == daz)
822
            if (animategoal[i] == daz)
823
                animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz;
823
                animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz;
824
            else
824
            else
825
                animategoal[i] = daz;
825
                animategoal[i] = daz;
826
            animatevel[i] = 0;
826
            animatevel[i] = 0;
827
        }
827
        }
828
        else      //else insert the elevator's ceiling on the animation list
828
        else      //else insert the elevator's ceiling on the animation list
829
        {
829
        {
830
            if (sector[dasector].floorz == sector[dasector].ceilingz)
830
            if (sector[dasector].floorz == sector[dasector].ceilingz)
831
                daz = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz;
831
                daz = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz;
832
            else
832
            else
833
            {
833
            {
834
                if (datag == 8)
834
                if (datag == 8)
835
                    daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
835
                    daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
836
                else
836
                else
837
                    daz = sector[dasector].ceilingz;
837
                    daz = sector[dasector].ceilingz;
838
            }
838
            }
839
            if ((j = setanimation(&sector[dasector].floorz,daz,6L,6L)) >= 0)
839
            if ((j = setanimation(&sector[dasector].floorz,daz,6L,6L)) >= 0)
840
                wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,&centx,&centy,0);
840
                wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,&centx,&centy,0);
841
        }
841
        }
842
    }
842
    }
843
843
844
    if (datag == 9)   //Smooshy-wall sideways double-door
844
    if (datag == 9)   //Smooshy-wall sideways double-door
845
    {
845
    {
846
        //find any points with either same x or same y coordinate
846
        //find any points with either same x or same y coordinate
847
        //  as center (centx, centy) - should be 2 points found.
847
        //  as center (centx, centy) - should be 2 points found.
848
        wallfind[0] = -1;
848
        wallfind[0] = -1;
849
        wallfind[1] = -1;
849
        wallfind[1] = -1;
850
        for (i=startwall; i<endwall; i++)
850
        for (i=startwall; i<endwall; i++)
851
            if ((wall[i].x == centx) || (wall[i].y == centy))
851
            if ((wall[i].x == centx) || (wall[i].y == centy))
852
            {
852
            {
853
                if (wallfind[0] == -1)
853
                if (wallfind[0] == -1)
854
                    wallfind[0] = i;
854
                    wallfind[0] = i;
855
                else
855
                else
856
                    wallfind[1] = i;
856
                    wallfind[1] = i;
857
            }
857
            }
858
858
859
        for (j=0; j<2; j++)
859
        for (j=0; j<2; j++)
860
        {
860
        {
861
            if ((wall[wallfind[j]].x == centx) && (wall[wallfind[j]].y == centy))
861
            if ((wall[wallfind[j]].x == centx) && (wall[wallfind[j]].y == centy))
862
            {
862
            {
863
                //find what direction door should open by averaging the
863
                //find what direction door should open by averaging the
864
                //  2 neighboring points of wallfind[0] & wallfind[1].
864
                //  2 neighboring points of wallfind[0] & wallfind[1].
865
                i = wallfind[j]-1; if (i < startwall) i = endwall-1;
865
                i = wallfind[j]-1; if (i < startwall) i = endwall-1;
866
                dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
866
                dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
867
                day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
867
                day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
868
                if (dax2 != 0)
868
                if (dax2 != 0)
869
                {
869
                {
870
                    dax2 = wall[wall[wall[wallfind[j]].point2].point2].x;
870
                    dax2 = wall[wall[wall[wallfind[j]].point2].point2].x;
871
                    dax2 -= wall[wall[wallfind[j]].point2].x;
871
                    dax2 -= wall[wall[wallfind[j]].point2].x;
872
                    setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L);
872
                    setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L);
873
                    setanimation(&wall[i].x,wall[i].x+dax2,4L,0L);
873
                    setanimation(&wall[i].x,wall[i].x+dax2,4L,0L);
874
                    setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L);
874
                    setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L);
875
                }
875
                }
876
                else if (day2 != 0)
876
                else if (day2 != 0)
877
                {
877
                {
878
                    day2 = wall[wall[wall[wallfind[j]].point2].point2].y;
878
                    day2 = wall[wall[wall[wallfind[j]].point2].point2].y;
879
                    day2 -= wall[wall[wallfind[j]].point2].y;
879
                    day2 -= wall[wall[wallfind[j]].point2].y;
880
                    setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L);
880
                    setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L);
881
                    setanimation(&wall[i].y,wall[i].y+day2,4L,0L);
881
                    setanimation(&wall[i].y,wall[i].y+day2,4L,0L);
882
                    setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L);
882
                    setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L);
883
                }
883
                }
884
            }
884
            }
885
            else
885
            else
886
            {
886
            {
887
                i = wallfind[j]-1; if (i < startwall) i = endwall-1;
887
                i = wallfind[j]-1; if (i < startwall) i = endwall-1;
888
                dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
888
                dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
889
                day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
889
                day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
890
                if (dax2 != 0)
890
                if (dax2 != 0)
891
                {
891
                {
892
                    setanimation(&wall[wallfind[j]].x,centx,4L,0L);
892
                    setanimation(&wall[wallfind[j]].x,centx,4L,0L);
893
                    setanimation(&wall[i].x,centx+dax2,4L,0L);
893
                    setanimation(&wall[i].x,centx+dax2,4L,0L);
894
                    setanimation(&wall[wall[wallfind[j]].point2].x,centx+dax2,4L,0L);
894
                    setanimation(&wall[wall[wallfind[j]].point2].x,centx+dax2,4L,0L);
895
                }
895
                }
896
                else if (day2 != 0)
896
                else if (day2 != 0)
897
                {
897
                {
898
                    setanimation(&wall[wallfind[j]].y,centy,4L,0L);
898
                    setanimation(&wall[wallfind[j]].y,centy,4L,0L);
899
                    setanimation(&wall[i].y,centy+day2,4L,0L);
899
                    setanimation(&wall[i].y,centy+day2,4L,0L);
900
                    setanimation(&wall[wall[wallfind[j]].point2].y,centy+day2,4L,0L);
900
                    setanimation(&wall[wall[wallfind[j]].point2].y,centy+day2,4L,0L);
901
                }
901
                }
902
            }
902
            }
903
        }
903
        }
904
        wsayfollow("updowndr.wav",4096L-256L,256L,&centx,&centy,0);
904
        wsayfollow("updowndr.wav",4096L-256L,256L,&centx,&centy,0);
905
        wsayfollow("updowndr.wav",4096L+256L,256L,&centx,&centy,0);
905
        wsayfollow("updowndr.wav",4096L+256L,256L,&centx,&centy,0);
906
    }
906
    }
907
907
908
    if (datag == 13)  //Swinging door
908
    if (datag == 13)  //Swinging door
909
    {
909
    {
910
        for (i=0; i<swingcnt; i++)
910
        for (i=0; i<swingcnt; i++)
911
        {
911
        {
912
            if (swingsector[i] == dasector)
912
            if (swingsector[i] == dasector)
913
            {
913
            {
914
                if (swinganginc[i] == 0)
914
                if (swinganginc[i] == 0)
915
                {
915
                {
916
                    if (swingang[i] == swingangclosed[i])
916
                    if (swingang[i] == swingangclosed[i])
917
                    {
917
                    {
918
                        swinganginc[i] = swingangopendir[i];
918
                        swinganginc[i] = swingangopendir[i];
919
                        wsayfollow("opendoor.wav",4096L+(krand()&511)-256,256L,&centx,&centy,0);
919
                        wsayfollow("opendoor.wav",4096L+(krand()&511)-256,256L,&centx,&centy,0);
920
                    }
920
                    }
921
                    else
921
                    else
922
                        swinganginc[i] = -swingangopendir[i];
922
                        swinganginc[i] = -swingangopendir[i];
923
                }
923
                }
924
                else
924
                else
925
                    swinganginc[i] = -swinganginc[i];
925
                    swinganginc[i] = -swinganginc[i];
926
926
927
                for (j=1; j<=3; j++)
927
                for (j=1; j<=3; j++)
928
                {
928
                {
929
                    setinterpolation(&wall[swingwall[i][j]].x);
929
                    setinterpolation(&wall[swingwall[i][j]].x);
930
                    setinterpolation(&wall[swingwall[i][j]].y);
930
                    setinterpolation(&wall[swingwall[i][j]].y);
931
                }
931
                }
932
            }
932
            }
933
        }
933
        }
934
    }
934
    }
935
935
936
    if (datag == 16)  //True sideways double-sliding door
936
    if (datag == 16)  //True sideways double-sliding door
937
    {
937
    {
938
        //get 2 closest line segments to center (dax, day)
938
        //get 2 closest line segments to center (dax, day)
939
        wallfind[0] = -1;
939
        wallfind[0] = -1;
940
        wallfind[1] = -1;
940
        wallfind[1] = -1;
941
        for (i=startwall; i<endwall; i++)
941
        for (i=startwall; i<endwall; i++)
942
            if (wall[i].lotag == 6)
942
            if (wall[i].lotag == 6)
943
            {
943
            {
944
                if (wallfind[0] == -1)
944
                if (wallfind[0] == -1)
945
                    wallfind[0] = i;
945
                    wallfind[0] = i;
946
                else
946
                else
947
                    wallfind[1] = i;
947
                    wallfind[1] = i;
948
            }
948
            }
949
949
950
        for (j=0; j<2; j++)
950
        for (j=0; j<2; j++)
951
        {
951
        {
952
            if ((((wall[wallfind[j]].x+wall[wall[wallfind[j]].point2].x)>>1) == centx) && (((wall[wallfind[j]].y+wall[wall[wallfind[j]].point2].y)>>1) == centy))
952
            if ((((wall[wallfind[j]].x+wall[wall[wallfind[j]].point2].x)>>1) == centx) && (((wall[wallfind[j]].y+wall[wall[wallfind[j]].point2].y)>>1) == centy))
953
            {
953
            {
954
                //door was closed
954
                //door was closed
955
                //find what direction door should open
955
                //find what direction door should open
956
                i = wallfind[j]-1; if (i < startwall) i = endwall-1;
956
                i = wallfind[j]-1; if (i < startwall) i = endwall-1;
957
                dax2 = wall[i].x-wall[wallfind[j]].x;
957
                dax2 = wall[i].x-wall[wallfind[j]].x;
958
                day2 = wall[i].y-wall[wallfind[j]].y;
958
                day2 = wall[i].y-wall[wallfind[j]].y;
959
                if (dax2 != 0)
959
                if (dax2 != 0)
960
                {
960
                {
961
                    dax2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].x;
961
                    dax2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].x;
962
                    dax2 -= wall[wall[wall[wallfind[j]].point2].point2].x;
962
                    dax2 -= wall[wall[wall[wallfind[j]].point2].point2].x;
963
                    setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L);
963
                    setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L);
964
                    setanimation(&wall[i].x,wall[i].x+dax2,4L,0L);
964
                    setanimation(&wall[i].x,wall[i].x+dax2,4L,0L);
965
                    setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L);
965
                    setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L);
966
                    setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,wall[wall[wall[wallfind[j]].point2].point2].x+dax2,4L,0L);
966
                    setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,wall[wall[wall[wallfind[j]].point2].point2].x+dax2,4L,0L);
967
                }
967
                }
968
                else if (day2 != 0)
968
                else if (day2 != 0)
969
                {
969
                {
970
                    day2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].y;
970
                    day2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].y;
971
                    day2 -= wall[wall[wall[wallfind[j]].point2].point2].y;
971
                    day2 -= wall[wall[wall[wallfind[j]].point2].point2].y;
972
                    setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L);
972
                    setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L);
973
                    setanimation(&wall[i].y,wall[i].y+day2,4L,0L);
973
                    setanimation(&wall[i].y,wall[i].y+day2,4L,0L);
974
                    setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L);
974
                    setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L);
975
                    setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,wall[wall[wall[wallfind[j]].point2].point2].y+day2,4L,0L);
975
                    setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,wall[wall[wall[wallfind[j]].point2].point2].y+day2,4L,0L);
976
                }
976
                }
977
            }
977
            }
978
            else
978
            else
979
            {
979
            {
980
                //door was not closed
980
                //door was not closed
981
                i = wallfind[j]-1; if (i < startwall) i = endwall-1;
981
                i = wallfind[j]-1; if (i < startwall) i = endwall-1;
982
                dax2 = wall[i].x-wall[wallfind[j]].x;
982
                dax2 = wall[i].x-wall[wallfind[j]].x;
983
                day2 = wall[i].y-wall[wallfind[j]].y;
983
                day2 = wall[i].y-wall[wallfind[j]].y;
984
                if (dax2 != 0)
984
                if (dax2 != 0)
985
                {
985
                {
986
                    setanimation(&wall[wallfind[j]].x,centx,4L,0L);
986
                    setanimation(&wall[wallfind[j]].x,centx,4L,0L);
987
                    setanimation(&wall[i].x,centx+dax2,4L,0L);
987
                    setanimation(&wall[i].x,centx+dax2,4L,0L);
988
                    setanimation(&wall[wall[wallfind[j]].point2].x,centx,4L,0L);
988
                    setanimation(&wall[wall[wallfind[j]].point2].x,centx,4L,0L);
989
                    setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,centx+dax2,4L,0L);
989
                    setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,centx+dax2,4L,0L);
990
                }
990
                }
991
                else if (day2 != 0)
991
                else if (day2 != 0)
992
                {
992
                {
993
                    setanimation(&wall[wallfind[j]].y,centy,4L,0L);
993
                    setanimation(&wall[wallfind[j]].y,centy,4L,0L);
994
                    setanimation(&wall[i].y,centy+day2,4L,0L);
994
                    setanimation(&wall[i].y,centy+day2,4L,0L);
995
                    setanimation(&wall[wall[wallfind[j]].point2].y,centy,4L,0L);
995
                    setanimation(&wall[wall[wallfind[j]].point2].y,centy,4L,0L);
996
                    setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,centy+day2,4L,0L);
996
                    setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,centy+day2,4L,0L);
997
                }
997
                }
998
            }
998
            }
999
        }
999
        }
1000
        wsayfollow("updowndr.wav",4096L-64L,256L,&centx,&centy,0);
1000
        wsayfollow("updowndr.wav",4096L-64L,256L,&centx,&centy,0);
1001
        wsayfollow("updowndr.wav",4096L+64L,256L,&centx,&centy,0);
1001
        wsayfollow("updowndr.wav",4096L+64L,256L,&centx,&centy,0);
1002
    }
1002
    }
1003
}
1003
}
1004
1004
1005
void operatesprite(short dasprite)
1005
void operatesprite(short dasprite)
1006
{
1006
{
1007
    int datag;
1007
    int datag;
1008
1008
1009
    datag = sprite[dasprite].lotag;
1009
    datag = sprite[dasprite].lotag;
1010
1010
1011
    if (datag == 2)    //A sprite that shoots a bomb
1011
    if (datag == 2)    //A sprite that shoots a bomb
1012
    {
1012
    {
1013
        vec3_t vector = { sprite[dasprite].x,sprite[dasprite].y,sprite[dasprite].z };
1013
        vec3_t vector = { sprite[dasprite].x,sprite[dasprite].y,sprite[dasprite].z };
1014
        shootgun(dasprite, &vector,
1014
        shootgun(dasprite, &vector,
1015
                 sprite[dasprite].ang,100L,sprite[dasprite].sectnum,2);
1015
                 sprite[dasprite].ang,100L,sprite[dasprite].sectnum,2);
1016
    }
1016
    }
1017
}
1017
}
1018
1018
1019
int changehealth(short snum, short deltahealth)
1019
int changehealth(short snum, short deltahealth)
1020
{
1020
{
1021
    // int dax, day;
1021
    // int dax, day;
1022
    // short good, k, startwall, endwall, s;
1022
    // short good, k, startwall, endwall, s;
1023
1023
1024
    if (health[snum] > 0)
1024
    if (health[snum] > 0)
1025
    {
1025
    {
1026
        health[snum] += deltahealth;
1026
        health[snum] += deltahealth;
1027
        if (health[snum] > 999) health[snum] = 999;
1027
        if (health[snum] > 999) health[snum] = 999;
1028
1028
1029
        if (health[snum] <= 0)
1029
        if (health[snum] <= 0)
1030
        {
1030
        {
1031
            health[snum] = -1;
1031
            health[snum] = -1;
1032
            wsayfollow("death.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1);
1032
            wsayfollow("death.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1);
1033
            sprite[playersprite[snum]].picnum = SKELETON;
1033
            sprite[playersprite[snum]].picnum = SKELETON;
1034
        }
1034
        }
1035
1035
1036
        if ((snum == screenpeek) && (screensize <= xdim))
1036
        if ((snum == screenpeek) && (screensize <= xdim))
1037
        {
1037
        {
1038
            if (health[snum] > 0)
1038
            if (health[snum] > 0)
1039
                sprintf((char *)tempbuf,"Health:%3d",health[snum]);
1039
                sprintf((char *)tempbuf,"Health:%3d",health[snum]);
1040
            else
1040
            else
1041
                sprintf((char *)tempbuf,"YOU STINK!");
1041
                sprintf((char *)tempbuf,"YOU STINK!");
1042
1042
1043
            printext((xdim>>1)-(Bstrlen((char *)tempbuf)<<2),ydim-24,(char *)tempbuf,ALPHABET /*,80*/);
1043
            printext((xdim>>1)-(Bstrlen((char *)tempbuf)<<2),ydim-24,(char *)tempbuf,ALPHABET /*,80*/);
1044
        }
1044
        }
1045
    }
1045
    }
1046
    return health[snum] <= 0;       //You were just injured
1046
    return health[snum] <= 0;       //You were just injured
1047
}
1047
}
1048
1048
1049
void changenumbombs(short snum, short deltanumbombs)     // Andy did this
1049
void changenumbombs(short snum, short deltanumbombs)     // Andy did this
1050
{
1050
{
1051
    numbombs[snum] += deltanumbombs;
1051
    numbombs[snum] += deltanumbombs;
1052
    if (numbombs[snum] > 999) numbombs[snum] = 999;
1052
    if (numbombs[snum] > 999) numbombs[snum] = 999;
1053
    if (numbombs[snum] <= 0)
1053
    if (numbombs[snum] <= 0)
1054
    {
1054
    {
1055
        wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1);
1055
        wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1);
1056
        numbombs[snum] = 0;
1056
        numbombs[snum] = 0;
1057
    }
1057
    }
1058
1058
1059
    if ((snum == screenpeek) && (screensize <= xdim))
1059
    if ((snum == screenpeek) && (screensize <= xdim))
1060
    {
1060
    {
1061
        sprintf((char *)tempbuf,"B:%3d",numbombs[snum]);
1061
        sprintf((char *)tempbuf,"B:%3d",numbombs[snum]);
1062
        printext(8L,(ydim - 28L),(char *)tempbuf,ALPHABET /*,80*/);
1062
        printext(8L,(ydim - 28L),(char *)tempbuf,ALPHABET /*,80*/);
1063
    }
1063
    }
1064
}
1064
}
1065
1065
1066
void changenummissiles(short snum, short deltanummissiles)     // Andy did this
1066
void changenummissiles(short snum, short deltanummissiles)     // Andy did this
1067
{
1067
{
1068
    nummissiles[snum] += deltanummissiles;
1068
    nummissiles[snum] += deltanummissiles;
1069
    if (nummissiles[snum] > 999) nummissiles[snum] = 999;
1069
    if (nummissiles[snum] > 999) nummissiles[snum] = 999;
1070
    if (nummissiles[snum] <= 0)
1070
    if (nummissiles[snum] <= 0)
1071
    {
1071
    {
1072
        wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1);
1072
        wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1);
1073
        nummissiles[snum] = 0;
1073
        nummissiles[snum] = 0;
1074
    }
1074
    }
1075
1075
1076
    if ((snum == screenpeek) && (screensize <= xdim))
1076
    if ((snum == screenpeek) && (screensize <= xdim))
1077
    {
1077
    {
1078
        sprintf((char *)tempbuf,"M:%3d",nummissiles[snum]);
1078
        sprintf((char *)tempbuf,"M:%3d",nummissiles[snum]);
1079
        printext(8L,(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/);
1079
        printext(8L,(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/);
1080
    }
1080
    }
1081
}
1081
}
1082
1082
1083
void changenumgrabbers(short snum, short deltanumgrabbers)     // Andy did this
1083
void changenumgrabbers(short snum, short deltanumgrabbers)     // Andy did this
1084
{
1084
{
1085
    numgrabbers[snum] += deltanumgrabbers;
1085
    numgrabbers[snum] += deltanumgrabbers;
1086
    if (numgrabbers[snum] > 999) numgrabbers[snum] = 999;
1086
    if (numgrabbers[snum] > 999) numgrabbers[snum] = 999;
1087
    if (numgrabbers[snum] <= 0)
1087
    if (numgrabbers[snum] <= 0)
1088
    {
1088
    {
1089
        wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1);
1089
        wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1);
1090
        numgrabbers[snum] = 0;
1090
        numgrabbers[snum] = 0;
1091
    }
1091
    }
1092
1092
1093
    if ((snum == screenpeek) && (screensize <= xdim))
1093
    if ((snum == screenpeek) && (screensize <= xdim))
1094
    {
1094
    {
1095
        sprintf((char *)tempbuf,"G:%3d",numgrabbers[snum]);
1095
        sprintf((char *)tempbuf,"G:%3d",numgrabbers[snum]);
1096
        printext(8L,(ydim - 12L),(char *)tempbuf,ALPHABET /*,80*/);
1096
        printext(8L,(ydim - 12L),(char *)tempbuf,ALPHABET /*,80*/);
1097
    }
1097
    }
1098
}
1098
}
1099
1099
1100
static int ostatusflytime = 0x80000000;
1100
static int ostatusflytime = 0x80000000;
1101
void drawstatusflytime(short snum)     // Andy did this
1101
void drawstatusflytime(short snum)     // Andy did this
1102
{
1102
{
1103
    int nstatusflytime;
1103
    int nstatusflytime;
1104
1104
1105
    if ((snum == screenpeek) && (screensize <= xdim))
1105
    if ((snum == screenpeek) && (screensize <= xdim))
1106
    {
1106
    {
1107
        nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120);
1107
        nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120);
1108
        if (nstatusflytime > 1000) nstatusflytime = 1000;
1108
        if (nstatusflytime > 1000) nstatusflytime = 1000;
1109
        else if (nstatusflytime < 0) nstatusflytime = 0;
1109
        else if (nstatusflytime < 0) nstatusflytime = 0;
1110
        if (nstatusflytime != ostatusflytime)
1110
        if (nstatusflytime != ostatusflytime)
1111
        {
1111
        {
1112
            if (nstatusflytime > 999) sprintf((char *)tempbuf,"FT:BIG");
1112
            if (nstatusflytime > 999) sprintf((char *)tempbuf,"FT:BIG");
1113
            else sprintf((char *)tempbuf,"FT:%3d",nstatusflytime);
1113
            else sprintf((char *)tempbuf,"FT:%3d",nstatusflytime);
1114
            printext((xdim - 56L),(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/);
1114
            printext((xdim - 56L),(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/);
1115
            ostatusflytime = nstatusflytime;
1115
            ostatusflytime = nstatusflytime;
1116
        }
1116
        }
1117
    }
1117
    }
1118
}
1118
}
1119
1119
1120
void drawstatusbar(short snum)     // Andy did this
1120
void drawstatusbar(short snum)     // Andy did this
1121
{
1121
{
1122
    int nstatusflytime;
1122
    int nstatusflytime;
1123
1123
1124
    if ((snum == screenpeek) && (screensize <= xdim))
1124
    if ((snum == screenpeek) && (screensize <= xdim))
1125
    {
1125
    {
1126
        sprintf((char *)tempbuf,"Deaths:%d",deaths[snum]);
1126
        sprintf((char *)tempbuf,"Deaths:%d",deaths[snum]);
1127
        printext((xdim>>1)-(strlen((char *)tempbuf)<<2),ydim-16,(char *)tempbuf,ALPHABET /*,80*/);
1127
        printext((xdim>>1)-(strlen((char *)tempbuf)<<2),ydim-16,(char *)tempbuf,ALPHABET /*,80*/);
1128
        sprintf((char *)tempbuf,"Health:%3d",health[snum]);
1128
        sprintf((char *)tempbuf,"Health:%3d",health[snum]);
1129
        printext((xdim>>1)-(strlen((char *)tempbuf)<<2),ydim-24,(char *)tempbuf,ALPHABET /*,80*/);
1129
        printext((xdim>>1)-(strlen((char *)tempbuf)<<2),ydim-24,(char *)tempbuf,ALPHABET /*,80*/);
1130
1130
1131
        sprintf((char *)tempbuf,"B:%3d",numbombs[snum]);
1131
        sprintf((char *)tempbuf,"B:%3d",numbombs[snum]);
1132
        printext(8L,(ydim - 28L),(char *)tempbuf,ALPHABET /*,80*/);
1132
        printext(8L,(ydim - 28L),(char *)tempbuf,ALPHABET /*,80*/);
1133
        sprintf((char *)tempbuf,"M:%3d",nummissiles[snum]);
1133
        sprintf((char *)tempbuf,"M:%3d",nummissiles[snum]);
1134
        printext(8L,(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/);
1134
        printext(8L,(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/);
1135
        sprintf((char *)tempbuf,"G:%3d",numgrabbers[snum]);
1135
        sprintf((char *)tempbuf,"G:%3d",numgrabbers[snum]);
1136
        printext(8L,(ydim - 12L),(char *)tempbuf,ALPHABET /*,80*/);
1136
        printext(8L,(ydim - 12L),(char *)tempbuf,ALPHABET /*,80*/);
1137
1137
1138
        nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120);
1138
        nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120);
1139
        if (nstatusflytime < 0)
1139
        if (nstatusflytime < 0)
1140
        {
1140
        {
1141
            sprintf((char *)tempbuf,"FT:  0");
1141
            sprintf((char *)tempbuf,"FT:  0");
1142
            ostatusflytime = 0;
1142
            ostatusflytime = 0;
1143
        }
1143
        }
1144
        else if (nstatusflytime > 999)
1144
        else if (nstatusflytime > 999)
1145
        {
1145
        {
1146
            sprintf((char *)tempbuf,"FT:BIG");
1146
            sprintf((char *)tempbuf,"FT:BIG");
1147
            ostatusflytime = 999;
1147
            ostatusflytime = 999;
1148
        }
1148
        }
1149
        else
1149
        else
1150
        {
1150
        {
1151
            sprintf((char *)tempbuf,"FT:%3d",nstatusflytime);
1151
            sprintf((char *)tempbuf,"FT:%3d",nstatusflytime);
1152
            ostatusflytime = nstatusflytime;
1152
            ostatusflytime = nstatusflytime;
1153
        }
1153
        }
1154
        printext((xdim - 56L),(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/);
1154
        printext((xdim - 56L),(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/);
1155
    }
1155
    }
1156
}
1156
}
1157
1157
1158
void prepareboard(char *daboardfilename)
1158
void prepareboard(char *daboardfilename)
1159
{
1159
{
1160
    short startwall, endwall, dasector;
1160
    short startwall, endwall, dasector;
1161
    int i, j, k=0, s, dax, day, /*daz,*/ dax2, day2;
1161
    int i, j, k=0, s, dax, day, /*daz,*/ dax2, day2;
1162
1162
1163
    getmessageleng = 0;
1163
    getmessageleng = 0;
1164
    typemessageleng = 0;
1164
    typemessageleng = 0;
1165
1165
1166
    randomseed = 17L;
1166
    randomseed = 17L;
1167
1167
1168
    //Clear (do)animation's list
1168
    //Clear (do)animation's list
1169
    animatecnt = 0;
1169
    animatecnt = 0;
1170
    typemode = 0;
1170
    typemode = 0;
1171
    locselectedgun = 0;
1171
    locselectedgun = 0;
1172
    locselectedgun2 = 0;
1172
    locselectedgun2 = 0;
1173
1173
1174
    if (engineLoadBoard(daboardfilename,0,&pos[0],&ang[0],&cursectnum[0]) == -1)
1174
    if (engineLoadBoard(daboardfilename,0,&pos[0],&ang[0],&cursectnum[0]) == -1)
1175
    {
1175
    {
1176
        musicoff();
1176
        musicoff();
1177
        uninitmultiplayers();
1177
        uninitmultiplayers();
1178
        timerUninit();
1178
        timerUninit();
1179
        uninitinput();
1179
        uninitinput();
1180
        uninitsb();
1180
        uninitsb();
1181
        engineUnInit();
1181
        engineUnInit();
1182
        uninitgroupfile();
1182
        uninitgroupfile();
1183
        printf("Board not found\n");
1183
        printf("Board not found\n");
1184
        exit(0);
1184
        exit(0);
1185
    }
1185
    }
1186
    else
1186
    else
1187
    {
1187
    {
1188
        char tempfn[BMAX_PATH + 1], *fp;
1188
        char tempfn[BMAX_PATH + 1], *fp;
1189
1189
1190
        strncpy(tempfn, daboardfilename, BMAX_PATH);
1190
        strncpy(tempfn, daboardfilename, BMAX_PATH);
1191
        tempfn[BMAX_PATH] = 0;
1191
        tempfn[BMAX_PATH] = 0;
1192
1192
1193
        fp = strrchr(tempfn,'.');
1193
        fp = strrchr(tempfn,'.');
1194
        if (fp) *fp = 0;
1194
        if (fp) *fp = 0;
1195
1195
1196
        if (strlen(tempfn) <= BMAX_PATH-4)
1196
        if (strlen(tempfn) <= BMAX_PATH-4)
1197
        {
1197
        {
1198
            strcat(tempfn,".mhk");
1198
            strcat(tempfn,".mhk");
1199
            engineLoadMHK(tempfn);
1199
            engineLoadMHK(tempfn);
1200
        }
1200
        }
1201
    }
1201
    }
1202
1202
1203
    setup3dscreen();
1203
    setup3dscreen();
1204
1204
1205
    for (i=0; i<MAXPLAYERS; i++)
1205
    for (i=0; i<MAXPLAYERS; i++)
1206
    {
1206
    {
1207
        pos[i] = pos[0];
1207
        pos[i] = pos[0];
1208
        ang[i] = ang[0];
1208
        ang[i] = ang[0];
1209
        cursectnum[i] = cursectnum[0];
1209
        cursectnum[i] = cursectnum[0];
1210
        ocursectnum[i] = cursectnum[0];
1210
        ocursectnum[i] = cursectnum[0];
1211
        horiz[i] = 100;
1211
        horiz[i] = 100;
1212
        lastchaingun[i] = 0;
1212
        lastchaingun[i] = 0;
1213
        health[i] = 100;
1213
        health[i] = 100;
1214
        dimensionmode[i] = 3;
1214
        dimensionmode[i] = 3;
1215
        numbombs[i] = 0;
1215
        numbombs[i] = 0;
1216
        numgrabbers[i] = 0;
1216
        numgrabbers[i] = 0;
1217
        nummissiles[i] = 0;
1217
        nummissiles[i] = 0;
1218
        flytime[i] = 0L;
1218
        flytime[i] = 0L;
1219
        zoom[i] = 768L;
1219
        zoom[i] = 768L;
1220
        deaths[i] = 0L;
1220
        deaths[i] = 0L;
1221
        playersprite[i] = -1;
1221
        playersprite[i] = -1;
1222
        screensize = xdim;
1222
        screensize = xdim;
1223
1223
1224
        opos[i] = pos[0];
1224
        opos[i] = pos[0];
1225
        ohoriz[i] = horiz[0];
1225
        ohoriz[i] = horiz[0];
1226
        ozoom[i] = zoom[0];
1226
        ozoom[i] = zoom[0];
1227
        oang[i] = ang[0];
1227
        oang[i] = ang[0];
1228
    }
1228
    }
1229
1229
1230
    my = omy = pos[myconnectindex];
1230
    my = omy = pos[myconnectindex];
1231
    myhoriz = omyhoriz = horiz[myconnectindex];
1231
    myhoriz = omyhoriz = horiz[myconnectindex];
1232
    myang = omyang = ang[myconnectindex];
1232
    myang = omyang = ang[myconnectindex];
1233
    mycursectnum = cursectnum[myconnectindex];
1233
    mycursectnum = cursectnum[myconnectindex];
1234
    myzvel = 0;
1234
    myzvel = 0;
1235
1235
1236
    movefifoplc = fakemovefifoplc = 0;
1236
    movefifoplc = fakemovefifoplc = 0;
1237
    syncvalhead = 0L; othersyncvalhead = 0L;
1237
    syncvalhead = 0L; othersyncvalhead = 0L;
1238
    syncvaltottail = 0L; syncvaltail = 0L;
1238
    syncvaltottail = 0L; syncvaltail = 0L;
1239
    numinterpolations = 0;
1239
    numinterpolations = 0;
1240
1240
1241
    clearbufbyte(&oloc,sizeof(input),0L);
1241
    clearbufbyte(&oloc,sizeof(input),0L);
1242
    for (i=0; i<MAXPLAYERS; i++)
1242
    for (i=0; i<MAXPLAYERS; i++)
1243
    {
1243
    {
1244
        movefifoend[i] = 0;
1244
        movefifoend[i] = 0;
1245
        clearbufbyte(&ffsync[i],sizeof(input),0L);
1245
        clearbufbyte(&ffsync[i],sizeof(input),0L);
1246
        clearbufbyte(&ssync[i],sizeof(input),0L);
1246
        clearbufbyte(&ssync[i],sizeof(input),0L);
1247
        clearbufbyte(&osync[i],sizeof(input),0L);
1247
        clearbufbyte(&osync[i],sizeof(input),0L);
1248
    }
1248
    }
1249
1249
1250
    //Scan sector tags
1250
    //Scan sector tags
1251
1251
1252
    for (i=0; i<MAXPLAYERS; i++)
1252
    for (i=0; i<MAXPLAYERS; i++)
1253
    {
1253
    {
1254
        waterfountainwall[i] = -1;
1254
        waterfountainwall[i] = -1;
1255
        waterfountaincnt[i] = 0;
1255
        waterfountaincnt[i] = 0;
1256
        slimesoundcnt[i] = 0;
1256
        slimesoundcnt[i] = 0;
1257
    }
1257
    }
1258
    warpsectorcnt = 0;      //Make a list of warping sectors
1258
    warpsectorcnt = 0;      //Make a list of warping sectors
1259
    xpanningsectorcnt = 0;  //Make a list of wall x-panning sectors
1259
    xpanningsectorcnt = 0;  //Make a list of wall x-panning sectors
1260
    floorpanningcnt = 0;    //Make a list of slime sectors
1260
    floorpanningcnt = 0;    //Make a list of slime sectors
1261
    dragsectorcnt = 0;      //Make a list of moving platforms
1261
    dragsectorcnt = 0;      //Make a list of moving platforms
1262
    swingcnt = 0;           //Make a list of swinging doors
1262
    swingcnt = 0;           //Make a list of swinging doors
1263
    revolvecnt = 0;         //Make a list of revolving doors
1263
    revolvecnt = 0;         //Make a list of revolving doors
1264
    subwaytrackcnt = 0;     //Make a list of subways
1264
    subwaytrackcnt = 0;     //Make a list of subways
1265
1265
1266
    floormirrorcnt = 0;
1266
    floormirrorcnt = 0;
1267
    tilesiz[FLOORMIRROR].x = 0;
1267
    tilesiz[FLOORMIRROR].x = 0;
1268
    tilesiz[FLOORMIRROR].y = 0;
1268
    tilesiz[FLOORMIRROR].y = 0;
1269
1269
1270
    for (i=0; i<numsectors; i++)
1270
    for (i=0; i<numsectors; i++)
1271
    {
1271
    {
1272
        switch (sector[i].lotag)
1272
        switch (sector[i].lotag)
1273
        {
1273
        {
1274
        case 4:
1274
        case 4:
1275
            floorpanninglist[floorpanningcnt++] = i;
1275
            floorpanninglist[floorpanningcnt++] = i;
1276
            break;
1276
            break;
1277
        case 10:
1277
        case 10:
1278
            warpsectorlist[warpsectorcnt++] = i;
1278
            warpsectorlist[warpsectorcnt++] = i;
1279
            break;
1279
            break;
1280
        case 11:
1280
        case 11:
1281
            xpanningsectorlist[xpanningsectorcnt++] = i;
1281
            xpanningsectorlist[xpanningsectorcnt++] = i;
1282
            break;
1282
            break;
1283
        case 12:
1283
        case 12:
1284
            dasector = i;
1284
            dasector = i;
1285
            dax = 0x7fffffff;
1285
            dax = 0x7fffffff;
1286
            day = 0x7fffffff;
1286
            day = 0x7fffffff;
1287
            dax2 = 0x80000000;
1287
            dax2 = 0x80000000;
1288
            day2 = 0x80000000;
1288
            day2 = 0x80000000;
1289
            startwall = sector[i].wallptr;
1289
            startwall = sector[i].wallptr;
1290
            endwall = startwall+sector[i].wallnum;
1290
            endwall = startwall+sector[i].wallnum;
1291
            for (j=startwall; j<endwall; j++)
1291
            for (j=startwall; j<endwall; j++)
1292
            {
1292
            {
1293
                if (wall[j].x < dax) dax = wall[j].x;
1293
                if (wall[j].x < dax) dax = wall[j].x;
1294
                if (wall[j].y < day) day = wall[j].y;
1294
                if (wall[j].y < day) day = wall[j].y;
1295
                if (wall[j].x > dax2) dax2 = wall[j].x;
1295
                if (wall[j].x > dax2) dax2 = wall[j].x;
1296
                if (wall[j].y > day2) day2 = wall[j].y;
1296
                if (wall[j].y > day2) day2 = wall[j].y;
1297
                if (wall[j].lotag == 3) k = j;
1297
                if (wall[j].lotag == 3) k = j;
1298
            }
1298
            }
1299
            if (wall[k].x == dax) dragxdir[dragsectorcnt] = -16;
1299
            if (wall[k].x == dax) dragxdir[dragsectorcnt] = -16;
1300
            if (wall[k].y == day) dragydir[dragsectorcnt] = -16;
1300
            if (wall[k].y == day) dragydir[dragsectorcnt] = -16;
1301
            if (wall[k].x == dax2) dragxdir[dragsectorcnt] = 16;
1301
            if (wall[k].x == dax2) dragxdir[dragsectorcnt] = 16;
1302
            if (wall[k].y == day2) dragydir[dragsectorcnt] = 16;
1302
            if (wall[k].y == day2) dragydir[dragsectorcnt] = 16;
1303
1303
1304
            dasector = wall[startwall].nextsector;
1304
            dasector = wall[startwall].nextsector;
1305
            dragx1[dragsectorcnt] = 0x7fffffff;
1305
            dragx1[dragsectorcnt] = 0x7fffffff;
1306
            dragy1[dragsectorcnt] = 0x7fffffff;
1306
            dragy1[dragsectorcnt] = 0x7fffffff;
1307
            dragx2[dragsectorcnt] = 0x80000000;
1307
            dragx2[dragsectorcnt] = 0x80000000;
1308
            dragy2[dragsectorcnt] = 0x80000000;
1308
            dragy2[dragsectorcnt] = 0x80000000;
1309
            startwall = sector[dasector].wallptr;
1309
            startwall = sector[dasector].wallptr;
1310
            endwall = startwall+sector[dasector].wallnum;
1310
            endwall = startwall+sector[dasector].wallnum;
1311
            for (j=startwall; j<endwall; j++)
1311
            for (j=startwall; j<endwall; j++)
1312
            {
1312
            {
1313
                if (wall[j].x < dragx1[dragsectorcnt]) dragx1[dragsectorcnt] = wall[j].x;
1313
                if (wall[j].x < dragx1[dragsectorcnt]) dragx1[dragsectorcnt] = wall[j].x;
1314
                if (wall[j].y < dragy1[dragsectorcnt]) dragy1[dragsectorcnt] = wall[j].y;
1314
                if (wall[j].y < dragy1[dragsectorcnt]) dragy1[dragsectorcnt] = wall[j].y;
1315
                if (wall[j].x > dragx2[dragsectorcnt]) dragx2[dragsectorcnt] = wall[j].x;
1315
                if (wall[j].x > dragx2[dragsectorcnt]) dragx2[dragsectorcnt] = wall[j].x;
1316
                if (wall[j].y > dragy2[dragsectorcnt]) dragy2[dragsectorcnt] = wall[j].y;
1316
                if (wall[j].y > dragy2[dragsectorcnt]) dragy2[dragsectorcnt] = wall[j].y;
1317
1317
1318
                setinterpolation(&sector[dasector].floorz);
1318
                setinterpolation(&sector[dasector].floorz);
1319
                setinterpolation(&wall[j].x);
1319
                setinterpolation(&wall[j].x);
1320
                setinterpolation(&wall[j].y);
1320
                setinterpolation(&wall[j].y);
1321
                auto const nextwall = wall[j].nextwall;
1321
                auto const nextwall = wall[j].nextwall;
1322
                if ((unsigned)nextwall < MAXWALLS)
1322
                if ((unsigned)nextwall < MAXWALLS)
1323
                {
1323
                {
1324
                    setinterpolation(&wall[nextwall].x);
1324
                    setinterpolation(&wall[nextwall].x);
1325
                    setinterpolation(&wall[nextwall].y);
1325
                    setinterpolation(&wall[nextwall].y);
1326
                }
1326
                }
1327
            }
1327
            }
1328
1328
1329
            dragx1[dragsectorcnt] += (wall[sector[i].wallptr].x-dax);
1329
            dragx1[dragsectorcnt] += (wall[sector[i].wallptr].x-dax);
1330
            dragy1[dragsectorcnt] += (wall[sector[i].wallptr].y-day);
1330
            dragy1[dragsectorcnt] += (wall[sector[i].wallptr].y-day);
1331
            dragx2[dragsectorcnt] -= (dax2-wall[sector[i].wallptr].x);
1331
            dragx2[dragsectorcnt] -= (dax2-wall[sector[i].wallptr].x);
1332
            dragy2[dragsectorcnt] -= (day2-wall[sector[i].wallptr].y);
1332
            dragy2[dragsectorcnt] -= (day2-wall[sector[i].wallptr].y);
1333
1333
1334
            dragfloorz[dragsectorcnt] = sector[i].floorz;
1334
            dragfloorz[dragsectorcnt] = sector[i].floorz;
1335
1335
1336
            dragsectorlist[dragsectorcnt++] = i;
1336
            dragsectorlist[dragsectorcnt++] = i;
1337
            break;
1337
            break;
1338
        case 13:
1338
        case 13:
1339
            startwall = sector[i].wallptr;
1339
            startwall = sector[i].wallptr;
1340
            endwall = startwall+sector[i].wallnum;
1340
            endwall = startwall+sector[i].wallnum;
1341
            for (j=startwall; j<endwall; j++)
1341
            for (j=startwall; j<endwall; j++)
1342
            {
1342
            {
1343
                if (wall[j].lotag == 4)
1343
                if (wall[j].lotag == 4)
1344
                {
1344
                {
1345
                    k = wall[wall[wall[wall[j].point2].point2].point2].point2;
1345
                    k = wall[wall[wall[wall[j].point2].point2].point2].point2;
1346
                    if ((wall[j].x == wall[k].x) && (wall[j].y == wall[k].y))
1346
                    if ((wall[j].x == wall[k].x) && (wall[j].y == wall[k].y))
1347
                    {
1347
                    {
1348
                        //Door opens counterclockwise
1348
                        //Door opens counterclockwise
1349
                        swingwall[swingcnt][0] = j;
1349
                        swingwall[swingcnt][0] = j;
1350
                        swingwall[swingcnt][1] = wall[j].point2;
1350
                        swingwall[swingcnt][1] = wall[j].point2;
1351
                        swingwall[swingcnt][2] = wall[wall[j].point2].point2;
1351
                        swingwall[swingcnt][2] = wall[wall[j].point2].point2;
1352
                        swingwall[swingcnt][3] = wall[wall[wall[j].point2].point2].point2;
1352
                        swingwall[swingcnt][3] = wall[wall[wall[j].point2].point2].point2;
1353
                        swingangopen[swingcnt] = 1536;
1353
                        swingangopen[swingcnt] = 1536;
1354
                        swingangclosed[swingcnt] = 0;
1354
                        swingangclosed[swingcnt] = 0;
1355
                        swingangopendir[swingcnt] = -1;
1355
                        swingangopendir[swingcnt] = -1;
1356
                    }
1356
                    }
1357
                    else
1357
                    else
1358
                    {
1358
                    {
1359
                        //Door opens clockwise
1359
                        //Door opens clockwise
1360
                        swingwall[swingcnt][0] = wall[j].point2;
1360
                        swingwall[swingcnt][0] = wall[j].point2;
1361
                        swingwall[swingcnt][1] = j;
1361
                        swingwall[swingcnt][1] = j;
1362
                        swingwall[swingcnt][2] = lastwall(j);
1362
                        swingwall[swingcnt][2] = lastwall(j);
1363
                        swingwall[swingcnt][3] = lastwall(swingwall[swingcnt][2]);
1363
                        swingwall[swingcnt][3] = lastwall(swingwall[swingcnt][2]);
1364
                        swingwall[swingcnt][4] = lastwall(swingwall[swingcnt][3]);
1364
                        swingwall[swingcnt][4] = lastwall(swingwall[swingcnt][3]);
1365
                        swingangopen[swingcnt] = 512;
1365
                        swingangopen[swingcnt] = 512;
1366
                        swingangclosed[swingcnt] = 0;
1366
                        swingangclosed[swingcnt] = 0;
1367
                        swingangopendir[swingcnt] = 1;
1367
                        swingangopendir[swingcnt] = 1;
1368
                    }
1368
                    }
1369
                    for (k=0; k<4; k++)
1369
                    for (k=0; k<4; k++)
1370
                    {
1370
                    {
1371
                        swingx[swingcnt][k] = wall[swingwall[swingcnt][k]].x;
1371
                        swingx[swingcnt][k] = wall[swingwall[swingcnt][k]].x;
1372
                        swingy[swingcnt][k] = wall[swingwall[swingcnt][k]].y;
1372
                        swingy[swingcnt][k] = wall[swingwall[swingcnt][k]].y;
1373
                    }
1373
                    }
1374
1374
1375
                    swingsector[swingcnt] = i;
1375
                    swingsector[swingcnt] = i;
1376
                    swingang[swingcnt] = swingangclosed[swingcnt];
1376
                    swingang[swingcnt] = swingangclosed[swingcnt];
1377
                    swinganginc[swingcnt] = 0;
1377
                    swinganginc[swingcnt] = 0;
1378
                    swingcnt++;
1378
                    swingcnt++;
1379
                }
1379
                }
1380
            }
1380
            }
1381
            break;
1381
            break;
1382
        case 14:
1382
        case 14:
1383
            startwall = sector[i].wallptr;
1383
            startwall = sector[i].wallptr;
1384
            endwall = startwall+sector[i].wallnum;
1384
            endwall = startwall+sector[i].wallnum;
1385
            dax = 0L;
1385
            dax = 0L;
1386
            day = 0L;
1386
            day = 0L;
1387
            for (j=startwall; j<endwall; j++)
1387
            for (j=startwall; j<endwall; j++)
1388
            {
1388
            {
1389
                dax += wall[j].x;
1389
                dax += wall[j].x;
1390
                day += wall[j].y;
1390
                day += wall[j].y;
1391
            }
1391
            }
1392
            revolvepivotx[revolvecnt] = dax / (endwall-startwall);
1392
            revolvepivotx[revolvecnt] = dax / (endwall-startwall);
1393
            revolvepivoty[revolvecnt] = day / (endwall-startwall);
1393
            revolvepivoty[revolvecnt] = day / (endwall-startwall);
1394
1394
1395
            k = 0;
1395
            k = 0;
1396
            for (j=startwall; j<endwall; j++)
1396
            for (j=startwall; j<endwall; j++)
1397
            {
1397
            {
1398
                revolvex[revolvecnt][k] = wall[j].x;
1398
                revolvex[revolvecnt][k] = wall[j].x;
1399
                revolvey[revolvecnt][k] = wall[j].y;
1399
                revolvey[revolvecnt][k] = wall[j].y;
1400
1400
1401
                setinterpolation(&wall[j].x);
1401
                setinterpolation(&wall[j].x);
1402
                setinterpolation(&wall[j].y);
1402
                setinterpolation(&wall[j].y);
1403
                setinterpolation(&wall[wall[j].nextwall].x);
1403
                setinterpolation(&wall[wall[j].nextwall].x);
1404
                setinterpolation(&wall[wall[j].nextwall].y);
1404
                setinterpolation(&wall[wall[j].nextwall].y);
1405
1405
1406
                k++;
1406
                k++;
1407
            }
1407
            }
1408
            revolvesector[revolvecnt] = i;
1408
            revolvesector[revolvecnt] = i;
1409
            revolveang[revolvecnt] = 0;
1409
            revolveang[revolvecnt] = 0;
1410
1410
1411
            revolvecnt++;
1411
            revolvecnt++;
1412
            break;
1412
            break;
1413
        case 15:
1413
        case 15:
1414
            subwaytracksector[subwaytrackcnt][0] = i;
1414
            subwaytracksector[subwaytrackcnt][0] = i;
1415
1415
1416
            subwaystopcnt[subwaytrackcnt] = 0;
1416
            subwaystopcnt[subwaytrackcnt] = 0;
1417
            dax = 0x7fffffff;
1417
            dax = 0x7fffffff;
1418
            day = 0x7fffffff;
1418
            day = 0x7fffffff;
1419
            dax2 = 0x80000000;
1419
            dax2 = 0x80000000;
1420
            day2 = 0x80000000;
1420
            day2 = 0x80000000;
1421
            startwall = sector[i].wallptr;
1421
            startwall = sector[i].wallptr;
1422
            endwall = startwall+sector[i].wallnum;
1422
            endwall = startwall+sector[i].wallnum;
1423
            for (j=startwall; j<endwall; j++)
1423
            for (j=startwall; j<endwall; j++)
1424
            {
1424
            {
1425
                if (wall[j].x < dax) dax = wall[j].x;
1425
                if (wall[j].x < dax) dax = wall[j].x;
1426
                if (wall[j].y < day) day = wall[j].y;
1426
                if (wall[j].y < day) day = wall[j].y;
1427
                if (wall[j].x > dax2) dax2 = wall[j].x;
1427
                if (wall[j].x > dax2) dax2 = wall[j].x;
1428
                if (wall[j].y > day2) day2 = wall[j].y;
1428
                if (wall[j].y > day2) day2 = wall[j].y;
1429
            }
1429
            }
1430
            for (j=startwall; j<endwall; j++)
1430
            for (j=startwall; j<endwall; j++)
1431
            {
1431
            {
1432
                if (wall[j].lotag == 5)
1432
                if (wall[j].lotag == 5)
1433
                {
1433
                {
1434
                    if ((wall[j].x > dax) && (wall[j].y > day) && (wall[j].x < dax2) && (wall[j].y < day2))
1434
                    if ((wall[j].x > dax) && (wall[j].y > day) && (wall[j].x < dax2) && (wall[j].y < day2))
1435
                    {
1435
                    {
1436
                        subwayx[subwaytrackcnt] = wall[j].x;
1436
                        subwayx[subwaytrackcnt] = wall[j].x;
1437
                    }
1437
                    }
1438
                    else
1438
                    else
1439
                    {
1439
                    {
1440
                        subwaystop[subwaytrackcnt][subwaystopcnt[subwaytrackcnt]] = wall[j].x;
1440
                        subwaystop[subwaytrackcnt][subwaystopcnt[subwaytrackcnt]] = wall[j].x;
1441
                        subwaystopcnt[subwaytrackcnt]++;
1441
                        subwaystopcnt[subwaytrackcnt]++;
1442
                    }
1442
                    }
1443
                }
1443
                }
1444
            }
1444
            }
1445
1445
1446
            for (j=1; j<subwaystopcnt[subwaytrackcnt]; j++)
1446
            for (j=1; j<subwaystopcnt[subwaytrackcnt]; j++)
1447
                for (k=0; k<j; k++)
1447
                for (k=0; k<j; k++)
1448
                    if (subwaystop[subwaytrackcnt][j] < subwaystop[subwaytrackcnt][k])
1448
                    if (subwaystop[subwaytrackcnt][j] < subwaystop[subwaytrackcnt][k])
1449
                    {
1449
                    {
1450
                        s = subwaystop[subwaytrackcnt][j];
1450
                        s = subwaystop[subwaytrackcnt][j];
1451
                        subwaystop[subwaytrackcnt][j] = subwaystop[subwaytrackcnt][k];
1451
                        subwaystop[subwaytrackcnt][j] = subwaystop[subwaytrackcnt][k];
1452
                        subwaystop[subwaytrackcnt][k] = s;
1452
                        subwaystop[subwaytrackcnt][k] = s;
1453
                    }
1453
                    }
1454
1454
1455
            subwaygoalstop[subwaytrackcnt] = 0;
1455
            subwaygoalstop[subwaytrackcnt] = 0;
1456
            for (j=0; j<subwaystopcnt[subwaytrackcnt]; j++)
1456
            for (j=0; j<subwaystopcnt[subwaytrackcnt]; j++)
1457
                if (klabs(subwaystop[subwaytrackcnt][j]-subwayx[subwaytrackcnt]) < klabs(subwaystop[subwaytrackcnt][subwaygoalstop[subwaytrackcnt]]-subwayx[subwaytrackcnt]))
1457
                if (klabs(subwaystop[subwaytrackcnt][j]-subwayx[subwaytrackcnt]) < klabs(subwaystop[subwaytrackcnt][subwaygoalstop[subwaytrackcnt]]-subwayx[subwaytrackcnt]))
1458
                    subwaygoalstop[subwaytrackcnt] = j;
1458
                    subwaygoalstop[subwaytrackcnt] = j;
1459
1459
1460
            subwaytrackx1[subwaytrackcnt] = dax;
1460
            subwaytrackx1[subwaytrackcnt] = dax;
1461
            subwaytracky1[subwaytrackcnt] = day;
1461
            subwaytracky1[subwaytrackcnt] = day;
1462
            subwaytrackx2[subwaytrackcnt] = dax2;
1462
            subwaytrackx2[subwaytrackcnt] = dax2;
1463
            subwaytracky2[subwaytrackcnt] = day2;
1463
            subwaytracky2[subwaytrackcnt] = day2;
1464
1464
1465
            subwaynumsectors[subwaytrackcnt] = 1;
1465
            subwaynumsectors[subwaytrackcnt] = 1;
1466
            for (j=0; j<numsectors; j++)
1466
            for (j=0; j<numsectors; j++)
1467
                if (j != i)
1467
                if (j != i)
1468
                {
1468
                {
1469
                    startwall = sector[j].wallptr;
1469
                    startwall = sector[j].wallptr;
1470
                    if (wall[startwall].x > subwaytrackx1[subwaytrackcnt])
1470
                    if (wall[startwall].x > subwaytrackx1[subwaytrackcnt])
1471
                        if (wall[startwall].y > subwaytracky1[subwaytrackcnt])
1471
                        if (wall[startwall].y > subwaytracky1[subwaytrackcnt])
1472
                            if (wall[startwall].x < subwaytrackx2[subwaytrackcnt])
1472
                            if (wall[startwall].x < subwaytrackx2[subwaytrackcnt])
1473
                                if (wall[startwall].y < subwaytracky2[subwaytrackcnt])
1473
                                if (wall[startwall].y < subwaytracky2[subwaytrackcnt])
1474
                                {
1474
                                {
1475
                                    if (sector[j].floorz != sector[i].floorz)
1475
                                    if (sector[j].floorz != sector[i].floorz)
1476
                                    {
1476
                                    {
1477
                                        sector[j].ceilingstat |= 64;
1477
                                        sector[j].ceilingstat |= 64;
1478
                                        sector[j].floorstat |= 64;
1478
                                        sector[j].floorstat |= 64;
1479
                                    }
1479
                                    }
1480
                                    subwaytracksector[subwaytrackcnt][subwaynumsectors[subwaytrackcnt]] = j;
1480
                                    subwaytracksector[subwaytrackcnt][subwaynumsectors[subwaytrackcnt]] = j;
1481
                                    subwaynumsectors[subwaytrackcnt]++;
1481
                                    subwaynumsectors[subwaytrackcnt]++;
1482
                                }
1482
                                }
1483
                }
1483
                }
1484
1484
1485
            subwayvel[subwaytrackcnt] = 64;
1485
            subwayvel[subwaytrackcnt] = 64;
1486
            subwaypausetime[subwaytrackcnt] = 720;
1486
            subwaypausetime[subwaytrackcnt] = 720;
1487
1487
1488
            startwall = sector[i].wallptr;
1488
            startwall = sector[i].wallptr;
1489
            endwall = startwall+sector[i].wallnum;
1489
            endwall = startwall+sector[i].wallnum;
1490
            for (k=startwall; k<endwall; k++)
1490
            for (k=startwall; k<endwall; k++)
1491
                if (wall[k].x > subwaytrackx1[subwaytrackcnt])
1491
                if (wall[k].x > subwaytrackx1[subwaytrackcnt])
1492
                    if (wall[k