Subversion Repositories eduke32

Rev

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

Rev 8478 Rev 8488
1
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
1
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
2
// Ken Silverman's official web site: "http://www.advsys.net/ken"
2
// Ken Silverman's official web site: "http://www.advsys.net/ken"
3
// See the included license file "BUILDLIC.TXT" for license info.
3
// See the included license file "BUILDLIC.TXT" for license info.
4
//
4
//
5
// This file has been modified from Ken Silverman's original release
5
// This file has been modified from Ken Silverman's original release
6
// by Jonathon Fowler (jf@jonof.id.au)
6
// by Jonathon Fowler (jf@jonof.id.au)
7
// by the EDuke32 team (development@voidpoint.com)
7
// by the EDuke32 team (development@voidpoint.com)
8
8
9
#include "build.h"
9
#include "build.h"
10
10
11
#include "baselayer.h"
11
#include "baselayer.h"
12
#include "cache1d.h"
12
#include "cache1d.h"
13
#include "colmatch.h"
13
#include "colmatch.h"
14
#include "common.h"
14
#include "common.h"
15
#include "compat.h"
15
#include "compat.h"
16
#include "editor.h"
16
#include "editor.h"
17
#include "m32script.h"
17
#include "m32script.h"
18
#include "osd.h"
18
#include "osd.h"
19
#include "palette.h"
19
#include "palette.h"
20
#include "pragmas.h"
20
#include "pragmas.h"
21
#include "renderlayer.h"
21
#include "renderlayer.h"
22
#include "scancodes.h"
22
#include "scancodes.h"
23
#include "vfs.h"
23
#include "vfs.h"
24
24
25
#ifdef _WIN32
25
#ifdef _WIN32
26
#include "winbits.h"
26
#include "winbits.h"
27
#endif
27
#endif
28
28
29
char levelname[BMAX_PATH] = {0};
29
char levelname[BMAX_PATH] = {0};
30
30
31
#define updatecrc16(crc,dat) (crc = (((crc<<8)&65535)^crctable[((((uint16_t)crc)>>8)&65535)^dat]))
31
#define updatecrc16(crc,dat) (crc = (((crc<<8)&65535)^crctable[((((uint16_t)crc)>>8)&65535)^dat]))
32
static int32_t crctable[256];
32
static int32_t crctable[256];
33
static char kensig[64];
33
static char kensig[64];
34
34
35
static const char *CallExtGetVer(void);
35
static const char *CallExtGetVer(void);
36
static int32_t CallExtInit(void);
36
static int32_t CallExtInit(void);
37
static int32_t CallExtPreInit(int32_t argc,char const * const * argv);
37
static int32_t CallExtPreInit(int32_t argc,char const * const * argv);
38
static int32_t CallExtPostStartupWindow(void);
38
static int32_t CallExtPostStartupWindow(void);
39
static void CallExtPostInit(void);
39
static void CallExtPostInit(void);
40
static void CallExtUnInit(void);
40
static void CallExtUnInit(void);
41
static void CallExtPreCheckKeys(void);
41
static void CallExtPreCheckKeys(void);
42
static void CallExtAnalyzeSprites(int32_t, int32_t, int32_t, int32_t, int32_t);
42
static void CallExtAnalyzeSprites(int32_t, int32_t, int32_t, int32_t, int32_t);
43
static void CallExtCheckKeys(void);
43
static void CallExtCheckKeys(void);
44
static void CallExtPreLoadMap(void);
44
static void CallExtPreLoadMap(void);
45
static void CallExtSetupMapFilename(const char *mapname);
45
static void CallExtSetupMapFilename(const char *mapname);
46
static void CallExtLoadMap(const char *mapname);
46
static void CallExtLoadMap(const char *mapname);
47
static int32_t CallExtPreSaveMap(void);
47
static int32_t CallExtPreSaveMap(void);
48
static void CallExtSaveMap(const char *mapname);
48
static void CallExtSaveMap(const char *mapname);
49
static inline const char *CallExtGetSectorCaption(int16_t sectnum) { return ExtGetSectorCaption(sectnum); }
49
static inline const char *CallExtGetSectorCaption(int16_t sectnum) { return ExtGetSectorCaption(sectnum); }
50
static inline const char *CallExtGetWallCaption(int16_t wallnum) { return ExtGetWallCaption(wallnum); }
50
static inline const char *CallExtGetWallCaption(int16_t wallnum) { return ExtGetWallCaption(wallnum); }
51
static inline const char *CallExtGetSpriteCaption(int16_t spritenum) { return ExtGetSpriteCaption(spritenum); }
51
static inline const char *CallExtGetSpriteCaption(int16_t spritenum) { return ExtGetSpriteCaption(spritenum); }
52
static void CallExtShowSectorData(int16_t sectnum);
52
static void CallExtShowSectorData(int16_t sectnum);
53
static void CallExtShowWallData(int16_t wallnum);
53
static void CallExtShowWallData(int16_t wallnum);
54
static void CallExtShowSpriteData(int16_t spritenum);
54
static void CallExtShowSpriteData(int16_t spritenum);
55
static void CallExtEditSectorData(int16_t sectnum);
55
static void CallExtEditSectorData(int16_t sectnum);
56
static void CallExtEditWallData(int16_t wallnum);
56
static void CallExtEditWallData(int16_t wallnum);
57
static void CallExtEditSpriteData(int16_t spritenum);
57
static void CallExtEditSpriteData(int16_t spritenum);
58
// static const char *CallExtGetSectorType(int32_t lotag);
58
// static const char *CallExtGetSectorType(int32_t lotag);
59
59
60
int8_t m32_clipping=2;
60
int8_t m32_clipping=2;
61
static int32_t m32_rotateang = 0;
61
static int32_t m32_rotateang = 0;
62
62
63
// 0   1     2     3      4       5      6      7
63
// 0   1     2     3      4       5      6      7
64
// up, down, left, right, lshift, rctrl, lctrl, space
64
// up, down, left, right, lshift, rctrl, lctrl, space
65
// 8  9  10    11    12   13
65
// 8  9  10    11    12   13
66
// a, z, pgdn, pgup, [,], [.]
66
// a, z, pgdn, pgup, [,], [.]
67
// 14       15     16 17 18   19
67
// 14       15     16 17 18   19
68
// kpenter, enter, =, -, tab, `
68
// kpenter, enter, =, -, tab, `
69
uint8_t buildkeys[NUMBUILDKEYS] =
69
uint8_t buildkeys[NUMBUILDKEYS] =
70
{
70
{
71
    0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39,
71
    0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39,
72
    0x1e,0x2c,0xd1,0xc9,0x33,0x34,
72
    0x1e,0x2c,0xd1,0xc9,0x33,0x34,
73
    0x9c,0x1c,0xd,0xc,0xf,0x29
73
    0x9c,0x1c,0xd,0xc,0xf,0x29
74
};
74
};
75
75
76
// Start position
76
// Start position
77
vec3_t startpos;
77
vec3_t startpos;
78
int16_t startang, startsectnum;
78
int16_t startang, startsectnum;
79
79
80
// Current position
80
// Current position
81
vec3_t pos;
81
vec3_t pos;
82
int32_t horiz = 100;
82
int32_t horiz = 100;
83
int16_t ang, cursectnum;
83
int16_t ang, cursectnum;
84
static int32_t hvel, vel, svel, angvel;
84
static int32_t hvel, vel, svel, angvel;
85
int32_t g_doHardcodedMovement = 1;
85
int32_t g_doHardcodedMovement = 1;
86
86
87
static int32_t mousexsurp = 0, mouseysurp = 0;
87
static int32_t mousexsurp = 0, mouseysurp = 0;
88
double msens = 1.0;
88
double msens = 1.0;
89
89
90
int32_t grponlymode = 0;
90
int32_t grponlymode = 0;
91
int32_t graphicsmode = 0;
91
int32_t graphicsmode = 0;
92
92
93
int32_t synctics = 0, lockclock = 0;
93
int32_t synctics = 0, lockclock = 0;
94
94
95
// those ones save the respective 3d video vars while in 2d mode
95
// those ones save the respective 3d video vars while in 2d mode
96
// so that exiting from mapster32 in 2d mode saves the correct ones
96
// so that exiting from mapster32 in 2d mode saves the correct ones
97
float vid_gamma_3d=-1, vid_contrast_3d=-1, vid_brightness_3d=-1;
97
float vid_gamma_3d=-1, vid_contrast_3d=-1, vid_brightness_3d=-1;
98
98
99
int32_t xdim2d = 640, ydim2d = 480, xdimgame = 640, ydimgame = 480, bppgame = 8;
99
int32_t xdim2d = 640, ydim2d = 480, xdimgame = 640, ydimgame = 480, bppgame = 8;
100
int32_t forcesetup = 1;
100
int32_t forcesetup = 1;
101
101
102
#ifndef GEKKO
102
#ifndef GEKKO
103
int32_t g_maxCacheSize = 128<<20;
103
int32_t g_maxCacheSize = 128<<20;
104
#else
104
#else
105
int32_t g_maxCacheSize = 8<<20;
105
int32_t g_maxCacheSize = 8<<20;
106
#endif
106
#endif
107
107
108
static int16_t oldmousebstatus = 0;
108
static int16_t oldmousebstatus = 0;
109
109
110
char game_executable[BMAX_PATH] = {0};
110
char game_executable[BMAX_PATH] = {0};
111
111
112
int32_t zlock = 0x7fffffff, zmode = 0, kensplayerheight = 32;
112
int32_t zlock = 0x7fffffff, zmode = 0, kensplayerheight = 32;
113
int16_t defaultspritecstat = 0;
113
int16_t defaultspritecstat = 0;
114
114
115
int16_t localartfreq[MAXTILES];
115
int16_t localartfreq[MAXTILES];
116
int16_t localartlookup[MAXTILES], localartlookupnum;
116
int16_t localartlookup[MAXTILES], localartlookupnum;
117
117
118
char tempbuf[4096];
118
char tempbuf[4096];
119
119
120
char names[MAXTILES][25];
120
char names[MAXTILES][25];
121
const char *g_namesFileName = "NAMES.H";
121
const char *g_namesFileName = "NAMES.H";
122
122
123
int16_t asksave = 0;
123
int16_t asksave = 0;
124
int32_t osearchx, osearchy;                               //old search input
124
int32_t osearchx, osearchy;                               //old search input
125
125
126
int32_t grid = 0, autogrid = 1, gridlock = 1, showtags = 2;
126
int32_t grid = 0, autogrid = 1, gridlock = 1, showtags = 2;
127
int32_t zoom = 768, gettilezoom = 1, ztarget = 768;
127
int32_t zoom = 768, gettilezoom = 1, ztarget = 768;
128
int32_t lastpm16time = 0;
128
int32_t lastpm16time = 0;
129
129
130
extern int32_t mapversion;
130
extern int32_t mapversion;
131
131
132
int16_t highlight[MAXWALLS+MAXSPRITES];
132
int16_t highlight[MAXWALLS+MAXSPRITES];
133
int16_t highlightsector[MAXSECTORS], highlightsectorcnt = -1;
133
int16_t highlightsector[MAXSECTORS], highlightsectorcnt = -1;
134
extern char textfont[128][8];
134
extern char textfont[128][8];
135
135
136
int32_t tempsectornum = -1;  // for auto ceiling/floor alignment
136
int32_t tempsectornum = -1;  // for auto ceiling/floor alignment
137
int32_t temppicnum, tempcstat, templotag, temphitag, tempextra;
137
int32_t temppicnum, tempcstat, templotag, temphitag, tempextra;
138
uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning=0, tempypanning=0;
138
uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning=0, tempypanning=0;
139
int32_t tempshade, tempxvel, tempyvel, tempzvel;
139
int32_t tempshade, tempxvel, tempyvel, tempzvel;
140
int32_t tempstatnum=0, tempblend=0;
140
int32_t tempstatnum=0, tempblend=0;
141
char somethingintab = 255;
141
char somethingintab = 255;
142
142
143
// Only valid when highlightsectorcnt>0 and no structural
143
// Only valid when highlightsectorcnt>0 and no structural
144
// modifications (deleting/inserting sectors or points, setting new firstwall)
144
// modifications (deleting/inserting sectors or points, setting new firstwall)
145
// have been made:
145
// have been made:
146
static int16_t onextwall[MAXWALLS];  // onextwall[i]>=0 implies wall[i].nextwall < 0
146
static int16_t onextwall[MAXWALLS];  // onextwall[i]>=0 implies wall[i].nextwall < 0
147
static void mkonwvalid(void) { chsecptr_onextwall = onextwall; }
147
static void mkonwvalid(void) { chsecptr_onextwall = onextwall; }
148
static void mkonwinvalid(void) { chsecptr_onextwall = NULL; tempsectornum=-1; }
148
static void mkonwinvalid(void) { chsecptr_onextwall = NULL; tempsectornum=-1; }
149
static void mkonwinvalid_keeptempsect(void) { chsecptr_onextwall = NULL; }
149
static void mkonwinvalid_keeptempsect(void) { chsecptr_onextwall = NULL; }
150
static int32_t onwisvalid(void) { return chsecptr_onextwall != NULL; }
150
static int32_t onwisvalid(void) { return chsecptr_onextwall != NULL; }
151
151
152
int32_t mlook = 0, mskip=0;
152
int32_t mlook = 0, mskip=0;
153
int32_t revertCTRL=0,scrollamount=3;
153
int32_t revertCTRL=0,scrollamount=3;
154
int32_t unrealedlook=1, quickmapcycling=1; //PK
154
int32_t unrealedlook=1, quickmapcycling=1; //PK
155
155
156
char program_origcwd[BMAX_PATH];
156
char program_origcwd[BMAX_PATH];
157
const char *mapster32_fullpath;
157
const char *mapster32_fullpath;
158
char *testplay_addparam = 0;
158
char *testplay_addparam = 0;
159
159
160
static char boardfilename[BMAX_PATH], selectedboardfilename[BMAX_PATH];
160
static char boardfilename[BMAX_PATH], selectedboardfilename[BMAX_PATH];
161
//extern char levelname[BMAX_PATH];  // in astub.c   XXX: clean up this mess!!!
161
//extern char levelname[BMAX_PATH];  // in astub.c   XXX: clean up this mess!!!
162
162
163
void B_SetBoardFileName(const char *fn)
163
void B_SetBoardFileName(const char *fn)
164
{
164
{
165
    Bstrncpyz(boardfilename, fn, BMAX_PATH);
165
    Bstrncpyz(boardfilename, fn, BMAX_PATH);
166
}
166
}
167
167
168
static fnlist_t fnlist;
168
static fnlist_t fnlist;
169
static BUILDVFS_FIND_REC *finddirshigh=NULL, *findfileshigh=NULL;
169
static BUILDVFS_FIND_REC *finddirshigh=NULL, *findfileshigh=NULL;
170
static int32_t currentlist=0;
170
static int32_t currentlist=0;
171
171
172
//static int32_t repeatcountx, repeatcounty;
172
//static int32_t repeatcountx, repeatcounty;
173
173
174
static int32_t fillist[640];
174
static int32_t fillist[640];
175
// used for fillsector, batch point insertion, backup_highlighted_map
175
// used for fillsector, batch point insertion, backup_highlighted_map
176
static int32_t tempxyar[MAXWALLS][2];
176
static int32_t tempxyar[MAXWALLS][2];
177
177
178
static int32_t mousx, mousy;
178
static int32_t mousx, mousy;
179
int16_t prefixtiles[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
179
int16_t prefixtiles[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
180
uint8_t hlsectorbitmap[(MAXSECTORS+7)>>3];  // show2dsector is already taken...
180
uint8_t hlsectorbitmap[(MAXSECTORS+7)>>3];  // show2dsector is already taken...
181
static int32_t minhlsectorfloorz, numhlsecwalls;
181
static int32_t minhlsectorfloorz, numhlsecwalls;
182
int32_t searchlock = 0;
182
int32_t searchlock = 0;
183
183
184
// used for:
184
// used for:
185
//  - hl_all_bunch_sectors_p
185
//  - hl_all_bunch_sectors_p
186
//  - AlignWalls
186
//  - AlignWalls
187
//  - trace_loop
187
//  - trace_loop
188
static uint8_t visited[(MAXWALLS+7)>>3];
188
static uint8_t visited[(MAXWALLS+7)>>3];
189
189
190
int32_t m32_2d3dmode = 0;
190
int32_t m32_2d3dmode = 0;
191
int32_t m32_2d3dsize = 4;
191
int32_t m32_2d3dsize = 4;
192
vec2_t m32_2d3d = { 0xffff, 4 };
192
vec2_t m32_2d3d = { 0xffff, 4 };
193
193
194
int32_t m32_3dundo = 1;
194
int32_t m32_3dundo = 1;
195
195
196
typedef struct
196
typedef struct
197
{
197
{
198
    int16_t numsectors, numwalls, numsprites;
198
    int16_t numsectors, numwalls, numsprites;
199
#ifdef YAX_ENABLE
199
#ifdef YAX_ENABLE
200
    int16_t numyaxbunches;
200
    int16_t numyaxbunches;
201
    int16_t *bunchnum;  // [numsectors][2]
201
    int16_t *bunchnum;  // [numsectors][2]
202
    int16_t *ynextwall;  // [numwalls][2]
202
    int16_t *ynextwall;  // [numwalls][2]
203
#endif
203
#endif
204
    usectortype *sector;
204
    usectortype *sector;
205
    uwalltype *wall;
205
    uwalltype *wall;
206
    uspritetype *sprite;
206
    uspritetype *sprite;
207
} mapinfofull_t;
207
} mapinfofull_t;
208
208
209
int32_t g_doScreenShot;
209
int32_t g_doScreenShot;
210
210
211
#define eitherALT   (keystatus[sc_LeftAlt]|keystatus[sc_RightAlt])
211
#define eitherALT   (keystatus[sc_LeftAlt]|keystatus[sc_RightAlt])
212
#define eitherCTRL  (keystatus[sc_LeftControl]|keystatus[sc_RightControl])
212
#define eitherCTRL  (keystatus[sc_LeftControl]|keystatus[sc_RightControl])
213
#define eitherSHIFT (keystatus[sc_LeftShift]|keystatus[sc_RightShift])
213
#define eitherSHIFT (keystatus[sc_LeftShift]|keystatus[sc_RightShift])
214
214
215
#define DOWN_BK(BuildKey) (keystatus[buildkeys[BK_##BuildKey]])
215
#define DOWN_BK(BuildKey) (keystatus[buildkeys[BK_##BuildKey]])
216
216
217
int32_t pk_turnaccel=16;
217
int32_t pk_turnaccel=16;
218
int32_t pk_turndecel=12;
218
int32_t pk_turndecel=12;
219
int32_t pk_uedaccel=3;
219
int32_t pk_uedaccel=3;
220
220
221
int8_t keeptexturestretch = 1;
221
int8_t keeptexturestretch = 1;
222
int8_t sideview_reversehrot = 0;
222
int8_t sideview_reversehrot = 0;
223
223
224
int16_t pointhighlightdist = 256;
224
int16_t pointhighlightdist = 256;
225
int16_t linehighlightdist = 1024;
225
int16_t linehighlightdist = 1024;
226
226
227
char lastpm16buf[156];
227
char lastpm16buf[156];
228
228
229
//static int32_t checksectorpointer_warn = 0;
229
//static int32_t checksectorpointer_warn = 0;
230
static int32_t saveboard_savedtags, saveboard_fixedsprites;
230
static int32_t saveboard_savedtags, saveboard_fixedsprites;
231
static int32_t saveboard_canceled;
231
static int32_t saveboard_canceled;
232
232
233
static int32_t backup_highlighted_map(mapinfofull_t *mapinfo);
233
static int32_t backup_highlighted_map(mapinfofull_t *mapinfo);
234
static int32_t restore_highlighted_map(mapinfofull_t *mapinfo, int32_t forreal);
234
static int32_t restore_highlighted_map(mapinfofull_t *mapinfo, int32_t forreal);
235
static void SaveBoardAndPrintMessage(const char *fn);
235
static void SaveBoardAndPrintMessage(const char *fn);
236
236
237
static int32_t adjustmark(int32_t *xplc, int32_t *yplc, int16_t danumwalls);
237
static int32_t adjustmark(int32_t *xplc, int32_t *yplc, int16_t danumwalls);
238
static void locktogrid(int32_t *dax, int32_t *day);
238
static void locktogrid(int32_t *dax, int32_t *day);
239
static int32_t checkautoinsert(int32_t dax, int32_t day, int16_t danumwalls);
239
static int32_t checkautoinsert(int32_t dax, int32_t day, int16_t danumwalls);
240
static void keytimerstuff(void);
240
static void keytimerstuff(void);
241
static void flipwalls(int16_t numwalls, int16_t newnumwalls);
241
static void flipwalls(int16_t numwalls, int16_t newnumwalls);
242
static int32_t insertpoint(int16_t linehighlight, int32_t dax, int32_t day, int32_t *mapwallnum);
242
static int32_t insertpoint(int16_t linehighlight, int32_t dax, int32_t day, int32_t *mapwallnum);
243
static void deletepoint(int16_t point, int32_t runi);
243
static void deletepoint(int16_t point, int32_t runi);
244
static int32_t deletesector(int16_t sucksect);
244
static int32_t deletesector(int16_t sucksect);
245
static int16_t whitelinescan(int16_t sucksect, int16_t dalinehighlight);
245
static int16_t whitelinescan(int16_t sucksect, int16_t dalinehighlight);
246
static void printcoords16(int32_t posxe, int32_t posye, int16_t ange);
246
static void printcoords16(int32_t posxe, int32_t posye, int16_t ange);
247
static void overheadeditor(void);
247
static void overheadeditor(void);
248
static int32_t getlinehighlight(int32_t xplc, int32_t yplc, int32_t line, int8_t ignore_pointhighlight);
248
static int32_t getlinehighlight(int32_t xplc, int32_t yplc, int32_t line, int8_t ignore_pointhighlight);
249
static int32_t movewalls(int32_t start, int32_t offs);
249
static int32_t movewalls(int32_t start, int32_t offs);
250
static void loadnames(const char *namesfile);
250
static void loadnames(const char *namesfile);
251
static void getclosestpointonwall(int32_t x, int32_t y, int32_t dawall, int32_t *nx, int32_t *ny,
251
static void getclosestpointonwall(int32_t x, int32_t y, int32_t dawall, int32_t *nx, int32_t *ny,
252
                                  int32_t maybe_screen_coord_p);
252
                                  int32_t maybe_screen_coord_p);
253
static void initcrc(void);
253
static void initcrc(void);
254
254
255
static int32_t menuselect(void);
255
static int32_t menuselect(void);
256
static int32_t menuselect_auto(int, int); //PK
256
static int32_t menuselect_auto(int, int); //PK
257
257
258
static int32_t insert_sprite_common(int32_t sectnum, int32_t dax, int32_t day);
258
static int32_t insert_sprite_common(int32_t sectnum, int32_t dax, int32_t day);
259
static void correct_ornamented_sprite(int32_t i, int32_t hitw);
259
static void correct_ornamented_sprite(int32_t i, int32_t hitw);
260
260
261
static int32_t getfilenames(const char *path, const char *kind);
261
static int32_t getfilenames(const char *path, const char *kind);
262
262
263
// Get basename of BUILD file name (forward slashes as directory separators).
263
// Get basename of BUILD file name (forward slashes as directory separators).
264
static const char *getbasefn(const char *fn)
264
static const char *getbasefn(const char *fn)
265
{
265
{
266
    const char *slash = Bstrrchr(fn, '/');
266
    const char *slash = Bstrrchr(fn, '/');
267
    return slash ? slash+1 : fn;
267
    return slash ? slash+1 : fn;
268
}
268
}
269
269
270
void clearkeys(void)
270
void clearkeys(void)
271
{
271
{
272
    Bmemset(keystatus,0,sizeof(keystatus));
272
    Bmemset(keystatus,0,sizeof(keystatus));
273
}
273
}
274
274
275
#ifdef USE_OPENGL
275
#ifdef USE_OPENGL
276
int osdcmd_restartvid(osdcmdptr_t UNUSED(parm))
276
int osdcmd_restartvid(osdcmdptr_t UNUSED(parm))
277
{
277
{
278
    UNREFERENCED_CONST_PARAMETER(parm);
278
    UNREFERENCED_CONST_PARAMETER(parm);
279
279
280
    if (!in3dmode()) return OSDCMD_OK;
280
    if (!in3dmode()) return OSDCMD_OK;
281
281
282
    videoResetMode();
282
    videoResetMode();
283
    if (videoSetGameMode(fullscreen,xres,yres,bpp,upscalefactor))
283
    if (videoSetGameMode(fullscreen,xres,yres,bpp,upscalefactor))
284
        OSD_Printf("restartvid: Reset failed...\n");
284
        OSD_Printf("restartvid: Reset failed...\n");
285
285
286
    return OSDCMD_OK;
286
    return OSDCMD_OK;
287
}
287
}
288
#endif
288
#endif
289
289
290
static int osdcmd_vidmode(osdcmdptr_t parm)
290
static int osdcmd_vidmode(osdcmdptr_t parm)
291
{
291
{
292
    int32_t newx = xres, newy = yres, newbpp = bpp, newfullscreen = fullscreen;
292
    int32_t newx = xres, newy = yres, newbpp = bpp, newfullscreen = fullscreen;
293
#ifdef USE_OPENGL
293
#ifdef USE_OPENGL
294
    int32_t tmp;
294
    int32_t tmp;
295
#endif
295
#endif
296
296
297
    switch (parm->numparms)
297
    switch (parm->numparms)
298
    {
298
    {
299
#ifdef USE_OPENGL
299
#ifdef USE_OPENGL
300
    case 1:     // bpp switch
300
    case 1:     // bpp switch
301
        tmp = Batol(parm->parms[0]);
301
        tmp = Batol(parm->parms[0]);
302
        if (!(tmp==8 || tmp==16 || tmp==32))
302
        if (!(tmp==8 || tmp==16 || tmp==32))
303
            return OSDCMD_SHOWHELP;
303
            return OSDCMD_SHOWHELP;
304
        newbpp = tmp;
304
        newbpp = tmp;
305
        break;
305
        break;
306
    case 4:     // fs, res, bpp switch
306
    case 4:     // fs, res, bpp switch
307
        newfullscreen = (Batol(parm->parms[3]) != 0);
307
        newfullscreen = (Batol(parm->parms[3]) != 0);
308
        fallthrough__;
308
        fallthrough__;
309
    case 3:     // res & bpp switch
309
    case 3:     // res & bpp switch
310
        tmp = Batol(parm->parms[2]);
310
        tmp = Batol(parm->parms[2]);
311
        if (!(tmp==8 || tmp==16 || tmp==32))
311
        if (!(tmp==8 || tmp==16 || tmp==32))
312
            return OSDCMD_SHOWHELP;
312
            return OSDCMD_SHOWHELP;
313
        newbpp = tmp;
313
        newbpp = tmp;
314
        fallthrough__;
314
        fallthrough__;
315
#endif
315
#endif
316
    case 2: // res switch
316
    case 2: // res switch
317
        newx = Batol(parm->parms[0]);
317
        newx = Batol(parm->parms[0]);
318
        newy = Batol(parm->parms[1]);
318
        newy = Batol(parm->parms[1]);
319
        break;
319
        break;
320
    default:
320
    default:
321
        return OSDCMD_SHOWHELP;
321
        return OSDCMD_SHOWHELP;
322
    }
322
    }
323
323
324
    if (!in3dmode())
324
    if (!in3dmode())
325
    {
325
    {
326
        videoSet2dMode(newx,newy);
326
        videoSet2dMode(newx,newy);
327
        xdim2d = xdim;
327
        xdim2d = xdim;
328
        ydim2d = ydim;
328
        ydim2d = ydim;
329
329
330
        videoBeginDrawing();    //{{{
330
        videoBeginDrawing();    //{{{
331
        CLEARLINES2D(0, ydim16, 0);
331
        CLEARLINES2D(0, ydim16, 0);
332
        videoEndDrawing();      //}}}
332
        videoEndDrawing();      //}}}
333
333
334
        ydim16 = ydim-STATUS2DSIZ2;
334
        ydim16 = ydim-STATUS2DSIZ2;
335
335
336
        return OSDCMD_OK;
336
        return OSDCMD_OK;
337
    }
337
    }
338
338
339
    if (videoSetGameMode(newfullscreen,newx,newy,newbpp,upscalefactor))
339
    if (videoSetGameMode(newfullscreen,newx,newy,newbpp,upscalefactor))
340
        OSD_Printf("vidmode: Mode change failed!\n");
340
        OSD_Printf("vidmode: Mode change failed!\n");
341
341
342
    xdimgame = newx;
342
    xdimgame = newx;
343
    ydimgame = newy;
343
    ydimgame = newy;
344
    bppgame = newbpp;
344
    bppgame = newbpp;
345
    fullscreen = newfullscreen;
345
    fullscreen = newfullscreen;
346
346
347
    return OSDCMD_OK;
347
    return OSDCMD_OK;
348
}
348
}
349
349
350
350
351
#ifdef M32_SHOWDEBUG
351
#ifdef M32_SHOWDEBUG
352
char m32_debugstr[64][128];
352
char m32_debugstr[64][128];
353
int32_t m32_numdebuglines=0;
353
int32_t m32_numdebuglines=0;
354
354
355
static void M32_drawdebug(void)
355
static void M32_drawdebug(void)
356
{
356
{
357
    int32_t i;
357
    int32_t i;
358
    int32_t x=4, y=8;
358
    int32_t x=4, y=8;
359
359
360
#if 0
360
#if 0
361
    {
361
    {
362
        static char tstr[128];
362
        static char tstr[128];
363
        Bsprintf(tstr, "search... stat=%d, sector=%d, wall=%d (%d), isbottom=%d, asksave=%d",
363
        Bsprintf(tstr, "search... stat=%d, sector=%d, wall=%d (%d), isbottom=%d, asksave=%d",
364
                 searchstat, searchsector, searchwall, searchbottomwall, searchisbottom, asksave);
364
                 searchstat, searchsector, searchwall, searchbottomwall, searchisbottom, asksave);
365
        printext256(x,y,whitecol,0,tstr,xdimgame>640?0:1);
365
        printext256(x,y,whitecol,0,tstr,xdimgame>640?0:1);
366
    }
366
    }
367
#endif
367
#endif
368
    if (m32_numdebuglines>0)
368
    if (m32_numdebuglines>0)
369
    {
369
    {
370
        videoBeginDrawing();
370
        videoBeginDrawing();
371
        for (i=0; i<m32_numdebuglines && y<ydim-8; i++, y+=8)
371
        for (i=0; i<m32_numdebuglines && y<ydim-8; i++, y+=8)
372
            printext256(x,y,whitecol,0,m32_debugstr[i],xdimgame>640?0:1);
372
            printext256(x,y,whitecol,0,m32_debugstr[i],xdimgame>640?0:1);
373
        videoEndDrawing();
373
        videoEndDrawing();
374
    }
374
    }
375
    m32_numdebuglines=0;
375
    m32_numdebuglines=0;
376
}
376
}
377
#endif
377
#endif
378
378
379
#ifdef YAX_ENABLE
379
#ifdef YAX_ENABLE
380
// Check whether bunchnum has exactly one corresponding floor and ceiling
380
// Check whether bunchnum has exactly one corresponding floor and ceiling
381
// and return it in this case. If not 1-to-1, return -1.
381
// and return it in this case. If not 1-to-1, return -1.
382
int32_t yax_is121(int16_t bunchnum, int16_t getfloor)
382
int32_t yax_is121(int16_t bunchnum, int16_t getfloor)
383
{
383
{
384
    int32_t i;
384
    int32_t i;
385
    i = headsectbunch[0][bunchnum];
385
    i = headsectbunch[0][bunchnum];
386
    if (i<0 || nextsectbunch[0][i]>=0)
386
    if (i<0 || nextsectbunch[0][i]>=0)
387
        return -1;
387
        return -1;
388
    i = headsectbunch[1][bunchnum];
388
    i = headsectbunch[1][bunchnum];
389
    if (i<0 || nextsectbunch[1][i]>=0)
389
    if (i<0 || nextsectbunch[1][i]>=0)
390
        return -1;
390
        return -1;
391
391
392
    return headsectbunch[getfloor][bunchnum];
392
    return headsectbunch[getfloor][bunchnum];
393
}
393
}
394
394
395
static int32_t yax_numsectsinbunch(int16_t bunchnum, int16_t cf)
395
static int32_t yax_numsectsinbunch(int16_t bunchnum, int16_t cf)
396
{
396
{
397
    int32_t i, n=0;
397
    int32_t i, n=0;
398
398
399
    if (bunchnum<0 || bunchnum>=numyaxbunches)
399
    if (bunchnum<0 || bunchnum>=numyaxbunches)
400
        return -1;
400
        return -1;
401
401
402
    for (SECTORS_OF_BUNCH(bunchnum, cf, i))
402
    for (SECTORS_OF_BUNCH(bunchnum, cf, i))
403
        n++;
403
        n++;
404
404
405
    return n;
405
    return n;
406
}
406
}
407
407
408
static void yax_fixreverselinks(int16_t oldwall, int16_t newwall)
408
static void yax_fixreverselinks(int16_t oldwall, int16_t newwall)
409
{
409
{
410
    int32_t cf, ynw;
410
    int32_t cf, ynw;
411
    for (cf=0; cf<2; cf++)
411
    for (cf=0; cf<2; cf++)
412
    {
412
    {
413
        ynw = yax_getnextwall(oldwall, cf);
413
        ynw = yax_getnextwall(oldwall, cf);
414
        if (ynw >= 0)
414
        if (ynw >= 0)
415
            yax_setnextwall(ynw, !cf, newwall);
415
            yax_setnextwall(ynw, !cf, newwall);
416
    }
416
    }
417
}
417
}
418
418
419
static void yax_tweakwalls(int16_t start, int16_t offs)
419
static void yax_tweakwalls(int16_t start, int16_t offs)
420
{
420
{
421
    int32_t i, nw, cf;
421
    int32_t i, nw, cf;
422
    for (i=0; i<numwalls; i++)
422
    for (i=0; i<numwalls; i++)
423
        for (cf=0; cf<2; cf++)
423
        for (cf=0; cf<2; cf++)
424
        {
424
        {
425
            nw = yax_getnextwall(i, cf);
425
            nw = yax_getnextwall(i, cf);
426
            if (nw >= start)
426
            if (nw >= start)
427
                yax_setnextwall(i, cf, nw+offs);
427
                yax_setnextwall(i, cf, nw+offs);
428
        }
428
        }
429
}
429
}
430
430
431
static void yax_resetbunchnums(void)
431
static void yax_resetbunchnums(void)
432
{
432
{
433
    int32_t i;
433
    int32_t i;
434
434
435
    for (i=0; i<MAXSECTORS; i++)
435
    for (i=0; i<MAXSECTORS; i++)
436
        yax_setbunches(i, -1, -1);
436
        yax_setbunches(i, -1, -1);
437
    yax_update(1);
437
    yax_update(1);
438
    yax_updategrays(pos.z);
438
    yax_updategrays(pos.z);
439
}
439
}
440
440
441
// Whether a wall is constrained by sector extensions.
441
// Whether a wall is constrained by sector extensions.
442
// If false, it's a wall that you can freely move around,
442
// If false, it's a wall that you can freely move around,
443
// attach points to, etc...
443
// attach points to, etc...
444
static int32_t yax_islockedwall(int16_t line)
444
static int32_t yax_islockedwall(int16_t line)
445
{
445
{
446
#ifdef NEW_MAP_FORMAT
446
#ifdef NEW_MAP_FORMAT
447
    return (wall[line].upwall>=0 || wall[line].dnwall>=0);
447
    return (wall[line].upwall>=0 || wall[line].dnwall>=0);
448
#else
448
#else
449
    return !!(wall[line].cstat&YAX_NEXTWALLBITS);
449
    return !!(wall[line].cstat&YAX_NEXTWALLBITS);
450
#endif
450
#endif
451
}
451
}
452
452
453
# define DEFAULT_YAX_HEIGHT (2048<<4)
453
# define DEFAULT_YAX_HEIGHT (2048<<4)
454
#endif
454
#endif
455
455
456
static void reset_default_mapstate(void)
456
static void reset_default_mapstate(void)
457
{
457
{
458
    pos.x = 32768;          //new board!
458
    pos.x = 32768;          //new board!
459
    pos.y = 32768;
459
    pos.y = 32768;
460
    pos.z = 0;
460
    pos.z = 0;
461
    ang = 1536;
461
    ang = 1536;
462
    cursectnum = -1;
462
    cursectnum = -1;
463
463
464
    numsectors = 0;
464
    numsectors = 0;
465
    numwalls = 0;
465
    numwalls = 0;
466
466
467
    editorzrange[0] = INT32_MIN;
467
    editorzrange[0] = INT32_MIN;
468
    editorzrange[1] = INT32_MAX;
468
    editorzrange[1] = INT32_MAX;
469
469
470
    initspritelists();
470
    initspritelists();
471
    taglab_init();
471
    taglab_init();
472
    artClearMapArt();
472
    artClearMapArt();
473
#ifdef YAX_ENABLE
473
#ifdef YAX_ENABLE
474
    yax_resetbunchnums();
474
    yax_resetbunchnums();
475
#endif
475
#endif
476
    g_loadedMapVersion = -1;
476
    g_loadedMapVersion = -1;
477
}
477
}
478
478
479
static void m32_keypresscallback(int32_t code, int32_t downp)
479
static void m32_keypresscallback(int32_t code, int32_t downp)
480
{
480
{
481
    UNREFERENCED_PARAMETER(downp);
481
    UNREFERENCED_PARAMETER(downp);
482
482
483
    g_iReturnVar = code;
483
    g_iReturnVar = code;
484
    VM_OnEvent(EVENT_KEYPRESS, -1);
484
    VM_OnEvent(EVENT_KEYPRESS, -1);
485
}
485
}
486
486
487
void M32_ResetFakeRORTiles(void)
487
void M32_ResetFakeRORTiles(void)
488
{
488
{
489
#ifdef POLYMER
489
#ifdef POLYMER
490
# ifdef YAX_ENABLE
490
# ifdef YAX_ENABLE
491
        // END_TWEAK ceiling/floor fake 'TROR' pics, see BEGIN_TWEAK in engine.c
491
        // END_TWEAK ceiling/floor fake 'TROR' pics, see BEGIN_TWEAK in engine.c
492
        if (videoGetRenderMode() == REND_POLYMER && showinvisibility)
492
        if (videoGetRenderMode() == REND_POLYMER && showinvisibility)
493
        {
493
        {
494
            int32_t i;
494
            int32_t i;
495
495
496
            for (i=0; i<numyaxbunches; i++)
496
            for (i=0; i<numyaxbunches; i++)
497
            {
497
            {
498
                yax_tweakpicnums(i, YAX_CEILING, 1);
498
                yax_tweakpicnums(i, YAX_CEILING, 1);
499
                yax_tweakpicnums(i, YAX_FLOOR, 1);
499
                yax_tweakpicnums(i, YAX_FLOOR, 1);
500
            }
500
            }
501
        }
501
        }
502
# endif
502
# endif
503
#endif
503
#endif
504
}
504
}
505
505
506
void M32_DrawRoomsAndMasks(void)
506
void M32_DrawRoomsAndMasks(void)
507
{
507
{
508
    static int srchwall = -1;
508
    static int srchwall = -1;
509
    const int32_t tmpyx=yxaspect, tmpvr=viewingrange;
509
    const int32_t tmpyx=yxaspect, tmpvr=viewingrange;
510
510
511
    if (r_usenewaspect)
511
    if (r_usenewaspect)
512
    {
512
    {
513
        newaspect_enable = 1;
513
        newaspect_enable = 1;
514
        videoSetCorrectedAspect();
514
        videoSetCorrectedAspect();
515
    }
515
    }
516
516
517
    VM_OnEvent(EVENT_PREDRAW3DSCREEN, -1);
517
    VM_OnEvent(EVENT_PREDRAW3DSCREEN, -1);
518
518
519
    yax_preparedrawrooms();
519
    yax_preparedrawrooms();
520
    drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum);
520
    drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum);
521
    yax_drawrooms(CallExtAnalyzeSprites, cursectnum, 0, 0);
521
    yax_drawrooms(CallExtAnalyzeSprites, cursectnum, 0, 0);
522
522
523
    const int osearchwall=searchwall, osearchstat=searchstat;
523
    const int osearchwall=searchwall, osearchstat=searchstat;
524
    if (srchwall >= 0)
524
    if (srchwall >= 0)
525
    {
525
    {
526
        // a.m32 states 'tduprot' and 'tduplin' need searchstat to check for
526
        // a.m32 states 'tduprot' and 'tduplin' need searchstat to check for
527
        // whether we've hit a sprite, but these would be only set after the
527
        // whether we've hit a sprite, but these would be only set after the
528
        // drawmasks(). Hence this hackish workaround.
528
        // drawmasks(). Hence this hackish workaround.
529
        searchstat = 3;
529
        searchstat = 3;
530
        searchwall = srchwall;
530
        searchwall = srchwall;
531
    }
531
    }
532
    CallExtAnalyzeSprites(0,0,0,0,0);
532
    CallExtAnalyzeSprites(0,0,0,0,0);
533
    searchwall = osearchwall, searchstat=osearchstat;
533
    searchwall = osearchwall, searchstat=osearchstat;
534
534
535
    renderDrawMasks();
535
    renderDrawMasks();
536
    srchwall = (searchstat == 3) ? searchwall : -1;
536
    srchwall = (searchstat == 3) ? searchwall : -1;
537
    M32_ResetFakeRORTiles();
537
    M32_ResetFakeRORTiles();
538
538
539
#ifdef POLYMER
539
#ifdef POLYMER
540
    if (videoGetRenderMode() == REND_POLYMER && searchit == 2)
540
    if (videoGetRenderMode() == REND_POLYMER && searchit == 2)
541
    {
541
    {
542
        polymer_editorpick();
542
        polymer_editorpick();
543
        drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum);
543
        drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum);
544
        CallExtAnalyzeSprites(0,0,0,0,0);
544
        CallExtAnalyzeSprites(0,0,0,0,0);
545
        renderDrawMasks();
545
        renderDrawMasks();
546
        M32_ResetFakeRORTiles();
546
        M32_ResetFakeRORTiles();
547
    }
547
    }
