1 // "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
2 // Ken Silverman's official web site: "http://www.advsys.net/ken"
3 // See the included license file "BUILDLIC.TXT" for license info.
4 //
5 // This file has been modified from Ken Silverman's original release
6 // by Jonathon Fowler (jf@jonof.id.au)
7 // by the EDuke32 team (development@voidpoint.com)
8 
9 #ifndef editor_h_
10 #define editor_h_
11 
12 #include "compat.h"
13 #include "baselayer.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 extern const char *defaultsetupfilename;
20 extern char setupfilename[BMAX_PATH];
21 
22 extern char levelname[BMAX_PATH];
23 
24 // Build keys
25 #define BK_MOVEFORWARD   0
26 #define BK_MOVEBACKWARD  1
27 #define BK_TURNLEFT 	 2
28 #define BK_TURNRIGHT	 3
29 #define BK_RUN  		 4
30 #define BK_STRAFE   	 5
31 //#define BK_SHOOT		 6
32 //#define BK_OPEN 		 7
33 #define BK_MOVEUP   	 8
34 #define BK_MOVEDOWN 	 9
35 //#define BK_LOOKUP   	10
36 //#define BK_LOOKDOWN 	11
37 //#define BK_STRAFELEFT   12
38 //#define BK_STRAFERIGHT  13
39 #define BK_MODE2D_3D	14
40 //#define BK_PLAYERVIEW   15
41 //#define BK_ZOOMIN   	16
42 //#define BK_ZOOMOUT  	17
43 //#define BK_MESSAGE  	18
44 #define BK_CONSOLE  	19
45 #define NUMBUILDKEYS 20
46 
47 extern int32_t horiz;
48 extern vec3_t pos;
49 extern int16_t ang, cursectnum;
50 extern int32_t g_doHardcodedMovement;
51 
52 extern int8_t m32_clipping;  // 0: none, 1: only white walls, 2: like game
53 
54 extern int16_t editstatus, searchit;
55 extern int32_t searchx, searchy, osearchx, osearchy;      //search input
56 
57 extern int16_t searchsector, searchwall, searchstat;  //search output
58 extern int16_t searchbottomwall, searchisbottom;
59 extern int32_t zmode, kensplayerheight, zlock;
60 
61 extern int16_t highlightsector[MAXSECTORS], highlightsectorcnt;
62 extern int16_t highlight[MAXWALLS+MAXSPRITES];
63 extern int16_t asksave;
64 
65 extern int16_t pointhighlight, linehighlight, sectorhighlight, highlightcnt;
66 
67 extern int16_t defaultspritecstat;
68 
69 extern int32_t tempsectornum;
70 extern int32_t temppicnum, tempcstat, templotag, temphitag, tempextra;
71 extern uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning, tempypanning;
72 extern int32_t tempshade, tempxvel, tempyvel, tempzvel;
73 extern int32_t tempstatnum, tempblend;
74 extern char somethingintab;
75 
76 extern char names[MAXTILES][25];
77 extern uint8_t buildkeys[NUMBUILDKEYS];
78 
79 extern float vid_gamma_3d, vid_contrast_3d, vid_brightness_3d;
80 extern double msens;
81 
82 extern vec3_t startpos;
83 extern int16_t startang, startsectnum;
84 
85 extern int32_t lastpm16time, synctics;
86 extern int32_t halfxdim16, midydim16, zoom;
87 extern int32_t ydim16, xdimgame, ydimgame, bppgame, xdim2d, ydim2d, forcesetup;
88 extern int32_t unrealedlook, quickmapcycling;
89 extern int32_t pk_turnaccel,pk_turndecel,pk_uedaccel;
90 extern int32_t revertCTRL,scrollamount;
91 extern int32_t autosave;
92 extern int32_t mlook;
93 extern int16_t prefixtiles[10];
94 
95 extern int32_t showfirstwall;
96 
97 extern int32_t graphicsmode;
98 
99 extern int32_t grid, autogrid;
100 extern int32_t editorgridextent;	// in engine.c
101 
102 extern char game_executable[BMAX_PATH];
103 extern const char* DefaultGameExec;
104 extern const char* DefaultGameLocalExec;
105 
106 extern char program_origcwd[BMAX_PATH];
107 extern const char *mapster32_fullpath;
108 extern char *testplay_addparam;
109 extern const char *g_namesFileName;
110 
111 extern int32_t gridlock;
112 
113 extern int32_t g_maxCacheSize;
114 
115 extern int32_t g_lazy_tileselector;
116 extern bool m32_osd_tryscript;
117 extern int32_t showheightindicators;
118 extern int32_t showambiencesounds;
119 
120 extern int32_t numgraysects;
121 extern uint8_t graysectbitmap[(MAXSECTORS+7)>>3];
122 extern uint8_t graywallbitmap[(MAXWALLS+7)>>3];
123 extern int32_t autogray, showinnergray;
124 
125 extern void drawgradient(void);
126 
127 #ifdef YAX_ENABLE
128 int32_t yax_is121(int16_t bunchnum, int16_t getfloor);
129 #endif
130 
131 extern void M32_DrawRoomsAndMasks(void);
132 
133 extern void yax_tweakpicnums(int32_t bunchnum, int32_t cf, int32_t restore);  // editor-only
134 extern void M32_ResetFakeRORTiles(void);
135 
136 // set to 1 to enable:
137 #define M32_UNDO 1
138 extern int32_t map_revision;
139 extern int32_t map_undoredo(int32_t dir);
140 extern void map_undoredo_free(void);
141 extern void create_map_snapshot(void);
142 
143 enum
144 {
145     UNDO_SECTORS,
146     UNDO_WALLS,
147     UNDO_SPRITES
148 };
149 
150 typedef struct mapundo_
151 {
152     int32_t revision;
153     int32_t num[3];  // numsectors, numwalls, numsprites
154 
155     // These exist temporarily as sector/wall/sprite data, but are always compressed
156     // +4 bytes refcount at the beginning.
157     char *lz4Blocks[3];  // sector, wall, sprite
158     int   lz4Size[3];
159 
160     uintptr_t crc[3];
161 
162     struct mapundo_ *next;  // 'redo' loads this
163     struct mapundo_ *prev;  // 'undo' loads this
164 } mapundo_t;
165 extern mapundo_t *mapstate;
166 
167 extern void FuncMenu(void);
168 
169 // editor side view
170 extern int32_t m32_sideview;
171 extern int32_t m32_sideelev;
172 extern int16_t m32_sideang;
173 extern int32_t m32_sidecos, m32_sidesin;
174 extern int32_t m32_swcnt;
175 extern int32_t m32_wallscreenxy[MAXWALLS][2];
176 extern int16_t m32_wallsprite[MAXWALLS+MAXSPRITES];
177 extern int8_t sideview_reversehrot;
178 extern int32_t scalescreeny(int32_t sy);
179 extern void editorGet2dScreenCoordinates(int32_t *xres, int32_t *yres, int32_t x, int32_t y, int32_t zoome) ATTRIBUTE((nonnull));
180 //extern void invscreencoords(int32_t *dx, int32_t *dy, int32_t sx, int32_t sy, int32_t zoome);
181 extern int32_t getinvdisplacement(int32_t *dx, int32_t *dy, int32_t dz) ATTRIBUTE((nonnull));
182 extern int32_t getscreenvdisp(int32_t bz, int32_t zoome);
183 extern void editorSetup2dSideView(void);
184 
185 extern int8_t keeptexturestretch;
186 extern int16_t pointhighlightdist, linehighlightdist;
187 
188 extern int32_t wallength(int16_t i);
189 extern void fixrepeats(int16_t i);
190 extern uint32_t getlenbyrep(int32_t len, int32_t repeat);
191 extern void fixxrepeat(int16_t wallnum, uint32_t lenrepquot);
192 extern void AlignWallPoint2(int32_t w0);
193 extern int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs);
194 
195 extern void SetFirstWall(int32_t sectnum, int32_t wallnum, int32_t alsoynw);
196 extern int32_t fixspritesectors(void);
197 extern void clearkeys(void);
198 
199 extern const char *ExtGetVer(void);
200 extern int32_t ExtInit(void);
201 extern int32_t ExtPreInit(int32_t argc,char const * const * argv);
202 extern int32_t ExtPostStartupWindow(void);
203 extern void ExtPostInit(void);
204 extern void ExtUnInit(void);
205 extern void ExtPreCheckKeys(void);
206 extern void ExtAnalyzeSprites(int32_t, int32_t, int32_t, int32_t, int32_t);
207 extern void ExtCheckKeys(void);
208 extern void ExtPreLoadMap(void);
209 extern void ExtSetupMapFilename(const char *mapname);
210 extern void ExtLoadMap(const char *mapname);
211 extern int32_t ExtPreSaveMap(void);
212 extern void ExtSaveMap(const char *mapname);
213 extern const char *ExtGetSectorCaption(int16_t sectnum);
214 extern const char *ExtGetWallCaption(int16_t wallnum);
215 extern const char *ExtGetSpriteCaption(int16_t spritenum);
216 extern void ExtShowSectorData(int16_t sectnum);
217 extern void ExtShowWallData(int16_t wallnum);
218 extern void ExtShowSpriteData(int16_t spritenum);
219 extern void ExtEditSectorData(int16_t sectnum);
220 extern void ExtEditWallData(int16_t wallnum);
221 extern void ExtEditSpriteData(int16_t spritenum);
222 extern const char *ExtGetSectorType(int32_t lotag);
223 
224 extern void B_SetBoardFileName(const char *fn);
225 extern int32_t LoadBoard(const char *filename, uint32_t flags);
226 extern const char *SaveBoard(const char *fn, uint32_t flags);
227 extern const char *GetSaveBoardFilename(const char *fn);
228 
229 extern int32_t clockdir(int32_t wallstart);
230 extern int32_t loopinside(int32_t x, int32_t y, int16_t startwall);
231 
232 enum {
233     // NOTE: These must not be changed, see e.g. loopinside().
234     CLOCKDIR_CW = 0,  // outer loop
235     CLOCKDIR_CCW = 1,  // inner loop
236 };
237 
238 // <loopstart> has to be the starting (i.e. least index) wall of a loop!
239 //
240 // The returned value will be either
241 //  - the starting wall of the next loop of this sector,
242 //  - the first wall of the next sector, or
243 //  - out of bounds (== MAXWALLS).
244 // Thus, it MUST be checked for a proper bound!
get_nextloopstart(int32_t loopstart)245 static inline int32_t get_nextloopstart(int32_t loopstart)
246 {
247     int32_t i = loopstart;
248 
249     while (++i)  // sic
250         if (wall[i].point2 == loopstart)
251             return i + 1;
252 
253     return MAXWALLS;
254 }
255 
256 #define CORRUPT_SECTOR (1<<17)
257 #define CORRUPT_WALL (1<<18)
258 #define CORRUPT_SPRITE (1<<19)
259 #define CORRUPT_MASK (CORRUPT_SECTOR|CORRUPT_WALL|CORRUPT_SPRITE)
260 #define MAXCORRUPTTHINGS 64
261 extern int32_t corruptlevel, numcorruptthings, corruptthings[MAXCORRUPTTHINGS];
262 extern int32_t autocorruptcheck;
263 extern int32_t corruptcheck_noalreadyrefd, corruptcheck_heinum;
264 extern int32_t corruptcheck_game_duke3d;
265 extern int32_t corrupt_tryfix_alt;
266 extern int32_t CheckMapCorruption(int32_t printfromlev, uint64_t tryfixing);
267 
268 extern int32_t fixmaponsave_sprites;
269 extern int32_t m32_script_expertmode;  // if true, make read-only vars writable
270 
271 extern void showsectordata(int16_t sectnum, int16_t small);
272 extern void showwalldata(int16_t wallnum, int16_t small);
273 extern void showspritedata(int16_t spritenum, int16_t small);
274 
275 extern void drawsmallabel(const char *text, char col, char backcol, char border, int32_t dax, int32_t day, int32_t daz);
276 
277 extern int32_t circlewall;
278 extern int32_t searchlock;
279 
280 int32_t loadsetup(const char *fn);	// from config.c
281 int32_t writesetup(const char *fn);	// from config.c
282 
283 void editinput(void);
284 void clearmidstatbar16(void);
285 void fade_editor_screen(int32_t keepcol);
286 
287 // internal getnumber* helpers:
288 extern int32_t getnumber_internal1(char ch, int32_t *danumptr, int32_t maxnumber, char sign);
289 extern int32_t getnumber_autocomplete(const char *namestart, char ch, int32_t *danum, int32_t flags);
290 
291 // always CRLF for us
292 #ifdef _WIN32
293 # define OURNEWL "\n"
294 #else
295 # define OURNEWL "\r\n"
296 #endif
297 
298 #ifdef YAX_ENABLE
299 extern const char *yupdownwall[2];
300 extern const char *YUPDOWNWALL[2];
301 #endif
302 
303 int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t));
304 #define getnumber256(namestart, num, maxnumber, sign) _getnumber256(namestart, num, maxnumber, sign, NULL)
305 int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t));
306 #define getnumber16(namestart, num, maxnumber, sign) _getnumber16(namestart, num, maxnumber, sign, NULL)
307 void printmessage256(int32_t x, int32_t y, const char *name);
308 void message(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
309 void silentmessage(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
310 extern int32_t AskIfSure(const char *text);
311 
312 extern char getmessage[162], getmessageleng;
313 extern int32_t getmessagetimeoff;
314 
315 extern int32_t mouseaction;
316 
317 const char* getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen, int32_t completion);
318 
319 // like snprintf, but pads the output buffer with 'fill' at the end
320 //int32_t snfillprintf(char *outbuf, size_t bufsiz, int32_t fill, const char *fmt, ...);
321 void _printmessage16(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
322 
323 #define printmessage16(fmt, ...) lastpm16time = (int32_t) totalclock, _printmessage16(fmt, ## __VA_ARGS__)
324 
325 extern char lastpm16buf[156];
326 
327 int32_t fillsector_maybetrans(int16_t sectnum, int32_t fillcolor, uint8_t dotrans);  // fillcolor == -1: default (pulsating)
328 int32_t ask_if_sure(const char *query, uint32_t flags);
329 int32_t editor_ask_function(const char *question, const char *dachars, int32_t numchars);
330 
fillsector(int16_t sectnum,int32_t fillcolor)331 static inline int32_t fillsector(int16_t sectnum, int32_t fillcolor)
332 {
333     return fillsector_maybetrans(sectnum, fillcolor, 1);
334 }
335 
fillsector_notrans(int16_t sectnum,int32_t fillcolor)336 static inline int32_t fillsector_notrans(int16_t sectnum, int32_t fillcolor)
337 {
338     return fillsector_maybetrans(sectnum, fillcolor, 0);
339 }
340 
341 void spriteoncfz(int32_t i, int32_t *czptr, int32_t *fzptr) ATTRIBUTE((nonnull(2,3)));
342 void DoSpriteOrnament(int32_t i);
343 
344 void getpoint(int32_t searchxe, int32_t searchye, int32_t *x, int32_t *y);
345 int32_t getpointhighlight(int32_t xplc, int32_t yplc, int32_t point);
346 void update_highlight(void);
347 void update_highlightsector(void);
348 void reset_highlightsector(void);
349 void reset_highlight(void);
350 void handlesecthighlight1(int32_t i, int32_t sub, int32_t nograycheck);
351 void ovh_whiteoutgrab(int32_t restoreredwalls);
352 
353 int32_t inside_editor_curpos(int16_t sectnum);
354 void correct_sprite_yoffset(int32_t i);
355 
356 void inflineintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
357                       int32_t x3, int32_t y3, int32_t x4, int32_t y4,
358                       int32_t *intx, int32_t *inty, int32_t *sign12, int32_t *sign34);
359 
360 void ovhscrcoords(int32_t x, int32_t y, int32_t *scrx, int32_t *scry);
361 
362 extern uint8_t hlsectorbitmap[(MAXSECTORS+7)>>3];
363 
364 void test_map(int32_t mode);
365 
366 extern void M32RunScript(const char *s);
367 
368 ////////// tag labeling system //////////
369 // max (strlen+1), i.e. array length to allocate for a tag label:
370 #define TAGLAB_MAX 40
371 
372 extern int32_t taglab_load(const char *filename, int32_t flags);
373 extern int32_t taglab_save(const char *mapname);
374 
375 extern void taglab_init();
376 extern int32_t taglab_add(const char *label, int16_t tag);
377 extern const char *taglab_getlabel(int16_t tag);
378 extern int32_t taglab_gettag(const char *label);
379 
380 extern int32_t taglab_linktags(int32_t spritep, int32_t num);
381 extern int32_t taglab_getnextfreetag(int32_t *duetoptr);
382 
383 extern int32_t showtags;
384 
385 int32_t select_sprite_tag(int32_t spritenum);
386 
387 extern int32_t m32_2d3dmode, m32_2d3dsize;
388 extern vec2_t m32_2d3d;
389 extern int32_t m32_3dundo;
390 
391 #define XSIZE_2D3D (xdim2d / m32_2d3dsize)
392 #define YSIZE_2D3D (ydim2d / m32_2d3dsize)
393 
m32_2d3d_resolutions_match()394 static inline int32_t m32_2d3d_resolutions_match()
395 {
396     return (xdimgame == xdim2d && ydimgame == ydim2d);
397 }
398 
m32_is2d3dmode(void)399 static inline int32_t m32_is2d3dmode(void)
400 {
401     return !in3dmode() && m32_2d3dmode && (unsigned)cursectnum < MAXSECTORS &&
402         m32_2d3d_resolutions_match() &&
403         searchx > m32_2d3d.x && searchx < (m32_2d3d.x + XSIZE_2D3D) &&
404         searchy > m32_2d3d.y && searchy < (m32_2d3d.y + YSIZE_2D3D);
405 }
406 
407 extern int32_t editorGet2dSpriteColor(int32_t spr);
408 
409 #define SPRITESEC(j) (sector[sprite[j].sectnum])
410 
411 #define SCRIPTHISTSIZ 32  // should be the same as OSD_HISTORYDEPTH for maximum win, should be a power of two
412 extern char *scripthist[SCRIPTHISTSIZ];
413 extern int32_t scripthistend;
414 
415 //////////////////// Aiming ////////////////////
416 #define SEARCH_WALL 0
417 #define SEARCH_CEILING 1
418 #define SEARCH_FLOOR 2
419 #define SEARCH_SPRITE 3
420 #define SEARCH_MASKWALL 4
421 
422 #define ASSERT_AIMING ((unsigned)searchstat<=4)
423 
424 #define AIMING_AT_WALL (searchstat==0)
425 #define AIMING_AT_CEILING (searchstat==1)
426 #define AIMING_AT_FLOOR (searchstat==2)
427 #define AIMING_AT_SPRITE (searchstat==3)
428 #define AIMING_AT_MASKWALL (searchstat==4)
429 
430 #define AIMING_AT_WALL_OR_MASK (AIMING_AT_WALL || AIMING_AT_MASKWALL)
431 #define AIMING_AT_CEILING_OR_FLOOR (AIMING_AT_CEILING || AIMING_AT_FLOOR)
432 
433 // SaveBoard flags.
434 enum SaveBoardFlags
435 {
436     M32_SB_NOEXT = 1,  // no ExtSaveMap (backup.map) and no taglabels saving
437     M32_SB_ASKOV = 2,  // for NEW_MAP_FORMAT build, ask whether write map if going from V7/8 to VX
438 };
439 
440 // showdebug is now used as a general informational on-screen display
441 #define M32_SHOWDEBUG
442 
443 // this should be only used if there's no dependency on endwall after the loop.
444 // of course, users of this macro should know that it modifies startwall and endwall.
445 #define WALLS_OF_SECTOR(Sect, Itervar) \
446     startwall=sector[(Sect)].wallptr, endwall=startwall+sector[(Sect)].wallnum, Itervar=startwall; \
447     Itervar < endwall; \
448     Itervar++
449 
450 #define SET_PROTECT_BITS(Var, Newval, Bitstoprotect) do {  \
451     (Var) &= (Bitstoprotect);  \
452     (Var) |= (Newval) & ~(Bitstoprotect); } while (0)
453 
454 #define BTAG_MAX 65535
455 #define BZ_MAX 8388608
456 #define BHEINUM_MAX 32767
457 
458 #define M32_MAXPALOOKUPS (MAXPALOOKUPS-RESERVEDPALS-1)
459 
inpclamp(int32_t * x,int32_t mi,int32_t ma)460 static FORCE_INLINE void inpclamp(int32_t *x, int32_t mi, int32_t ma)
461 {
462     if (*x > ma) *x = ma;
463     if (*x < mi) *x = mi;
464 }
465 
466 #define drawtranspixel(p, col) drawpixel(p, blendtable[0][(readpixel(p) * 256) + col])
467 
468 // Timed offset for Mapster32 color index cycling.
469 // Range: 0 .. 16
470 #define M32_THROB klabs(sintable[(((int32_t) totalclock << 4) & 2047)] >> 10)
471 
472 void m32_showmouse(void);
473 
474 #ifdef __cplusplus
475 }
476 #endif
477 
478 #endif
479