Subversion Repositories eduke32

Rev

Rev 8673 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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