548
#endif
548
#endif
549
549
550
    VM_OnEvent(EVENT_DRAW3DSCREEN, -1);
550
    VM_OnEvent(EVENT_DRAW3DSCREEN, -1);
551
551
552
    if (g_doScreenShot)
552
    if (g_doScreenShot)
553
    {
553
    {
554
        videoCaptureScreen("mcapxxxx.tga", 0);
554
        videoCaptureScreen("mcapxxxx.tga", 0);
555
        g_doScreenShot = 0;
555
        g_doScreenShot = 0;
556
    }
556
    }
557
557
558
    if (r_usenewaspect)
558
    if (r_usenewaspect)
559
    {
559
    {
560
        newaspect_enable = 0;
560
        newaspect_enable = 0;
561
        renderSetAspect(tmpvr, tmpyx);
561
        renderSetAspect(tmpvr, tmpyx);
562
    }
562
    }
563
}
563
}
564
564
565
void M32_OnShowOSD(int shown)
565
void M32_OnShowOSD(int shown)
566
{
566
{
567
    mouseLockToWindow((!shown) + 2);
567
    mouseLockToWindow((!shown) + 2);
568
}
568
}
569
569
570
static void M32_FatalEngineError(void)
570
static void M32_FatalEngineError(void)
571
{
571
{
572
#ifdef DEBUGGINGAIDS
572
#ifdef DEBUGGINGAIDS
573
    debug_break();
573
    debug_break();
574
#endif
574
#endif
575
    Bsprintf(tempbuf, "There was a problem initializing the engine: %s\n", engineerrstr);
575
    Bsprintf(tempbuf, "There was a problem initializing the engine: %s\n", engineerrstr);
576
    ERRprintf("%s", tempbuf);
576
    ERRprintf("%s", tempbuf);
577
    fatal_exit(tempbuf);
577
    fatal_exit(tempbuf);
578
}
578
}
579
579
580
static void InitCustomColors()
580
static void InitCustomColors()
581
{
581
{
582
    /* blue */
582
    /* blue */
583
    vgapal16[9*4+0] = 252;
583
    vgapal16[9*4+0] = 252;
584
    vgapal16[9*4+1] = 124;
584
    vgapal16[9*4+1] = 124;
585
    vgapal16[9*4+2] = 28;
585
    vgapal16[9*4+2] = 28;
586
586
587
    /* orange */
587
    /* orange */
588
    vgapal16[31*4+0] = 80; // blue
588
    vgapal16[31*4+0] = 80; // blue
589
    vgapal16[31*4+1] = 180; // green
589
    vgapal16[31*4+1] = 180; // green
590
    vgapal16[31*4+2] = 240; // red
590
    vgapal16[31*4+2] = 240; // red
591
591
592
    // UNUSED?
592
    // UNUSED?
593
    vgapal16[39*4+0] = 144;
593
    vgapal16[39*4+0] = 144;
594
    vgapal16[39*4+1] = 212;
594
    vgapal16[39*4+1] = 212;
595
    vgapal16[39*4+2] = 252;
595
    vgapal16[39*4+2] = 252;
596
596
597
597
598
    /* light yellow */
598
    /* light yellow */
599
    vgapal16[22*4+0] = 204;
599
    vgapal16[22*4+0] = 204;
600
    vgapal16[22*4+1] = 252;
600
    vgapal16[22*4+1] = 252;
601
    vgapal16[22*4+2] = 252;
601
    vgapal16[22*4+2] = 252;
602
602
603
    /* grey */
603
    /* grey */
604
    vgapal16[23*4+0] = 180;
604
    vgapal16[23*4+0] = 180;
605
    vgapal16[23*4+1] = 180;
605
    vgapal16[23*4+1] = 180;
606
    vgapal16[23*4+2] = 180;
606
    vgapal16[23*4+2] = 180;
607
607
608
    /* blue */
608
    /* blue */
609
    vgapal16[24*4+0] = 204;
609
    vgapal16[24*4+0] = 204;
610
    vgapal16[24*4+1] = 164;
610
    vgapal16[24*4+1] = 164;
611
    vgapal16[24*4+2] = 48;
611
    vgapal16[24*4+2] = 48;
612
612
613
    vgapal16[32*4+0] = 240;
613
    vgapal16[32*4+0] = 240;
614
    vgapal16[32*4+1] = 200;
614
    vgapal16[32*4+1] = 200;
615
    vgapal16[32*4+2] = 84;
615
    vgapal16[32*4+2] = 84;
616
616
617
    // grid color
617
    // grid color
618
    vgapal16[25*4+0] = 64;
618
    vgapal16[25*4+0] = 64;
619
    vgapal16[25*4+1] = 56;
619
    vgapal16[25*4+1] = 56;
620
    vgapal16[25*4+2] = 56;
620
    vgapal16[25*4+2] = 56;
621
621
622
    vgapal16[26*4+0] = 96;
622
    vgapal16[26*4+0] = 96;
623
    vgapal16[26*4+1] = 96;
623
    vgapal16[26*4+1] = 96;
624
    vgapal16[26*4+2] = 96;
624
    vgapal16[26*4+2] = 96;
625
625
626
    // UNUSED?
626
    // UNUSED?
627
    vgapal16[33*4+0] = 0; //60; // blue
627
    vgapal16[33*4+0] = 0; //60; // blue
628
    vgapal16[33*4+1] = 0; //120; // green
628
    vgapal16[33*4+1] = 0; //120; // green
629
    vgapal16[33*4+2] = 192; //180; // red
629
    vgapal16[33*4+2] = 192; //180; // red
630
630
631
    // UNUSED?
631
    // UNUSED?
632
    vgapal16[41*4+0] = 0; //96;
632
    vgapal16[41*4+0] = 0; //96;
633
    vgapal16[41*4+1] = 0; //160;
633
    vgapal16[41*4+1] = 0; //160;
634
    vgapal16[41*4+2] = 252; //192;
634
    vgapal16[41*4+2] = 252; //192;
635
635
636
    for (int i = 0; i<256; i++)
636
    for (int i = 0; i<256; i++)
637
    {
637
    {
638
        if (editorcolors[i] == 0)
638
        if (editorcolors[i] == 0)
639
        {
639
        {
640
            palette_t *edcol = (palette_t *)&vgapal16[4*i];
640
            palette_t *edcol = (palette_t *)&vgapal16[4*i];
641
            editorcolors[i] = getclosestcol_lim(edcol->b,edcol->g,edcol->r, 239);
641
            editorcolors[i] = paletteGetClosestColorUpToIndex(edcol->b,edcol->g,edcol->r, 239);
642
        }
642
        }
643
    }
643
    }
644
}
644
}
645
645
646
int app_main(int argc, char const * const * argv)
646
int app_main(int argc, char const * const * argv)
647
{
647
{
648
#ifdef STARTUP_SETUP_WINDOW
648
#ifdef STARTUP_SETUP_WINDOW
649
    char cmdsetup = 0;
649
    char cmdsetup = 0;
650
#endif
650
#endif
651
    char quitflag;
651
    char quitflag;
652
    int32_t i;
652
    int32_t i;
653
653
654
    pathsearchmode = 1;         // unrestrict findfrompath so that full access to the filesystem can be had
654
    pathsearchmode = 1;         // unrestrict findfrompath so that full access to the filesystem can be had
655
655
656
#ifdef USE_OPENGL
656
#ifdef USE_OPENGL
657
    OSD_RegisterFunction("restartvid","restartvid: reinitialize the video mode",osdcmd_restartvid);
657
    OSD_RegisterFunction("restartvid","restartvid: reinitialize the video mode",osdcmd_restartvid);
658
    OSD_RegisterFunction("vidmode","vidmode <xdim> <ydim> <bpp> <fullscreen>: immediately change the video mode",osdcmd_vidmode);
658
    OSD_RegisterFunction("vidmode","vidmode <xdim> <ydim> <bpp> <fullscreen>: immediately change the video mode",osdcmd_vidmode);
659
    baselayer_osdcmd_vidmode_func = osdcmd_vidmode;
659
    baselayer_osdcmd_vidmode_func = osdcmd_vidmode;
660
#else
660
#else
661
    OSD_RegisterFunction("vidmode","vidmode <xdim> <ydim>: immediately change the video mode",osdcmd_vidmode);
661
    OSD_RegisterFunction("vidmode","vidmode <xdim> <ydim>: immediately change the video mode",osdcmd_vidmode);
662
#endif
662
#endif
663
663
664
    wm_setapptitle(AppProperName);
664
    wm_setapptitle(AppProperName);
665
665
666
    editstatus = 1;
666
    editstatus = 1;
667
667
668
    if ((i = CallExtPreInit(argc,argv)) < 0) return -1;
668
    if ((i = CallExtPreInit(argc,argv)) < 0) return -1;
669
669
670
#ifdef _WIN32
670
#ifdef _WIN32
671
    win_priorityclass = 1;
671
    win_priorityclass = 1;
672
#endif
672
#endif
673
673
674
    for (i=1; i<argc; i++)
674
    for (i=1; i<argc; i++)
675
    {
675
    {
676
        if (argv[i][0] == '-')
676
        if (argv[i][0] == '-')
677
        {
677
        {
678
#ifdef STARTUP_SETUP_WINDOW
678
#ifdef STARTUP_SETUP_WINDOW
679
            if (!Bstrcmp(argv[i], "-setup")) cmdsetup = 1;
679
            if (!Bstrcmp(argv[i], "-setup")) cmdsetup = 1;
680
            else
680
            else
681
#endif
681
#endif
682
            if (!Bstrcmp(argv[i], "-help") || !Bstrcmp(argv[i], "--help") || !Bstrcmp(argv[i], "-?"))
682
            if (!Bstrcmp(argv[i], "-help") || !Bstrcmp(argv[i], "--help") || !Bstrcmp(argv[i], "-?"))
683
            {
683
            {
684
#ifdef WM_MSGBOX_WINDOW
684
#ifdef WM_MSGBOX_WINDOW
685
                wm_msgbox(AppProperName,
685
                wm_msgbox(AppProperName,
686
#else
686
#else
687
                Bprintf(
687
                Bprintf(
688
#endif
688
#endif
689
                    "%s\n"
689
                    "%s\n"
690
                    "Syntax: %s [options] mapname\n"
690
                    "Syntax: %s [options] mapname\n"
691
                    "Options:\n"
691
                    "Options:\n"
692
                    "\t-grp\tUse an extra GRP or ZIP file.\n"
692
                    "\t-grp\tUse an extra GRP or ZIP file.\n"
693
                    "\t-g\tSame as above.\n"
693
                    "\t-g\tSame as above.\n"
694
#ifdef STARTUP_SETUP_WINDOW
694
#ifdef STARTUP_SETUP_WINDOW
695
                    "\t-setup\tDisplays the configuration dialogue box before entering the editor.\n"
695
                    "\t-setup\tDisplays the configuration dialogue box before entering the editor.\n"
696
#endif
696
#endif
697
                    , AppProperName, AppTechnicalName);
697
                    , AppProperName, AppTechnicalName);
698
                return 0;
698
                return 0;
699
            }
699
            }
700
            continue;
700
            continue;
701
        }
701
        }
702
    }
702
    }
703
703
704
    if (boardfilename[0] == 0)
704
    if (boardfilename[0] == 0)
705
        Bstrcpy(boardfilename,"newboard.map");
705
        Bstrcpy(boardfilename,"newboard.map");
706
    else if (Bstrchr(boardfilename,'.') == 0)
706
    else if (Bstrchr(boardfilename,'.') == 0)
707
        Bstrcat(boardfilename, ".map");
707
        Bstrcat(boardfilename, ".map");
708
    //Bcanonicalisefilename(boardfilename,0);
708
    //Bcanonicalisefilename(boardfilename,0);
709
709
710
    OSD_SetFunctions(
710
    OSD_SetFunctions(
711
        NULL, NULL, NULL, NULL, NULL,
711
        NULL, NULL, NULL, NULL, NULL,
712
        COMMON_clearbackground,
712
        COMMON_clearbackground,
713
        BGetTime,
713
        BGetTime,
714
        M32_OnShowOSD
714
        M32_OnShowOSD
715
    );
715
    );
716
716
717
    if (!buildvfs_getcwd(program_origcwd,BMAX_PATH))
717
    if (!buildvfs_getcwd(program_origcwd,BMAX_PATH))
718
        program_origcwd[0] = '\0';
718
        program_origcwd[0] = '\0';
719
719
720
    Bstrncpy(game_executable, DefaultGameLocalExec, sizeof(game_executable));
720
    Bstrncpy(game_executable, DefaultGameLocalExec, sizeof(game_executable));
721
721
722
    if (enginePreInit())
722
    if (enginePreInit())
723
        M32_FatalEngineError();
723
        M32_FatalEngineError();
724
724
725
    if ((i = CallExtInit()) < 0) return -1;
725
    if ((i = CallExtInit()) < 0) return -1;
726
726
727
#ifdef STARTUP_SETUP_WINDOW
727
#ifdef STARTUP_SETUP_WINDOW
728
    if (i || forcesetup || cmdsetup)
728
    if (i || forcesetup || cmdsetup)
729
    {
729
    {
730
        if (quitevent || !startwin_run())
730
        if (quitevent || !startwin_run())
731
        {
731
        {
732
            engineUnInit();
732
            engineUnInit();
733
            exit(EXIT_SUCCESS);
733
            exit(EXIT_SUCCESS);
734
        }
734
        }
735
    }
735
    }
736
#endif
736
#endif
737
737
738
    if (CallExtPostStartupWindow() < 0) return -1;
738
    if (CallExtPostStartupWindow() < 0) return -1;
739
739
740
    loadnames(g_namesFileName);
740
    loadnames(g_namesFileName);
741
741
742
    if (initinput()) return -1;
742
    if (initinput()) return -1;
743
743
744
    mouseInit();
744
    mouseInit();
745
745
746
    timerInit(CLOCKTICKSPERSECOND);
746
    timerInit(CLOCKTICKSPERSECOND);
747
    timerSetCallback(keytimerstuff);
747
    timerSetCallback(keytimerstuff);
748
748
749
    artLoadFiles("tiles000.art", g_maxCacheSize);
749
    artLoadFiles("tiles000.art", g_maxCacheSize);
750
750
751
    Bstrcpy(kensig,"Uses BUILD technology by Ken Silverman");
751
    Bstrcpy(kensig,"Uses BUILD technology by Ken Silverman");
752
    initcrc();
752
    initcrc();
753
753
754
    const char *defsfile = G_DefFile();
754
    const char *defsfile = G_DefFile();
755
755
756
    if (testkopen("editor.def", 0))
756
    if (testkopen("editor.def", 0))
757
        G_AddDefModule("editor.def");
757
        G_AddDefModule("editor.def");
758
758
759
    if (!loaddefinitionsfile(defsfile))
759
    if (!loaddefinitionsfile(defsfile))
760
        initprintf("Definitions file \"%s\" loaded.\n",defsfile);
760
        initprintf("Definitions file \"%s\" loaded.\n",defsfile);
761
761
762
    for (char * m : g_defModules)
762
    for (char * m : g_defModules)
763
        free(m);
763
        free(m);
764
    g_defModules.clear();
764
    g_defModules.clear();
765
765
766
    if (enginePostInit())
766
    if (enginePostInit())
767
        M32_FatalEngineError();
767
        M32_FatalEngineError();
768
768
769
    InitCustomColors();
769
    InitCustomColors();
770
770
771
    CallExtPostInit();
771
    CallExtPostInit();
772
772
773
#ifdef YAX_ENABLE
773
#ifdef YAX_ENABLE
774
    // init dummy texture for YAX
774
    // init dummy texture for YAX
775
    // must be after loadpics(), which inits BUILD's cache
775
    // must be after loadpics(), which inits BUILD's cache
776
776
777
    i = MAXTILES-1;
777
    i = MAXTILES-1;
778
    if (tilesiz[i].x==0 && tilesiz[i].y==0)
778
    if (tilesiz[i].x==0 && tilesiz[i].y==0)
779
    {
779
    {
780
        static char R[8*16] = { //
780
        static char R[8*16] = { //
781
            0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
781
            0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
782
            0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
782
            0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
783
            0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
783
            0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
784
            0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0,
784
            0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0,
785
            0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0,
785
            0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0,
786
            0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0,
786
            0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0,
787
            0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0,
787
            0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0,
788
        };
788
        };
789
789
790
        char *newtile;
790
        char *newtile;
791
        int32_t sx=32, sy=32, col, j;
791
        int32_t sx=32, sy=32, col, j;
792
792
793
        walock[i] = CACHE1D_PERMANENT;
793
        walock[i] = CACHE1D_PERMANENT;
794
        picsiz[i] = 5 + (5<<4);
794
        picsiz[i] = 5 + (5<<4);
795
        tilesiz[i].x = sx; tilesiz[i].y = sy;
795
        tilesiz[i].x = sx; tilesiz[i].y = sy;
796
        g_cache.allocateBlock(&waloff[i], sx*sy, &walock[i]);
796
        g_cache.allocateBlock(&waloff[i], sx*sy, &walock[i]);
797
        newtile = (char *)waloff[i];
797
        newtile = (char *)waloff[i];
798
798
799
        col = paletteGetClosestColor(128, 128, 0);
799
        col = paletteGetClosestColor(128, 128, 0);
800
        for (j=0; j<(signed)sizeof(R); j++)
800
        for (j=0; j<(signed)sizeof(R); j++)
801
            R[j] *= col;
801
            R[j] *= col;
802
802
803
        Bmemset(newtile, 0, sx*sy);
803
        Bmemset(newtile, 0, sx*sy);
804
        for (j=0; j<8; j++)
804
        for (j=0; j<8; j++)
805
            Bmemcpy(&newtile[32*j], &R[16*j], 16);
805
            Bmemcpy(&newtile[32*j], &R[16*j], 16);
806
    }
806
    }
807
#endif
807
#endif
808
808
809
#ifdef HAVE_CLIPSHAPE_FEATURE
809
#ifdef HAVE_CLIPSHAPE_FEATURE
810
    int k = engineLoadClipMaps();
810
    int k = engineLoadClipMaps();
811
    if (k>0)
811
    if (k>0)
812
        initprintf("There was an error loading the sprite clipping map (status %d).\n", k);
812
        initprintf("There was an error loading the sprite clipping map (status %d).\n", k);
813
813
814
    for (char * f : g_clipMapFiles)
814
    for (char * f : g_clipMapFiles)
815
        free(f);
815
        free(f);
816
    g_clipMapFiles.clear();
816
    g_clipMapFiles.clear();
817
#endif
817
#endif
818
818
819
    taglab_init();
819
    taglab_init();
820
820
821
    mkonwinvalid();
821
    mkonwinvalid();
822
822
823
    // executed once per init
823
    // executed once per init
824
    OSD_Exec("m32_autoexec.cfg");
824
    OSD_Exec("m32_autoexec.cfg");
825
825
826
    if (LoadBoard(boardfilename, 1))
826
    if (LoadBoard(boardfilename, 1))
827
        reset_default_mapstate();
827
        reset_default_mapstate();
828
828
829
    totalclock = 0;
829
    totalclock = 0;
830
830
831
    updatesector(pos.x,pos.y,&cursectnum);
831
    updatesector(pos.x,pos.y,&cursectnum);
832
832
833
    keySetCallback(&m32_keypresscallback);
833
    keySetCallback(&m32_keypresscallback);
834
    M32_OnShowOSD(0);  // make sure the desktop's mouse cursor is hidden
834
    M32_OnShowOSD(0);  // make sure the desktop's mouse cursor is hidden
835
835
836
    if (cursectnum == -1)
836
    if (cursectnum == -1)
837
    {
837
    {
838
        vid_gamma_3d = g_videoGamma;
838
        vid_gamma_3d = g_videoGamma;
839
        vid_brightness_3d = g_videoBrightness;
839
        vid_brightness_3d = g_videoBrightness;
840
        vid_contrast_3d = g_videoContrast;
840
        vid_contrast_3d = g_videoContrast;
841
841
842
        g_videoGamma = g_videoContrast = 1.0;
842
        g_videoGamma = g_videoContrast = 1.0;
843
        g_videoBrightness = 0.0;
843
        g_videoBrightness = 0.0;
844
844
845
        videoSetPalette(0,0,0);
845
        videoSetPalette(0,0,0);
846
        if (videoSetGameMode(fullscreen, xdim2d, ydim2d, 8, upscalefactor) < 0)
846
        if (videoSetGameMode(fullscreen, xdim2d, ydim2d, 8, upscalefactor) < 0)
847
        {
847
        {
848
            CallExtUnInit();
848
            CallExtUnInit();
849
            engineUnInit();
849
            engineUnInit();
850
            Bprintf("%d * %d not supported in this graphics mode\n",xdim2d,ydim2d);
850
            Bprintf("%d * %d not supported in this graphics mode\n",xdim2d,ydim2d);
851
            Bexit(EXIT_SUCCESS);
851
            Bexit(EXIT_SUCCESS);
852
        }
852
        }
853
853
854
        system_getcvars();
854
        system_getcvars();
855
855
856
        overheadeditor();
856
        overheadeditor();
857
        keystatus[buildkeys[BK_MODE2D_3D]] = 0;
857
        keystatus[buildkeys[BK_MODE2D_3D]] = 0;
858
858
859
        g_videoGamma = vid_gamma_3d;
859
        g_videoGamma = vid_gamma_3d;
860
        g_videoContrast = vid_contrast_3d;
860
        g_videoContrast = vid_contrast_3d;
861
        g_videoBrightness = vid_brightness_3d;
861
        g_videoBrightness = vid_brightness_3d;
862
862
863
        vid_gamma_3d = vid_contrast_3d = vid_brightness_3d = -1;
863
        vid_gamma_3d = vid_contrast_3d = vid_brightness_3d = -1;
864
864
865
        videoSetPalette(GAMMA_CALC,0,0);
865
        videoSetPalette(GAMMA_CALC,0,0);
866
    }
866
    }
867
    else
867
    else
868
    {
868
    {
869
        if (videoSetGameMode(fullscreen, xdimgame, ydimgame, bppgame, upscalefactor) < 0)
869
        if (videoSetGameMode(fullscreen, xdimgame, ydimgame, bppgame, upscalefactor) < 0)
870
        {
870
        {
871
            CallExtUnInit();
871
            CallExtUnInit();
872
            engineUnInit();
872
            engineUnInit();
873
            Bprintf("%d * %d not supported in this graphics mode\n",xdim,ydim);
873
            Bprintf("%d * %d not supported in this graphics mode\n",xdim,ydim);
874
            Bexit(EXIT_SUCCESS);
874
            Bexit(EXIT_SUCCESS);
875
        }
875
        }
876
876
877
        system_getcvars();
877
        system_getcvars();
878
878
879
        videoSetPalette(GAMMA_CALC,0,0);
879
        videoSetPalette(GAMMA_CALC,0,0);
880
    }
880
    }
881
881
882
CANCEL:
882
CANCEL:
883
    quitflag = 0;
883
    quitflag = 0;
884
    while (quitflag == 0)
884
    while (quitflag == 0)
885
    {
885
    {
886
        if (handleevents())
886
        if (handleevents())
887
        {
887
        {
888
            if (quitevent)
888
            if (quitevent)
889
            {
889
            {
890
                keystatus[sc_Escape] = 1;
890
                keystatus[sc_Escape] = 1;
891
                quitevent = 0;
891
                quitevent = 0;
892
            }
892
            }
893
        }
893
        }
894
894
895
        OSD_DispatchQueued();
895
        OSD_DispatchQueued();
896
896
897
        videoNextPage();
897
        videoNextPage();
898
        synctics = (int32_t) totalclock-lockclock;
898
        synctics = (int32_t) totalclock-lockclock;
899
        lockclock += synctics;
899
        lockclock += synctics;
900
900
901
        CallExtPreCheckKeys();
901
        CallExtPreCheckKeys();
902
902
903
        M32_DrawRoomsAndMasks();
903
        M32_DrawRoomsAndMasks();
904
904
905
        inputchecked = 1;
905
        inputchecked = 1;
906
906
907
#ifdef M32_SHOWDEBUG
907
#ifdef M32_SHOWDEBUG
908
        if (searchstat>=0 && (searchwall<0 || searchsector<0))
908
        if (searchstat>=0 && (searchwall<0 || searchsector<0))
909
        {
909
        {
910
            if (m32_numdebuglines<64)
910
            if (m32_numdebuglines<64)
911
                Bsprintf(m32_debugstr[m32_numdebuglines++], "inconsistent search variables!");
911
                Bsprintf(m32_debugstr[m32_numdebuglines++], "inconsistent search variables!");
912
            searchstat = -1;
912
            searchstat = -1;
913
        }
913
        }
914
914
915
        M32_drawdebug();
915
        M32_drawdebug();
916
#endif
916
#endif
917
        CallExtCheckKeys();
917
        CallExtCheckKeys();
918
918
919
919
920
        if (keystatus[sc_Escape])
920
        if (keystatus[sc_Escape])
921
        {
921
        {
922
            keystatus[sc_Escape] = 0;
922
            keystatus[sc_Escape] = 0;
923
923
924
            printext256(0,0,whitecol,0,"Are you sure you want to quit?",0);
924
            printext256(0,0,whitecol,0,"Are you sure you want to quit?",0);
925
925
926
            videoShowFrame(1);
926
            videoShowFrame(1);
927
            synctics = (int32_t) totalclock-lockclock;
927
            synctics = (int32_t) totalclock-lockclock;
928
            lockclock += synctics;
928
            lockclock += synctics;
929
929
930
            while ((keystatus[sc_Escape]|keystatus[sc_Enter]|keystatus[sc_Space]|keystatus[sc_N]) == 0)
930
            while ((keystatus[sc_Escape]|keystatus[sc_Enter]|keystatus[sc_Space]|keystatus[sc_N]) == 0)
931
            {
931
            {
932
                idle_waitevent();
932
                idle_waitevent();
933
                if (handleevents())
933
                if (handleevents())
934
                {
934
                {
935
                    if (quitevent)
935
                    if (quitevent)
936
                    {
936
                    {
937
                        quitflag = 1;
937
                        quitflag = 1;
938
                        break;
938
                        break;
939
                    }
939
                    }
940
                }
940
                }
941
941
942
                if (keystatus[sc_Y]||keystatus[sc_Enter]) // Y or ENTER
942
                if (keystatus[sc_Y]||keystatus[sc_Enter]) // Y or ENTER
943
                {
943
                {
944
                    keystatus[sc_Y] = 0;
944
                    keystatus[sc_Y] = 0;
945
                    keystatus[sc_Enter] = 0;
945
                    keystatus[sc_Enter] = 0;
946
                    quitflag = 1; break;
946
                    quitflag = 1; break;
947
                }
947
                }
948
            }
948
            }
949
            while (keystatus[sc_Escape])
949
            while (keystatus[sc_Escape])
950
            {
950
            {
951
                keystatus[sc_Escape] = 0;
951
                keystatus[sc_Escape] = 0;
952
                quitevent = 0;
952
                quitevent = 0;
953
                goto CANCEL;
953
                goto CANCEL;
954
            }
954
            }
955
        }
955
        }
956
    }
956
    }
957
957
958
    if (asksave)
958
    if (asksave)
959
    {
959
    {
960
        i = CheckMapCorruption(4, 0);
960
        i = CheckMapCorruption(4, 0);
961
961
962
        printext256(0,8,whitecol,0,i<4?"Save changes?":"Map is heavily corrupt. Save changes?",0);
962
        printext256(0,8,whitecol,0,i<4?"Save changes?":"Map is heavily corrupt. Save changes?",0);
963
        videoShowFrame(1);
963
        videoShowFrame(1);
964
964
965
        while ((keystatus[sc_Escape]|keystatus[sc_Enter]|keystatus[sc_Space]|keystatus[sc_N]|keystatus[sc_C]) == 0)
965
        while ((keystatus[sc_Escape]|keystatus[sc_Enter]|keystatus[sc_Space]|keystatus[sc_N]|keystatus[sc_C]) == 0)
966
        {
966
        {
967
            idle_waitevent();
967
            idle_waitevent();
968
            if (handleevents()) { if (quitevent) break; } // like saying no
968
            if (handleevents()) { if (quitevent) break; } // like saying no
969
969
970
            if (keystatus[sc_Y] || keystatus[sc_Enter]) // Y or ENTER
970
            if (keystatus[sc_Y] || keystatus[sc_Enter]) // Y or ENTER
971
            {
971
            {
972
                keystatus[sc_Y] = keystatus[sc_Enter] = 0;
972
                keystatus[sc_Y] = keystatus[sc_Enter] = 0;
973
973
974
                SaveBoard(NULL, M32_SB_ASKOV);
974
                SaveBoard(NULL, M32_SB_ASKOV);
975
975
976
                break;
976
                break;
977
            }
977
            }
978
        }
978
        }
979
        while (keystatus[sc_Escape]||keystatus[sc_C])
979
        while (keystatus[sc_Escape]||keystatus[sc_C])
980
        {
980
        {
981
            keystatus[sc_Escape] = keystatus[sc_C] = 0;
981
            keystatus[sc_Escape] = keystatus[sc_C] = 0;
982
            quitevent = 0;
982
            quitevent = 0;
983
            goto CANCEL;
983
            goto CANCEL;
984
        }
984
        }
985
    }
985
    }
986
986
987
987
988
    CallExtUnInit();
988
    CallExtUnInit();
989
//    clearfilenames();
989
//    clearfilenames();
990
    engineUnInit();
990
    engineUnInit();
991
991
992
    return 0;
992
    return 0;
993
}
993
}
994
994
995
static int32_t mhk=0;
995
static int32_t mhk=0;
996
static void loadmhk(int32_t domessage)
996
static void loadmhk(int32_t domessage)
997
{
997
{
998
    char levname[BMAX_PATH];
998
    char levname[BMAX_PATH];
999
999
1000
    if (!mhk)
1000
    if (!mhk)
1001
        return;
1001
        return;
1002
1002
1003
    Bstrcpy(levname, boardfilename);
1003
    Bstrcpy(levname, boardfilename);
1004
    append_ext_UNSAFE(levname, ".mhk");
1004
    append_ext_UNSAFE(levname, ".mhk");
1005
1005
1006
    if (!engineLoadMHK(levname))
1006
    if (!engineLoadMHK(levname))
1007
    {
1007
    {
1008
        if (domessage)
1008
        if (domessage)
1009
            message("Loaded map hack file \"%s\"",levname);
1009
            message("Loaded map hack file \"%s\"",levname);
1010
        else
1010
        else
1011
            initprintf("Loaded map hack file \"%s\"\n",levname);
1011
            initprintf("Loaded map hack file \"%s\"\n",levname);
1012
    }
1012
    }
1013
    else
1013
    else
1014
    {
1014
    {
1015
        mhk=2;
1015
        mhk=2;
1016
        if (domessage)
1016
        if (domessage)
1017
            message("No maphack found for map \"%s\"",boardfilename);
1017
            message("No maphack found for map \"%s\"",boardfilename);
1018
    }
1018
    }
1019
}
1019
}
1020
1020
1021
// this is spriteon{ceiling,ground}z from astub.c packed into
1021
// this is spriteon{ceiling,ground}z from astub.c packed into
1022
// one convenient function
1022
// one convenient function
1023
void spriteoncfz(int32_t i, int32_t *czptr, int32_t *fzptr)
1023
void spriteoncfz(int32_t i, int32_t *czptr, int32_t *fzptr)
1024
{
1024
{
1025
    int32_t height, zofs;
1025
    int32_t height, zofs;
1026
1026
1027
    getzsofslope(sprite[i].sectnum, sprite[i].x,sprite[i].y, czptr, fzptr);
1027
    getzsofslope(sprite[i].sectnum, sprite[i].x,sprite[i].y, czptr, fzptr);
1028
    if ((sprite[i].cstat&48)==32)
1028
    if ((sprite[i].cstat&48)==32)
1029
        return;
1029
        return;
1030
1030
1031
    zofs = spriteheightofs(i, &height, 0);
1031
    zofs = spriteheightofs(i, &height, 0);
1032
1032
1033
    *czptr += height - zofs;
1033
    *czptr += height - zofs;
1034
    *fzptr -= zofs;
1034
    *fzptr -= zofs;
1035
}
1035
}
1036
1036
1037
static void move_and_update(int32_t xvect, int32_t yvect, int32_t addshr)
1037
static void move_and_update(int32_t xvect, int32_t yvect, int32_t addshr)
1038
{
1038
{
1039
    if (m32_clipping==0)
1039
    if (m32_clipping==0)
1040
    {
1040
    {
1041
        pos.x += xvect>>(14+addshr);
1041
        pos.x += xvect>>(14+addshr);
1042
        pos.y += yvect>>(14+addshr);
1042
        pos.y += yvect>>(14+addshr);
1043
        updatesector(pos.x,pos.y, &cursectnum);
1043
        updatesector(pos.x,pos.y, &cursectnum);
1044
    }
1044
    }
1045
    else
1045
    else
1046
    {
1046
    {
1047
        clipmove(&pos,&cursectnum, xvect>>addshr,yvect>>addshr,
1047
        clipmove(&pos,&cursectnum, xvect>>addshr,yvect>>addshr,
1048
                 128,4<<8,4<<8, (m32_clipping==1) ? 0 : CLIPMASK0);
1048
                 128,4<<8,4<<8, (m32_clipping==1) ? 0 : CLIPMASK0);
1049
    }
1049
    }
1050
1050
1051
    if (in3dmode())
1051
    if (in3dmode())
1052
    {
1052
    {
1053
        silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz);
1053
        silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz);
1054
        getmessagetimeoff = (int32_t) totalclock+30;
1054
        getmessagetimeoff = (int32_t) totalclock+30;
1055
    }
1055
    }
1056
}
1056
}
1057
1057
1058
static void mainloop_move(void)
1058
static void mainloop_move(void)
1059
{
1059
{
1060
    int32_t xvect, yvect, doubvel;
1060
    int32_t xvect, yvect, doubvel;
1061
1061
1062
    if (angvel != 0)  //ang += angvel * constant
1062
    if (angvel != 0)  //ang += angvel * constant
1063
    {
1063
    {
1064
        if (eitherCTRL && m32_2d3dmode)
1064
        if (eitherCTRL && m32_2d3dmode)
1065
        {
1065
        {
1066
            int x = m32_2d3d.x + (angvel / 32);
1066
            int x = m32_2d3d.x + (angvel / 32);
1067
            int xx = m32_2d3d.x + XSIZE_2D3D + (angvel / 32);
1067
            int xx = m32_2d3d.x + XSIZE_2D3D + (angvel / 32);
1068
1068
1069
            if (x > 4 && xx < xdim2d - 4)
1069
            if (x > 4 && xx < xdim2d - 4)
1070
            {
1070
            {
1071
                silentmessage("2d3d x:%d y:%d", m32_2d3d.x, m32_2d3d.y);
1071
                silentmessage("2d3d x:%d y:%d", m32_2d3d.x, m32_2d3d.y);
1072
                m32_2d3d.x += (angvel / 32);
1072
                m32_2d3d.x += (angvel / 32);
1073
            }
1073
            }
1074
        }
1074
        }
1075
        else
1075
        else
1076
        {
1076
        {
1077
            //ENGINE calculates angvel for you
1077
            //ENGINE calculates angvel for you
1078
1078
1079
            //Lt. shift makes turn velocity 50% faster
1079
            //Lt. shift makes turn velocity 50% faster
1080
            doubvel = (synctics + DOWN_BK(RUN)*(synctics>>1));
1080
            doubvel = (synctics + DOWN_BK(RUN)*(synctics>>1));
1081
1081
1082
            ang += ((angvel*doubvel)>>4);
1082
            ang += ((angvel*doubvel)>>4);
1083
            ang &= 2047;
1083
            ang &= 2047;
1084
1084
1085
            if (in3dmode())
1085
            if (in3dmode())
1086
            {
1086
            {
1087
                silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz);
1087
                silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz);
1088
                getmessagetimeoff = (int32_t) totalclock+30;
1088
                getmessagetimeoff = (int32_t) totalclock+30;
1089
            }
1089
            }
1090
        }
1090
        }
1091
    }
1091
    }
1092
    if ((vel|svel) != 0)
1092
    if ((vel|svel) != 0)
1093
    {
1093
    {
1094
        if (eitherCTRL && m32_2d3dmode)
1094
        if (eitherCTRL && m32_2d3dmode)
1095
        {
1095
        {
1096
            int y = m32_2d3d.y - (vel / 64);
1096
            int y = m32_2d3d.y - (vel / 64);
1097
            int yy = m32_2d3d.y + YSIZE_2D3D - (vel / 64);
1097
            int yy = m32_2d3d.y + YSIZE_2D3D - (vel / 64);
1098
1098
1099
            if (y > 4 && yy < ydim2d - STATUS2DSIZ2 - 4)
1099
            if (y > 4 && yy < ydim2d - STATUS2DSIZ2 - 4)
1100
            {
1100
            {
1101
                silentmessage("2d3d x:%d y:%d", m32_2d3d.x, m32_2d3d.y);
1101
                silentmessage("2d3d x:%d y:%d", m32_2d3d.x, m32_2d3d.y);
1102
                m32_2d3d.y -= (vel / 64);
1102
                m32_2d3d.y -= (vel / 64);
1103
            }
1103
            }
1104
        }
1104
        }
1105
        else
1105
        else
1106
1106
1107
        {
1107
        {
1108
            //Lt. shift doubles forward velocity
1108
            //Lt. shift doubles forward velocity
1109
            doubvel = (1+(DOWN_BK(RUN)))*synctics;
1109
            doubvel = (1+(DOWN_BK(RUN)))*synctics;
1110
1110
1111
            xvect = 0;
1111
            xvect = 0;
1112
            yvect = 0;
1112
            yvect = 0;
1113
1113
1114
            if (vel != 0)
1114
            if (vel != 0)
1115
            {
1115
            {
1116
                xvect += ((vel*doubvel)>>3)*(int32_t) sintable[(ang+2560)&2047];
1116
                xvect += ((vel*doubvel)>>3)*(int32_t) sintable[(ang+2560)&2047];
1117
                yvect += ((vel*doubvel)>>3)*(int32_t) sintable[(ang+2048)&2047];
1117
                yvect += ((vel*doubvel)>>3)*(int32_t) sintable[(ang+2048)&2047];
1118
            }
1118
            }
1119
            if (svel != 0)
1119
            if (svel != 0)
1120
            {
1120
            {
1121
                xvect += ((svel*doubvel)>>3)*(int32_t) sintable[(ang+2048)&2047];
1121
                xvect += ((svel*doubvel)>>3)*(int32_t) sintable[(ang+2048)&2047];
1122
                yvect += ((svel*doubvel)>>3)*(int32_t) sintable[(ang+1536)&2047];
1122
                yvect += ((svel*doubvel)>>3)*(int32_t) sintable[(ang+1536)&2047];
1123
            }
1123
            }
1124
1124
1125
            move_and_update(xvect, yvect, 0);
1125
            move_and_update(xvect, yvect, 0);
1126
        }
1126
        }
1127
    }
1127
    }
1128
}
1128
}
1129
1129
1130
static void handle_sprite_in_clipboard(int32_t i)
1130
static void handle_sprite_in_clipboard(int32_t i)
1131
{
1131
{
1132
    if (somethingintab == 3)
1132
    if (somethingintab == 3)
1133
    {
1133
    {
1134
        int32_t j, k;
1134
        int32_t j, k;
1135
1135
1136
        sprite[i].picnum = temppicnum;
1136
        sprite[i].picnum = temppicnum;
1137
        if (tilesiz[temppicnum].x <= 0 || tilesiz[temppicnum].y <= 0)
1137
        if (tilesiz[temppicnum].x <= 0 || tilesiz[temppicnum].y <= 0)
1138
        {
1138
        {
1139
            j = 0;
1139
            j = 0;
1140
            for (k=0; k<MAXTILES; k++)
1140
            for (k=0; k<MAXTILES; k++)
1141
                if (tilesiz[k].x > 0 && tilesiz[k].y > 0)
1141
                if (tilesiz[k].x > 0 && tilesiz[k].y > 0)
1142
                {
1142
                {
1143
                    j = k;
1143
                    j = k;
1144
                    break;
1144
                    break;
1145
                }
1145
                }
1146
            sprite[i].picnum = j;
1146
            sprite[i].picnum = j;
1147
        }
1147
        }
1148
        sprite[i].shade = tempshade;
1148
        sprite[i].shade = tempshade;
1149
        sprite[i].blend = tempblend;
1149
        sprite[i].blend = tempblend;
1150
        sprite[i].pal = temppal;
1150
        sprite[i].pal = temppal;
1151
        sprite[i].xrepeat = max(tempxrepeat, 1u);
1151
        sprite[i].xrepeat = max(tempxrepeat, 1u);
1152
        sprite[i].yrepeat = max(tempyrepeat, 1u);
1152
        sprite[i].yrepeat = max(tempyrepeat, 1u);
1153
        sprite[i].cstat = tempcstat;
1153
        sprite[i].cstat = tempcstat;
1154
    }
1154
    }
1155
}
1155
}
1156
1156
1157
1157
1158
void editinput(void)
1158
void editinput(void)
1159
{
1159
{
1160
    int32_t mousz, bstatus;
1160
    int32_t mousz, bstatus;
1161
    int32_t i, tempint=0;
1161
    int32_t i, tempint=0;
1162
    int32_t goalz, xvect, yvect, hiz, loz, oposz;
1162
    int32_t goalz, xvect, yvect, hiz, loz, oposz;
1163
    int32_t hihit, lohit, omlook=mlook;
1163
    int32_t hihit, lohit, omlook=mlook;
1164
1164
1165
// 3B  3C  3D  3E   3F  40  41  42   43  44  57  58          46
1165
// 3B  3C  3D  3E   3F  40  41  42   43  44  57  58          46
1166
// F1  F2  F3  F4   F5  F6  F7  F8   F9 F10 F11 F12        SCROLL
1166
// F1  F2  F3  F4   F5  F6  F7  F8   F9 F10 F11 F12        SCROLL
1167
1167
1168
    mousz = 0;
1168
    mousz = 0;
1169
    mouseGetValues(&mousx,&mousy,&bstatus);
1169
    mouseGetValues(&mousx,&mousy,&bstatus);
1170
    mousx = (mousx<<16) + mousexsurp;
1170
    mousx = (mousx<<16) + mousexsurp;
1171
    mousy = (mousy<<16) + mouseysurp;
1171
    mousy = (mousy<<16) + mouseysurp;
1172
1172
1173
    if (unrealedlook && !mskip)
1173
    if (unrealedlook && !mskip)
1174
    {
1174
    {
1175
        if (mlook==0 && (bstatus&(1|2|4))==2)
1175
        if (mlook==0 && (bstatus&(1|2|4))==2)
1176
            mlook = 3;
1176
            mlook = 3;
1177
        else if ((bstatus&(1|2|4))==1)
1177
        else if ((bstatus&(1|2|4))==1)
1178
            mlook = 3;
1178
            mlook = 3;
1179
    }
1179
    }
1180
1180
1181
    {
1181
    {
1182
        ldiv_t ld;
1182
        ldiv_t ld;
1183
        if (mlook)
1183
        if (mlook)
1184
        {
1184
        {
1185
            ld = ldiv(mousx, (int32_t)((1<<16)/(msens*0.5f))); mousx = ld.quot; mousexsurp = ld.rem;
1185
            ld = ldiv(mousx, (int32_t)((1<<16)/(msens*0.5f))); mousx = ld.quot; mousexsurp = ld.rem;
1186
            ld = ldiv(mousy, (int32_t)((1<<16)/(msens*0.25f))); mousy = ld.quot; mouseysurp = ld.rem;
1186
            ld = ldiv(mousy, (int32_t)((1<<16)/(msens*0.25f))); mousy = ld.quot; mouseysurp = ld.rem;
1187
        }
1187
        }
1188
        else
1188
        else
1189
        {
1189
        {
1190
            ld = ldiv(mousx, (int32_t)((1<<16)/msens)); mousx = ld.quot; mousexsurp = ld.rem;
1190
            ld = ldiv(mousx, (int32_t)((1<<16)/msens)); mousx = ld.quot; mousexsurp = ld.rem;
1191
            ld = ldiv(mousy, (int32_t)((1<<16)/msens)); mousy = ld.quot; mouseysurp = ld.rem;
1191
            ld = ldiv(mousy, (int32_t)((1<<16)/msens)); mousy = ld.quot; mouseysurp = ld.rem;
1192
        }
1192
        }
1193
    }
1193
    }
1194
1194
1195
    if (mlook == 3)
1195
    if (mlook == 3)
1196
        mlook = omlook;
1196
        mlook = omlook;
1197
1197
1198
    // UnrealEd:
1198
    // UnrealEd:
1199
    // rmb: mouselook
1199
    // rmb: mouselook
1200
    // lbm: x:turn y:fwd/back local x
1200
    // lbm: x:turn y:fwd/back local x
1201
    // lmb&rmb: x:strafe y:up/dn (move in local yz plane)
1201
    // lmb&rmb: x:strafe y:up/dn (move in local yz plane)
1202
    // mmb: fwd/back in viewing vector
1202
    // mmb: fwd/back in viewing vector
1203
1203
1204
    if (unrealedlook && !mskip)    //PK
1204
    if (unrealedlook && !mskip)    //PK
1205
    {
1205
    {
1206
        if ((bstatus&(1|2|4))==1)
1206
        if ((bstatus&(1|2|4))==1)
1207
        {
1207
        {
1208
            ang += mousx;
1208
            ang += mousx;
1209
            xvect = -((mousy*(int32_t)sintable[(ang+2560)&2047])<<(3+pk_uedaccel));
1209
            xvect = -((mousy*(int32_t)sintable[(ang+2560)&2047])<<(3+pk_uedaccel));
1210
            yvect = -((mousy*(int32_t)sintable[(ang+2048)&2047])<<(3+pk_uedaccel));
1210
            yvect = -((mousy*(int32_t)sintable[(ang+2048)&2047])<<(3+pk_uedaccel));
1211
1211
1212
            move_and_update(xvect, yvect, 0);
1212
            move_and_update(xvect, yvect, 0);
1213
        }
1213
        }
1214
        else if (!mlook && (bstatus&(1|2|4))==2)
1214
        else if (!mlook && (bstatus&(1|2|4))==2)
1215
        {
1215
        {
1216
            mlook=2;
1216
            mlook=2;
1217
        }
1217
        }
1218
        else if ((bstatus&(1|2|4))==(1|2))
1218
        else if ((bstatus&(1|2|4))==(1|2))
1219
        {
1219
        {
1220
            zmode = 2;
1220
            zmode = 2;
1221
            xvect = -((mousx*(int32_t)sintable[(ang+2048)&2047])<<pk_uedaccel);
1221
            xvect = -((mousx*(int32_t)sintable[(ang+2048)&2047])<<pk_uedaccel);
1222
            yvect = -((mousx*(int32_t)sintable[(ang+1536)&2047])<<pk_uedaccel);
1222
            yvect = -((mousx*(int32_t)sintable[(ang+1536)&2047])<<pk_uedaccel);
1223
            pos.z += mousy<<(4+pk_uedaccel);
1223
            pos.z += mousy<<(4+pk_uedaccel);
1224
1224
1225
            move_and_update(xvect, yvect, 0);
1225
            move_and_update(xvect, yvect, 0);
1226
        }
1226
        }
1227
        else if ((bstatus&(1|2|4))==4)
1227
        else if ((bstatus&(1|2|4))==4)
1228
        {
1228
        {
1229
            zmode = 2;
1229
            zmode = 2;
1230
1230
1231
            // horiz-100 of 200 is viewing at 326.4 build angle units (=atan(200/128)) upward
1231
            // horiz-100 of 200 is viewing at 326.4 build angle units (=atan(200/128)) upward
1232
            tempint = getangle(128, horiz-100);
1232
            tempint = getangle(128, horiz-100);
1233
1233
1234
            xvect = -((mousy*
1234
            xvect = -((mousy*
1235
                       ((int32_t)sintable[(ang+2560)&2047]>>6)*
1235
                       ((int32_t)sintable[(ang+2560)&2047]>>6)*
1236
                       ((int32_t)sintable[(tempint+512)&2047])>>6)
1236
                       ((int32_t)sintable[(tempint+512)&2047])>>6)
1237
                      <<pk_uedaccel);
1237
                      <<pk_uedaccel);
1238
            yvect = -((mousy*
1238
            yvect = -((mousy*
1239
                       ((int32_t)sintable[(ang+2048)&2047]>>6)*
1239
                       ((int32_t)sintable[(ang+2048)&2047]>>6)*
1240
                       ((int32_t)sintable[(tempint+512)&2047])>>6)
1240
                       ((int32_t)sintable[(tempint+512)&2047])>>6)
1241
                      <<pk_uedaccel);
1241
                      <<pk_uedaccel);
1242
1242
1243
            pos.z += mousy*(((int32_t)sintable[(tempint+2048)&2047])>>(10-pk_uedaccel));
1243
            pos.z += mousy*(((int32_t)sintable[(tempint+2048)&2047])>>(10-pk_uedaccel));
1244
1244
1245
            move_and_update(xvect, yvect, 2);
1245
            move_and_update(xvect, yvect, 2);
1246
        }
1246
        }
1247
    }
1247
    }
1248
1248
1249
    if (mskip)
1249
    if (mskip)
1250
    {
1250
    {
1251
        // mskip was set in astub.c to not trigger UEd mouse movements.
1251
        // mskip was set in astub.c to not trigger UEd mouse movements.
1252
        // Reset now.
1252
        // Reset now.
1253
        mskip = 0;
1253
        mskip = 0;
1254
    }
1254
    }
1255
    else
1255
    else
1256
    {
1256
    {
1257
        if (mlook && (unrealedlook==0 || (bstatus&(1|4))==0))
1257
        if (mlook && (unrealedlook==0 || (bstatus&(1|4))==0))
1258
        {
1258
        {
1259
            ang += mousx;
1259
            ang += mousx;
1260
            horiz -= mousy;
1260
            horiz -= mousy;
1261
1261
1262
            /*
1262
            /*
1263
            if (mousy && !(mousy/4))
1263
            if (mousy && !(mousy/4))
1264
                horiz--;
1264
                horiz--;
1265
            if (mousx && !(mousx/2))
1265
            if (mousx && !(mousx/2))
1266
                ang++;
1266
                ang++;
1267
            */
1267
            */
1268
1268
1269
            inpclamp(&horiz, -99, 299);
1269
            inpclamp(&horiz, -99, 299);
1270
1270
1271
            if (mlook == 1)
1271
            if (mlook == 1)
1272
            {
1272
            {
1273
                searchx = xdim>>1;
1273
                searchx = xdim>>1;
1274
                searchy = ydim>>1;
1274
                searchy = ydim>>1;
1275
            }
1275
            }
1276
            osearchx = searchx-mousx;
1276
            osearchx = searchx-mousx;
1277
            osearchy = searchy-mousy;
1277
            osearchy = searchy-mousy;
1278
1278
1279
            if (mousx || mousy)
1279
            if (mousx || mousy)
1280
            {
1280
            {
1281
                silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz);
1281
                silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz);
1282
                getmessagetimeoff = (int32_t) totalclock+30;
1282
                getmessagetimeoff = (int32_t) totalclock+30;
1283
            }
1283
            }
1284
        }
1284
        }
1285
        else if (unrealedlook==0 || (bstatus&(1|2|4))==0)
1285
        else if (unrealedlook==0 || (bstatus&(1|2|4))==0)
1286
        {
1286
        {
1287
            osearchx = searchx;
1287
            osearchx = searchx;
1288
            osearchy = searchy;
1288
            osearchy = searchy;
1289
            searchx += mousx;
1289
            searchx += mousx;
1290
            searchy += mousy;
1290
            searchy += mousy;
1291
1291
1292
            inpclamp(&searchx, 12, xdim-13);
1292
            inpclamp(&searchx, 12, xdim-13);
1293
            inpclamp(&searchy, 12, ydim-13);
1293
            inpclamp(&searchy, 12, ydim-13);
1294
        }
1294
        }
1295
    }
1295
    }
1296
1296
1297
//    showmouse();
1297
//    showmouse();
1298
1298
1299
    if (keystatus[sc_F9])  // F9
1299
    if (keystatus[sc_F9])  // F9
1300
    {
1300
    {
1301
        if (mhk)
1301
        if (mhk)
1302
        {
1302
        {
1303
            Bmemset(spriteext, 0, sizeof(spriteext_t) * MAXSPRITES);
1303
            Bmemset(spriteext, 0, sizeof(spriteext_t) * MAXSPRITES);
1304
            Bmemset(spritesmooth, 0, sizeof(spritesmooth_t) * (MAXSPRITES+MAXUNIQHUDID));
1304
            Bmemset(spritesmooth, 0, sizeof(spritesmooth_t) * (MAXSPRITES+MAXUNIQHUDID));
1305
            engineClearLightsFromMHK();
1305
            engineClearLightsFromMHK();
1306
            mhk = 0;
1306
            mhk = 0;
1307
            message("Maphacks disabled");
1307
            message("Maphacks disabled");
1308
        }
1308
        }
1309
        else
1309
        else
1310
        {
1310
        {
1311
            mhk = 1;
1311
            mhk = 1;
1312
            loadmhk(1);
1312
            loadmhk(1);
1313
        }
1313
        }
1314
1314
1315
        keystatus[sc_F9] = 0;
1315
        keystatus[sc_F9] = 0;
1316
    }
1316
    }
1317
1317
1318
    mainloop_move();
1318
    mainloop_move();
1319
1319
1320
    getzrange(&pos,cursectnum, &hiz,&hihit, &loz,&lohit, 128, (m32_clipping==1)?0:CLIPMASK0);
1320
    getzrange(&pos,cursectnum, &hiz,&hihit, &loz,&lohit, 128, (m32_clipping==1)?0:CLIPMASK0);
1321
/*
1321
/*
1322
{
1322
{
1323
    int32_t his = !(hihit&32768), los = !(lohit&32768);
1323
    int32_t his = !(hihit&32768), los = !(lohit&32768);
1324
    if (m32_numdebuglines<64)
1324
    if (m32_numdebuglines<64)
1325
        Bsprintf(m32_debugstr[m32_numdebuglines++], "s%d: cf[%s%d, %s%d] z(%d, %d)", cursectnum,
1325
        Bsprintf(m32_debugstr[m32_numdebuglines++], "s%d: cf[%s%d, %s%d] z(%d, %d)", cursectnum,
1326
                 his?"s":"w",hihit&16383, los?"s":"w",lohit&16383, hiz,loz);
1326
                 his?"s":"w",hihit&16383, los?"s":"w",lohit&16383, hiz,loz);
1327
}
1327
}
1328
*/
1328
*/
1329
    oposz = pos.z;
1329
    oposz = pos.z;
1330
    if (zmode == 0)
1330
    if (zmode == 0)
1331
    {
1331
    {
1332
        goalz = loz-(kensplayerheight<<8);  //playerheight pixels above floor
1332
        goalz = loz-(kensplayerheight<<8);  //playerheight pixels above floor
1333
        if (goalz < hiz+(16<<8))  //ceiling&floor too close
1333
        if (goalz < hiz+(16<<8))  //ceiling&floor too close
1334
            goalz = (loz+hiz)>>1;
1334
            goalz = (loz+hiz)>>1;
1335
        goalz += mousz;
1335
        goalz += mousz;
1336
1336
1337
        if (DOWN_BK(MOVEUP))  //A (stand high)
1337
        if (DOWN_BK(MOVEUP))  //A (stand high)
1338
        {
1338
        {
1339
            goalz -= (16<<8);
1339
            goalz -= (16<<8);
1340
            if (DOWN_BK(RUN))
1340
            if (DOWN_BK(RUN))
1341
                goalz -= (24<<8);
1341
                goalz -= (24<<8);
1342
        }
1342
        }
1343
        if (DOWN_BK(MOVEDOWN))  //Z (stand low)
1343
        if (DOWN_BK(MOVEDOWN))  //Z (stand low)
1344
        {
1344
        {
1345
            goalz += (12<<8);
1345
            goalz += (12<<8);
1346
            if (DOWN_BK(RUN))
1346
            if (DOWN_BK(RUN))
1347
                goalz += (12<<8);
1347
                goalz += (12<<8);
1348
        }
1348
        }
1349
1349
1350
        if (goalz != pos.z)
1350
        if (goalz != pos.z)
1351
        {
1351
        {
1352
            if (pos.z < goalz) hvel += 64;
1352
            if (pos.z < goalz) hvel += 64;
1353
            if (pos.z > goalz) hvel = ((goalz-pos.z)>>3);
1353
            if (pos.z > goalz) hvel = ((goalz-pos.z)>>3);
1354
1354
1355
            pos.z += hvel;
1355
            pos.z += hvel;
1356
            if (pos.z > loz-(4<<8)) pos.z = loz-(4<<8), hvel = 0;
1356
            if (pos.z > loz-(4<<8)) pos.z = loz-(4<<8), hvel = 0;
1357
            if (pos.z < hiz+(4<<8)) pos.z = hiz+(4<<8), hvel = 0;
1357
            if (pos.z < hiz+(4<<8)) pos.z = hiz+(4<<8), hvel = 0;
1358
        }
1358
        }
1359
    }
1359
    }
1360
    else
1360
    else
1361
    {
1361
    {
1362
        goalz = pos.z;
1362
        goalz = pos.z;
1363
        if (DOWN_BK(MOVEUP))  //A
1363
        if (DOWN_BK(MOVEUP))  //A
1364
        {
1364
        {
1365
            if (eitherALT)
1365
            if (eitherALT)
1366
            {
1366
            {
1367
                horiz = max(-100,horiz-((DOWN_BK(RUN)+1)*synctics*2));
1367
                horiz = max(-100,horiz-((DOWN_BK(RUN)+1)*synctics*2));
1368
            }
1368
            }
1369
            else
1369
            else
1370
            {
1370
            {
1371
                if (zmode != 1)
1371
                if (zmode != 1)
1372
                    goalz -= (8<<8);
1372
                    goalz -= (8<<8);
1373
                else
1373
                else
1374
                {
1374
                {
1375
                    zlock += (4<<8);
1375
                    zlock += (4<<8);
1376
                    DOWN_BK(MOVEUP) = 0;
1376
                    DOWN_BK(MOVEUP) = 0;
1377
                }
1377
                }
1378
            }
1378
            }
1379
        }
1379
        }
1380
        if (DOWN_BK(MOVEDOWN))  //Z (stand low)
1380
        if (DOWN_BK(MOVEDOWN))  //Z (stand low)
1381
        {
1381
        {
1382
            if (eitherALT)
1382
            if (eitherALT)
1383
            {
1383
            {
1384
                horiz = min(300,horiz+((DOWN_BK(RUN)+1)*synctics*2));
1384
                horiz = min(300,horiz+((DOWN_BK(RUN)+1)*synctics*2));
1385
            }
1385
            }
1386
            else
1386
            else
1387
            {
1387
            {
1388
                if (zmode != 1)
1388
                if (zmode != 1)
1389
                    goalz += (8<<8);
1389
                    goalz += (8<<8);
1390
                else if (zlock > 0)
1390
                else if (zlock > 0)
1391
                {
1391
                {
1392
                    zlock -= (4<<8);
1392
                    zlock -= (4<<8);
1393
                    DOWN_BK(MOVEDOWN) = 0;
1393
                    DOWN_BK(MOVEDOWN) = 0;
1394
                }
1394
                }
1395
            }
1395
            }
1396
        }
1396
        }
1397
1397
1398
        if (m32_clipping)
1398
        if (m32_clipping)
1399
            inpclamp(&goalz, hiz+(4<<8), loz-(4<<8));
1399
            inpclamp(&goalz, hiz+(4<<8), loz-(4<<8));
1400
1400
1401
        if (zmode == 1) goalz = loz-zlock;
1401
        if (zmode == 1) goalz = loz-zlock;
1402
        if (m32_clipping && (goalz < hiz+(4<<8)))
1402
        if (m32_clipping && (goalz < hiz+(4<<8)))
1403
            goalz = ((loz+hiz)>>1);  //ceiling&floor too close
1403
            goalz = ((loz+hiz)>>1);  //ceiling&floor too close
1404
        if (zmode == 1) pos.z = goalz;
1404
        if (zmode == 1) pos.z = goalz;
1405
1405
1406
        if (goalz != pos.z)
1406
        if (goalz != pos.z)
1407
        {
1407
        {
1408
            //if (pos.z < goalz) hvel += (32<<DOWN_BK(RUN));
1408
            //if (pos.z < goalz) hvel += (32<<DOWN_BK(RUN));
1409
            //if (pos.z > goalz) hvel -= (32<<DOWN_BK(RUN));
1409
            //if (pos.z > goalz) hvel -= (32<<DOWN_BK(RUN));
1410
            if (pos.z < goalz)
1410
            if (pos.z < goalz)
1411
                hvel = ((192*synctics)<<DOWN_BK(RUN));
1411
                hvel = ((192*synctics)<<DOWN_BK(RUN));
1412
            else
1412
            else
1413
                hvel = -((192*synctics)<<DOWN_BK(RUN));
1413
                hvel = -((192*synctics)<<DOWN_BK(RUN));
1414
1414
1415
            pos.z += hvel;
1415
            pos.z += hvel;
1416
1416
1417
            if (m32_clipping)
1417
            if (m32_clipping)
1418
            {
1418
            {
1419
                if (pos.z > loz-(4<<8)) pos.z = loz-(4<<8), hvel = 0;
1419
                if (pos.z > loz-(4<<8)) pos.z = loz-(4<<8), hvel = 0;
1420
                if (pos.z < hiz+(4<<8)) pos.z = hiz+(4<<8), hvel = 0;
1420
                if (pos.z < hiz+(4<<8)) pos.z = hiz+(4<<8), hvel = 0;
1421
            }
1421
            }
1422
        }
1422
        }
1423
        else
1423
        else
1424
            hvel = 0;
1424
            hvel = 0;
1425
    }
1425
    }
1426
1426
1427
    {
1427
    {
1428
        int16_t ocursectnum = cursectnum;
1428
        int16_t ocursectnum = cursectnum;
1429
        updatesectorz(pos.x,pos.y,pos.z, &cursectnum);
1429
        updatesectorz(pos.x,pos.y,pos.z, &cursectnum);
1430
        if (cursectnum<0)
1430
        if (cursectnum<0)
1431
        {
1431
        {
1432
            if (zmode != 2)
1432
            if (zmode != 2)
1433
                pos.z = oposz;  // don't allow to fall into infinity when in void space
1433
                pos.z = oposz;  // don't allow to fall into infinity when in void space
1434
            cursectnum = ocursectnum;
1434
            cursectnum = ocursectnum;
1435
        }
1435
        }
1436
    }
1436
    }
1437
1437
1438
    if (pos.z != oposz && in3dmode())
1438
    if (pos.z != oposz && in3dmode())
1439
    {
1439
    {
1440
        silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz);
1440
        silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz);
1441
        getmessagetimeoff = (int32_t) totalclock+30;
1441
        getmessagetimeoff = (int32_t) totalclock+30;
1442
    }
1442
    }
1443
1443
1444
    searchit = 2;
1444
    searchit = 2;
1445
    if (searchstat >= 0)
1445
    if (searchstat >= 0)
1446
    {
1446
    {
1447
        if ((bstatus&(1|2|4)) || keystatus[sc_Space])  // SPACE
1447
        if ((bstatus&(1|2|4)) || keystatus[sc_Space])  // SPACE
1448
            searchit = 0;
1448
            searchit = 0;
1449
1449
1450
        if (keystatus[sc_S])  //S (insert sprite) (3D)
1450
        if (keystatus[sc_S])  //S (insert sprite) (3D)
1451
        {
1451
        {
1452
            hitdata_t hit;
1452
            hitdata_t hit;
1453
            vec2_t osearch = {searchx, searchy};
1453
            vec2_t osearch = {searchx, searchy};
1454
            vec2_t bdim = {xdim, ydim};
1454
            vec2_t bdim = {xdim, ydim};
1455
            if (m32_is2d3dmode())
1455
            if (m32_is2d3dmode())
1456
            {
1456
            {
1457
                xdim = XSIZE_2D3D;
1457
                xdim = XSIZE_2D3D;
1458
                ydim = YSIZE_2D3D;
1458
                ydim = YSIZE_2D3D;
1459
                searchx -= m32_2d3d.x;
1459
                searchx -= m32_2d3d.x;
1460
                searchy -= m32_2d3d.y;
1460
                searchy -= m32_2d3d.y;
1461
            }
1461
            }
1462
1462
1463
            vec2_t da = { 16384, divscale14(searchx-(xdim>>1), xdim>>1) };
1463
            vec2_t da = { 16384, divscale14(searchx-(xdim>>1), xdim>>1) };
1464
1464
1465
            rotatepoint(zerovec, da, ang, &da);
1465
            rotatepoint(zerovec, da, ang, &da);
1466
1466
1467
#ifdef USE_OPENGL
1467
#ifdef USE_OPENGL
1468
            if (videoGetRenderMode() == REND_POLYMOST)
1468
            if (videoGetRenderMode() == REND_POLYMOST)
1469
                hit = polymost_hitdata;
1469
                hit = polymost_hitdata;
1470
            else
1470
            else
1471
#endif
1471
#endif
1472
                hitscan((const vec3_t *)&pos,cursectnum,              //Start position
1472
                hitscan((const vec3_t *)&pos,cursectnum,              //Start position
1473
                    da.x,da.y,(scale(searchy,200,ydim)-horiz)*2000, //vector of 3D ang
1473
                    da.x,da.y,(scale(searchy,200,ydim)-horiz)*2000, //vector of 3D ang
1474
                    &hit,CLIPMASK1);
1474
                    &hit,CLIPMASK1);
1475
1475
1476
            if (hit.sect >= 0)
1476
            if (hit.sect >= 0)
1477
            {
1477
            {
1478
                da.x = hit.pos.x;
1478
                da.x = hit.pos.x;
1479
                da.y = hit.pos.y;
1479
                da.y = hit.pos.y;
1480
                if (gridlock && grid > 0)
1480
                if (gridlock && grid > 0)
1481
                {
1481
                {
1482
                    if (AIMING_AT_WALL || AIMING_AT_MASKWALL)
1482
                    if (AIMING_AT_WALL || AIMING_AT_MASKWALL)
1483
                        hit.pos.z &= 0xfffffc00;
1483
                        hit.pos.z &= 0xfffffc00;
1484
                    else
1484
                    else
1485
                        locktogrid(&da.x, &da.y);
1485
                        locktogrid(&da.x, &da.y);
1486
                }
1486
                }
1487
1487
1488
                i = insert_sprite_common(hit.sect, da.x, da.y);
1488
                i = insert_sprite_common(hit.sect, da.x, da.y);
1489
1489
1490
                if (i < 0)
1490
                if (i < 0)
1491
                    message("Couldn't insert sprite.");
1491
                    message("Couldn't insert sprite.");
1492
                else
1492
                else
1493
                {
1493
                {
1494
                    int32_t cz, fz;
1494
                    int32_t cz, fz;
1495
1495
1496
                    handle_sprite_in_clipboard(i);
1496
                    handle_sprite_in_clipboard(i);
1497
1497
1498
                    spriteoncfz(i, &cz, &fz);
1498
                    spriteoncfz(i, &cz, &fz);
1499
                    sprite[i].z = clamp2(hit.pos.z, cz, fz);
1499
                    sprite[i].z = clamp2(hit.pos.z, cz, fz);
1500
1500
1501
                    if (AIMING_AT_WALL || AIMING_AT_MASKWALL)
1501
                    if (AIMING_AT_WALL || AIMING_AT_MASKWALL)
1502
                    {
1502
                    {
1503
                        sprite[i].cstat &= ~48;
1503
                        sprite[i].cstat &= ~48;
1504
                        sprite[i].cstat |= (16+64);
1504
                        sprite[i].cstat |= (16+64);
1505
1505
1506
                        correct_ornamented_sprite(i, hit.wall);
1506
                        correct_ornamented_sprite(i, hit.wall);
1507
                    }
1507
                    }
1508
                    else
1508
                    else
1509
                        sprite[i].cstat |= (tilesiz[sprite[i].picnum].y>=32);
1509
                        sprite[i].cstat |= (tilesiz[sprite[i].picnum].y>=32);
1510
1510
1511
                    correct_sprite_yoffset(i);
1511
                    correct_sprite_yoffset(i);
1512
1512
1513
                    asksave = 1;
1513
                    asksave = 1;
1514
1514
1515
                    VM_OnEvent(EVENT_INSERTSPRITE3D, i);
1515
                    VM_OnEvent(EVENT_INSERTSPRITE3D, i);
1516
                }
1516
                }
1517
            }
1517
            }
1518
1518
1519
            xdim = bdim.x;
1519
            xdim = bdim.x;
1520
            ydim = bdim.y;
1520
            ydim = bdim.y;
1521
            searchx = osearch.x;
1521
            searchx = osearch.x;
1522
            searchy = osearch.y;
1522
            searchy = osearch.y;
1523
            keystatus[sc_S] = 0;
1523
            keystatus[sc_S] = 0;
1524
        }
1524
        }
1525
1525
1526
        if (keystatus[sc_F5]||keystatus[sc_F6])  //F5,F6
1526
        if (keystatus[sc_F5]||keystatus[sc_F6])  //F5,F6
1527
        {
1527
        {
1528
            switch (searchstat)
1528
            switch (searchstat)
1529
            {
1529
            {
1530
            case SEARCH_CEILING:
1530
            case SEARCH_CEILING:
1531
            case SEARCH_FLOOR:
1531
            case SEARCH_FLOOR:
1532
                CallExtShowSectorData(searchsector); break;
1532
                CallExtShowSectorData(searchsector); break;
1533
            case SEARCH_WALL:
1533
            case SEARCH_WALL:
1534
            case SEARCH_MASKWALL:
1534
            case SEARCH_MASKWALL:
1535
                CallExtShowWallData(searchwall); break;
1535
                CallExtShowWallData(searchwall); break;
1536
            case SEARCH_SPRITE:
1536
            case SEARCH_SPRITE:
1537
                CallExtShowSpriteData(searchwall); break;
1537
                CallExtShowSpriteData(searchwall); break;
1538
            }
1538
            }
1539
1539
1540
            keystatus[sc_F5] = keystatus[sc_F6] = 0;
1540
            keystatus[sc_F5] = keystatus[sc_F6] = 0;
1541
        }
1541
        }
1542
        if (keystatus[sc_F7]||keystatus[sc_F8])  //F7,F8
1542
        if (keystatus[sc_F7]||keystatus[sc_F8])  //F7,F8
1543
        {
1543
        {
1544
            switch (searchstat)
1544
            switch (searchstat)
1545
            {
1545
            {
1546
            case SEARCH_CEILING:
1546
            case SEARCH_CEILING:
1547
            case SEARCH_FLOOR:
1547
            case SEARCH_FLOOR:
1548
                CallExtEditSectorData(searchsector); break;
1548
                CallExtEditSectorData(searchsector); break;
1549
            case SEARCH_WALL:
1549
            case SEARCH_WALL:
1550
            case SEARCH_MASKWALL:
1550
            case SEARCH_MASKWALL:
1551
                CallExtEditWallData(searchwall); break;
1551
                CallExtEditWallData(searchwall); break;
1552
            case SEARCH_SPRITE:
1552
            case SEARCH_SPRITE:
1553
                CallExtEditSpriteData(searchwall); break;
1553
                CallExtEditSpriteData(searchwall); break;
1554
            }
1554
            }
1555
1555
1556
            keystatus[sc_F7] = keystatus[sc_F8] = 0;
1556
            keystatus[sc_F7] = keystatus[sc_F8] = 0;
1557
        }
1557
        }
1558
1558
1559
    }
1559
    }
1560
1560
1561
    if (keystatus[buildkeys[BK_MODE2D_3D]] && !m32_is2d3dmode())  // Enter
1561
    if (keystatus[buildkeys[BK_MODE2D_3D]] && !m32_is2d3dmode())  // Enter
1562
    {
1562
    {
1563
1563
1564
        vid_gamma_3d = g_videoGamma;
1564
        vid_gamma_3d = g_videoGamma;
1565
        vid_contrast_3d = g_videoContrast;
1565
        vid_contrast_3d = g_videoContrast;
1566
        vid_brightness_3d = g_videoBrightness;
1566
        vid_brightness_3d = g_videoBrightness;
1567
1567
1568
        g_videoGamma = g_videoContrast = 1.0;
1568
        g_videoGamma = g_videoContrast = 1.0;
1569
        g_videoBrightness = 0.0;
1569
        g_videoBrightness = 0.0;
1570
1570
1571
        videoSetPalette(0,0,0);
1571
        videoSetPalette(0,0,0);
1572
1572
1573
        keystatus[buildkeys[BK_MODE2D_3D]] = 0;
1573
        keystatus[buildkeys[BK_MODE2D_3D]] = 0;
1574
        overheadeditor();
1574
        overheadeditor();
1575
        keystatus[buildkeys[BK_MODE2D_3D]] = 0;
1575
        keystatus[buildkeys[BK_MODE2D_3D]] = 0;
1576
1576
1577
        g_videoGamma = vid_gamma_3d;
1577
        g_videoGamma = vid_gamma_3d;
1578
        g_videoContrast = vid_contrast_3d;
1578
        g_videoContrast = vid_contrast_3d;
1579
        g_videoBrightness = vid_brightness_3d;
1579
        g_videoBrightness = vid_brightness_3d;
1580
1580
1581
        vid_gamma_3d = vid_contrast_3d = vid_brightness_3d = -1;
1581
        vid_gamma_3d = vid_contrast_3d = vid_brightness_3d = -1;
1582
1582
1583
        videoSetPalette(GAMMA_CALC,0,0);
1583
        videoSetPalette(GAMMA_CALC,0,0);
1584
    }
1584
    }
1585
}
1585
}
1586
1586
1587
char changechar(char dachar, int32_t dadir, char smooshyalign, char boundcheck)
1587
char changechar(char dachar, int32_t dadir, char smooshyalign, char boundcheck)
1588
{
1588
{
1589
    if (dadir < 0)
1589
    if (dadir < 0)
1590
    {
1590
    {
1591
        if ((dachar > 0) || (boundcheck == 0))
1591
        if ((dachar > 0) || (boundcheck == 0))
1592
        {
1592
        {
1593
            dachar--;
1593
            dachar--;
1594
            if (smooshyalign > 0)
1594
            if (smooshyalign > 0)
1595
                dachar = (dachar&0xf8);
1595
                dachar = (dachar&0xf8);
1596
        }
1596
        }
1597
    }
1597
    }
1598
    else if (dadir > 0)
1598
    else if (dadir > 0)
1599
    {
1599
    {
1600
        if ((dachar < 255) || (boundcheck == 0))
1600
        if ((dachar < 255) || (boundcheck == 0))
1601
        {
1601
        {
1602
            dachar++;
1602
            dachar++;
1603
            if (smooshyalign > 0)
1603
            if (smooshyalign > 0)
1604
            {
1604
            {
1605
                if (dachar >= 256-8) dachar = 255;
1605
                if (dachar >= 256-8) dachar = 255;
1606
                else dachar = ((dachar+7)&0xf8);
1606
                else dachar = ((dachar+7)&0xf8);
1607
            }
1607
            }
1608
        }
1608
        }
1609
    }
1609
    }
1610
    return dachar;
1610
    return dachar;
1611
}
1611
}
1612
1612
1613
1613
1614
////////////////////// OVERHEADEDITOR //////////////////////
1614
////////////////////// OVERHEADEDITOR //////////////////////
1615
1615
1616
// some 2d mode state
1616
// some 2d mode state
1617
static struct overheadstate
1617
static struct overheadstate
1618
{
1618
{
1619
    // number of backed up drawn walls
1619
    // number of backed up drawn walls
1620
    int32_t bak_wallsdrawn;
1620
    int32_t bak_wallsdrawn;
1621
1621
1622
    // state related to line drawing
1622
    // state related to line drawing
1623
    int16_t suckwall, split;
1623
    int16_t suckwall, split;
1624
    int16_t splitsect;
1624
    int16_t splitsect;
1625
    int16_t splitstartwall;
1625
    int16_t splitstartwall;
1626
} ovh;
1626
} ovh;
1627
1627
1628
1628
1629
static int32_t inside_editor(const vec3_t *pos, int32_t searchx, int32_t searchy, int32_t zoom,
1629
static int32_t inside_editor(const vec3_t *pos, int32_t searchx, int32_t searchy, int32_t zoom,
1630
                             int32_t x, int32_t y, int16_t sectnum)
1630
                             int32_t x, int32_t y, int16_t sectnum)
1631
{
1631
{
1632
    if (!m32_sideview)
1632
    if (!m32_sideview)
1633
        return inside(x, y, sectnum);
1633
        return inside(x, y, sectnum);
1634
1634
1635
    // if in side-view mode, use the screen coords instead
1635
    // if in side-view mode, use the screen coords instead
1636
    {
1636
    {
1637
        int32_t dst = MAXSECTORS+M32_FIXME_SECTORS-1, i, oi;
1637
        int32_t dst = MAXSECTORS+M32_FIXME_SECTORS-1, i, oi;
1638
        int32_t srcw=sector[sectnum].wallptr, dstw=MAXWALLS;
1638
        int32_t srcw=sector[sectnum].wallptr, dstw=MAXWALLS;
1639
        int32_t ret;
1639
        int32_t ret;
1640
1640
1641
        if (sector[sectnum].wallnum > M32_FIXME_WALLS)
1641
        if (sector[sectnum].wallnum > M32_FIXME_WALLS)
1642
            return -1;
1642
            return -1;
1643
1643
1644
        Bmemcpy(&sector[dst], &sector[sectnum], sizeof(sectortype));
1644
        Bmemcpy(&sector[dst], &sector[sectnum], sizeof(sectortype));
1645
        sector[dst].wallptr = dstw;
1645
        sector[dst].wallptr = dstw;
1646
1646
1647
        Bmemcpy(&wall[dstw], &wall[srcw], sector[dst].wallnum*sizeof(walltype));
1647
        Bmemcpy(&wall[dstw], &wall[srcw], sector[dst].wallnum*sizeof(walltype));
1648
        for (i=dstw, oi=srcw; i<dstw+sector[dst].wallnum; i++, oi++)
1648
        for (i=dstw, oi=srcw; i<dstw+sector[dst].wallnum; i++, oi++)
1649
        {
1649
        {
1650
            wall[i].point2 += dstw-srcw;
1650
            wall[i].point2 += dstw-srcw;
1651
1651
1652
            editorGet2dScreenCoordinates(&wall[i].x, &wall[i].y, wall[i].x-pos->x, wall[i].y-pos->y, zoom);
1652
            editorGet2dScreenCoordinates(&wall[i].x, &wall[i].y, wall[i].x-pos->x, wall[i].y-pos->y, zoom);
1653
            wall[i].y += getscreenvdisp(getflorzofslope(sectnum,wall[oi].x,wall[oi].y)-pos->z, zoom);
1653
            wall[i].y += getscreenvdisp(getflorzofslope(sectnum,wall[oi].x,wall[oi].y)-pos->z, zoom);
1654
            wall[i].x += halfxdim16;
1654
            wall[i].x += halfxdim16;
1655
            wall[i].y += midydim16;
1655
            wall[i].y += midydim16;
1656
        }
1656
        }
1657
1657
1658
        i = numsectors;
1658
        i = numsectors;
1659
        numsectors = dst+1;
1659
        numsectors = dst+1;
1660
        ret = inside(searchx, searchy, dst);
1660
        ret = inside(searchx, searchy, dst);
1661
        numsectors = i;
1661
        numsectors = i;
1662
        return ret;
1662
        return ret;
1663
    }
1663
    }
1664
}
1664
}
1665
1665
1666
int32_t inside_editor_curpos(int16_t sectnum)
1666
int32_t inside_editor_curpos(int16_t sectnum)
1667
{
1667
{
1668
    // TODO: take care: mous[xy]plc global vs overheadeditor auto
1668
    // TODO: take care: mous[xy]plc global vs overheadeditor auto
1669
    return inside_editor(&pos, searchx,searchy, zoom, mousxplc,mousyplc, sectnum);
1669
    return inside_editor(&pos, searchx,searchy, zoom, mousxplc,mousyplc, sectnum);
1670
}
1670
}
1671
1671
1672
1672
1673
static inline void drawline16base(int32_t bx, int32_t by, int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col)
1673
static inline void drawline16base(int32_t bx, int32_t by, int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col)
1674
{
1674
{
1675
    editorDraw2dLine(bx+x1, by+y1, bx+x2, by+y2, col);
1675
    editorDraw2dLine(bx+x1, by+y1, bx+x2, by+y2, col);
1676
}
1676
}
1677
1677
1678
void drawsmallabel(const char *text, char col, char backcol, char border, int32_t dax, int32_t day, int32_t daz)
1678
void drawsmallabel(const char *text, char col, char backcol, char border, int32_t dax, int32_t day, int32_t daz)
1679
{
1679
{
1680
    editorGet2dScreenCoordinates(&dax,&day, dax-pos.x,day-pos.y, zoom);
1680
    editorGet2dScreenCoordinates(&dax,&day, dax-pos.x,day-pos.y, zoom);
1681
1681
1682
    if (m32_sideview)
1682
    if (m32_sideview)
1683
        day += getscreenvdisp(daz-pos.z, zoom);
1683
        day += getscreenvdisp(daz-pos.z, zoom);
1684
1684
1685
    int32_t const x1 = halfxdim16+dax-(Bstrlen(text)<<1);
1685
    int32_t const x1 = halfxdim16+dax-(Bstrlen(text)<<1);
1686
    int32_t const y1 = midydim16+day-4;
1686
    int32_t const y1 = midydim16+day-4;
1687
    int32_t const x2 = x1 + (Bstrlen(text)<<2)+2;
1687
    int32_t const x2 = x1 + (Bstrlen(text)<<2)+2;
1688
    int32_t const y2 = y1 + 7;
1688
    int32_t const y2 = y1 + 7;
1689
1689
1690
    int f = mulscale8(x2-x1, zoom);
1690
    int f = mulscale8(x2-x1, zoom);
1691
1691
1692
    if ((x1 <= -f) || (x2 >= xdim + f) || (y1 <= -f) || (y2 >= ydim16 + f))
1692
    if ((x1 <= -f) || (x2 >= xdim + f) || (y1 <= -f) || (y2 >= ydim16 + f))
1693
        return;
1693
        return;
1694
1694
1695
    printext16(x1,y1, col,backcol, text,1);
1695
    printext16(x1,y1, col,backcol, text,1);
1696
1696
1697
    editorDraw2dLine(x1-2, y1-2, x2-2, y1-2, border);
1697
    editorDraw2dLine(x1-2, y1-2, x2-2, y1-2, border);
1698
    editorDraw2dLine(x1-2, y2+1, x2-2, y2+1, border);
1698
    editorDraw2dLine(x1-2, y2+1, x2-2, y2+1, border);
1699
1699
1700
    editorDraw2dLine(x1-3, y1-1, x1-3, y2+0, border);
1700
    editorDraw2dLine(x1-3, y1-1, x1-3, y2+0, border);
1701
    editorDraw2dLine(x2-1, y1-1, x2-1, y2+0, border);
1701
    editorDraw2dLine(x2-1, y1-1, x2-1, y2+0, border);
1702
1702
1703
    editorDraw2dLine(x1-1,y1-1, x2-3,y1-1, backcol);
1703
    editorDraw2dLine(x1-1,y1-1, x2-3,y1-1, backcol);
1704
    editorDraw2dLine(x1-1,y2+0, x2-3,y2+0, backcol);
1704
    editorDraw2dLine(x1-1,y2+0, x2-3,y2+0, backcol);
1705
1705
1706
    editorDraw2dLine(x1-2,y1+0, x1-2,y2-1, backcol);
1706
    editorDraw2dLine(x1-2,y1+0, x1-2,y2-1, backcol);
1707
    editorDraw2dLine(x2-2,y1+0, x2-2,y2-1, backcol);
1707
    editorDraw2dLine(x2-2,y1+0, x2-2,y2-1, backcol);
1708
    editorDraw2dLine(x2-3,y1+0, x2-3,y2+0, backcol);
1708
    editorDraw2dLine(x2-3,y1+0, x2-3,y2+0, backcol);
1709
1709
1710
    videoBeginDrawing(); //{{{
1710
    videoBeginDrawing(); //{{{
1711
1711
1712
    if ((unsigned)y1-1 < ydim16+0u && (unsigned) (x1-2) < xdim2d+0u && (unsigned) (x2-2) < xdim2d+0u)
1712
    if ((unsigned)y1-1 < ydim16+0u && (unsigned) (x1-2) < xdim2d+0u && (unsigned) (x2-2) < xdim2d+0u)
1713
    {
1713
    {
1714
        drawpixel((char *) (frameplace + ((y1-1) * bytesperline) + (x1-2)), border);
1714
        drawpixel((char *) (frameplace + ((y1-1) * bytesperline) + (x1-2)), border);
1715
        drawpixel((char *) (frameplace + ((y1-1) * bytesperline) + (x2-2)), border);
1715
        drawpixel((char *) (frameplace + ((y1-1) * bytesperline) + (x2-2)), border);
1716
    }
1716
    }
1717
1717
1718
    if ((unsigned) y2 < ydim16+0u && (unsigned) (x1-2) < xdim2d+0u && (unsigned) (x2-2) < xdim2d+0u)
1718
    if ((unsigned) y2 < ydim16+0u && (unsigned) (x1-2) < xdim2d+0u && (unsigned) (x2-2) < xdim2d+0u)
1719
    {
1719
    {
1720
        drawpixel((char *) (frameplace + ((y2) * bytesperline) + (x1-2)), border);
1720
        drawpixel((char *) (frameplace + ((y2) * bytesperline) + (x1-2)), border);
1721
        drawpixel((char *) (frameplace + ((y2) * bytesperline) + (x2-2)), border);
1721
        drawpixel((char *) (frameplace + ((y2) * bytesperline) + (x2-2)), border);
1722
    }
1722
    }
1723
1723
1724
    videoEndDrawing();
1724
    videoEndDrawing();
1725
}
1725
}
1726
1726
1727
// backup highlighted sectors with sprites as mapinfo for later restoration
1727
// backup highlighted sectors with sprites as mapinfo for later restoration
1728
// return values:
1728
// return values:
1729
//  -1: highlightsectorcnt<=0
1729
//  -1: highlightsectorcnt<=0
1730
//   0: ok
1730
//   0: ok
1731
static int32_t backup_highlighted_map(mapinfofull_t *mapinfo)
1731
static int32_t backup_highlighted_map(mapinfofull_t *mapinfo)
1732
{
1732
{
1733
    int32_t i, j, k, m, tmpnumwalls=0, tmpnumsprites=0;
1733
    int32_t i, j, k, m, tmpnumwalls=0, tmpnumsprites=0;
1734
    int16_t *const otonsect = (int16_t *)tempxyar;  // STRICTALIASING
1734
    int16_t *const otonsect = (int16_t *)tempxyar;  // STRICTALIASING
1735
    int16_t *const otonwall = ((int16_t *)tempxyar) + MAXWALLS;
1735
    int16_t *const otonwall = ((int16_t *)tempxyar) + MAXWALLS;
1736
#ifdef YAX_ENABLE
1736
#ifdef YAX_ENABLE
1737
    int16_t otonbunch[YAX_MAXBUNCHES];
1737
    int16_t otonbunch[YAX_MAXBUNCHES];
1738
    int16_t numsectsofbunch[YAX_MAXBUNCHES];  // ceilings + floors
1738
    int16_t numsectsofbunch[YAX_MAXBUNCHES];  // ceilings + floors
1739
#endif
1739
#endif
1740
1740
1741
    if (highlightsectorcnt <= 0)
1741
    if (highlightsectorcnt <= 0)
1742
        return -1;
1742
        return -1;
1743
1743
1744
#ifdef YAX_ENABLE
1744
#ifdef YAX_ENABLE
1745
    for (i=0; i<numyaxbunches; i++)
1745
    for (i=0; i<numyaxbunches; i++)
1746
        numsectsofbunch[i] = 0;
1746
        numsectsofbunch[i] = 0;
1747
#endif
1747
#endif
1748
1748
1749
    // set up old-->new mappings
1749
    // set up old-->new mappings
1750
    j = 0;
1750
    j = 0;
1751
    k = 0;
1751
    k = 0;
1752
    for (i=0; i<numsectors; i++)
1752
    for (i=0; i<numsectors; i++)
1753
    {
1753
    {
1754
        int32_t startwall, endwall;
1754
        int32_t startwall, endwall;
1755
1755
1756
        if (hlsectorbitmap[i>>3]&pow2char[i&7])
1756
        if (hlsectorbitmap[i>>3]&pow2char[i&7])
1757
        {
1757
        {
1758
#ifdef YAX_ENABLE
1758
#ifdef YAX_ENABLE
1759
            int16_t bn[2], cf;
1759
            int16_t bn[2], cf;
1760
1760
1761
            yax_getbunches(i, &bn[0], &bn[1]);
1761
            yax_getbunches(i, &bn[0], &bn[1]);
1762
            for (cf=0; cf<2; cf++)
1762
            for (cf=0; cf<2; cf++)
1763
                if (bn[cf] >= 0)
1763
                if (bn[cf] >= 0)
1764
                    numsectsofbunch[bn[cf]]++;
1764
                    numsectsofbunch[bn[cf]]++;
1765
#endif
1765
#endif
1766
            otonsect[i] = j++;
1766
            otonsect[i] = j++;
1767
1767
1768
            for (WALLS_OF_SECTOR(i, m))
1768
            for (WALLS_OF_SECTOR(i, m))
1769
                otonwall[m] = k++;
1769
                otonwall[m] = k++;
1770
        }
1770
        }
1771
        else
1771
        else
1772
        {
1772
        {
1773
            otonsect[i] = -1;
1773
            otonsect[i] = -1;
1774
1774
1775
            for (WALLS_OF_SECTOR(i, m))
1775
            for (WALLS_OF_SECTOR(i, m))
1776
                otonwall[m] = -1;
1776
                otonwall[m] = -1;
1777
        }
1777
        }
1778
    }
1778
    }
1779
1779
1780
#ifdef YAX_ENABLE
1780
#ifdef YAX_ENABLE
1781
    j = 0;
1781
    j = 0;
1782
    for (i=0; i<numyaxbunches; i++)
1782
    for (i=0; i<numyaxbunches; i++)
1783
    {
1783
    {
1784
        // only back up complete bunches
1784
        // only back up complete bunches
1785
        if (numsectsofbunch[i] == yax_numsectsinbunch(i, 0)+yax_numsectsinbunch(i, 1))
1785
        if (numsectsofbunch[i] == yax_numsectsinbunch(i, 0)+yax_numsectsinbunch(i, 1))
1786
            otonbunch[i] = j++;  // kept bunch
1786
            otonbunch[i] = j++;  // kept bunch
1787
        else
1787
        else
1788
            otonbunch[i] = -1;  // discarded bunch
1788
            otonbunch[i] = -1;  // discarded bunch
1789
    }
1789
    }
1790
    mapinfo->numyaxbunches = j;
1790
    mapinfo->numyaxbunches = j;
1791
#endif
1791
#endif
1792
1792
1793
    // count walls & sprites
1793
    // count walls & sprites
1794
    for (i=0; i<highlightsectorcnt; i++)
1794
    for (i=0; i<highlightsectorcnt; i++)
1795
    {
1795
    {
1796
        tmpnumwalls += sector[highlightsector[i]].wallnum;
1796
        tmpnumwalls += sector[highlightsector[i]].wallnum;
1797
1797
1798
        m = headspritesect[highlightsector[i]];
1798
        m = headspritesect[highlightsector[i]];
1799
        while (m != -1)
1799
        while (m != -1)
1800
        {
1800
        {
1801
            tmpnumsprites++;
1801
            tmpnumsprites++;
1802
            m = nextspritesect[m];
1802
            m = nextspritesect[m];
1803
        }
1803
        }
1804
    }
1804
    }
1805
1805
1806
    // allocate temp storage
1806
    // allocate temp storage
1807
    mapinfo->sector = (usectortype *)Xmalloc(highlightsectorcnt * sizeof(sectortype));
1807
    mapinfo->sector = (usectortype *)Xmalloc(highlightsectorcnt * sizeof(sectortype));