From 1ad3b39e70c5e2ffc6c2a78fc3d18f63730fb82f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 17 Sep 2019 20:19:11 +0200 Subject: [PATCH] - removed the editor code. --- source/build/src/build.cpp | 11192 ----------------------------------- 1 file changed, 11192 deletions(-) delete mode 100644 source/build/src/build.cpp diff --git a/source/build/src/build.cpp b/source/build/src/build.cpp deleted file mode 100644 index c44a595fb..000000000 --- a/source/build/src/build.cpp +++ /dev/null @@ -1,11192 +0,0 @@ -// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman -// Ken Silverman's official web site: "http://www.advsys.net/ken" -// See the included license file "BUILDLIC.TXT" for license info. -// -// This file has been modified from Ken Silverman's original release -// by Jonathon Fowler (jf@jonof.id.au) -// by the EDuke32 team (development@voidpoint.com) - -#include "build.h" -#include "compat.h" -#include "pragmas.h" -#include "osd.h" -#include "cache1d.h" -#include "editor.h" -#include "common.h" -#include "colmatch.h" -#include "palette.h" -#include "scancodes.h" -#include "baselayer.h" -#include "renderlayer.h" - -#include "vfs.h" - -#ifdef _WIN32 -# include "winbits.h" -#endif - - -#include "m32script.h" - -char levelname[BMAX_PATH] = {0}; - -#define TIMERINTSPERSECOND 120 - -#define updatecrc16(crc,dat) (crc = (((crc<<8)&65535)^crctable[((((uint16_t)crc)>>8)&65535)^dat])) -static int32_t crctable[256]; -static char kensig[64]; - -static const char *CallExtGetVer(void); -static int32_t CallExtInit(void); -static int32_t CallExtPreInit(int32_t argc,char const * const * argv); -static int32_t CallExtPostStartupWindow(void); -static void CallExtPostInit(void); -static void CallExtUnInit(void); -static void CallExtPreCheckKeys(void); -static void CallExtAnalyzeSprites(int32_t, int32_t, int32_t, int32_t); -static void CallExtCheckKeys(void); -static void CallExtPreLoadMap(void); -static void CallExtSetupMapFilename(const char *mapname); -static void CallExtLoadMap(const char *mapname); -static int32_t CallExtPreSaveMap(void); -static void CallExtSaveMap(const char *mapname); -static inline const char *CallExtGetSectorCaption(int16_t sectnum) { return ExtGetSectorCaption(sectnum); } -static inline const char *CallExtGetWallCaption(int16_t wallnum) { return ExtGetWallCaption(wallnum); } -static inline const char *CallExtGetSpriteCaption(int16_t spritenum) { return ExtGetSpriteCaption(spritenum); } -static void CallExtShowSectorData(int16_t sectnum); -static void CallExtShowWallData(int16_t wallnum); -static void CallExtShowSpriteData(int16_t spritenum); -static void CallExtEditSectorData(int16_t sectnum); -static void CallExtEditWallData(int16_t wallnum); -static void CallExtEditSpriteData(int16_t spritenum); -// static const char *CallExtGetSectorType(int32_t lotag); - -int8_t m32_clipping=2; -static int32_t m32_rotateang = 0; - -// 0 1 2 3 4 5 6 7 -// up, down, left, right, lshift, rctrl, lctrl, space -// 8 9 10 11 12 13 -// a, z, pgdn, pgup, [,], [.] -// 14 15 16 17 18 19 -// kpenter, enter, =, -, tab, ` -uint8_t buildkeys[NUMBUILDKEYS] = -{ - 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, - 0x1e,0x2c,0xd1,0xc9,0x33,0x34, - 0x9c,0x1c,0xd,0xc,0xf,0x29 -}; - -// Start position -vec3_t startpos; -int16_t startang, startsectnum; - -// Current position -vec3_t pos; -int32_t horiz = 100; -int16_t ang, cursectnum; -static int32_t hvel, vel, svel, angvel; -int32_t g_doHardcodedMovement = 1; - -static int32_t mousexsurp = 0, mouseysurp = 0; -double msens = 1.0; - -int32_t grponlymode = 0; -int32_t graphicsmode = 0; - -int32_t synctics = 0, lockclock = 0; - -// those ones save the respective 3d video vars while in 2d mode -// so that exiting from mapster32 in 2d mode saves the correct ones -float vid_gamma_3d=-1, vid_contrast_3d=-1, vid_brightness_3d=-1; - -int32_t xdim2d = 640, ydim2d = 480, xdimgame = 640, ydimgame = 480, bppgame = 8; -int32_t forcesetup = 1; - -#ifndef GEKKO -int32_t g_maxCacheSize = 24<<20; -#else -int32_t g_maxCacheSize = 8<<20; -#endif - -static int16_t oldmousebstatus = 0; - -char game_executable[BMAX_PATH] = {0}; - -int32_t zlock = 0x7fffffff, zmode = 0, kensplayerheight = 32; -//int16_t defaultspritecstat = 0; - -int16_t localartfreq[MAXTILES]; -int16_t localartlookup[MAXTILES], localartlookupnum; - -char tempbuf[4096]; - -char names[MAXTILES][25]; -const char *g_namesFileName = "NAMES.H"; - -int16_t asksave = 0; -int32_t osearchx, osearchy; //old search input - -int32_t grid = 0, autogrid = 1, gridlock = 1, showtags = 2; -int32_t zoom = 768, gettilezoom = 1, ztarget = 768; -int32_t lastpm16time = 0; - -extern int32_t mapversion; - -int16_t highlight[MAXWALLS+MAXSPRITES]; -int16_t highlightsector[MAXSECTORS], highlightsectorcnt = -1; -extern char textfont[128][8]; - -int32_t tempsectornum = -1; // for auto ceiling/floor alignment -int32_t temppicnum, tempcstat, templotag, temphitag, tempextra; -uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning=0, tempypanning=0; -int32_t tempshade, tempxvel, tempyvel, tempzvel; -int32_t tempstatnum=0, tempblend=0; -char somethingintab = 255; - -// Only valid when highlightsectorcnt>0 and no structural -// modifications (deleting/inserting sectors or points, setting new firstwall) -// have been made: -static int16_t onextwall[MAXWALLS]; // onextwall[i]>=0 implies wall[i].nextwall < 0 -static void mkonwvalid(void) { chsecptr_onextwall = onextwall; } -static void mkonwinvalid(void) { chsecptr_onextwall = NULL; tempsectornum=-1; } -static void mkonwinvalid_keeptempsect(void) { chsecptr_onextwall = NULL; } -static int32_t onwisvalid(void) { return chsecptr_onextwall != NULL; } - -int32_t mlook = 0, mskip=0; -int32_t revertCTRL=0,scrollamount=3; -int32_t unrealedlook=1, quickmapcycling=1; //PK - -char program_origcwd[BMAX_PATH]; -const char *mapster32_fullpath; -char *testplay_addparam = 0; - -static char boardfilename[BMAX_PATH], selectedboardfilename[BMAX_PATH]; -//extern char levelname[BMAX_PATH]; // in astub.c XXX: clean up this mess!!! - -void B_SetBoardFileName(const char *fn) -{ - Bstrncpyz(boardfilename, fn, BMAX_PATH); -} - -static fnlist_t fnlist; -static CACHE1D_FIND_REC *finddirshigh=NULL, *findfileshigh=NULL; -static int32_t currentlist=0; - -//static int32_t repeatcountx, repeatcounty; - -static int32_t fillist[640]; -// used for fillsector, batch point insertion, backup_highlighted_map -static int32_t tempxyar[MAXWALLS][2]; - -static int32_t mousx, mousy; -int16_t prefixtiles[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; -uint8_t hlsectorbitmap[MAXSECTORS>>3]; // show2dsector is already taken... -static int32_t minhlsectorfloorz, numhlsecwalls; -int32_t searchlock = 0; - -// used for: -// - hl_all_bunch_sectors_p -// - AlignWalls -// - trace_loop -static uint8_t visited[MAXWALLS>>3]; - -int32_t m32_2d3dmode = 0; -int32_t m32_2d3dsize = 4; -vec2_t m32_2d3d = { 0xffff, 4 }; - -typedef struct -{ - int16_t numsectors, numwalls, numsprites; -#ifdef YAX_ENABLE - int16_t numyaxbunches; - int16_t *bunchnum; // [numsectors][2] - int16_t *ynextwall; // [numwalls][2] -#endif - usectortype *sector; - uwalltype *wall; - uspritetype *sprite; -} mapinfofull_t; - -int32_t g_doScreenShot; - -#define eitherALT (keystatus[sc_LeftAlt]|keystatus[sc_RightAlt]) -#define eitherCTRL (keystatus[sc_LeftControl]|keystatus[sc_RightControl]) -#define eitherSHIFT (keystatus[sc_LeftShift]|keystatus[sc_RightShift]) - -#define DOWN_BK(BuildKey) (keystatus[buildkeys[BK_##BuildKey]]) - -int32_t pk_turnaccel=16; -int32_t pk_turndecel=12; -int32_t pk_uedaccel=3; - -int8_t keeptexturestretch = 1; -int8_t sideview_reversehrot = 0; - -int16_t pointhighlightdist = 256; -int16_t linehighlightdist = 1024; - -char lastpm16buf[156]; - -//static int32_t checksectorpointer_warn = 0; -static int32_t saveboard_savedtags, saveboard_fixedsprites; -static int32_t saveboard_canceled; - -static int32_t backup_highlighted_map(mapinfofull_t *mapinfo); -static int32_t restore_highlighted_map(mapinfofull_t *mapinfo, int32_t forreal); -static void SaveBoardAndPrintMessage(const char *fn); - -static int32_t adjustmark(int32_t *xplc, int32_t *yplc, int16_t danumwalls); -static void locktogrid(int32_t *dax, int32_t *day); -static int32_t checkautoinsert(int32_t dax, int32_t day, int16_t danumwalls); -static void keytimerstuff(void); -static void flipwalls(int16_t numwalls, int16_t newnumwalls); -static int32_t insertpoint(int16_t linehighlight, int32_t dax, int32_t day, int32_t *mapwallnum); -static void deletepoint(int16_t point, int32_t runi); -static int32_t deletesector(int16_t sucksect); -static int16_t whitelinescan(int16_t sucksect, int16_t dalinehighlight); -static void printcoords16(int32_t posxe, int32_t posye, int16_t ange); -static void overheadeditor(void); -static int32_t getlinehighlight(int32_t xplc, int32_t yplc, int32_t line, int8_t ignore_pointhighlight); -static int32_t movewalls(int32_t start, int32_t offs); -static void loadnames(const char *namesfile); -static void getclosestpointonwall(int32_t x, int32_t y, int32_t dawall, int32_t *nx, int32_t *ny, - int32_t maybe_screen_coord_p); -static void initcrc(void); - -static int32_t menuselect(void); -static int32_t menuselect_auto(int, int); //PK - -static int32_t insert_sprite_common(int32_t sectnum, int32_t dax, int32_t day); -static void correct_ornamented_sprite(int32_t i, int32_t hitw); - -static int32_t getfilenames(const char *path, const char *kind); - -// Get basename of BUILD file name (forward slashes as directory separators). -static const char *getbasefn(const char *fn) -{ - const char *slash = Bstrrchr(fn, '/'); - return slash ? slash+1 : fn; -} - -void clearkeys(void) -{ - Bmemset(keystatus,0,sizeof(keystatus)); -} - -#ifdef USE_OPENGL -int osdcmd_restartvid(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - - if (!in3dmode()) return OSDCMD_OK; - - videoResetMode(); - if (videoSetGameMode(fullscreen,xres,yres,bpp,upscalefactor)) - OSD_Printf("restartvid: Reset failed...\n"); - - return OSDCMD_OK; -} -#endif - -static int osdcmd_vidmode(osdcmdptr_t parm) -{ - int32_t newx = xres, newy = yres, newbpp = bpp, newfullscreen = fullscreen; -#ifdef USE_OPENGL - int32_t tmp; -#endif - - switch (parm->numparms) - { -#ifdef USE_OPENGL - case 1: // bpp switch - tmp = Batol(parm->parms[0]); - if (!(tmp==8 || tmp==16 || tmp==32)) - return OSDCMD_SHOWHELP; - newbpp = tmp; - break; - case 4: // fs, res, bpp switch - newfullscreen = (Batol(parm->parms[3]) != 0); - fallthrough__; - case 3: // res & bpp switch - tmp = Batol(parm->parms[2]); - if (!(tmp==8 || tmp==16 || tmp==32)) - return OSDCMD_SHOWHELP; - newbpp = tmp; - fallthrough__; -#endif - case 2: // res switch - newx = Batol(parm->parms[0]); - newy = Batol(parm->parms[1]); - break; - default: - return OSDCMD_SHOWHELP; - } - - if (!in3dmode()) - { - videoSet2dMode(newx,newy); - xdim2d = xdim; - ydim2d = ydim; - - videoBeginDrawing(); //{{{ - CLEARLINES2D(0, ydim16, 0); - videoEndDrawing(); //}}} - - ydim16 = ydim-STATUS2DSIZ2; - - return OSDCMD_OK; - } - - if (videoSetGameMode(newfullscreen,newx,newy,newbpp,upscalefactor)) - OSD_Printf("vidmode: Mode change failed!\n"); - - xdimgame = newx; - ydimgame = newy; - bppgame = newbpp; - fullscreen = newfullscreen; - - return OSDCMD_OK; -} - - -#ifdef M32_SHOWDEBUG -char m32_debugstr[64][128]; -int32_t m32_numdebuglines=0; - -static void M32_drawdebug(void) -{ - int32_t i; - int32_t x=4, y=8; - -#if 0 - { - static char tstr[128]; - Bsprintf(tstr, "search... stat=%d, sector=%d, wall=%d (%d), isbottom=%d, asksave=%d", - searchstat, searchsector, searchwall, searchbottomwall, searchisbottom, asksave); - printext256(x,y,whitecol,0,tstr,xdimgame>640?0:1); - } -#endif - if (m32_numdebuglines>0) - { - videoBeginDrawing(); - for (i=0; i640?0:1); - videoEndDrawing(); - } - m32_numdebuglines=0; -} -#endif - -#ifdef YAX_ENABLE -// Check whether bunchnum has exactly one corresponding floor and ceiling -// and return it in this case. If not 1-to-1, return -1. -int32_t yax_is121(int16_t bunchnum, int16_t getfloor) -{ - int32_t i; - i = headsectbunch[0][bunchnum]; - if (i<0 || nextsectbunch[0][i]>=0) - return -1; - i = headsectbunch[1][bunchnum]; - if (i<0 || nextsectbunch[1][i]>=0) - return -1; - - return headsectbunch[getfloor][bunchnum]; -} - -static int32_t yax_numsectsinbunch(int16_t bunchnum, int16_t cf) -{ - int32_t i, n=0; - - if (bunchnum<0 || bunchnum>=numyaxbunches) - return -1; - - for (SECTORS_OF_BUNCH(bunchnum, cf, i)) - n++; - - return n; -} - -static void yax_fixreverselinks(int16_t oldwall, int16_t newwall) -{ - int32_t cf, ynw; - for (cf=0; cf<2; cf++) - { - ynw = yax_getnextwall(oldwall, cf); - if (ynw >= 0) - yax_setnextwall(ynw, !cf, newwall); - } -} - -static void yax_tweakwalls(int16_t start, int16_t offs) -{ - int32_t i, nw, cf; - for (i=0; i= start) - yax_setnextwall(i, cf, nw+offs); - } -} - -static void yax_resetbunchnums(void) -{ - int32_t i; - - for (i=0; i=0 || wall[line].dnwall>=0); -#else - return !!(wall[line].cstat&YAX_NEXTWALLBITS); -#endif -} - -# define DEFAULT_YAX_HEIGHT (2048<<4) -#endif - -static void reset_default_mapstate(void) -{ - pos.x = 32768; //new board! - pos.y = 32768; - pos.z = 0; - ang = 1536; - cursectnum = -1; - - numsectors = 0; - numwalls = 0; - - editorzrange[0] = INT32_MIN; - editorzrange[1] = INT32_MAX; - - initspritelists(); - taglab_init(); - artClearMapArt(); -#ifdef YAX_ENABLE - yax_resetbunchnums(); -#endif - g_loadedMapVersion = -1; -} - -static void m32_keypresscallback(int32_t code, int32_t downp) -{ - UNREFERENCED_PARAMETER(downp); - - g_iReturnVar = code; - VM_OnEvent(EVENT_KEYPRESS, -1); -} - -void M32_ResetFakeRORTiles(void) -{ -#ifdef POLYMER -# ifdef YAX_ENABLE - // END_TWEAK ceiling/floor fake 'TROR' pics, see BEGIN_TWEAK in engine.c - if (videoGetRenderMode() == REND_POLYMER && showinvisibility) - { - int32_t i; - - for (i=0; i= 0) - { - // a.m32 states 'tduprot' and 'tduplin' need searchstat to check for - // whether we've hit a sprite, but these would be only set after the - // drawmasks(). Hence this hackish workaround. - searchstat = 3; - searchwall = srchwall; - } - CallExtAnalyzeSprites(0,0,0,0); - searchwall = osearchwall, searchstat=osearchstat; - - renderDrawMasks(); - srchwall = (searchstat == 3) ? searchwall : -1; - M32_ResetFakeRORTiles(); - -#ifdef POLYMER - if (videoGetRenderMode() == REND_POLYMER && searchit == 2) - { - polymer_editorpick(); - drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); - CallExtAnalyzeSprites(0,0,0,0); - renderDrawMasks(); - M32_ResetFakeRORTiles(); - } -#endif - - VM_OnEvent(EVENT_DRAW3DSCREEN, -1); - - if (g_doScreenShot) - { - videoCaptureScreen("mcapxxxx.tga", 0); - g_doScreenShot = 0; - } - - if (r_usenewaspect) - { - newaspect_enable = 0; - renderSetAspect(tmpvr, tmpyx); - } -} - -void M32_OnShowOSD(int shown) -{ - mouseLockToWindow((!shown) + 2); -} - -static void M32_FatalEngineError(void) -{ - wm_msgbox("Build Engine Initialization Error", - "There was a problem initializing the Build engine: %s", engineerrstr); - ERRprintf("app_main: There was a problem initializing the Build engine: %s\n", engineerrstr); - exit(2); -} - -int app_main(int argc, char const * const * argv) -{ -#ifdef STARTUP_SETUP_WINDOW - char cmdsetup = 0; -#endif - char quitflag; - int32_t i; - - pathsearchmode = 1; // unrestrict findfrompath so that full access to the filesystem can be had - -#ifdef USE_OPENGL - OSD_RegisterFunction("restartvid","restartvid: reinitialize the video mode",osdcmd_restartvid); - OSD_RegisterFunction("vidmode","vidmode : immediately change the video mode",osdcmd_vidmode); - baselayer_osdcmd_vidmode_func = osdcmd_vidmode; -#else - OSD_RegisterFunction("vidmode","vidmode : immediately change the video mode",osdcmd_vidmode); -#endif - - wm_setapptitle(AppProperName); - - editstatus = 1; - - if ((i = CallExtPreInit(argc,argv)) < 0) return -1; - -#ifdef _WIN32 - backgroundidle = 1; -#endif - - for (i=1; i0) - initprintf("There was an error loading the sprite clipping map (status %d).\n", k); - - for (char * f : g_clipMapFiles) - free(f); - g_clipMapFiles.clear(); -#endif - - taglab_init(); - - mkonwinvalid(); - - // executed once per init - OSD_Exec("m32_autoexec.cfg"); - - if (LoadBoard(boardfilename, 1)) - reset_default_mapstate(); - - totalclock = 0; - - updatesector(pos.x,pos.y,&cursectnum); - - keySetCallback(&m32_keypresscallback); - M32_OnShowOSD(0); // make sure the desktop's mouse cursor is hidden - - if (cursectnum == -1) - { - vid_gamma_3d = g_videoGamma; - vid_brightness_3d = g_videoBrightness; - vid_contrast_3d = g_videoContrast; - - g_videoGamma = g_videoContrast = 1.0; - g_videoBrightness = 0.0; - - videoSetPalette(0,0,0); - if (videoSetGameMode(fullscreen, xdim2d, ydim2d, 8, upscalefactor) < 0) - { - CallExtUnInit(); - engineUnInit(); - Bprintf("%d * %d not supported in this graphics mode\n",xdim2d,ydim2d); - Bexit(0); - } - - system_getcvars(); - - overheadeditor(); - keystatus[buildkeys[BK_MODE2D_3D]] = 0; - - g_videoGamma = vid_gamma_3d; - g_videoContrast = vid_contrast_3d; - g_videoBrightness = vid_brightness_3d; - - vid_gamma_3d = vid_contrast_3d = vid_brightness_3d = -1; - - videoSetPalette(GAMMA_CALC,0,0); - } - else - { - if (videoSetGameMode(fullscreen, xdimgame, ydimgame, bppgame, upscalefactor) < 0) - { - CallExtUnInit(); - engineUnInit(); - Bprintf("%d * %d not supported in this graphics mode\n",xdim,ydim); - Bexit(0); - } - - system_getcvars(); - - videoSetPalette(GAMMA_CALC,0,0); - } - -CANCEL: - quitflag = 0; - while (quitflag == 0) - { - if (handleevents()) - { - if (quitevent) - { - keystatus[sc_Escape] = 1; - quitevent = 0; - } - } - - OSD_DispatchQueued(); - - videoNextPage(); - synctics = totalclock-lockclock; - lockclock += synctics; - - CallExtPreCheckKeys(); - - M32_DrawRoomsAndMasks(); - - inputchecked = 1; - -#ifdef M32_SHOWDEBUG - if (searchstat>=0 && (searchwall<0 || searchsector<0)) - { - if (m32_numdebuglines<64) - Bsprintf(m32_debugstr[m32_numdebuglines++], "inconsistent search variables!"); - searchstat = -1; - } - - M32_drawdebug(); -#endif - CallExtCheckKeys(); - - - if (keystatus[sc_Escape]) - { - keystatus[sc_Escape] = 0; - - printext256(0,0,whitecol,0,"Are you sure you want to quit?",0); - - videoShowFrame(1); - synctics = totalclock-lockclock; - lockclock += synctics; - - while ((keystatus[sc_Escape]|keystatus[sc_Enter]|keystatus[sc_Space]|keystatus[sc_N]) == 0) - { - idle_waitevent(); - if (handleevents()) - { - if (quitevent) - { - quitflag = 1; - break; - } - } - - if (keystatus[sc_Y]||keystatus[sc_Enter]) // Y or ENTER - { - keystatus[sc_Y] = 0; - keystatus[sc_Enter] = 0; - quitflag = 1; break; - } - } - while (keystatus[sc_Escape]) - { - keystatus[sc_Escape] = 0; - quitevent = 0; - goto CANCEL; - } - } - } - - if (asksave) - { - i = CheckMapCorruption(4, 0); - - printext256(0,8,whitecol,0,i<4?"Save changes?":"Map is heavily corrupt. Save changes?",0); - videoShowFrame(1); - - while ((keystatus[sc_Escape]|keystatus[sc_Enter]|keystatus[sc_Space]|keystatus[sc_N]|keystatus[sc_C]) == 0) - { - idle_waitevent(); - if (handleevents()) { if (quitevent) break; } // like saying no - - if (keystatus[sc_Y] || keystatus[sc_Enter]) // Y or ENTER - { - keystatus[sc_Y] = keystatus[sc_Enter] = 0; - - SaveBoard(NULL, M32_SB_ASKOV); - - break; - } - } - while (keystatus[sc_Escape]||keystatus[sc_C]) - { - keystatus[sc_Escape] = keystatus[sc_C] = 0; - quitevent = 0; - goto CANCEL; - } - } - - - CallExtUnInit(); -// clearfilenames(); - engineUnInit(); - - return 0; -} - -static int32_t mhk=0; -static void loadmhk(int32_t domessage) -{ - char levname[BMAX_PATH]; - - if (!mhk) - return; - - Bstrcpy(levname, boardfilename); - append_ext_UNSAFE(levname, ".mhk"); - - if (!engineLoadMHK(levname)) - { - if (domessage) - message("Loaded map hack file \"%s\"",levname); - else - initprintf("Loaded map hack file \"%s\"\n",levname); - } - else - { - mhk=2; - if (domessage) - message("No maphack found for map \"%s\"",boardfilename); - } -} - -// this is spriteon{ceiling,ground}z from astub.c packed into -// one convenient function -void spriteoncfz(int32_t i, int32_t *czptr, int32_t *fzptr) -{ - int32_t height, zofs; - - getzsofslope(sprite[i].sectnum, sprite[i].x,sprite[i].y, czptr, fzptr); - if ((sprite[i].cstat&48)==32) - return; - - zofs = spriteheightofs(i, &height, 0); - - *czptr += height - zofs; - *fzptr -= zofs; -} - -static void move_and_update(int32_t xvect, int32_t yvect, int32_t addshr) -{ - if (m32_clipping==0) - { - pos.x += xvect>>(14+addshr); - pos.y += yvect>>(14+addshr); - updatesector(pos.x,pos.y, &cursectnum); - } - else - { - clipmove(&pos,&cursectnum, xvect>>addshr,yvect>>addshr, - 128,4<<8,4<<8, (m32_clipping==1) ? 0 : CLIPMASK0); - } - - if (in3dmode()) - { - silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz); - getmessagetimeoff = totalclock+30; - } -} - -static void mainloop_move(void) -{ - int32_t xvect, yvect, doubvel; - - if (angvel != 0) //ang += angvel * constant - { - if (eitherCTRL && m32_2d3dmode) - { - int x = m32_2d3d.x + (angvel / 32); - int xx = m32_2d3d.x + XSIZE_2D3D + (angvel / 32); - - if (x > 4 && xx < xdim2d - 4) - { - silentmessage("2d3d x:%d y:%d", m32_2d3d.x, m32_2d3d.y); - m32_2d3d.x += (angvel / 32); - } - } - else - { - //ENGINE calculates angvel for you - - //Lt. shift makes turn velocity 50% faster - doubvel = (synctics + DOWN_BK(RUN)*(synctics>>1)); - - ang += ((angvel*doubvel)>>4); - ang &= 2047; - - if (in3dmode()) - { - silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz); - getmessagetimeoff = totalclock+30; - } - } - } - if ((vel|svel) != 0) - { - if (eitherCTRL && m32_2d3dmode) - { - int y = m32_2d3d.y - (vel / 64); - int yy = m32_2d3d.y + YSIZE_2D3D - (vel / 64); - - if (y > 4 && yy < ydim2d - STATUS2DSIZ2 - 4) - { - silentmessage("2d3d x:%d y:%d", m32_2d3d.x, m32_2d3d.y); - m32_2d3d.y -= (vel / 64); - } - } - else - - { - //Lt. shift doubles forward velocity - doubvel = (1+(DOWN_BK(RUN)))*synctics; - - xvect = 0; - yvect = 0; - - if (vel != 0) - { - xvect += ((vel*doubvel)>>3)*(int32_t) sintable[(ang+2560)&2047]; - yvect += ((vel*doubvel)>>3)*(int32_t) sintable[(ang+2048)&2047]; - } - if (svel != 0) - { - xvect += ((svel*doubvel)>>3)*(int32_t) sintable[(ang+2048)&2047]; - yvect += ((svel*doubvel)>>3)*(int32_t) sintable[(ang+1536)&2047]; - } - - move_and_update(xvect, yvect, 0); - } - } -} - -static void handle_sprite_in_clipboard(int32_t i) -{ - if (somethingintab == 3) - { - int32_t j, k; - - sprite[i].picnum = temppicnum; - if (tilesiz[temppicnum].x <= 0 || tilesiz[temppicnum].y <= 0) - { - j = 0; - for (k=0; k 0 && tilesiz[k].y > 0) - { - j = k; - break; - } - sprite[i].picnum = j; - } - sprite[i].shade = tempshade; - sprite[i].blend = tempblend; - sprite[i].pal = temppal; - sprite[i].xrepeat = max(tempxrepeat, 1u); - sprite[i].yrepeat = max(tempyrepeat, 1u); - sprite[i].cstat = tempcstat; - } -} - - -void editinput(void) -{ - int32_t mousz, bstatus; - int32_t i, tempint=0; - int32_t goalz, xvect, yvect, hiz, loz, oposz; - int32_t hihit, lohit, omlook=mlook; - -// 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 46 -// F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SCROLL - - mousz = 0; - mouseGetValues(&mousx,&mousy,&bstatus); - mousx = (mousx<<16) + mousexsurp; - mousy = (mousy<<16) + mouseysurp; - - if (unrealedlook && !mskip) - { - if (mlook==0 && (bstatus&(1|2|4))==2) - mlook = 3; - else if ((bstatus&(1|2|4))==1) - mlook = 3; - } - - { - ldiv_t ld; - if (mlook) - { - ld = ldiv(mousx, (int32_t)((1<<16)/(msens*0.5f))); mousx = ld.quot; mousexsurp = ld.rem; - ld = ldiv(mousy, (int32_t)((1<<16)/(msens*0.25f))); mousy = ld.quot; mouseysurp = ld.rem; - } - else - { - ld = ldiv(mousx, (int32_t)((1<<16)/msens)); mousx = ld.quot; mousexsurp = ld.rem; - ld = ldiv(mousy, (int32_t)((1<<16)/msens)); mousy = ld.quot; mouseysurp = ld.rem; - } - } - - if (mlook == 3) - mlook = omlook; - - // UnrealEd: - // rmb: mouselook - // lbm: x:turn y:fwd/back local x - // lmb&rmb: x:strafe y:up/dn (move in local yz plane) - // mmb: fwd/back in viewing vector - - if (unrealedlook && !mskip) //PK - { - if ((bstatus&(1|2|4))==1) - { - ang += mousx; - xvect = -((mousy*(int32_t)sintable[(ang+2560)&2047])<<(3+pk_uedaccel)); - yvect = -((mousy*(int32_t)sintable[(ang+2048)&2047])<<(3+pk_uedaccel)); - - move_and_update(xvect, yvect, 0); - } - else if (!mlook && (bstatus&(1|2|4))==2) - { - mlook=2; - } - else if ((bstatus&(1|2|4))==(1|2)) - { - zmode = 2; - xvect = -((mousx*(int32_t)sintable[(ang+2048)&2047])<>6)* - ((int32_t)sintable[(tempint+512)&2047])>>6) - <>6)* - ((int32_t)sintable[(tempint+512)&2047])>>6) - <>(10-pk_uedaccel)); - - move_and_update(xvect, yvect, 2); - } - } - - if (mskip) - { - // mskip was set in astub.c to not trigger UEd mouse movements. - // Reset now. - mskip = 0; - } - else - { - if (mlook && (unrealedlook==0 || (bstatus&(1|4))==0)) - { - ang += mousx; - horiz -= mousy; - - /* - if (mousy && !(mousy/4)) - horiz--; - if (mousx && !(mousx/2)) - ang++; - */ - - inpclamp(&horiz, -99, 299); - - if (mlook == 1) - { - searchx = xdim>>1; - searchy = ydim>>1; - } - osearchx = searchx-mousx; - osearchy = searchy-mousy; - - if (mousx || mousy) - { - silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz); - getmessagetimeoff = totalclock+30; - } - } - else if (unrealedlook==0 || (bstatus&(1|2|4))==0) - { - osearchx = searchx; - osearchy = searchy; - searchx += mousx; - searchy += mousy; - - inpclamp(&searchx, 12, xdim-13); - inpclamp(&searchy, 12, ydim-13); - } - } - -// showmouse(); - - if (keystatus[sc_F9]) // F9 - { - if (mhk) - { - Bmemset(spriteext, 0, sizeof(spriteext_t) * MAXSPRITES); - Bmemset(spritesmooth, 0, sizeof(spritesmooth_t) * (MAXSPRITES+MAXUNIQHUDID)); - engineClearLightsFromMHK(); - mhk = 0; - message("Maphacks disabled"); - } - else - { - mhk = 1; - loadmhk(1); - } - - keystatus[sc_F9] = 0; - } - - mainloop_move(); - - getzrange(&pos,cursectnum, &hiz,&hihit, &loz,&lohit, 128, (m32_clipping==1)?0:CLIPMASK0); -/* -{ - int32_t his = !(hihit&32768), los = !(lohit&32768); - if (m32_numdebuglines<64) - Bsprintf(m32_debugstr[m32_numdebuglines++], "s%d: cf[%s%d, %s%d] z(%d, %d)", cursectnum, - his?"s":"w",hihit&16383, los?"s":"w",lohit&16383, hiz,loz); -} -*/ - oposz = pos.z; - if (zmode == 0) - { - goalz = loz-(kensplayerheight<<8); //playerheight pixels above floor - if (goalz < hiz+(16<<8)) //ceiling&floor too close - goalz = (loz+hiz)>>1; - goalz += mousz; - - if (DOWN_BK(MOVEUP)) //A (stand high) - { - goalz -= (16<<8); - if (DOWN_BK(RUN)) - goalz -= (24<<8); - } - if (DOWN_BK(MOVEDOWN)) //Z (stand low) - { - goalz += (12<<8); - if (DOWN_BK(RUN)) - goalz += (12<<8); - } - - if (goalz != pos.z) - { - if (pos.z < goalz) hvel += 64; - if (pos.z > goalz) hvel = ((goalz-pos.z)>>3); - - pos.z += hvel; - if (pos.z > loz-(4<<8)) pos.z = loz-(4<<8), hvel = 0; - if (pos.z < hiz+(4<<8)) pos.z = hiz+(4<<8), hvel = 0; - } - } - else - { - goalz = pos.z; - if (DOWN_BK(MOVEUP)) //A - { - if (eitherALT) - { - horiz = max(-100,horiz-((DOWN_BK(RUN)+1)*synctics*2)); - } - else - { - if (zmode != 1) - goalz -= (8<<8); - else - { - zlock += (4<<8); - DOWN_BK(MOVEUP) = 0; - } - } - } - if (DOWN_BK(MOVEDOWN)) //Z (stand low) - { - if (eitherALT) - { - horiz = min(300,horiz+((DOWN_BK(RUN)+1)*synctics*2)); - } - else - { - if (zmode != 1) - goalz += (8<<8); - else if (zlock > 0) - { - zlock -= (4<<8); - DOWN_BK(MOVEDOWN) = 0; - } - } - } - - if (m32_clipping) - inpclamp(&goalz, hiz+(4<<8), loz-(4<<8)); - - if (zmode == 1) goalz = loz-zlock; - if (m32_clipping && (goalz < hiz+(4<<8))) - goalz = ((loz+hiz)>>1); //ceiling&floor too close - if (zmode == 1) pos.z = goalz; - - if (goalz != pos.z) - { - //if (pos.z < goalz) hvel += (32< goalz) hvel -= (32< loz-(4<<8)) pos.z = loz-(4<<8), hvel = 0; - if (pos.z < hiz+(4<<8)) pos.z = hiz+(4<<8), hvel = 0; - } - } - else - hvel = 0; - } - - { - int16_t ocursectnum = cursectnum; - updatesectorz(pos.x,pos.y,pos.z, &cursectnum); - if (cursectnum<0) - { - if (zmode != 2) - pos.z = oposz; // don't allow to fall into infinity when in void space - cursectnum = ocursectnum; - } - } - - if (pos.z != oposz && in3dmode()) - { - silentmessage("x:%d y:%d z:%d ang:%d horiz:%d", pos.x, pos.y, pos.z, ang, horiz); - getmessagetimeoff = totalclock+30; - } - - searchit = 2; - if (searchstat >= 0) - { - if ((bstatus&(1|2|4)) || keystatus[sc_Space]) // SPACE - searchit = 0; - - if (keystatus[sc_S]) //S (insert sprite) (3D) - { - hitdata_t hit; - - vec2_t da = { 16384, divscale14(searchx-(xdim>>1), xdim>>1) }; - - rotatepoint(zerovec, da, ang, &da); - -#ifdef USE_OPENGL - if (videoGetRenderMode() == REND_POLYMOST) - hit = polymost_hitdata; - else -#endif - hitscan((const vec3_t *)&pos,cursectnum, //Start position - da.x,da.y,(scale(searchy,200,ydim)-horiz)*2000, //vector of 3D ang - &hit,CLIPMASK1); - - if (hit.sect >= 0) - { - da.x = hit.pos.x; - da.y = hit.pos.y; - if (gridlock && grid > 0) - { - if (AIMING_AT_WALL || AIMING_AT_MASKWALL) - hit.pos.z &= 0xfffffc00; - else - locktogrid(&da.x, &da.y); - } - - i = insert_sprite_common(hit.sect, da.x, da.y); - - if (i < 0) - message("Couldn't insert sprite."); - else - { - int32_t cz, fz; - - handle_sprite_in_clipboard(i); - - spriteoncfz(i, &cz, &fz); - sprite[i].z = clamp2(hit.pos.z, cz, fz); - - if (AIMING_AT_WALL || AIMING_AT_MASKWALL) - { - sprite[i].cstat &= ~48; - sprite[i].cstat |= (16+64); - - correct_ornamented_sprite(i, hit.wall); - } - else - sprite[i].cstat |= (tilesiz[sprite[i].picnum].y>=32); - - correct_sprite_yoffset(i); - - asksave = 1; - - VM_OnEvent(EVENT_INSERTSPRITE3D, i); - } - } - - keystatus[sc_S] = 0; - } - - if (keystatus[sc_F5]||keystatus[sc_F6]) //F5,F6 - { - switch (searchstat) - { - case SEARCH_CEILING: - case SEARCH_FLOOR: - CallExtShowSectorData(searchsector); break; - case SEARCH_WALL: - case SEARCH_MASKWALL: - CallExtShowWallData(searchwall); break; - case SEARCH_SPRITE: - CallExtShowSpriteData(searchwall); break; - } - - keystatus[sc_F5] = keystatus[sc_F6] = 0; - } - if (keystatus[sc_F7]||keystatus[sc_F8]) //F7,F8 - { - switch (searchstat) - { - case SEARCH_CEILING: - case SEARCH_FLOOR: - CallExtEditSectorData(searchsector); break; - case SEARCH_WALL: - case SEARCH_MASKWALL: - CallExtEditWallData(searchwall); break; - case SEARCH_SPRITE: - CallExtEditSpriteData(searchwall); break; - } - - keystatus[sc_F7] = keystatus[sc_F8] = 0; - } - - } - - if (keystatus[buildkeys[BK_MODE2D_3D]] && !m32_is2d3dmode()) // Enter - { - - vid_gamma_3d = g_videoGamma; - vid_contrast_3d = g_videoContrast; - vid_brightness_3d = g_videoBrightness; - - g_videoGamma = g_videoContrast = 1.0; - g_videoBrightness = 0.0; - - videoSetPalette(0,0,0); - - keystatus[buildkeys[BK_MODE2D_3D]] = 0; - overheadeditor(); - keystatus[buildkeys[BK_MODE2D_3D]] = 0; - - g_videoGamma = vid_gamma_3d; - g_videoContrast = vid_contrast_3d; - g_videoBrightness = vid_brightness_3d; - - vid_gamma_3d = vid_contrast_3d = vid_brightness_3d = -1; - - videoSetPalette(GAMMA_CALC,0,0); - } -} - -char changechar(char dachar, int32_t dadir, char smooshyalign, char boundcheck) -{ - if (dadir < 0) - { - if ((dachar > 0) || (boundcheck == 0)) - { - dachar--; - if (smooshyalign > 0) - dachar = (dachar&0xf8); - } - } - else if (dadir > 0) - { - if ((dachar < 255) || (boundcheck == 0)) - { - dachar++; - if (smooshyalign > 0) - { - if (dachar >= 256-8) dachar = 255; - else dachar = ((dachar+7)&0xf8); - } - } - } - return dachar; -} - - -////////////////////// OVERHEADEDITOR ////////////////////// - -// some 2d mode state -static struct overheadstate -{ - // number of backed up drawn walls - int32_t bak_wallsdrawn; - - // state related to line drawing - int16_t suckwall, split; - int16_t splitsect; - int16_t splitstartwall; -} ovh; - - -static int32_t inside_editor(const vec3_t *pos, int32_t searchx, int32_t searchy, int32_t zoom, - int32_t x, int32_t y, int16_t sectnum) -{ - if (!m32_sideview) - return inside(x, y, sectnum); - - // if in side-view mode, use the screen coords instead - { - int32_t dst = MAXSECTORS+M32_FIXME_SECTORS-1, i, oi; - int32_t srcw=sector[sectnum].wallptr, dstw=MAXWALLS; - int32_t ret; - - if (sector[sectnum].wallnum > M32_FIXME_WALLS) - return -1; - - Bmemcpy(§or[dst], §or[sectnum], sizeof(sectortype)); - sector[dst].wallptr = dstw; - - Bmemcpy(&wall[dstw], &wall[srcw], sector[dst].wallnum*sizeof(walltype)); - for (i=dstw, oi=srcw; ix, wall[i].y-pos->y, zoom); - wall[i].y += getscreenvdisp(getflorzofslope(sectnum,wall[oi].x,wall[oi].y)-pos->z, zoom); - wall[i].x += halfxdim16; - wall[i].y += midydim16; - } - - i = numsectors; - numsectors = dst+1; - ret = inside(searchx, searchy, dst); - numsectors = i; - return ret; - } -} - -int32_t inside_editor_curpos(int16_t sectnum) -{ - // TODO: take care: mous[xy]plc global vs overheadeditor auto - return inside_editor(&pos, searchx,searchy, zoom, mousxplc,mousyplc, sectnum); -} - - -static inline void drawline16base(int32_t bx, int32_t by, int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col) -{ - editorDraw2dLine(bx+x1, by+y1, bx+x2, by+y2, col); -} - -void drawsmallabel(const char *text, char col, char backcol, char border, int32_t dax, int32_t day, int32_t daz) -{ - editorGet2dScreenCoordinates(&dax,&day, dax-pos.x,day-pos.y, zoom); - - if (m32_sideview) - day += getscreenvdisp(daz-pos.z, zoom); - - int32_t const x1 = halfxdim16+dax-(Bstrlen(text)<<1); - int32_t const y1 = midydim16+day-4; - int32_t const x2 = x1 + (Bstrlen(text)<<2)+2; - int32_t const y2 = y1 + 7; - - int f = mulscale8(x2-x1, zoom); - - if ((x1 <= -f) || (x2 >= xdim + f) || (y1 <= -f) || (y2 >= ydim16 + f)) - return; - - printext16(x1,y1, col,backcol, text,1); - - editorDraw2dLine(x1-2, y1-2, x2-2, y1-2, border); - editorDraw2dLine(x1-2, y2+1, x2-2, y2+1, border); - - editorDraw2dLine(x1-3, y1-1, x1-3, y2+0, border); - editorDraw2dLine(x2-1, y1-1, x2-1, y2+0, border); - - editorDraw2dLine(x1-1,y1-1, x2-3,y1-1, backcol); - editorDraw2dLine(x1-1,y2+0, x2-3,y2+0, backcol); - - editorDraw2dLine(x1-2,y1+0, x1-2,y2-1, backcol); - editorDraw2dLine(x2-2,y1+0, x2-2,y2-1, backcol); - editorDraw2dLine(x2-3,y1+0, x2-3,y2+0, backcol); - - videoBeginDrawing(); //{{{ - - if ((unsigned)y1-1 < ydim16+0u && (unsigned) (x1-2) < xdim2d+0u && (unsigned) (x2-2) < xdim2d+0u) - { - drawpixel((char *) (frameplace + ((y1-1) * bytesperline) + (x1-2)), border); - drawpixel((char *) (frameplace + ((y1-1) * bytesperline) + (x2-2)), border); - } - - if ((unsigned) y2 < ydim16+0u && (unsigned) (x1-2) < xdim2d+0u && (unsigned) (x2-2) < xdim2d+0u) - { - drawpixel((char *) (frameplace + ((y2) * bytesperline) + (x1-2)), border); - drawpixel((char *) (frameplace + ((y2) * bytesperline) + (x2-2)), border); - } - - videoEndDrawing(); -} - -// backup highlighted sectors with sprites as mapinfo for later restoration -// return values: -// -1: highlightsectorcnt<=0 -// 0: ok -static int32_t backup_highlighted_map(mapinfofull_t *mapinfo) -{ - int32_t i, j, k, m, tmpnumwalls=0, tmpnumsprites=0; - int16_t *const otonsect = (int16_t *)tempxyar; // STRICTALIASING - int16_t *const otonwall = ((int16_t *)tempxyar) + MAXWALLS; -#ifdef YAX_ENABLE - int16_t otonbunch[YAX_MAXBUNCHES]; - int16_t numsectsofbunch[YAX_MAXBUNCHES]; // ceilings + floors -#endif - - if (highlightsectorcnt <= 0) - return -1; - -#ifdef YAX_ENABLE - for (i=0; inew mappings - j = 0; - k = 0; - for (i=0; i>3]&(1<<(i&7))) - { -#ifdef YAX_ENABLE - int16_t bn[2], cf; - - yax_getbunches(i, &bn[0], &bn[1]); - for (cf=0; cf<2; cf++) - if (bn[cf] >= 0) - numsectsofbunch[bn[cf]]++; -#endif - otonsect[i] = j++; - - for (WALLS_OF_SECTOR(i, m)) - otonwall[m] = k++; - } - else - { - otonsect[i] = -1; - - for (WALLS_OF_SECTOR(i, m)) - otonwall[m] = -1; - } - } - -#ifdef YAX_ENABLE - j = 0; - for (i=0; inumyaxbunches = j; -#endif - - // count walls & sprites - for (i=0; isector = (usectortype *)Xmalloc(highlightsectorcnt * sizeof(sectortype)); - mapinfo->wall = (uwalltype *)Xmalloc(tmpnumwalls * sizeof(walltype)); - -#ifdef YAX_ENABLE - if (mapinfo->numyaxbunches > 0) - { - mapinfo->bunchnum = (int16_t *)Xmalloc(highlightsectorcnt*2*sizeof(int16_t)); - mapinfo->ynextwall = (int16_t *)Xmalloc(tmpnumwalls*2*sizeof(int16_t)); - } - else - { - mapinfo->bunchnum = mapinfo->ynextwall = NULL; - } -#endif - - if (tmpnumsprites>0) - { - mapinfo->sprite = (uspritetype *)Xmalloc(tmpnumsprites * sizeof(spritetype)); - } - else - { - // would never be accessed because mapinfo->numsprites is 0, but cleaner - mapinfo->sprite = NULL; - } - - - // copy everything over - tmpnumwalls = 0; - tmpnumsprites = 0; - for (i=0; isector[i], §or[k], sizeof(sectortype)); - mapinfo->sector[i].wallptr = tmpnumwalls; - -#ifdef YAX_ENABLE - if (mapinfo->numyaxbunches > 0 || numyaxbunches > 0) - { - int16_t bn[2]; - - yax_getbunches(k, &bn[0], &bn[1]); - for (j=0; j<2; j++) - { - // old bunchnum, new bunchnum - int32_t obn=bn[j], nbn=(obn>=0) ? otonbunch[obn] : -1; - - if (mapinfo->numyaxbunches > 0) - mapinfo->bunchnum[2*i + j] = nbn; - - if (obn >= 0 && nbn < 0) - { - // A bunch was discarded. - usectortype *const sec = &mapinfo->sector[i]; -# if !defined NEW_MAP_FORMAT - uint16_t *const cs = j==YAX_CEILING ? &sec->ceilingstat : &sec->floorstat; - uint8_t *const xp = j==YAX_CEILING ? &sec->ceilingxpanning : &sec->floorxpanning; - - *cs &= ~YAX_BIT; - *xp = 0; -# else - if (j == YAX_CEILING) - sec->ceilingbunch = -1; - else - sec->floorbunch = -1; -# endif - } - } - } -#endif - - for (j=0; jwall[tmpnumwalls+j], &wall[m+j], sizeof(walltype)); - mapinfo->wall[tmpnumwalls+j].point2 += (tmpnumwalls-m); - -#ifdef YAX_ENABLE - if (mapinfo->numyaxbunches > 0 || numyaxbunches > 0) - { - int32_t cf; - - for (cf=0; cf<2; cf++) - { - const int32_t ynw = yax_getnextwall(m+j, cf); - const int32_t nynw = (ynw >= 0) ? otonwall[ynw] : -1; - - if (mapinfo->numyaxbunches > 0) - mapinfo->ynextwall[2*(tmpnumwalls+j) + cf] = nynw; - - if (ynw >= 0 && nynw < 0) // CLEAR_YNEXTWALLS - YAX_PTRNEXTWALL(mapinfo->wall, tmpnumwalls+j, cf) = YAX_NEXTWALLDEFAULT(cf); - } - } -#endif - m = mapinfo->wall[tmpnumwalls+j].nextsector; - if (m < 0 || otonsect[m] < 0) - { - mapinfo->wall[tmpnumwalls+j].nextsector = -1; - mapinfo->wall[tmpnumwalls+j].nextwall = -1; - } - else - { - mapinfo->wall[tmpnumwalls+j].nextsector = otonsect[m]; - m = mapinfo->wall[tmpnumwalls+j].nextwall; - mapinfo->wall[tmpnumwalls+j].nextwall = otonwall[m]; - } - } - tmpnumwalls += j; - - m = headspritesect[highlightsector[i]]; - while (m != -1) - { - Bmemcpy(&mapinfo->sprite[tmpnumsprites], &sprite[m], sizeof(spritetype)); - mapinfo->sprite[tmpnumsprites].sectnum = otonsect[highlightsector[i]]; - m = nextspritesect[m]; - tmpnumsprites++; - } - } - - - mapinfo->numsectors = highlightsectorcnt; - mapinfo->numwalls = tmpnumwalls; - mapinfo->numsprites = tmpnumsprites; - - return 0; -} - -static void mapinfofull_free(mapinfofull_t *mapinfo) -{ - Bfree(mapinfo->sector); -#ifdef YAX_ENABLE - if (mapinfo->numyaxbunches > 0) - { - Bfree(mapinfo->bunchnum); - Bfree(mapinfo->ynextwall); - } -#endif - Bfree(mapinfo->wall); - if (mapinfo->numsprites>0) - Bfree(mapinfo->sprite); -} - -// restore map saved with backup_highlighted_map, also -// frees mapinfo's sector, wall, (sprite) in any case. -// return values: -// -1: limits exceeded -// 0: ok -// forreal: if 0, only test if we have enough space (same return values) -static int32_t restore_highlighted_map(mapinfofull_t *mapinfo, int32_t forreal) -{ - int32_t i, j, onumsectors=numsectors, newnumsectors, newnumwalls; - - if (numsectors+mapinfo->numsectors>MAXSECTORS || numwalls+mapinfo->numwalls>MAXWALLS -#ifdef YAX_ENABLE - || numyaxbunches+mapinfo->numyaxbunches > YAX_MAXBUNCHES -#endif - || Numsprites+mapinfo->numsprites>MAXSPRITES) - { - mapinfofull_free(mapinfo); - return -1; - } - - if (!forreal) - return 0; - - newnumsectors = numsectors + mapinfo->numsectors; - newnumwalls = numwalls + mapinfo->numwalls; - - // copy sectors & walls - Bmemcpy(§or[numsectors], mapinfo->sector, mapinfo->numsectors*sizeof(sectortype)); - Bmemcpy(&wall[numwalls], mapinfo->wall, mapinfo->numwalls*sizeof(walltype)); - - // tweak index members - for (i=numwalls; i= 0) - { - wall[i].nextsector += numsectors; - wall[i].nextwall += numwalls; - } -#ifdef YAX_ENABLE - for (j=0; j<2; j++) - { - if (mapinfo->numyaxbunches > 0) - { - yax_setnextwall(i, j, mapinfo->ynextwall[2*(i-numwalls) + j]>=0 ? - numwalls+mapinfo->ynextwall[2*(i-numwalls) + j] : -1); - } - else - { -# if !defined NEW_MAP_FORMAT - // XXX: When copying a TROR portion into a non-TROR map (e.g. a - // new one), tags denoting ynextwalls are left in place. - wall[i].cstat &= ~YAX_NEXTWALLBIT(j); // CLEAR_YNEXTWALLS -# else - yax_setnextwall(i, j, -1); -# endif - } - } -#endif - } - for (i=numsectors; i>3] |= (1<<(i&7)); - -#ifdef YAX_ENABLE - for (j=0; j<2; j++) - { - if (mapinfo->numyaxbunches > 0) - { - int32_t bn = mapinfo->bunchnum[2*(i-onumsectors)+j]; - yax_setbunch(i, j, bn>=0 ? numyaxbunches+bn : -2); - // -2 clears forward yax-nextwall links. - // XXX: still may wrongly reset xpanning. - } - else - Bassert(yax_getbunch(i, j) < 0); - } -#endif - } - - // insert sprites - for (i=0; inumsprites; i++) - { - const uspritetype *srcspr = &mapinfo->sprite[i]; - int32_t sect = onumsectors + srcspr->sectnum; - - j = insertsprite(sect, srcspr->statnum); - Bassert(j >= 0); - Bmemcpy(&sprite[j], srcspr, sizeof(spritetype)); - sprite[j].sectnum = sect; - } - - mapinfofull_free(mapinfo); - - numwalls = newnumwalls; - - update_highlightsector(); - -#ifdef YAX_ENABLE - if (mapinfo->numyaxbunches > 0) - yax_update(0); -#endif - yax_updategrays(pos.z); - - return 0; -} - - -static int16_t newnumwalls=-1; - -void ovh_whiteoutgrab(int32_t restoreredwalls) -{ - int32_t i, j, k, startwall, endwall; -#if 0 -//def YAX_ENABLE - int16_t cb, fb; -#endif - - if (restoreredwalls) - { - // restore onextwalls first - for (i=0; i=0; i--) - for (WALLS_OF_SECTOR(highlightsector[i], j)) - { - if (wall[j].nextwall < 0) - continue; - - k = wall[j].nextsector; - - if (hlsectorbitmap[k>>3]&(1<<(k&7))) - continue; -#if 0 -//def YAX_ENABLE - // internal red walls are kept red - yax_getbunches(highlightsector[i], &cb, &fb); - if (cb>=0 && yax_getbunch(k, YAX_CEILING)>=0) - continue; - if (fb>=0 && yax_getbunch(k, YAX_FLOOR)>=0) - continue; -#endif - onextwall[j] = wall[j].nextwall; - - NEXTWALL(j).nextwall = -1; - NEXTWALL(j).nextsector = -1; - wall[j].nextwall = -1; - wall[j].nextsector = -1; - } - - if (highlightsectorcnt > 0) - mkonwvalid(); - else - mkonwinvalid_keeptempsect(); -} - -static void duplicate_selected_sectors(void) -{ - mapinfofull_t mapinfo; - int32_t i, j, onumsectors; -#ifdef YAX_ENABLE - int32_t onumyaxbunches; -#endif - int32_t minx=INT32_MAX, maxx=INT32_MIN, miny=INT32_MAX, maxy=INT32_MIN, dx, dy; - - i = backup_highlighted_map(&mapinfo); - - if (i < 0) - { - message("Out of memory!"); - return; - } - - i = restore_highlighted_map(&mapinfo, 0); - if (i < 0) - { - // XXX: no, might be another limit too. Better message needed. - printmessage16("Copying sectors would exceed sector or wall limit."); - return; - } - - // restoring would succeed, tweak things... - Bmemset(hlsectorbitmap, 0, sizeof(hlsectorbitmap)); - for (i=0; i= 0) - checksectorpointer(wall[j].nextwall,wall[j].nextsector); - checksectorpointer(j, highlightsector[i]); - - minx = min(minx, TrackerCast(wall[j].x)); - maxx = max(maxx, TrackerCast(wall[j].x)); - miny = min(miny, TrackerCast(wall[j].y)); - maxy = max(maxy, TrackerCast(wall[j].y)); - } - } - - // displace walls & sprites of new sectors by a small amount: - // calculate displacement - if (grid>0 && grid<9) - dx = max(2048>>grid, 128); - else - dx = 512; - dy = -dx; - if (maxx+dx >= editorgridextent) dx*=-1; - if (minx+dx <= -editorgridextent) dx*=-1; - if (maxy+dy >= editorgridextent) dy*=-1; - if (miny+dy <= -editorgridextent) dy*=-1; - - onumsectors = numsectors; -#ifdef YAX_ENABLE - onumyaxbunches = numyaxbunches; -#endif - // restore! this will not fail. - restore_highlighted_map(&mapinfo, 1); - - // displace - for (i=onumsectors; i=0; j=nextspritesect[j]) - { - sprite[j].x += dx; - sprite[j].y += dy; - } - } - -#ifdef YAX_ENABLE - if (numyaxbunches > onumyaxbunches) - printmessage16("Sectors duplicated, creating %d new bunches.", numyaxbunches-onumyaxbunches); - else -#endif - printmessage16("Sectors duplicated."); - asksave = 1; - -#ifdef YAX_ENABLE - if (numyaxbunches > onumyaxbunches) - yax_update(0); -#endif - yax_updategrays(pos.z); -} - - -static void duplicate_selected_sprites(void) -{ - int32_t i, j, k=0; - - for (i=0; i= 0) - { - sprite[i].ang = (getangle(POINT2(hitw).x-wall[hitw].x, - POINT2(hitw).y-wall[hitw].y)+512)&2047; - - //Make sure sprite's in right sector - if (inside(sprite[i].x, sprite[i].y, sprite[i].sectnum) != 1) - { - j = wall[hitw].point2; - sprite[i].x -= ksgn(wall[j].y-wall[hitw].y); - sprite[i].y += ksgn(wall[j].x-wall[hitw].x); - } - } -} - -void DoSpriteOrnament(int32_t i) -{ - hitdata_t hit; - - hitscan((const vec3_t *)&sprite[i],sprite[i].sectnum, - sintable[(sprite[i].ang+1536)&2047], - sintable[(sprite[i].ang+1024)&2047], - 0, - &hit,CLIPMASK1); - - if (hit.sect == -1) - return; - - sprite[i].x = hit.pos.x; - sprite[i].y = hit.pos.y; - sprite[i].z = hit.pos.z; - changespritesect(i, hit.sect); - - correct_ornamented_sprite(i, hit.wall); -} - -void update_highlight(void) -{ - int32_t i; - - highlightcnt = 0; - for (i=0; i>3]&(1<<(i&7))) - highlight[highlightcnt++] = i; - for (i=0; i>3]&(1<<(i&7))) - highlight[highlightcnt++] = i+16384; - } - else - show2dsprite[i>>3] &= ~(1<<(i&7)); - - if (highlightcnt == 0) - highlightcnt = -1; -} - -void update_highlightsector(void) -{ - int32_t i; - - minhlsectorfloorz = INT32_MAX; - numhlsecwalls = 0; - - highlightsectorcnt = 0; - for (i=0; i>3]&(1<<(i&7))) - { - highlightsector[highlightsectorcnt++] = i; - minhlsectorfloorz = min(minhlsectorfloorz, TrackerCast(sector[i].floorz)); - numhlsecwalls += sector[i].wallnum; - } - - if (highlightsectorcnt==0) - { - minhlsectorfloorz = 0; - highlightsectorcnt = -1; - } -} - -// Get average point of sectors -static void get_sectors_center(const int16_t *sectors, int32_t numsecs, int32_t *cx, int32_t *cy) -{ - int32_t i, j, k=0, dax = 0, day = 0; - int32_t startwall, endwall; - - for (i=0; i 0) - { - dax /= k; - day /= k; - } - - *cx = dax; - *cy = day; -} - -static int32_t insert_sprite_common(int32_t sectnum, int32_t dax, int32_t day) -{ - int32_t i, j, k; - - i = insertsprite(sectnum,0); - if (i < 0) - return -1; - - sprite[i].x = dax, sprite[i].y = day; - sprite[i].cstat = DEFAULT_SPRITE_CSTAT; - sprite[i].shade = 0; - sprite[i].pal = 0; - sprite[i].xrepeat = 64, sprite[i].yrepeat = 64; - sprite[i].xoffset = 0, sprite[i].yoffset = 0; - sprite[i].ang = 1536; - sprite[i].xvel = 0; sprite[i].yvel = 0; sprite[i].zvel = 0; - sprite[i].owner = -1; - sprite[i].clipdist = 32; - sprite[i].lotag = 0; - sprite[i].hitag = 0; - sprite[i].extra = -1; - - Bmemset(localartfreq, 0, sizeof(localartfreq)); - for (k=0; k localartfreq[j]) - j = k; - - if (localartfreq[j] > 0) - sprite[i].picnum = j; - else - sprite[i].picnum = 0; - - return i; -} - -void correct_sprite_yoffset(int32_t i) -{ - int32_t tileyofs = picanm[sprite[i].picnum].yofs; - int32_t tileysiz = tilesiz[sprite[i].picnum].y; - - if (klabs(tileyofs) >= tileysiz) - { - tileyofs *= -1; - if (tileyofs == 128) - tileyofs = 127; - - sprite[i].yoffset = tileyofs; - } - else - sprite[i].yoffset = 0; -} - -// keepcol >= 0 && <256: keep that idx-color -// keepcol < 0: keep none -// keepcol >= 256: 0x00ffffff is mask for 3 colors -void fade_editor_screen(int32_t keepcol) -{ - char blackcol=0, greycol=whitecol-25, *cp; - int32_t pix, i, threecols = (keepcol >= 256); - char cols[3] = {(char)(keepcol&0xff), (char)((keepcol>>8)&0xff), (char)((keepcol>>16)&0xff)}; - - videoBeginDrawing(); - cp = (char *)frameplace; - for (i=0; i= 0 ? (uwalltype *)&wall[src] : &nullwall; - - memset(&nullwall, 0, sizeof(nullwall)); - nullwall.yrepeat = 8; - nullwall.extra = -1; - - if (reset_some) - { - dstwal->cstat = srcwal->cstat; - } - else - { - dstwal->cstat &= ~(4+8+256); - dstwal->cstat |= (srcwal->cstat&(4+8+256)); - } - dstwal->shade = srcwal->shade; - dstwal->yrepeat = srcwal->yrepeat; - fixrepeats(dst); // xrepeat - dstwal->picnum = srcwal->picnum; - dstwal->overpicnum = srcwal->overpicnum; - - dstwal->pal = srcwal->pal; - dstwal->xpanning = srcwal->xpanning; - dstwal->ypanning = srcwal->ypanning; - - if (reset_some) - { - dstwal->nextwall = -1; - dstwal->nextsector = -1; - - dstwal->lotag = 0; //srcwal->lotag; - dstwal->hitag = 0; //srcwal->hitag; - dstwal->extra = -1; //srcwal->extra; -#ifdef YAX_ENABLE - yax_setnextwall(dst, YAX_CEILING, -1); - yax_setnextwall(dst, YAX_FLOOR, -1); -#endif - } -} - -static void init_new_wall1(int16_t *suckwall_ret, int32_t mousxplc, int32_t mousyplc) -{ - int32_t i; - - Bmemset(&wall[newnumwalls], 0, sizeof(walltype)); - wall[newnumwalls].extra = -1; - - wall[newnumwalls].x = mousxplc; - wall[newnumwalls].y = mousyplc; - wall[newnumwalls].nextsector = -1; - wall[newnumwalls].nextwall = -1; - - for (i=0; i= 0) - YAX_SKIPWALL(wall[i].nextwall); - - if (wall[i].x == mousxplc && wall[i].y == mousyplc) - *suckwall_ret = i; - } - - wall[newnumwalls].point2 = newnumwalls+1; - newnumwalls++; -} - -// helpers for often needed ops: -static int32_t do_while_copyloop1(int16_t startwall, int16_t endwall, - int16_t *danumwalls, int16_t lastpoint2) -{ - int32_t m = startwall; - - do - { - if (*danumwalls >= MAXWALLS + M32_FIXME_WALLS) - return 1; - - Bmemcpy(&wall[*danumwalls], &wall[m], sizeof(walltype)); - wall[*danumwalls].point2 = *danumwalls+1; - (*danumwalls)++; - m = wall[m].point2; - } - while (m != endwall); - - if (lastpoint2 >= 0) - wall[(*danumwalls)-1].point2 = lastpoint2; - - return 0; -} - -static void updatesprite1(int16_t i) -{ - setsprite(i, (vec3_t *)&sprite[i]); - - if (sprite[i].sectnum>=0) - { - int32_t cz, fz; - spriteoncfz(i, &cz, &fz); - inpclamp(&sprite[i].z, cz, fz); - } -} - -#ifdef YAX_ENABLE -// highlighted OR grayed-out sectors: -static uint8_t hlorgraysectbitmap[MAXSECTORS>>3]; -static int32_t ask_above_or_below(void); -#else -# define hlorgraysectbitmap hlsectorbitmap -#endif - -// returns: -// 0: continue -// >0: newnumwalls -// <0: error -// ignore_ret and refsect_ret are for the 'auto-red-wall' feature -static int32_t trace_loop(int32_t j, uint8_t *visitedwall, int16_t *ignore_ret, int16_t *refsect_ret, - int16_t trace_loop_yaxcf) -{ - int16_t refsect, ignore; - int32_t k, n, refwall; -#if 0 -//def YAX_ENABLE - int32_t yaxp = (ignore_ret==NULL); // bleh -#else - UNREFERENCED_PARAMETER(trace_loop_yaxcf); -#endif - - if (wall[j].nextwall>=0 || (visitedwall[j>>3]&(1<<(j&7)))) - return 0; - - n=2*MAXWALLS; // simple inf loop check - refwall = j; - k = numwalls; - - ignore = 0; - - if (ignore_ret) - { - refsect = -1; - updatesectorexclude(wall[j].x, wall[j].y, &refsect, hlorgraysectbitmap); - if (refsect<0) - return -1; - } - - do - { - if (j!=refwall && visitedwall[j>>3]&(1<<(j&7))) - ignore = 1; - visitedwall[j>>3] |= (1<<(j&7)); - - if (ignore_ret) - { - if (inside(wall[j].x, wall[j].y, refsect) != 1) - ignore = 1; - } - - if (!ignore) - { - if (k>=MAXWALLS) - { - message("Wall limits exceeded while tracing outer loop."); - return -2; - } - - if (ignore_ret) // auto-red wall feature - onextwall[k] = onextwall[j]; - - Bmemcpy(&wall[k], &wall[j], sizeof(walltype)); - wall[k].point2 = k+1; -// TODO: protect lotag/extra; see also hl-sector copying stuff - wall[k].nextsector = wall[k].nextwall = wall[k].extra = -1; -#ifdef YAX_ENABLE - if (trace_loop_yaxcf >= 0) - yax_setnextwall(k, trace_loop_yaxcf, j); -#endif - k++; - } - - j = wall[j].point2; - n--; - - while (wall[j].nextwall>=0 && n>0) - { -#if 0 -//def YAX_ENABLE - if (yaxp) - { - int32_t ns = wall[j].nextsector; - if ((hlsectorbitmap[ns>>3]&(1<<(ns&7)))==0) - break; - } -#endif - j = wall[wall[j].nextwall].point2; -// if (j!=refwall && (visitedwall[j>>3]&(1<<(j&7)))) -// ignore = 1; -// visitedwall[j>>3] |= (1<<(j&7)); - n--; - } - } - while (j!=refwall && n>0); - - if (j!=refwall) - { - message("internal error while tracing outer loop: didn't reach refwall"); - return -3; - } - - if (ignore_ret) - { - *ignore_ret = ignore; - if (refsect_ret) - *refsect_ret = refsect; - } - - return k; -} - -// Backup drawn walls for carrying out other operations in the middle. -// 0: back up, set newnumwalls to -1 -// 1: restore drawn walls and free mem -// 2: only free memory needed for backing up walls but don't restore walls -// (use this if the map has been mangled too much for a safe restoration) -// Context that needs special treatment: suckwall, splitsect, splitstartwall -static int32_t backup_drawn_walls(int32_t restore) -{ - static uwalltype *tmpwall; - - // back up - if (restore==0) - { - // ovh.bak_wallsdrawn should be 0 here - - if (newnumwalls != -1) - { - if (newnumwalls <= numwalls) // shouldn't happen - return 2; - - Bfree(tmpwall); - tmpwall = (uwalltype *)Xmalloc((newnumwalls-numwalls) * sizeof(walltype)); - - ovh.bak_wallsdrawn = newnumwalls-numwalls; - - Bmemcpy(tmpwall, &wall[numwalls], ovh.bak_wallsdrawn*sizeof(walltype)); - newnumwalls = -1; - } - - return 0; - } - - // restore/clear - if (tmpwall) - { - if (restore==1) // really restore - { - const int32_t nnumwalls = numwalls + ovh.bak_wallsdrawn; - - if (nnumwalls < MAXWALLS) // else, silently discard drawn walls - { - int32_t i; - - Bmemcpy(&wall[numwalls], tmpwall, ovh.bak_wallsdrawn*sizeof(walltype)); - - newnumwalls = nnumwalls; - for (i=numwalls; i>3]; - -static void collect_sectors1(int16_t *sectlist, uint8_t *sectbitmap, int32_t *numsectptr, - int16_t startsec, int32_t alsoyaxnext, int32_t alsoonw) -{ - int32_t j, startwall, endwall, sectcnt; - - bfirst_search_init(sectlist, sectbitmap, numsectptr, MAXSECTORS, startsec); - - for (sectcnt=0; sectcnt<*numsectptr; sectcnt++) - { - for (WALLS_OF_SECTOR(sectlist[sectcnt], j)) - { - if (wall[j].nextsector >= 0) - bfirst_search_try(sectlist, sectbitmap, numsectptr, wall[j].nextsector); - else if (alsoonw && onextwall[j]>=0) - bfirst_search_try(sectlist, sectbitmap, numsectptr, sectorofwall(onextwall[j])); - } - - if (alsoyaxnext) - { - int16_t bn[2], cf; - yax_getbunches(sectlist[sectcnt], &bn[0], &bn[1]); - for (cf=0; cf<2; cf++) - if (bn[cf]>=0) - { - for (SECTORS_OF_BUNCH(bn[cf], !cf, j)) - bfirst_search_try(sectlist, sectbitmap, numsectptr, j); - } - } - } -} - - -static int32_t sectors_components(int16_t hlsectcnt, const int16_t *hlsectors, int32_t alsoyaxnext, int32_t alsoonw); -static int32_t highlighted_sectors_components(int32_t alsoyaxnext, int32_t alsoonw) -{ - return sectors_components(highlightsectorcnt, highlightsector, alsoyaxnext, alsoonw); -} - -// whether all highlighted sectors are in one (returns 1), two (2) -// or more (>2) connected components wrt the nextsector relation -// -1 means error -// alsoyaxnext: also consider "yax-nextsector" relation -// alsoonw: also consider "old-nextwall" relation (must be valid) -static int32_t sectors_components(int16_t hlsectcnt, const int16_t *hlsector, int32_t alsoyaxnext, int32_t alsoonw) -{ - int32_t j, k, tmp; - - if (hlsectcnt<1) - return 0; - - collect_sectors1(collsectlist[0], collsectbitmap[0], &collnumsects[0], - hlsector[0], alsoyaxnext, alsoonw); - - for (k=1; k>3]&(1<<(j&7)))==0) - { - // sector j not collected --> more than 1 conn. comp. - collect_sectors1(collsectlist[1], collsectbitmap[1], &collnumsects[1], - j, alsoyaxnext, alsoonw); - break; - } - } - - if (k == hlsectcnt) - return 1; - - for (k=0; k>3]&(1<<(j&7)))!=0) + (((collsectbitmap[1][j>>3]&(1<<(j&7)))!=0)<<1)); - - if (tmp==3) - return -1; // components only weakly connected - - if (tmp==0) - return 3; // sector j not reached - } - - return 2; -} - -static int cmpgeomwal1(const void *w1, const void *w2) -{ - uwalltype const * const wal1 = (uwalltype *)&wall[B_UNBUF16(w1)]; - uwalltype const * const wal2 = (uwalltype *)&wall[B_UNBUF16(w2)]; - - if (wal1->x == wal2->x) - return wal1->y - wal2->y; - - return wal1->x - wal2->x; -} - -static void sort_walls_geometrically(int16_t *wallist, int32_t nwalls) -{ - qsort(wallist, nwalls, sizeof(int16_t), &cmpgeomwal1); -} -#endif - -void SetFirstWall(int32_t sectnum, int32_t wallnum, int32_t alsoynw) -{ -#ifdef YAX_ENABLE - int32_t i, j, k=0; -#endif - const sectortype *sec = §or[sectnum]; - - if (sec->wallptr == wallnum) - { - message("Wall %d already first wall of sector %d", wallnum, sectnum); - return; - } - -#ifdef YAX_ENABLE - if (alsoynw) - { - // Also consider upper/lower TROR neighbor walls. - int32_t startwall, endwall; - int16_t cf; - - for (i=0; i= 0 && - (tempsect=yax_is121(bunchnum, cf)) >= 0) - { - tempwall = yax_getnextwall(tempwall, cf); - if (tempwall < 0) - break; // corrupt! - wall[tempwall].cstat |= (1<<14); - } - } - - for (i=0; i. - int16_t cb = yax_getbunch(sectnum, YAX_CEILING); - int16_t fb = yax_getbunch(sectnum, YAX_FLOOR); - - if ((cb>=0 && (sec->ceilingstat&2)) || (fb >= 0 && (sec->floorstat&2))) - { - message("Extended ceilings/floors must not be sloped to set first wall"); - return; - } - } - - if (k > 0) - message("Set first walls (sector[].wallptr) for %d sectors", k+1); - - if (k == 0) -#endif - message("This wall now sector %d's first wall (sector[].wallptr)", sectnum); - - setfirstwall(sectnum, wallnum); - - mkonwinvalid_keeptempsect(); - - asksave = 1; -} - -void handlesecthighlight1(int32_t i, int32_t sub, int32_t nograycheck) -{ - int32_t j; - - if (sub) - { - hlsectorbitmap[i>>3] &= ~(1<<(i&7)); - for (j=sector[i].wallptr; j= 0) - checksectorpointer(wall[j].nextwall,wall[j].nextsector); - checksectorpointer(j, i); - } - } - else - { - if (nograycheck || (graysectbitmap[i>>3]&(1<<(i&7)))==0) - hlsectorbitmap[i>>3] |= (1<<(i&7)); - } -} - -#ifdef YAX_ENABLE -// 1: good, 0: bad -static int32_t hl_all_bunch_sectors_p() -{ - uint8_t *const havebunch = visited; - int16_t cf, cb, fb; - int32_t i, j; - - if (numyaxbunches > 0) - { - Bmemset(havebunch, 0, (numyaxbunches+7)>>3); - for (i=0; i=0) - havebunch[cb>>3] |= (1<<(cb&7)); - if (fb>=0) - havebunch[fb>>3] |= (1<<(fb&7)); - } - - for (i=0; i>3] & (1<<(i&7)))==0) - continue; - - for (cf=0; cf<2; cf++) - for (SECTORS_OF_BUNCH(i,cf, j)) - if ((hlsectorbitmap[j>>3]&(1<<(j&7)))==0) - return 0; - } - } - - return 1; -} -#endif - -static int32_t find_nextwall(int32_t sectnum, int32_t sectnum2) -{ - int32_t j, startwall, endwall; - - if (sectnum<0 || sectnum2<0) - return -1; - - for (WALLS_OF_SECTOR(sectnum, j)) - if (wall[j].nextsector == sectnum2) - return j; - - return -1; -} - -static int32_t bakframe_fillandfade(char **origframeptr, int32_t sectnum, const char *querystr) -{ - if (!*origframeptr) - { - *origframeptr = (char *)Xmalloc(xdim*ydim); - - videoBeginDrawing(); - Bmemcpy(*origframeptr, (char *)frameplace, xdim*ydim); - videoEndDrawing(); - } - else - { - videoBeginDrawing(); - Bmemcpy((char *)frameplace, *origframeptr, xdim*ydim); - videoEndDrawing(); - } - - fillsector_notrans(sectnum, editorcolors[9]); - fade_editor_screen(editorcolors[9]); - - return ask_if_sure(querystr, 0); -} - -#ifdef YAX_ENABLE -static void M32_MarkPointInsertion(int32_t thewall) -{ - int32_t i, tmpcf; - int32_t nextw = wall[thewall].nextwall; - - // round 1 - for (YAX_ITER_WALLS(thewall, i, tmpcf)) - wall[i].cstat |= (1<<14); - if (nextw >= 0) - for (YAX_ITER_WALLS(nextw, i, tmpcf)) - wall[i].cstat |= (1<<14); - // round 2 (enough?) - for (YAX_ITER_WALLS(thewall, i, tmpcf)) - if (wall[i].nextwall >= 0 && (wall[wall[i].nextwall].cstat&(1<<14))==0) - wall[wall[i].nextwall].cstat |= (1<<14); - if (nextw >= 0) - for (YAX_ITER_WALLS(nextw, i, tmpcf)) - if (wall[i].nextwall >= 0 && (wall[wall[i].nextwall].cstat&(1<<14))==0) - wall[wall[i].nextwall].cstat |= (1<<14); -} -#endif - -// High-level insert point, handles TROR constrained walls too -// onewnumwalls: old numwalls + drawn walls. -// : see insertpoint() -// Returns: -// 0 if wall limit would be reached. -// 1 if inserted point on a plain white or 2 points on a plain red wall. -// N >= 2 if inserted N points on TROR-constrained wall. -// N|(EXPECTED<<16) if inserted N points but EXPECTED walls were expected. -static int32_t M32_InsertPoint(int32_t thewall, int32_t dax, int32_t day, int16_t onewnumwalls, int32_t *mapwallnum) -{ -#ifdef YAX_ENABLE - int32_t nextw = wall[thewall].nextwall; - int32_t i, j, k, m; - - if (yax_islockedwall(thewall) || (nextw>=0 && yax_islockedwall(nextw))) - { - // yax'ed wall -- first find out which walls are affected - for (i=0; i MAXWALLS) - { - return 0; // no points inserted, would exceed limits - } - - // the actual insertion! - m = 0; - for (i=0; i= 0) - yax_setnextwall(i+1, YAX_CEILING, k+1); - k = yax_getnextwall(i+1, YAX_FLOOR); - if (k >= 0) - yax_setnextwall(i+1, YAX_FLOOR, k+1); - } - } - - if (m==j) - return m; - else - return m|(j<<16); - } - else -#endif - { - insertpoint(thewall, dax,day, mapwallnum); - return 1; - } -} - - -// based on lineintersect in engine.c, but lines are considered as infinitely -// extending -void inflineintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - int32_t x3, int32_t y3, int32_t x4, int32_t y4, - int32_t *intx, int32_t *inty, int32_t *sign12, int32_t *sign34) -{ - //p1 to p2 is a line segment - int64_t topt, topu, t; - - int64_t x21 = x2-x1; - int64_t x34 = x3-x4; - int64_t y21 = y2-y1; - int64_t y34 = y3-y4; - int64_t bot = x21*y34 - y21*x34; - - if (EDUKE32_PREDICT_FALSE(bot == 0)) - { - *sign12 = *sign34 = 0; - return; - } - else - { - int64_t const x31 = x3 - x1; - int64_t const y31 = y3 - y1; - - topt = x31 * y34 - y31 * x34; - topu = x21 * y31 - y21 * x31; - } - - t = (topt * (1 << 24)) / bot; - - *intx = x1 + ((x21 * t) >> 24); - *inty = y1 + ((y21 * t) >> 24); - - *sign12 = topt < 0 ? -1 : 1; - *sign34 = topu < 0 ? -1 : 1; -} - -static int32_t lineintersect2v(const vec2_t *p1, const vec2_t *p2, // line segment 1 - const vec2_t *q1, const vec2_t *q2, // line segment 2 - vec2_t *pint) -{ - int32_t intz; - return lintersect(p1->x, p1->y, 0, p2->x, p2->y, 0, - q1->x, q1->y, q2->x, q2->y, - &pint->x, &pint->y, &intz); -} - -static int32_t vec2eq(const vec2_t *v1, const vec2_t *v2) -{ - return (v1->x==v2->x && v1->y==v2->y); -} - -#ifdef YAX_ENABLE -// After auto-creating inner sector in existing sector , we need to -// see if some sprites contained in need to change their sector. -static void CorrectSpriteSectnums(int32_t os, int32_t ns) -{ - int32_t i, ni; - - for (SPRITES_OF_SECT_SAFE(os, i, ni)) - { - if (inside(sprite[i].x, sprite[i].y, ns)==1) - changespritesect(i, ns); - } -} -#endif - -// precondition: [numwalls, newnumwalls-1] form a new loop (may be of wrong orientation) -// ret_ofirstwallofs: if != NULL, *ret_ofirstwallofs will contain the offset of the old -// first wall from the new first wall of the sector k, and the automatic -// restoring of the old first wll will not be carried out -// returns: -// -1, -2: errors -// 0, 1: OK, 1 means it was an extended sector and an inner loop has been added automatically -static int32_t AddLoopToSector(int32_t k, int32_t *ret_ofirstwallofs) -{ - int32_t extendedSector=0, firstwall, i, j; -#ifdef YAX_ENABLE - int16_t cbunch, fbunch; - int32_t newnumwalls2; - - yax_getbunches(k, &cbunch, &fbunch); - extendedSector = (cbunch>=0 || fbunch>=0); -#endif - j = newnumwalls-numwalls; -#ifdef YAX_ENABLE - newnumwalls2 = newnumwalls + j; - - if (extendedSector) - { - if ((cbunch>=0 && (sector[k].ceilingstat&2)) - || (fbunch>=0 && (sector[k].floorstat&2))) - { - printmessage16("Sloped extended sectors cannot be subdivided."); - newnumwalls--; - return -1; - } - - if (newnumwalls + j > MAXWALLS || numsectors+1 > MAXSECTORS) - { - message("Automatically adding inner sector to new extended sector would exceed limits!"); - newnumwalls--; - return -2; - } - } -#endif - if (clockdir(numwalls) == CLOCKDIR_CW) - flipwalls(numwalls,newnumwalls); - - sector[k].wallnum += j; - for (i=k+1; i= firstwall) - wall[i].nextwall += j; - if (wall[i].point2 >= firstwall) - wall[i].point2 += j; - } -#ifdef YAX_ENABLE - yax_tweakwalls(firstwall, j); -#endif - - Bmemmove(&wall[firstwall+j], &wall[firstwall], (newnumwalls-firstwall)*sizeof(walltype)); - // add new loop to beginning of sector - Bmemmove(&wall[firstwall], &wall[newnumwalls], j*sizeof(walltype)); - - for (i=firstwall; ilotag; - if (lt&2) - return spr->hitag; - if (lt&4) - return spr->extra; - if (lt&8) - return spr->xvel; - if (lt&16) - return spr->yvel; - if (lt&32) - return spr->zvel; - if (lt&64) - return spr->extra; - - return INT32_MIN; -} - -static void drawlinebetween(const vec3_t *v1, const vec3_t *v2, int32_t col, uint32_t pat) -{ - // based on m32exec.c/drawline* - const int32_t xofs=halfxdim16, yofs=midydim16; - const uint32_t opat=drawlinepat; - - int32_t x1, x2, y1, y2; - - editorGet2dScreenCoordinates(&x1,&y1, v1->x-pos.x,v1->y-pos.y, zoom); - editorGet2dScreenCoordinates(&x2,&y2, v2->x-pos.x,v2->y-pos.y, zoom); - - if (m32_sideview) - { - y1 += getscreenvdisp(v1->z-pos.z,zoom); - y2 += getscreenvdisp(v2->z-pos.z,zoom); - } - - drawlinepat = pat; - editorDraw2dLine(xofs+x1,yofs+y1, xofs+x2,yofs+y2, col); - drawlinepat = opat; -} - -// world -> screen coords for overhead mode -void ovhscrcoords(int32_t x, int32_t y, int32_t *scrx, int32_t *scry) -{ - *scrx = halfxdim16 + mulscale14(x-pos.x, zoom); - *scry = midydim16 + mulscale14(y-pos.y, zoom); -} - -static void draw_cross(int32_t centerx, int32_t centery, int32_t radius, int32_t col) -{ - int32_t dax, day; - ovhscrcoords(centerx, centery, &dax, &day); - drawline16base(dax, day, -radius,-radius, +radius,+radius, col); - drawline16base(dax, day, -radius,+radius, +radius,-radius, col); -} - -static void draw_square(int32_t dax, int32_t day, int32_t ps, int32_t col) -{ - ovhscrcoords(dax, day, &dax, &day); - drawline16base(dax, day, -ps,-ps, +ps,-ps, col); - drawline16base(dax, day, +ps,-ps, +ps,+ps, col); - drawline16base(dax, day, +ps,+ps, -ps,+ps, col); - drawline16base(dax, day, -ps,+ps, -ps,-ps, col); -} - -//// Interactive Scaling -static struct { - int8_t active, rotatep; - vec2_t piv; // pivot point - int32_t dragx, dragy; // dragged point - int32_t xsc, ysc, ang; -} isc; - -static void isc_transform(int32_t *x, int32_t *y) -{ - if (!isc.rotatep) - { - *x = isc.piv.x + mulscale16(*x-isc.piv.x, isc.xsc); - *y = isc.piv.y + mulscale16(*y-isc.piv.y, isc.ysc); - } - else - { - vec2_t v = { *x, *y }; - rotatepoint(isc.piv, v, isc.ang, &v); - *x = v.x; - *y = v.y; - } -} - -static void drawspritelabel(int i) -{ - // XXX: oob 'i' may happen, such as passing pointhighlight-16384 when - // pointhighlight == -1. - if ((unsigned)i >= MAXSPRITES) - return; - - const char *dabuffer = CallExtGetSpriteCaption(i); - - if (!dabuffer[0]) - return; - - // KEEPINSYNC drawscreen_drawsprite() - uspritetype const * s = (uspritetype *)&sprite[i]; - uint8_t const spritecol = spritecol2d[s->picnum][(s->cstat&1)]; - int col = spritecol ? editorcolors[spritecol] : editorGet2dSpriteColor(i); - int const blocking = s->cstat & 1; - int bordercol = blocking ? editorcolors[5] : col; - - // group selection - if (show2dsprite[i>>3]&pow2char[i&7]) - { - bordercol = editorcolors[14]; - col = bordercol - (M32_THROB>>1); - } - else if (i == pointhighlight - 16384) - { - if (spritecol >= 8 && spritecol <= 15) - col -= M32_THROB>>1; - else col += M32_THROB>>2; - - if (bordercol > col && !blocking) - bordercol = col; - } - - else if (s->sectnum < 0) - col = bordercol = editorcolors[4]; // red - - drawsmallabel(dabuffer, editorcolors[0], col, bordercol, s->x, s->y, s->z); -} - -#define EDITING_MAP_P() (newnumwalls>=0 || joinsector[0]>=0 || circlewall>=0 || (bstatus&1) || isc.active) - -#define HLMEMBERX(Hl, Member) (*(((Hl)&16384) ? &sprite[(Hl)&16383].Member : &wall[Hl].Member)) -#define HLMEMBER(Hlidx, Member) HLMEMBERX(highlight[Hlidx], Member) - -static void maybedeletewalls(int32_t dax, int32_t day) -{ - int numdelpoints = 0; - int const havedrawnwalls = (newnumwalls != -1); - int restorestat = 1; - - // attempt to delete some points - for (int runi=0; runi<3; runi++) // check, tweak, carry out - for (int i=numwalls-1; i>=0; i--) - { - if (runi==0) - wall[i].cstat &= ~(1<<14); - - if (wall[i].x == POINT2(i).x && wall[i].y == POINT2(i).y) - { - if (havedrawnwalls) - { - if (i==ovh.suckwall || (ovh.split && i==ovh.splitstartwall)) - { - // if we're about to delete a wall that participates - // in splitting, discard the already drawn walls - restorestat = 2; - } - else if (runi == 1) - { - // correct drawn wall anchors - if (ovh.suckwall > i) - ovh.suckwall--; - if (ovh.split && ovh.splitstartwall > i) - ovh.splitstartwall--; - } - } - - if (runi == 0) - { - int32_t sectnum = sectorofwall(i); - if (sector[sectnum].wallnum <= 3) - { - message("Deleting wall %d would leave sector %d with %d walls.", - i, sectnum, sector[sectnum].wallnum-1); - goto end_after_dragging; - } - - sectnum = wall[i].nextsector; - if (sectnum >= 0 && sector[sectnum].wallnum <= 3) - { - message("Deleting wall %d would leave sector %d with %d walls.", - i, sectnum, sector[sectnum].wallnum-1); - goto end_after_dragging; - } - } - else - { - deletepoint(i, runi); - if (runi==2) - numdelpoints++; - } - } - } - - if (numdelpoints) - { - if (numdelpoints > 1) - message("Deleted %d points%s", numdelpoints, - (havedrawnwalls && restorestat==2) ? " and cleared drawn walls" : ""); - else - printmessage16("Point deleted%s", (havedrawnwalls && restorestat==2) ? - ", cleared drawn walls" : ""); - asksave = 1; - } - else - { - for (int i=0; i 3 && (wall[w].nextwall == -1 || sector[sectorofwall(wall[w].nextwall)].wallnum > 3)) - { - dragpoint(w, POINT2(w).x, POINT2(w).y, 0); - maybedeletewalls(wall[w].x, wall[w].y); - } -/* - else - { - deletesector(sectorofwall(w)); - mkonwinvalid(); - printmessage16("Sector deleted."); - } -*/ - } -} - -void overheadeditor(void) -{ - char buffer[80]; - const char *dabuffer; - int32_t i, j, k, m=0, mousxplc, mousyplc, firstx=0, firsty=0, oposz, col; - int32_t numwalls_bak; - int32_t startwall=0, endwall, dax, day, x1, y1, x2, y2, x3, y3; //, x4, y4; - int16_t bad, joinsector[2]; - int32_t bstatus, mousewaitmask=0; - int16_t circlepoints; - int32_t sectorhighlightx=0, sectorhighlighty=0; - int16_t cursectorhighlight, sectorhighlightstat; - int32_t prefixarg = 0, tsign; - int32_t resetsynctics = 0, lasttick=timerGetTicks(), waitdelay=totalclock, lastdraw=timerGetTicks(); - int32_t olen[2] = {0, 0}, dragwall[2] = {-1, -1}; - int16_t linehighlight2 = -1; - vec2_t highlight1 = { 0, 0 }, highlight2 = { 0, 0 }; - - ovh.suckwall = -1; - ovh.split = 0; - ovh.splitsect = -1; - ovh.splitstartwall = -1; - - videoSet2dMode(xdim2d,ydim2d); - xdim2d = xdim; - ydim2d = ydim; - - osearchx = searchx; - osearchy = searchy; - - searchx = clamp(scale(searchx,xdim2d,xdimgame), 8, xdim2d-8-1); - searchy = clamp(scale(searchy,ydim2d-STATUS2DSIZ2,ydimgame), 8, ydim2d-STATUS2DSIZ-8-1); - oposz = pos.z; - - yax_updategrays(pos.z); - - videoBeginDrawing(); //{{{ - CLEARLINES2D(0, ydim, 0); - videoEndDrawing(); //}}} - - ydim16 = ydim-STATUS2DSIZ2; - - cursectorhighlight = -1; - lastpm16time = -1; - - update_highlightsector(); - ovh_whiteoutgrab(0); - - highlightcnt = -1; - Bmemset(show2dwall, 0, sizeof(show2dwall)); //Clear all highlights - Bmemset(show2dsprite, 0, sizeof(show2dsprite)); - - RESET_EDITOR_VARS(); - bstatus = 0; - - while ((keystatus[buildkeys[BK_MODE2D_3D]]>>1) == 0) - { - int32_t mousx = 0, mousy = 0; - - if (zoom < ztarget) - { - if ((ztarget - zoom) >> 3) - zoom += synctics * ((ztarget - zoom) >> 3); - else zoom++; - zoom = min(zoom, ztarget); - } - else if (zoom > ztarget) - { - if ((zoom - ztarget) >> 3) - zoom -= synctics * ((zoom - ztarget) >> 3); - else zoom--; - zoom = max(zoom, ztarget); - } - - if (!((vel|angvel|svel) || m32_is2d3dmode() || ztarget != zoom//DOWN_BK(MOVEFORWARD) || DOWN_BK(MOVEBACKWARD) || DOWN_BK(TURNLEFT) || DOWN_BK(TURNRIGHT) - || DOWN_BK(MOVEUP) || DOWN_BK(MOVEDOWN) || keystatus[sc_Q] || keystatus[sc_W] - || keystatus[sc_kpad_8] || keystatus[sc_kpad_4] || keystatus[sc_kpad_6] || keystatus[sc_kpad_2] // keypad keys - || bstatus || OSD_IsMoving())) - { - if (totalclock > waitdelay) - { - uint32_t ms = 50;// (highlightsectorcnt>0) ? 75 : 200; - // wait for event, timeout after 200 ms - (last loop time) - idle_waitevent_timeout(ms - min(timerGetTicks()-lasttick, ms)); - // have synctics reset to 0 after we've slept to avoid zooming out to the max instantly - resetsynctics = 1; - } - } - else waitdelay = totalclock + 6; // should be 50 ms - - lasttick = timerGetTicks(); - - if (handleevents()) - { - if (quitevent) - { - keystatus[sc_Escape] = 1; - quitevent = 0; - } - } - - if (resetsynctics) - { - resetsynctics = 0; - lockclock = totalclock; - synctics = 0; - } - - OSD_DispatchQueued(); - - if (totalclock < 120*3) - printmessage16("Uses BUILD technology by Ken Silverman."); - else if (totalclock < 120*6) - { - printmessage16("Press F1 for help. This is a test release; always keep backups of your maps."); - // printext16(8L,ydim-STATUS2DSIZ+32L,editorcolors[9],-1,kensig,0); - } - - if (!m32_is2d3dmode()) - { - oldmousebstatus = bstatus; - mouseGetValues(&mousx, &mousy, &bstatus); - - { - int32_t bs = bstatus; - bstatus &= ~mousewaitmask; - mousewaitmask &= bs; - } - - mousx = (mousx<<16)+mousexsurp; - mousy = (mousy<<16)+mouseysurp; - { - ldiv_t ld; - ld = ldiv(mousx, 1<<16); mousx = ld.quot; mousexsurp = ld.rem; - ld = ldiv(mousy, 1<<16); mousy = ld.quot; mouseysurp = ld.rem; - } - searchx += mousx; - searchy += mousy; - - inpclamp(&searchx, 8, xdim-8-1); - inpclamp(&searchy, 8, ydim-8-1); - - mainloop_move(); - - getpoint(searchx, searchy, &mousxplc, &mousyplc); - linehighlight = getlinehighlight(mousxplc, mousyplc, linehighlight, 0); - linehighlight2 = getlinehighlight(mousxplc, mousyplc, linehighlight, 1); - } - - if ((unsigned)newnumwalls < MAXWALLS && newnumwalls >= numwalls) - { - // if we're in the process of drawing a wall, set the end point's coordinates - dax = mousxplc; - day = mousyplc; - adjustmark(&dax,&day,numwalls+!ovh.split); - wall[newnumwalls].x = dax; - wall[newnumwalls].y = day; - } - - ydim16 = ydim;// - STATUS2DSIZ2; - midydim16 = ydim>>1; - - numwalls_bak = numwalls; - numwalls = newnumwalls; - if (numwalls < 0) - numwalls = numwalls_bak; - - if ((timerGetTicks() - lastdraw) >= 5 || (vel|angvel|svel) || DOWN_BK(MOVEUP) || DOWN_BK(MOVEDOWN) - || mousx || mousy || bstatus || keystatus[sc_Q] || keystatus[sc_W] - || newnumwalls>=0 || OSD_IsMoving()) - { - lastdraw = timerGetTicks(); - - clear2dscreen(); - - editorSetup2dSideView(); - - VM_OnEvent(EVENT_PREDRAW2DSCREEN, -1); - - if (graphicsmode && (!m32_sideview || m32_sideelev == 512)) - { - Bmemset(show2dsector, 0, sizeof(show2dsector)); - for (i=0; i>3] |= (1<<(i&7)); - } - - videoSetViewableArea(0, 0, xdim-1, ydim16-1); - - if (graphicsmode == 2) - totalclocklock = totalclock; - - renderDrawMapView(pos.x, pos.y, zoom, m32_sideview ? (3584 - m32_sideang) & 2047: 1536); - } - - editorDraw2dGrid(pos.x,pos.y,pos.z,cursectnum,ang,zoom,grid); - CallExtPreCheckKeys(); - editorDraw2dScreen(&pos,cursectnum,ang,zoom,grid); - - // Draw brown arrow (start) - editorGet2dScreenCoordinates(&x2, &y2, startpos.x-pos.x,startpos.y-pos.y, zoom); - if (m32_sideview) - y2 += getscreenvdisp(startpos.z-pos.z, zoom); - - int32_t cx = halfxdim16+x2; - int32_t cy = midydim16+y2; - - videoBeginDrawing(); //{{{ LOCK_FRAME_1 - - if ((cx >= 2 && cx <= xdim-3) && (cy >= 2 && cy <= ydim16-3)) - { - int16_t angofs = m32_sideview ? m32_sideang : 0; - x1 = mulscale11(sintable[(startang+angofs+2560)&2047],zoom) / 768; - y1 = mulscale11(sintable[(startang+angofs+2048)&2047],zoom) / 768; - i = scalescreeny(x1); - j = scalescreeny(y1); - drawline16base(cx,cy, x1,j, -x1,-j, editorcolors[6]); - drawline16base(cx,cy, x1,j, +y1,-i, editorcolors[6]); - drawline16base(cx,cy, x1,j, -y1,+i, editorcolors[6]); - } - - if (keystatus[sc_LeftShift] && (pointhighlight&16384) && highlightcnt<=0) // LShift - { - // draw lines to linking sprites - const int32_t refspritenum = pointhighlight&16383; - const int32_t reftag = select_sprite_tag(refspritenum); - - if (reftag != INT32_MIN) - { - for (i=0; i= 768) - { - for (i=0; i= 0) - { - for (i=newnumwalls; i>=numwalls_bak; i--) - wall[i].cstat |= (1<<14); - } - - i = numwalls-1; - j = numsectors-1; // might be -1 if empty map! - if (newnumwalls >= 0) - i = newnumwalls-1; - for (; i>=0; i--) - { - walltype const * const wal = &wall[i]; - - if (j>=0 && sector[j].wallptr > i) - j--; - - if (zoom < 768 && !(wal->cstat & (1<<14))) - continue; - - YAX_SKIPWALL(i); - - //Get average point of wall -// if ((dax > x3) && (dax < x4) && (day > y3) && (day < y4)) - { - dabuffer = CallExtGetWallCaption(i); - if (dabuffer[0] == 0) - continue; - - dax = (wal->x+wall[wal->point2].x)>>1; - day = (wal->y+wall[wal->point2].y)>>1; - drawsmallabel(dabuffer, editorcolors[0], editorcolors[31], editorcolors[31] - 3, dax, day, (i >= numwalls || j<0) ? 0 : getflorzofslope(j, dax,day)); - } - } - - if (zoom >= 768) - { - int32_t alwaysshowgray = get_alwaysshowgray(); - - for (i=0, k=0; (m32_sideview && k= 0) - YAX_SKIPSECTOR(sprite[i].sectnum); - - drawspritelabel(i); - } - - if (pointhighlight & 16384) - drawspritelabel(pointhighlight - 16384); - } - } - - // stick this event right between begin- end enddrawing()... - // also after the above label stuff so users can redefine them - VM_OnEvent(EVENT_DRAW2DSCREEN, -1); - - printcoords16(pos.x,pos.y,ang); - - numwalls = numwalls_bak; - - if (highlightsectorcnt >= 0) - { - for (i=0; i>3]&(1<<(i&7))) - fillsector(i, -1); - } - - if (keystatus[sc_LeftShift]) // LShift - { - if (!m32_is2d3dmode() && (m32_sideview || highlightcnt <= 0)) - { - drawlinepat = 0x00ff00ff; - editorDraw2dLine(searchx,0, searchx,ydim2d-1, editorcolors[15]); - editorDraw2dLine(0,searchy, xdim2d-1,searchy, editorcolors[15]); - drawlinepat = 0xffffffff; - - _printmessage16("(%d,%d)",mousxplc,mousyplc); - } - else - { - // do interactive scaling - if (!isc.active) - { - if (pointhighlight >= 0 && (bstatus&3)) - { - // initialize by finding pivot point - int32_t minx=INT32_MAX, miny=INT32_MAX; - int32_t maxx=INT32_MIN, maxy=INT32_MIN; - - isc.rotatep = ((bstatus&3)==2); - bstatus &= ~3; - - for (i=0; i= 8) - xsc = min(klabs(divscale16(mdx, dx)), 1<<18); - if (mdy != 0 && dy != 0 && klabs(dy) >= 8) - ysc = min(klabs(divscale16(mdy, dy)), 1<<18); - - if (eitherCTRL) - xsc = ysc = max(xsc, ysc); - - isc.xsc = xsc; - isc.ysc = ysc; - - printmessage16("scale x=%.3f y=%.3f", (double)xsc/65536, (double)ysc/65536); - } - else - { - isc.ang = getangle(mdx, mdy) - getangle(dx, dy); - printmessage16("rotate ang %d", isc.ang); - } - - for (i=0; ipoint2, hlp=(show2dwall[p2>>3]&(1<<(p2&7))); - vec3_t v1 = { x, y, 0 }, v2 = { wall[p2].x, wall[p2].y, 0 }; - - isc_transform(&v2.x, &v2.y); - if (!hlp) - { - v2.x = wall[p2].x; - v2.y = wall[p2].y; - } - - drawlinebetween(&v1, &v2, !hlp ? 8 : - editorcolors[wal->nextwall >= 0 ? 12 : 7], - 0x11111111); - } - } - } - else - { - // finish interactive scaling - isc.active = 0; - - if ((!isc.rotatep && (isc.xsc!=1<<16 || isc.ysc!=1<<16)) || - (isc.rotatep && (isc.ang!=0))) - { - for (i=0; iang = (spr->ang + isc.ang)&2047; - } - } - - if (!isc.rotatep) - message("Highlights scaled by x=%.3f y=%.3f", - (double)isc.xsc/65536, (double)isc.ysc/65536); - else - message("Highlights rotated by %d BUILD degrees", isc.ang); - - asksave = 1; - } - else - printmessage16(" "); - } - } - } - } - else - { - if (isc.active) - { - isc.active = 0; - - printmessage16("Aborted interactive %s.", isc.rotatep ? "rotation" : "scaling"); - bstatus &= ~3; - mousewaitmask = 3; - pointhighlight = -1; - } - } - - editorDraw2dLine(searchx,0, searchx,8, editorcolors[15]); - editorDraw2dLine(0,searchy, 8,searchy, editorcolors[15]); - - // 2d3d mode - if (m32_2d3dmode && m32_2d3d_resolutions_match()) - { -#ifdef USE_OPENGL - int bakrendmode = rendmode; -#endif - vec2_t bdim = { xdim, ydim }; - - xdim = xdim2d; - ydim = ydim2d; -#ifdef USE_OPENGL - rendmode = REND_CLASSIC; -#endif - - if (m32_2d3d.x + XSIZE_2D3D > xdim2d - 4) - m32_2d3d.x = xdim2d - 4 - XSIZE_2D3D; - - if (m32_2d3d.y + YSIZE_2D3D > ydim2d - 4 - STATUS2DSIZ2) - m32_2d3d.y = ydim2d - 4 - YSIZE_2D3D - STATUS2DSIZ2; - - updatesectorz(pos.x, pos.y, pos.z, &cursectnum); - - if (cursectnum == -1) - updatesector(pos.x, pos.y, &cursectnum); - - if (cursectnum != -1) - { - int32_t cz, fz; - - getzsofslope(cursectnum, pos.x, pos.y, &cz, &fz); - - inpclamp(&pos.z, cz+(4<<8), fz-(4<<8)); - - videoEndDrawing(); - videoSetViewableArea(m32_2d3d.x, m32_2d3d.y, m32_2d3d.x + XSIZE_2D3D, m32_2d3d.y + YSIZE_2D3D); - videoClearViewableArea(-1); - - vec2_t osearch = { searchx, searchy }; - - searchx -= m32_2d3d.x; - searchy -= m32_2d3d.y; - - M32_DrawRoomsAndMasks(); - videoSetViewableArea(0, 0, xdim2d-1, ydim2d-1); - -#ifdef USE_OPENGL - rendmode = bakrendmode; -#endif - xdim = bdim.x; - ydim = bdim.y; - searchx = osearch.x; - searchy = osearch.y; - - videoBeginDrawing(); - editorDraw2dLine(m32_2d3d.x, m32_2d3d.y, m32_2d3d.x + XSIZE_2D3D, m32_2d3d.y, editorcolors[15]); - editorDraw2dLine(m32_2d3d.x + XSIZE_2D3D, m32_2d3d.y, m32_2d3d.x + XSIZE_2D3D, m32_2d3d.y + YSIZE_2D3D, editorcolors[15]); - editorDraw2dLine(m32_2d3d.x, m32_2d3d.y, m32_2d3d.x, m32_2d3d.y + YSIZE_2D3D, editorcolors[15]); - editorDraw2dLine(m32_2d3d.x, m32_2d3d.y + YSIZE_2D3D, m32_2d3d.x + XSIZE_2D3D, m32_2d3d.y + YSIZE_2D3D, editorcolors[15]); - } - } - - if (!m32_is2d3dmode()) - { - ////// draw mouse pointer - - col = editorcolors[0]; - - drawline16base(searchx+1, searchy+1, +0, -8, +0, -1, col); - drawline16base(searchx+1, searchy+1, +0, 1, +0, 8, col); - - drawline16base(searchx+1, searchy+1, -8, 0, -1, 0, col); - drawline16base(searchx+1, searchy+1, 1, 0, 8, 0, col); - - col = searchlock ? editorcolors[13] : editorcolors[15 - 3*gridlock]; - - if (joinsector[0] >= 0) - col = editorcolors[11]; - - if (numcorruptthings>0) - { - static char cbuf[64]; - - if ((pointhighlight&16384)==0) - { - // If aiming at wall, check whether it is corrupt, and print a - // warning message near the mouse pointer if that is the case. - for (i=0; i=MAXCORRUPTTHINGS ? ">=" : "", numcorruptthings); - printext16(8, 8, editorcolors[13]+(M32_THROB>>2), editorcolors[0], cbuf, 0); - } - - if (highlightsectorcnt==0 || highlightcnt==0) - { - if (keystatus[sc_SemiColon] || keystatus[sc_Quote]) // ' and ; - { - col = editorcolors[14]; - - drawline16base(searchx+16, searchy-16, -4, 0, +4, 0, col); - if (keystatus[sc_Quote]) - drawline16base(searchx+16, searchy-16, 0, -4, 0, +4, col); - } - - if (highlightsectorcnt == 0) - if (keystatus[sc_RightShift]) - printext16(searchx+6, searchy-2+8, editorcolors[12], -1, "ALL", 0); - - if (highlightcnt == 0) - { - if (eitherCTRL && (highlight1.x!=highlight2.x || highlight1.y!=highlight2.y)) - printext16(searchx+6, searchy-6-8, editorcolors[12], -1, "SPR ONLY", 0); -#ifdef YAX_ENABLE - if (keystatus[sc_End]) // End - printext16(searchx+6, searchy-2+8, editorcolors[12], -1, "ALL", 0); -#endif - } - } - - drawline16base(searchx, searchy, +0, -8, +0, -1, col); - drawline16base(searchx, searchy, +0, 1, +0, 8, col); - - drawline16base(searchx, searchy, -8, 0, -1, 0, col); - drawline16base(searchx, searchy, 1, 0, 8, 0, col); - - ////// Draw the white pixel closest to mouse cursor on linehighlight - if (linehighlight>=0) - { - char col = wall[linehighlight].nextsector >= 0 ? editorcolors[15] : editorcolors[5]; - - if (m32_sideview) - { - getclosestpointonwall(searchx, searchy, linehighlight, &dax, &day, 1); - drawline16base(dax, day, 0, 0, 0, 0, col); - } - else - { - getclosestpointonwall(mousxplc, mousyplc, linehighlight, &dax, &day, 0); - ovhscrcoords(dax, day, &x2, &y2); - drawline16base(x2, y2, 0, 0, 0, 0, col); - } - } - } - - videoEndDrawing(); //}}} LOCK_FRAME_1 - - OSD_Draw(); - } - - inputchecked = 1; - - - VM_OnEvent(EVENT_PREKEYS2D, -1); - CallExtCheckKeys(); // TX 20050101, it makes more sense to have this here so keys can be overwritten with new functions in bstub.c - - // 2d3d mode - if (m32_is2d3dmode()) - goto nokeys; - - // Flip/mirror sector Ed Coolidge - if (keystatus[sc_X] || keystatus[sc_Y]) // X or Y (2D) - { - int32_t about_x=keystatus[sc_X]; - int32_t doMirror = eitherALT; // mirror walls and wall/floor sprites - -#ifdef YAX_ENABLE - if (highlightsectorcnt > 0 && !hl_all_bunch_sectors_p()) - { - printmessage16("To flip extended sectors, all sectors of a bunch must be selected"); - keystatus[sc_X] = keystatus[sc_Y] = 0; - } - else -#endif - if (highlightsectorcnt > 0) - { - int16_t *const otonwall = onextwall; // OK, since we make old-nextwalls invalid - - mkonwinvalid(); - - keystatus[sc_X] = keystatus[sc_Y] = 0; - - for (j=0; j 0) - locktogrid(&dax, &day); - - for (i=0; i>1; - for (w=1; w<=numtoswap; w++) - { - Bmemcpy(&tempwall, &wall[startofloop+w], sizeof(walltype)); - Bmemcpy(&wall[startofloop+w], &wall[endofloop-w+1], sizeof(walltype)); - Bmemcpy(&wall[endofloop-w+1], &tempwall, sizeof(walltype)); - - otonwall[startofloop+w] = endofloop-w+1; - otonwall[endofloop-w+1] = startofloop+w; - } - - //make point2 point to next wall in loop - for (w=startofloop; w= 0) - wall[j].nextwall = otonwall[wall[j].nextwall]; -#ifdef YAX_ENABLE - { - int32_t cf, ynw; - for (cf=0; cf<2; cf++) - if ((ynw = yax_getnextwall(j, cf)) >= 0) - yax_setnextwall(j, cf, otonwall[ynw]); - } -#endif - } - } - - printmessage16("Selected sector(s) flipped"); - asksave = 1; - } - } - // end edit for sector flip - - if (keystatus[88]) //F12 - { - keystatus[88] = 0; -//__clearscreen_beforecapture__ - videoCaptureScreen("captxxxx.tga", eitherSHIFT); - - videoShowFrame(1); - } - if (keystatus[sc_B]) // B (clip Blocking xor) (2D) - { - pointhighlight = getpointhighlight(mousxplc, mousyplc, pointhighlight); - linehighlight = getlinehighlight(mousxplc, mousyplc, linehighlight, 0); - - if ((pointhighlight&0xc000) == 16384) - { - sprite[pointhighlight&16383].cstat ^= 1; - sprite[pointhighlight&16383].cstat &= ~256; - sprite[pointhighlight&16383].cstat |= ((sprite[pointhighlight&16383].cstat&1)<<8); - asksave = 1; - } - else if (linehighlight >= 0) - { - wall[linehighlight].cstat ^= 1; - wall[linehighlight].cstat &= ~64; - if ((wall[linehighlight].nextwall >= 0) && !eitherSHIFT) - { - NEXTWALL(linehighlight).cstat &= ~(1+64); - NEXTWALL(linehighlight).cstat |= (wall[linehighlight].cstat&1); - } - asksave = 1; - } - keystatus[sc_B] = 0; - } - if (keystatus[sc_F]) //F (F alone does nothing in 2D right now) - { - keystatus[sc_F] = 0; - if (eitherALT) //ALT-F (relative alignmment flip) - { - linehighlight = getlinehighlight(mousxplc, mousyplc, linehighlight, 0); - if (linehighlight >= 0) - SetFirstWall(sectorofwall(linehighlight), linehighlight, 1); - } - } - - if (keystatus[sc_O]) // O (ornament onto wall) (2D) - { - keystatus[sc_O] = 0; - if ((pointhighlight&0xc000) == 16384) - { - asksave = 1; - DoSpriteOrnament(pointhighlight&16383); - } - } - - - tsign = 0; - if (keystatus[sc_Comma] || (bstatus&33)==33) // , (2D) - tsign = +1; - if (keystatus[sc_Period] || (bstatus&17)==17) // . (2D) - tsign = -1; - - if (tsign) - { -#ifdef YAX_ENABLE - if (highlightsectorcnt > 0 && !hl_all_bunch_sectors_p()) - { - printmessage16("To rotate ext. sectors, all sectors of a bunch must be selected"); - } - else -#endif - if (highlightsectorcnt > 0) - { - int32_t smoothRotation = eitherSHIFT, manualAngle = eitherALT; - vec2_t da = { dax, day }; - - if (manualAngle) - { - tsign = getnumber16("Rotation BUILD angle: ", 0, 2047, 1); - if (tsign==0) - { - printmessage16(" "); - goto rotate_hlsect_out; - } - - printmessage16("Rotated highlighted sectors by %d BUILD degrees", tsign); - tsign &= 2047; - smoothRotation = 1; - } - - get_sectors_center(highlightsector, highlightsectorcnt, &da.x, &da.y); - - if (!smoothRotation) - { - if (gridlock && grid > 0) - locktogrid(&da.x, &da.y); - - tsign *= 512; - } - - - for (i=0; i= 16384) - { - i = pointhighlight-16384; - if (eitherSHIFT) - sprite[i].ang = (sprite[i].ang-tsign)&2047; - else - { - sprite[i].ang = (sprite[i].ang-128*tsign)&2047; - keystatus[sc_Comma] = keystatus[sc_Period] = 0; - } - - g_mouseBits &= ~(16|32); - bstatus &= ~(16|32); - } - } - } - - if (keystatus[sc_ScrollLock]) //Scroll lock (set starting position) - { - startpos = pos; - startang = ang; - startsectnum = cursectnum; - keystatus[sc_ScrollLock] = 0; - asksave = 1; - - printmessage16("Set starting position"); - } -#if 1 - if (keystatus[sc_F5]) //F5 - { - CallExtShowSectorData(0); - } - if (keystatus[sc_F6]) //F6 - { - if (pointhighlight >= 16384) - CallExtShowSpriteData(pointhighlight-16384); - else if (linehighlight >= 0) - CallExtShowWallData(linehighlight); - else - CallExtShowWallData(0); - } - if (keystatus[sc_F7]) //F7 - { - keystatus[sc_F7] = 0; - - for (i=0; i= 16384) - CallExtEditSpriteData(pointhighlight-16384); - else if (linehighlight >= 0) - CallExtEditWallData(linehighlight); - } -#endif - - if (keystatus[sc_H]) //H (Hi 16 bits of tag) - { - keystatus[sc_H] = 0; - if (eitherCTRL) //Ctrl-H - { - pointhighlight = getpointhighlight(mousxplc, mousyplc, pointhighlight); - linehighlight = getlinehighlight(mousxplc, mousyplc, linehighlight, 0); - - if ((pointhighlight&0xc000) == 16384) - { - sprite[pointhighlight&16383].cstat ^= 256; - asksave = 1; - } - else if (linehighlight >= 0) - { - wall[linehighlight].cstat ^= 64; - if ((wall[linehighlight].nextwall >= 0) && !eitherSHIFT) - { - NEXTWALL(linehighlight).cstat &= ~64; - NEXTWALL(linehighlight).cstat |= (wall[linehighlight].cstat&64); - } - asksave = 1; - } - } - else if (eitherALT) //ALT - { - if (pointhighlight >= 16384) - { - i = pointhighlight-16384; - j = taglab_linktags(1, i); - j = 2*(j&2); - Bsprintf(buffer, "Sprite (%d) Hi-tag: ", i); - sprite[i].hitag = getnumber16(buffer, sprite[i].hitag, BTAG_MAX, 0+j); - } - else if (linehighlight >= 0) - { - i = linehighlight; - j = taglab_linktags(1, i); - j = 2*(j&2); - Bsprintf(buffer, "Wall (%d) Hi-tag: ", i); - wall[i].hitag = getnumber16(buffer, wall[i].hitag, BTAG_MAX, 0+j); - } - } - else - { - for (i=0; i= 16384) - { - i = pointhighlight-16384; - Bsprintf(buffer, "Sprite (%d) Status list: ", i); - changespritestat(i, getnumber16(buffer, sprite[i].statnum, MAXSTATUS-1, 0)); - } - } -#ifdef YAX_ENABLE - else if (highlightsectorcnt > 0 && newnumwalls < 0) - { - ////////// YAX ////////// - static const char *cfs[2] = {"ceiling", "floor"}; - - int32_t cf, thez, ulz[2] = {0,0}; - int16_t bn, sandwichbunch=-1; - - if (numyaxbunches==YAX_MAXBUNCHES) - { - message("Bunch limit of %d reached, cannot extend", YAX_MAXBUNCHES); - goto end_yax; - } - - if (highlighted_sectors_components(0,0) != 1) - { - message("Sectors to extend must be in one connected component"); - goto end_yax; - } - - cf = ask_above_or_below(); - if (cf==-1) - goto end_yax; - - thez = SECTORFLD(highlightsector[0],z, cf); - for (i=0; i= 0 && bn!=sandwichbunch) - { - message("When sandwiching extension, must select only sectors of one bunch"); - goto end_yax; - } - - if (bn >= 0) - { - if (cf==YAX_FLOOR) - { - if (sandwichbunch < 0 && i!=0) - { - message("When sandwiching extension, must select only sectors of the bunch"); - goto end_yax; - } - sandwichbunch = bn; - } - else - { - message("Sector %d's %s is already extended", highlightsector[i], cfs[cf]); - goto end_yax; - } - } - - if (SECTORFLD(highlightsector[i],z, cf) != thez) - { - message("Sector %d's %s height doesn't match sector %d's", - highlightsector[i], cfs[cf], highlightsector[0]); - goto end_yax; - } - - if ((sandwichbunch>=0 || highlightsectorcnt>1) && SECTORFLD(highlightsector[i],stat, cf)&2) - { - message("Sector %ss must not be sloped%s", cfs[cf], - sandwichbunch>=0 ? "" : "if extending more than one"); - goto end_yax; - } - } - - if (sandwichbunch >= 0) - { - // cf==YAX_FLOOR here - - int32_t tempz, oldfz, swsecheight = DEFAULT_YAX_HEIGHT/4; - // highest floor z of lower sectors, lowest ceiling z of these sectors - int32_t minfloorz = INT32_MAX, maxceilz = INT32_MIN; - - // some preparation for making the sandwich - if (highlightsectorcnt != yax_numsectsinbunch(sandwichbunch, YAX_FLOOR)) - { - message("When sandwiching extension, must select all sectors of the bunch"); - goto end_yax; - } - - // "for i in sectors of sandwichbunch(floor)" is now the same as - // "for i in highlighted sectors" - - oldfz = sector[highlightsector[0]].floorz; - - // check if enough room in z - for (SECTORS_OF_BUNCH(sandwichbunch, YAX_CEILING, i)) - for (WALLS_OF_SECTOR(i, j)) - { - tempz = getflorzofslope(i, wall[j].x, wall[j].y); - minfloorz = min(minfloorz, tempz); - } - for (SECTORS_OF_BUNCH(sandwichbunch, YAX_FLOOR, i)) - for (WALLS_OF_SECTOR(i, j)) - { - tempz = getceilzofslope(i, wall[j].x, wall[j].y); - maxceilz = max(maxceilz, tempz); - } - - if (minfloorz - maxceilz < 2*swsecheight) - { - message("Too little z headroom for sandwiching, need at least %d", - 2*swsecheight); - goto end_yax; - } - - if (maxceilz >= oldfz || oldfz >= minfloorz) - { - message("Internal error while sandwiching: oldfz out of bounds"); - goto end_yax; - } - - // maxceilz ---| - // ^ | - // ulz[0] ^ - // ^ oldfz - // ulz[1] ^ - // ^ | - // minfloorz ---| - - ulz[0] = (int32_t)(oldfz - swsecheight*((double)(oldfz-maxceilz)/(minfloorz-maxceilz))); - ulz[0] &= ~255; - ulz[1] = ulz[0] + swsecheight; - - if (maxceilz >= ulz[0] || ulz[1] >= minfloorz) - { - message("Too little z headroom for sandwiching"); - goto end_yax; - } - } - - m = numwalls; - Bmemset(visited, 0, sizeof(visited)); - // construct! - for (i=0; i= 0) - { - if (YAX_NEXTWALL(j, cf) < 0) - { - message("Internal error while sandwiching (2): " - "YAX_NEXTWALL(%d, %d)<0!", j, cf); - numwalls = m; - goto end_yax; - } - } - } - for (i=m; i= 0) - { - int16_t oynw = YAX_NEXTWALL(j, cf); - yax_setnextwall(j, cf, i); - yax_setnextwall(i, cf, oynw); - yax_setnextwall(oynw, !cf, i); - } - else - { - yax_setnextwall(j, cf, i); - } - } - - // create new sector based on first highlighted one - i = highlightsector[0]; - Bmemcpy(§or[numsectors], §or[i], sizeof(sectortype)); - sector[numsectors].wallptr = m; - sector[numsectors].wallnum = numwalls-m; - - if (sandwichbunch < 0) - { - if (SECTORFLD(i,stat, cf)&2) - setslope(numsectors, !cf, SECTORFLD(i,heinum, cf)); - else - setslope(numsectors, !cf, 0); - setslope(numsectors, cf, 0); - - SECTORFLD(numsectors,z, !cf) = SECTORFLD(i,z, cf); - SECTORFLD(numsectors,z, cf) = SECTORFLD(i,z, cf) - (1-2*cf)*DEFAULT_YAX_HEIGHT; - } - else - { - for (SECTORS_OF_BUNCH(sandwichbunch, cf, i)) - sector[i].floorz = ulz[0]; - sector[numsectors].ceilingz = ulz[0]; - sector[numsectors].floorz = ulz[1]; - for (SECTORS_OF_BUNCH(sandwichbunch, !cf, i)) - sector[i].ceilingz = ulz[1]; - } - - newnumwalls = numwalls; - numwalls = m; - - SECTORFLD(numsectors,stat, !cf) &= ~1; // no plax - - // restore red walls of the selected sectors - for (i=0; i 0) - { - /// 'punch' wall loop through extension - - int32_t loopstartwall = -1, numloopwalls, cf; - int32_t srcsect, dstsect, ofirstwallofs; - int16_t cb, fb, bunchnum; - - if (EDITING_MAP_P()) - { - printmessage16("Must not be editing map to punch loop"); - goto end_yax; - } - - if (numyaxbunches >= YAX_MAXBUNCHES) - { - message("TROR bunch limit reached, cannot punch loop"); - goto end_yax; - } - - // determine start wall - for (i=0; i0 && wall[j-1].point2==j) - continue; - - if (clockdir(j)==CLOCKDIR_CCW) - { - YAX_SKIPWALL(j); - - if (loopstartwall >= 0) - { - message("Must have a unique highlighted CCW loop to punch"); - goto end_yax; - } - - loopstartwall = j; - } - } - - if (loopstartwall == -1) - { - message("Didn't find any non-grayed out CCW loop start walls"); - goto end_yax; - } - - // determine sector - srcsect = sectorofwall(loopstartwall); - yax_getbunches(srcsect, &cb, &fb); - if (cb < 0 && fb < 0) - { - message("Ceiling or floor must be extended to punch loop"); - goto end_yax; - } - - /// determine c/f - cf = -1; - if (fb < 0) - cf = YAX_CEILING; - else if (cb < 0) - cf = YAX_FLOOR; - - fade_editor_screen(-1); - - // query top/bottom - if (cf == -1) - { - char dachars[2] = {'a', 'z'}; - cf = editor_ask_function("Punch loop above (a) or below (z)?", dachars, 2); - if (cf == -1) - goto end_yax; - } - else - { - // ask even if only one choice -- I find it more - // consistent with 'extend sector' this way - if (-1 == editor_ask_function(cf==YAX_CEILING ? "Punch loop above (a)?" : - "Punch loop below (z)?", cf==YAX_CEILING?"a":"z", 1)) - goto end_yax; - } - - bunchnum = (cf==YAX_CEILING) ? cb : fb; - - // check 1 - j = loopstartwall; // will be real start wall of loop - numloopwalls = 1; // will be number of walls in loop - for (i=wall[loopstartwall].point2; i!=loopstartwall; i=wall[i].point2) - { - numloopwalls++; - if (i < j) - j = i; - - if ((show2dwall[i>>3]&(1<<(i&7)))==0) - { - message("All loop points must be highlighted to punch"); - goto end_yax; - } - - if (yax_getnextwall(loopstartwall, cf) >= 0 || yax_getnextwall(i, cf) >= 0) - { - // somewhat redundant, since it would also be caught by check 2 - message("Loop walls must not already have TROR neighbors"); - goto end_yax; - } - - if (wall[loopstartwall].nextwall < 0 || wall[i].nextwall < 0) - { - message("INTERNAL ERROR: All loop walls are expected to be red"); - goto end_yax; - } - } - loopstartwall = j; - - if (numwalls + 2*numloopwalls > MAXWALLS || numsectors+1 > MAXSECTORS) - { - message("Punching loop through extension would exceed limits"); - goto end_yax; - } - - // get other-side sector, j==loopstartwall - dstsect = yax_getneighborsect(wall[j].x, wall[j].y, srcsect, cf); - if (dstsect < 0) - { - message("Punch loop INTERNAL ERROR: dstsect < 0. Map corrupt?"); - goto end_yax; - } - - // check 2 - i = loopstartwall; - do - { - j = wall[i].point2; - - for (WALLS_OF_SECTOR(dstsect, k)) - { - vec2_t pint; - if (lineintersect2v((vec2_t *)&wall[i], (vec2_t *)&wall[j], - (vec2_t *)&wall[k], (vec2_t *)&POINT2(k), &pint)) - { - message("Loop lines must not intersect any destination sector's walls"); - goto end_yax; - } - } - } - while ((i = j) != loopstartwall); - - // construct new loop and (dummy yet) sector - Bmemcpy(&wall[numwalls], &wall[loopstartwall], numloopwalls*sizeof(walltype)); - newnumwalls = numwalls+numloopwalls; - - for (i=numwalls; iouter nextwall links - for (i=loopstartwall; i= 0 here! Assumption: we collect exactly - // one connected component of sectors - collect_sectors1(collsectlist[0], collsectbitmap[0], - &collnumsects[0], oneinnersect, 0, 0); - - // set new bunchnums - for (i=0; iouter nextwall links - for (i=loopstartwall; i=0) ? "" : " (ERRORS)"); - } - - mkonwinvalid(); - asksave = 1; - - yax_update(0); - yax_updategrays(pos.z); - } -end_yax: ; -#endif - } - - if (highlightsectorcnt < 0) - { - if (((bstatus & 5) == 1 && highlightcnt <= 0) || ((bstatus & 5) == 1 && pointhighlight == -1) || keystatus[sc_RightShift]) //Right shift (point highlighting) - { - if (highlightcnt == 0) - { - int32_t xx[] = { highlight1.x, highlight1.x, searchx, searchx, highlight1.x }; - int32_t yy[] = { highlight1.y, searchy, searchy, highlight1.y, highlight1.y }; - - highlight2.x = searchx; - highlight2.y = searchy; - ydim16 = ydim-STATUS2DSIZ2; - - plotlines2d(xx, yy, 5, -editorcolors[14]); - } - else if (pointhighlight == -1 || keystatus[sc_RightShift]) - { - highlightcnt = 0; - - highlight1.x = searchx; - highlight1.y = searchy; - highlight2.x = searchx; - highlight2.y = searchy; - } - } - else - { - if (highlightcnt == 0) - { - int32_t add=keystatus[sc_Quote], sub=(!add && keystatus[sc_SemiColon]), setop=(add||sub); - - if (!m32_sideview) - { - getpoint(highlight1.x,highlight1.y, &highlight1.x,&highlight1.y); - getpoint(highlight2.x,highlight2.y, &highlight2.x,&highlight2.y); - } - - if (highlight1.x > highlight2.x) - swaplong(&highlight1.x, &highlight2.x); - if (highlight1.y > highlight2.y) - swaplong(&highlight1.y, &highlight2.y); - - // Ctrl+RShift: select all wall-points of highlighted wall's loop: - if (eitherCTRL && highlight1.x==highlight2.x && highlight1.y==highlight2.y) - { - if (!setop) - { - Bmemset(show2dwall, 0, sizeof(show2dwall)); - Bmemset(show2dsprite, 0, sizeof(show2dsprite)); - } - - if (linehighlight >= 0 && linehighlight < MAXWALLS) - { - i = linehighlight; - do - { - if (!sub) - show2dwall[i>>3] |= (1<<(i&7)); - else - show2dwall[i>>3] &= ~(1<<(i&7)); - - // XXX: this selects too many walls, need something more like - // those of dragpoint() -- could be still too many for - // loop punching though - for (j=0; j>3] |= (1<<(j&7)); - else - show2dwall[j>>3] &= ~(1<<(j&7)); - } - - i = wall[i].point2; - } - while (i != linehighlight); - } - - update_highlight(); - } - else - { - int32_t tx, ty, onlySprites=eitherCTRL; - int32_t accum_dragged_verts = 0; - - if (!setop) - { - Bmemset(show2dwall, 0, sizeof(show2dwall)); - Bmemset(show2dsprite, 0, sizeof(show2dsprite)); - } - - for (i=0; i= highlight1.x && tx <= highlight2.x && - ty >= highlight1.y && ty <= highlight2.y) - { - if (!sub) - { - if (numgraysects > 0 || m32_sideview) - { - // Only called to find out which walls would get dragged: - dragpoint(i, wall[i].x, wall[i].y, accum_dragged_verts); - accum_dragged_verts = 1; - } - else - show2dwall[i>>3] |= (1<<(i&7)); - } - else - show2dwall[i>>3] &= ~(1<<(i&7)); - } - } - - if (!sub && (numgraysects > 0 || m32_sideview)) - { - for (i=0; i>3] |= (1<<(i&7)); - } - - for (i=0; i= highlight1.x && tx <= highlight2.x && - ty >= highlight1.y && ty <= highlight2.y) - { - if (!sub) - { - if (sprite[i].sectnum >= 0) // don't allow to select sprites in null space - show2dsprite[i>>3] |= (1<<(i&7)); - } - else - show2dsprite[i>>3] &= ~(1<<(i&7)); - } - } - - update_highlight(); - - for (i=0; i>3; i++) - hlorgraysectbitmap[i] = hlsectorbitmap[i]|graysectbitmap[i]; -#endif - for (i=0; i= 0) -// checksectorpointer(wall[j].nextwall,wall[j].nextsector); - if (wall[j].nextwall < 0) - didmakered |= !!checksectorpointer(j, highlightsector[i]); - - if (!didmakered) - { - updatesectorexclude(wall[j].x, wall[j].y, &tmpsect, hlorgraysectbitmap); - if (tmpsect<0) - hadouterpoint = 1; - } - } -#ifdef YAX_ENABLE - int16_t cb, fb; - - yax_getbunches(highlightsector[i], &cb, &fb); - if (cb>=0 || fb>=0) - { - // TROR stuff in the pasted sectors would really - // complicate things, so don't allow this - didmakered=1; - } -#endif - } - - if (!didmakered && !hadouterpoint && newnumwalls<0) - { - // fade the screen to have the user's attention - fade_editor_screen(-1); - - didmakered |= !ask_if_sure("Insert outer loop and make red walls? (Y/N)", 0); - clearkeys(); - } - - if (!didmakered && !hadouterpoint && newnumwalls<0) - { - int16_t ignore, refsect; - int32_t n; -#ifdef YAX_ENABLE - int16_t refsectbn[2] = {-1,-1}; - int32_t refextcf=-1; -#endif - Bmemset(visited, 0, sizeof(visited)); - - for (i=0; i=0 || refsectbn[1]>=0) - { - if (refsectbn[0]>=0 && refsectbn[1]>=0) - { - // at least one of ceiling/floor must be non-extended - didmakered = 1; - } - else - { - // ... and the other must be non-sloped - refextcf = (refsectbn[1]>=0); - if (SECTORFLD(refsect,stat, !refextcf)&2) - didmakered = 1; - } - } - - if (didmakered) - goto end_autoredwall; - - if (refextcf >= 0) - { - int32_t refz = SECTORFLD(refsect,z, refextcf), tmpsect; - int32_t neededzofs=0; - - // the reference sector is extended on one side - // (given by refextcf) and non-sloped on the other - if (highlighted_sectors_components(0,0) != 1) - { - message("Highlighted sectors must be in one connected component"); - goto end_autoredwall; - } - - for (m=0; m 0) - { - neededzofs += ksgn(neededzofs)*(512<<4); - neededzofs &= ~((256<<4)-1); - if (refextcf==1) - neededzofs *= -1; - for (m=0; m= begwalltomove) - wall[m].nextwall += n; - } -#ifdef YAX_ENABLE - yax_tweakwalls(begwalltomove, n); -#endif - for (m=refsect+1; m 0) - if (onwwasvalid && onextwall[wall[m].nextwall]>=0) - { -//initprintf("%d %d\n", m, onextwall[wall[m].nextwall]); - copy_some_wall_members(m, onextwall[wall[m].nextwall], 0); - } - -#ifndef YAX_ENABLE - message("Attached new inner loop to sector %d", refsect); -#else - { - const char *cfstr[2] = {"ceiling","floor"}; - message("Attached new inner loop to %s%ssector %d", - refextcf>=0 ? cfstr[refextcf] : "", - refextcf>=0 ? "-extended " : "", refsect); - } - - asksave = 1; - - if (refextcf >= 0) - { - yax_update(0); - goto end_autoredwall; - } -#endif - } - } - } -end_autoredwall: - newnumwalls = -1; -#ifdef YAX_ENABLE - yax_updategrays(pos.z); -#endif - } - - highlight1.x = searchx; - highlight1.y = searchy; - highlight2.x = searchx; - highlight2.y = searchy; - highlightsectorcnt = 0; - } - } - else - { - if (highlightsectorcnt == 0) - { - int32_t const add=keystatus[sc_Quote], sub=(!add && keystatus[sc_SemiColon]), setop=(add||sub); - int32_t const pointsel = eitherCTRL; - int32_t tx,ty; -#ifdef YAX_ENABLE - // home: ceilings, end: floors - int32_t fb, bunchsel = keystatus[sc_End] ? 1 : (keystatus[sc_Home] ? 0 : -1); - uint8_t bunchbitmap[YAX_MAXBUNCHES>>3]; - Bmemset(bunchbitmap, 0, sizeof(bunchbitmap)); -#endif - if (!m32_sideview) - { - getpoint(highlight1.x,highlight1.y, &highlight1.x,&highlight1.y); - getpoint(highlight2.x,highlight2.y, &highlight2.x,&highlight2.y); - } - - if (!pointsel) - { - if (highlight1.x > highlight2.x) - swaplong(&highlight1.x, &highlight2.x); - if (highlight1.y > highlight2.y) - swaplong(&highlight1.y, &highlight2.y); - } - - if (!setop) - Bmemset(hlsectorbitmap, 0, sizeof(hlsectorbitmap)); - - for (i=0; i highlight2.x) bad = 1; - if (ty < highlight1.y || ty > highlight2.y) bad = 1; - if (bad == 1) break; - } - } - - if (bad == 0) - { -#ifdef YAX_ENABLE - if (bunchsel!=-1 && (fb = yax_getbunch(i, YAX_FLOOR))>=0) - { - if ((sub || (graysectbitmap[i>>3]&(1<<(i&7)))==0) && - (bunchbitmap[fb>>3]&(1<<(fb&7)))==0) - { - bunchbitmap[fb>>3] |= (1<<(fb&7)); - for (SECTORS_OF_BUNCH(fb, bunchsel, j)) - handlesecthighlight1(j, sub, 1); - } - } - else -#endif - handlesecthighlight1(i, sub, eitherSHIFT); - } - } - - update_highlightsector(); - ovh_whiteoutgrab(0); - } - } - } - - if (((bstatus&1) < (oldmousebstatus&1)) && highlightsectorcnt < 0) //after dragging - { - - // restorestat is set to 2 whenever the drawn walls should NOT be - // restored afterwards - - int32_t err = backup_drawn_walls(0); - - if (err) - { - message("Error backing up drawn walls (code %d)!", err); - backup_drawn_walls(1); - goto end_after_dragging; - } - - j = 1; - for (i=0; i= 0) - { - k = getlenbyrep(olen[i], wall[nw].xrepeat); - fixxrepeat(nw, k); - } - } - } - } - } - else if ((pointhighlight&0xc000) == 16384) - { - dax = sprite[pointhighlight&16383].x; - day = sprite[pointhighlight&16383].y; - } - - dragwall[0] = dragwall[1] = -1; - - maybedeletewalls(dax, day); - } -end_after_dragging: - if ((bstatus&1) > 0) //drag points - { - if (highlightsectorcnt > 0) - { - if ((bstatus&1) > (oldmousebstatus&1)) - { - newnumwalls = -1; - sectorhighlightstat = -1; - -// updatesector(mousxplc,mousyplc,&cursectorhighlight); - cursectorhighlight = -1; - for (i=0; i= 0 && cursectorhighlight < numsectors) - { - //You clicked inside one of the flashing sectors! - sectorhighlightstat = 1; - - dax = mousxplc; - day = mousyplc; - if (gridlock && grid > 0) - locktogrid(&dax, &day); - - sectorhighlightx = dax; - sectorhighlighty = day; - } - } - else if (sectorhighlightstat == 1) - { - dax = mousxplc; - day = mousyplc; - if (gridlock && grid > 0) - locktogrid(&dax, &day); - - dax -= sectorhighlightx; - day -= sectorhighlighty; - sectorhighlightx += dax; - sectorhighlighty += day; -#ifdef YAX_ENABLE - if (!hl_all_bunch_sectors_p()) - printmessage16("To drag extended sectors, all sectors of a bunch must be selected"); - else -#endif - for (i=0; i=0; j=nextspritesect[j]) - { sprite[j].x += dax; sprite[j].y += day; } - } - - //for(i=0;i= 0) - // checksectorpointer(wall[j].nextwall,wall[j].nextsector); - // checksectorpointer((short)j,highlightsector[i]); - // } - //} - asksave = 1; - } - - } - else //if (highlightsectorcnt <= 0) - { - if ((bstatus&1) > (oldmousebstatus&1)) - { - pointhighlight = getpointhighlight(mousxplc, mousyplc, pointhighlight); - - if (pointhighlight >= 0 && (pointhighlight&0xc000)==0) - { - dragwall[0] = lastwall(pointhighlight); - dragwall[1] = pointhighlight; - olen[0] = wallength(dragwall[0]); - olen[1] = wallength(dragwall[1]); - } - } - - if (pointhighlight >= 0 && (!m32_sideview || m32_sideelev>=32)) - { - if (m32_sideview) - { - int32_t dz; - if (pointhighlight>=16384) - dz = sprite[pointhighlight&16383].z - pos.z; - else - dz = getflorzofslope(sectorofwall(pointhighlight), - wall[pointhighlight].x, wall[pointhighlight].y) - pos.z; - getinvdisplacement(&dax,&day, -dz); - dax += mousxplc; - day += mousyplc; - } - else - { - dax = mousxplc; - day = mousyplc; - } - - if (gridlock && grid > 0) - locktogrid(&dax, &day); - - j = 1; - if (highlightcnt > 0) - for (i=0; ix += dax; - daspr->y += day; - setspritez(daspr-sprite, (const vec3_t *)daspr); - } - } - } - else - { - if ((pointhighlight&0xc000) == 0) - { - if (newnumwalls >= numwalls && - wall[pointhighlight].x==firstx && wall[pointhighlight].y==firsty) - { - printmessage16("Can't drag point where drawing started."); - goto end_point_dragging; - } - - dragpoint(pointhighlight,dax,day,2); - wall[lastwall(pointhighlight)].cstat |= (1<<14); - } - else if ((pointhighlight&0xc000) == 16384) - { - int32_t daspr=pointhighlight&16383; - int16_t osec=sprite[daspr].sectnum, nsec=osec; - vec3_t vec, ovec; - - Bmemcpy(&ovec, (vec3_t *)&sprite[daspr], sizeof(vec3_t)); - vec.x = dax; - vec.y = day; - vec.z = sprite[daspr].z; - if (setspritez(daspr, &vec) == -1 && osec>=0) - { - updatesectorbreadth(dax, day, &nsec); - - if (nsec >= 0) - { - sprite[daspr].x = dax; - sprite[daspr].y = day; - // z updating is after we released the mouse button - if (sprite[daspr].sectnum != nsec) - changespritesect(daspr, nsec); - } - else - Bmemcpy(&sprite[daspr], &ovec, sizeof(vec3_t)); - } - } - } - - asksave = 1; - } - } - } - else //if ((bstatus&1) == 0) - { - pointhighlight = getpointhighlight(mousxplc, mousyplc, pointhighlight); - sectorhighlightstat = -1; - } -end_point_dragging: - - if (bstatus&(2) && (!(bstatus&5) || pointhighlight > 0 || highlightcnt > 0 || highlightsectorcnt > 0)) // change arrow position - { - if (eitherCTRL) - { - int16_t cursectornum; - - for (cursectornum=0; cursectornum= 16384) - CallExtEditSpriteData(pointhighlight-16384); - else if ((linehighlight >= 0) && ((bstatus&1) || sectorofwall(linehighlight) == cursectornum)) - CallExtEditWallData(linehighlight); - else if (cursectornum >= 0) - CallExtEditSectorData(cursectornum); - } - - bstatus &= ~2; - } - else - { - if (m32_sideview && (bstatus&4)) - { - pos.z += divscale18(searchy-midydim16,zoom); - getpoint(searchx,midydim16, &pos.x, &pos.y); -#ifdef YAX_ENABLE - yax_updategrays(pos.z); -#endif - } - else - { - pos.x = mousxplc; - pos.y = mousyplc; - } - - if (m32_sideview) - { - int32_t opat=drawlinepat; - - y1 = INT32_MAX; - - for (i=0; i 0) - updatesectorz(pos.x,pos.y,pos.z,&cursectnum); - - if (circlewall != -1 && (keystatus[sc_kpad_Minus] || ((bstatus&32) && !eitherCTRL))) // -, mousewheel down - { - if (circlepoints > 1) - circlepoints--; - keystatus[sc_kpad_Minus] = 0; - g_mouseBits &= ~32; - bstatus &= ~32; - } - if (circlewall != -1 && (keystatus[sc_kpad_Plus] || ((bstatus&16) && !eitherCTRL))) // +, mousewheel up - { - if (circlepoints < 63) - circlepoints++; - keystatus[sc_kpad_Plus] = 0; - g_mouseBits &= ~16; - bstatus &= ~16; - } - - if (keystatus[sc_F3]) // F3 - { - keystatus[sc_F3]=0; - if (!m32_sideview && EDITING_MAP_P()) - message("Must not be editing map while switching to side view mode."); - else - { - m32_sideview = !m32_sideview; - printmessage16("Side view %s", m32_sideview?"enabled":"disabled"); - } - } - - if (m32_sideview && (keystatus[sc_Q] || keystatus[sc_W])) - { - if (eitherCTRL) - { - if (m32_sideang&63) - { - m32_sideang += (1-2*keystatus[sc_Q])*(1-2*sideview_reversehrot)*32; - m32_sideang &= (2047&~63); - } - else - { - m32_sideang += (1-2*keystatus[sc_Q])*(1-2*sideview_reversehrot)*64; - m32_sideang &= 2047; - } - - keystatus[sc_Q] = keystatus[sc_W] = 0; - } - else - { - m32_sideang += (1-2*keystatus[sc_Q])*(1-2*sideview_reversehrot)*synctics<<(eitherSHIFT*2); - m32_sideang &= 2047; - } - _printmessage16("Sideview angle: %d", (int32_t)m32_sideang); - } - - if (m32_sideview && (eitherSHIFT || (bstatus&(16|32)))) - { - if ((DOWN_BK(MOVEUP) || (bstatus&16)) && m32_sideelev < 512) - { - if (DOWN_BK(MOVEUP)) - m32_sideelev += synctics<<1; - if (bstatus&16) - m32_sideelev += 4<<1; - - if (m32_sideelev > 512) - m32_sideelev = 512; - _printmessage16("Sideview elevation: %d", m32_sideelev); - } - if ((DOWN_BK(MOVEDOWN) || (bstatus&32)) && m32_sideelev > 0) - { - if (DOWN_BK(MOVEDOWN)) - m32_sideelev -= synctics<<1; - if (bstatus&32) - m32_sideelev -= 4<<1; - - if (m32_sideelev < 0) - m32_sideelev = 0; - _printmessage16("Sideview elevation: %d", m32_sideelev); - } - } - else - { - int32_t didzoom=0; - - if ((DOWN_BK(MOVEUP) || (bstatus&16)) && zoom < 39936) - { - if (DOWN_BK(MOVEUP)) - { - ztarget += (synctics*(ztarget>>4))>>(eitherSHIFT<<1); - - if (zoom < 64) - ztarget += (synctics*(ztarget>>4)) * (eitherSHIFT); - } - if (bstatus&16) - ztarget += 4*(ztarget>>4); - - if (zoom < 24) zoom += 2; - didzoom = 1; - } - if ((DOWN_BK(MOVEDOWN) || (bstatus&32)) && zoom > 16) - { - if (DOWN_BK(MOVEDOWN)) - { - ztarget -= (synctics*(ztarget>>4))>>(eitherSHIFT<<1); - - if (zoom < 64) - ztarget -= (synctics * (ztarget >> 4)) * (eitherSHIFT); - } - if (bstatus&32) - ztarget -= 4*(ztarget>>4); - - didzoom = 1; - } - - if (didzoom) - { - if (eitherALT) - { - searchx = halfxdim16; - searchy = midydim16; - pos.x = mousxplc; - pos.y = mousyplc; - } - ztarget = clamp(ztarget, 16, 39936); - - _printmessage16("Zoom: %d",ztarget); - } - } - - - if (keystatus[sc_G]) // G (grid on/off) - { - keystatus[sc_G] = 0; - grid++; - if (grid == 7) grid = 0; - } - if (keystatus[sc_L]) // L (grid lock) - { - keystatus[sc_L] = 0; - - if (eitherSHIFT) - { - searchlock = 1-searchlock; - silentmessage("Selection lock %s", searchlock ? "on" : "off"); - } - else - { - gridlock = !gridlock; - silentmessage("Grid locking %s", gridlock ? "on" : "off"); - } - } - - if (keystatus[sc_J]) // J (join sectors) - { - keystatus[sc_J] = 0; - - if (newnumwalls >= 0) - { - printmessage16("Can't join sectors while editing."); - goto end_join_sectors; - } - -#ifdef YAX_ENABLE - if (highlightsectorcnt > 0 && eitherCTRL) - { - // [component][ceiling(0) or floor(1)] - // compstat: &1: "has extension", &2: "differ in z", &4: "sloped", -1: "uninited" - int32_t cf, comp, compstat[2][2] = {{-1,-1},{-1,-1}}, compcfz[2][2]; - - // joinstat: join what to what? - // &1: ceil(comp 0) <-> flor(comp 1), &2: flor(comp 0) <-> ceil(comp 1) - // (doesn't yet say which is stationary) - // movestat: which component can be displaced? - // &1: first, &2: second - int32_t askres, joinstat, needsdisp, moveonwp; - int32_t movestat, dx=0,dy=0,dz, delayerr=0; - - int32_t numouterwalls[2] = {0,0}, numowals; - static int16_t outerwall[2][MAXWALLS]; - const uwalltype *wal0, *wal1, *wal0p2, *wal1p2; - - // join sector ceilings/floors to a new bunch - if (numyaxbunches==YAX_MAXBUNCHES) - { - message("Bunch limit of %d reached, cannot join", YAX_MAXBUNCHES); - goto end_join_sectors; - } - - // first, see whether we have exactly two connected components - // wrt wall[].nextsector - if (highlighted_sectors_components(0,0) != 2) - { - message("Sectors must be partitioned in two components to join"); - goto end_join_sectors; - } - - for (k=0; k>3]&(1<<(j&7))); - - for (cf=0; cf<2; cf++) - { - if (compstat[comp][cf]==-1) - { - compstat[comp][cf] = 0; - compcfz[comp][cf] = SECTORFLD(j,z, cf); - } - - if (yax_getbunch(j, cf)>=0) - compstat[comp][cf] |= 1; - if (SECTORFLD(j,z, cf) != compcfz[comp][cf]) - compstat[comp][cf] |= 2; - if (SECTORFLD(j,stat, cf)&2) - compstat[comp][cf] |= 4; - - compcfz[comp][cf] = SECTORFLD(j,z, cf); - } - } - - // check for consistency - joinstat = 0; - if (!compstat[0][YAX_CEILING] && !compstat[1][YAX_FLOOR]) - joinstat |= 1; - if (!compstat[0][YAX_FLOOR] && !compstat[1][YAX_CEILING]) - joinstat |= 2; - - if (joinstat==0) - { - message("No consistent joining combination found"); - OSD_Printf("comp0: c=%d,f=%d; comp1: c=%d,f=%d (1:extended, 2:z mismatch, 4:sloped)\n", - compstat[0][YAX_CEILING], compstat[0][YAX_FLOOR], - compstat[1][YAX_CEILING], compstat[1][YAX_FLOOR]); - //for (i=0; i<2; i++) for (j=0; j<2; j++) message("%d", compstat[i][j]); - goto end_join_sectors; - } - if (joinstat==3) - { - if (compcfz[0][YAX_CEILING] != compstat[1][YAX_FLOOR]) - joinstat &= 1; - if (compcfz[0][YAX_CEILING] != compstat[1][YAX_FLOOR]) - joinstat &= 2; - - if (joinstat == 0) - joinstat = 3; // we couldn't disambiguate - } - - for (comp=0; comp<2; comp++) - for (k=0; k0 && numouterwalls[1]>0) - delayerr = 1; - else - goto end_join_sectors; - } - numowals = min(numouterwalls[0], numouterwalls[1]); - - // now sort outer walls 'geometrically' - for (comp=0; comp<2; comp++) - sort_walls_geometrically(outerwall[comp], numouterwalls[comp]); - - for (k=0; kpoint2]; - wal1p2 = (uwalltype *)&wall[wal1->point2]; - - if (k==0) - { - dx = wal1->x - wal0->x; - dy = wal1->y - wal0->y; - } - - if (wal1->x - wal0->x != dx || wal1->y - wal0->y != dy || - wal1p2->x - wal0p2->x != dx || wal1p2->y - wal0p2->y != dy) - { - pos.x = wal0->x + (wal0p2->x - wal0->x)/4; - pos.y = wal0->y + (wal0p2->y - wal0->y)/4; - pos.z = getflorzofslope(sectorofwall(wal0-(uwalltype *)wall), pos.x, pos.y); - - if (!delayerr) - message("Outer wall coordinates must coincide for both components"); - OSD_Printf("wal0:%d (%d,%d)--(%d,%d)\n",(int)(wal0-(uwalltype *)wall), - wal0->x,wal0->y, wal0p2->x,wal0p2->y); - OSD_Printf("wal1:%d (%d,%d)--(%d,%d)\n",(int)(wal1-(uwalltype *)wall), - wal1->x,wal1->y, wal1p2->x,wal1p2->y); - - goto end_join_sectors; - } - } - - if (delayerr) - goto end_join_sectors; - - if (joinstat == 3) - { - char askchars[2] = {'1', 'v'}; - - // now is a good time to ask... - for (comp=0; comp<2; comp++) - for (k=0; kflor(1), 1:ceil(1)<->flor(0) - - dz = compcfz[1][!joinstat] - compcfz[0][joinstat]; - needsdisp = (dx || dy || dz); - - if (needsdisp) - { - // a component is more likely to be displaced if it's not - // extended on the non-joining side - movestat = (!(compstat[0][!joinstat]&1)) | ((!(compstat[1][joinstat]&1))<<1); - if (!movestat) - { - movestat = 3; -// message("Internal error while TROR-joining: movestat inconsistent!"); -// goto end_join_sectors; - } - - if (movestat==3) - { - char askchars[2] = {'y', 'b'}; - - for (comp=0; comp<2; comp++) - for (k=0; k>3]; - int16_t ocollnumsects=collnumsects[movestat], tmpsect; - - Bmemcpy(ocollsectlist, collsectlist[movestat], ocollnumsects*sizeof(int16_t)); - Bmemset(tcollbitmap, 0, sizeof(tcollbitmap)); - - for (k=0; k>3; m++) - tcollbitmap[m] |= collsectbitmap[0][m]; - moveonwp = 1; - } - - if (moveonwp) - { - int32_t movecol = movestat==0 ? 159 : editorcolors[11]; - for (i=0; i>3]&(1<<(i&7))) - fillsector_notrans(i, editorcolors[12]); - - fade_editor_screen(editorcolors[12] | (movecol<<8)); - moveonwp = ask_if_sure("Also move formerly wall-connected sectors?",0); - if (moveonwp==-1) - goto end_join_sectors; - } - } - - // now need to collect them wrt. the nextsector but also - // the yax-nextsector relation - if (highlighted_sectors_components(1,moveonwp) != 2) - { - message("Must not have TROR connections between the two components"); - goto end_join_sectors; - } - - // displace! - for (k=0; k=0; j=nextspritesect[j]) - { - sprite[j].x += dx; - sprite[j].y += dy; - sprite[j].z += dz; - } - } - - // restore old components, i.e. only the bunch sectors - highlighted_sectors_components(0,0); - - } // end if (needsdisp) - - /*** construct the YAX connection! ***/ - for (comp=0; comp<2; comp++) - { - // walls - for (j=0; j 1) - { - if (!bakframe_fillandfade(&origframe, i, "Use this as first joining sector? (Y/N)")) - continue; - } - - joinsector[0] = i; - printmessage16("Join sector - press J again on sector to join with."); - break; - } - } - - Bfree(origframe); - } - else - { - char *origframe = NULL; - int32_t numjoincandidates = 0; - - joinsector[1] = -1; - - for (i=0; i 1) - { - if (!bakframe_fillandfade(&origframe, i, "Use this as second joining sector? (Y/N)")) - continue; - - DO_FREE_AND_NULL(origframe); - } - - joinsector[1] = i; - - const int s1to0wall = find_nextwall(i, joinsector[0]); - const int s0to1wall = s1to0wall == -1 ? -1 : wall[s1to0wall].nextwall; -#ifdef YAX_ENABLE - int16_t jbn[2][2]; // [join index][c/f] - - for (k=0; k<2; k++) - yax_getbunches(joinsector[k], &jbn[k][YAX_CEILING], &jbn[k][YAX_FLOOR]); -#endif - // pressing J into the same sector is the same as saying 'no' - // v----------------v - if (s1to0wall == -1 && i != joinsector[0]) - { - int32_t good = 1; -#ifdef YAX_ENABLE - if (jbn[0][0]>=0 || jbn[0][1]>=0 || jbn[1][0]>=0 || jbn[1][1]>=0) - { - message("Joining non-adjacent extended sectors not allowed!"); - good = 0; - } -#endif - if (!m32_script_expertmode) - { - message("Joining non-adjacent disabled in non-expert mode"); - good = 0; - } - - if (!good) - { - joinsector[0] = joinsector[1] = -1; - goto end_join_sectors; - } - - { - fillsector_notrans(i, editorcolors[9]); - fillsector_notrans(joinsector[0], editorcolors[9]); - fade_editor_screen(editorcolors[9]); - - if (!ask_if_sure("Really join non-adjacent sectors? (Y/N)", 0)) - joinsector[1] = joinsector[0]; - } - } -#ifdef YAX_ENABLE - // unequal bunchnums (bitmap): 1:above, 2:below - int uneqbn = - (jbn[0][YAX_CEILING] != jbn[1][YAX_CEILING]) | - ((jbn[0][YAX_FLOOR] != jbn[1][YAX_FLOOR])<<1); - - if (uneqbn) - { - const int32_t cf=YAX_FLOOR; - int32_t whybad=0; - - if (uneqbn == 1) - { - OSD_Printf("Can't join two sectors with different ceiling bunchnums." - " To make them equal, join their upper neighbor's floors.\n"); - printmessage16("Can't join two sectors with different ceiling bunchnums. See OSD"); - joinsector[0] = joinsector[1] = -1; - goto end_join_sectors; - } - if (s0to1wall < 0) - { - printmessage16("INTERNAL ERROR: nextwalls inconsistent!"); - joinsector[0] = joinsector[1] = -1; - goto end_join_sectors; - } - - // both must be extended - if (jbn[0][cf]<0 || jbn[1][cf]<0) - uneqbn &= ~(1<=0 && jbn[1][cf]<0) - { - // 1st join sector extended, 2nd not... let's see - // if the latter is inner to the former one - - int32_t lowerstartsec = yax_vnextsec(s0to1wall, cf); - - m = (lowerstartsec < 0)<<1; - for (WALLS_OF_SECTOR(joinsector[1], k)) - { - if (m) break; - - m |= (wall[k].nextsector>=0 && wall[k].nextsector != joinsector[0]); - m |= (wall[k].nextwall>=0 && yax_vnextsec(wall[k].nextwall, cf)!=lowerstartsec)<<1; - } - - if (m==0) - { - yax_setbunch(joinsector[1], YAX_FLOOR, jbn[0][cf]); - yax_update(0); - yax_updategrays(pos.z); - asksave = 1; - - printmessage16("Added sector %d's floor to bunch %d", - joinsector[1], jbn[0][cf]); - } - else - { - if (m&1) - { - message("Can't add sector %d's floor to bunch %d: not inner to sector %d", - joinsector[1], jbn[0][cf], joinsector[0]); - } - else // if (m&2) - { - message("Can't add sector %d's floor to bunch %d: must have lower neighbor", - joinsector[1], jbn[0][cf]); - } - } - } - else -#endif - { - if (whybad&1) - message("Can't make floor bunchnums equal: both floors must be extended"); - else if (whybad&2) - message("Can't make floor bunchnums equal: both floors must be non-sloped"); - else if (whybad&4) - message("Can't make floor bunchnums equal: both floors must have equal height"); - else if (whybad&8) - message("Can't make floor bunchnums equal: INTERNAL ERROR"); - else if (whybad&16) - message("Can't make floor bunchnums equal: lower neighbors must be linked"); - } - } - else - { - int32_t vcf, newbn, ynw; - - // we're good to go for making floor bunchnums equal - for (SECTORS_OF_BUNCH(jbn[1][cf], YAX_FLOOR, k)) - yax_setbunch(k, YAX_FLOOR, jbn[0][cf]); - for (SECTORS_OF_BUNCH(jbn[1][cf], YAX_CEILING, k)) - yax_setbunch(k, YAX_CEILING, jbn[0][cf]); - - yax_update(0); - // now we can iterate the sectors with the new bunchnums - newbn = yax_getbunch(joinsector[0], cf); - - // clear all yax-nextwall links on walls that are inside the bunch - for (vcf=0; vcf<2; vcf++) - for (SECTORS_OF_BUNCH(newbn, vcf, k)) - for (WALLS_OF_SECTOR(k, m)) - { - ynw = yax_getnextwall(m, vcf); - if (ynw < 0 || wall[m].nextsector < 0) - continue; - - if (yax_getbunch(wall[m].nextsector, vcf) == newbn) - { - yax_setnextwall(ynw, !vcf, -1); - yax_setnextwall(m, vcf, -1); - } - } - - // shouldn't be needed again for the editor, but can't harm either: - yax_update(0); - yax_updategrays(pos.z); - - printmessage16("Made sector %d and %d floor bunchnums equal", - joinsector[0], joinsector[1]); - asksave = 1; - } - - joinsector[0] = joinsector[1] = -1; - goto end_join_sectors; - } -#endif - break; - } - } - - if (joinsector[1] < 0 || joinsector[0] == joinsector[1]) - { - printmessage16("No sectors joined."); - joinsector[0] = -1; - goto end_join_sectors; - } - - - for (i=0; i= MAXWALLS + M32_FIXME_WALLS) - { - message("Joining sectors failed: not enough space beyond wall[]"); - joinsector[0] = -1; - newnumwalls = -1; - - for (i=0; i0 && ((wall[i].cstat & (1<<14))==0) - && (wall[i].nextsector != joinsector[1-joink])); - - wall[newnumwalls-1].point2 = m; - - if (loopnum==0) - { - message("internal error while joining sectors: infloop!"); - newnumwalls = -1; - } - } - } - - if (newnumwalls > numwalls) - { - Bmemcpy(§or[numsectors], §or[joinsector[0]], sizeof(sectortype)); - sector[numsectors].wallptr = numwalls; - sector[numsectors].wallnum = newnumwalls-numwalls; - - //fix sprites - for (i=0; i<2; i++) - { - j = headspritesect[joinsector[i]]; - while (j != -1) - { - k = nextspritesect[j]; - changespritesect(j, numsectors); - j = k; - } - } - - numsectors++; - - for (i=numwalls; i= 0) - { - NEXTWALL(i).nextwall = i; - NEXTWALL(i).nextsector = numsectors-1; - } - } - - numwalls = newnumwalls; - newnumwalls = -1; - - // clean out nextwall links for deletesector - for (k=0; k<2; k++) - for (WALLS_OF_SECTOR(joinsector[k], j)) - { - wall[j].nextwall = wall[j].nextsector = -1; -#ifdef YAX_ENABLE - yax_setnextwall(j, YAX_CEILING, -1); - yax_setnextwall(j, YAX_FLOOR, -1); -#endif - } - - deletesector(joinsector[0]); - if (joinsector[0] < joinsector[1]) - joinsector[1]--; - deletesector(joinsector[1]); - - printmessage16("Sectors joined."); - mkonwinvalid(); - asksave = 1; -#ifdef YAX_ENABLE - yax_update(0); - yax_updategrays(pos.z); -#endif - } - - joinsector[0] = -1; - } - } -end_join_sectors: - -// PK - for (i=0x02; i<=0x0b; i++) // keys '1' to '0' on the upper row - if (keystatus[i]) - { - prefixarg = prefixtiles[i-2]; - break; - } - - if (eitherALT && keystatus[sc_S]) //ALT-S - { - keystatus[sc_S] = 0; - - if (linehighlight >= 0 && wall[linehighlight].nextwall == -1) - { - newnumwalls = whitelinescan(sectorofwall(linehighlight), linehighlight); - if (newnumwalls < numwalls) - { - printmessage16("Can't make a sector out there."); - newnumwalls = -1; - } - else if (newnumwalls > MAXWALLS) - { - printmessage16("Making new sector from inner loop would exceed wall limits."); - newnumwalls = -1; - } - else - { - for (i=numwalls; i= 0) - { - dax = mousxplc; - day = mousyplc; - if (gridlock && grid > 0) - locktogrid(&dax, &day); - - i = insert_sprite_common(sucksect, dax, day); - - if (i < 0) - printmessage16("Couldn't insert sprite."); - else - { - sprite[i].z = getflorzofslope(sucksect,dax,day); -// PK - if (prefixarg) - { - sprite[i].picnum = prefixarg; - sprite[i].xrepeat = sprite[i].yrepeat = 48; - prefixarg = 0; - } - else handle_sprite_in_clipboard(i); - - if (tilesiz[sprite[i].picnum].y >= 32) - sprite[i].cstat |= 1; - - correct_sprite_yoffset(i); - - printmessage16("Sprite inserted."); - - asksave = 1; - - VM_OnEvent(EVENT_INSERTSPRITE2D, i); - } - } - } - - if (keystatus[sc_C]) // C (make circle of points) - { - if (highlightsectorcnt > 0) - duplicate_selected_sectors(); - else if (highlightcnt > 0) - duplicate_selected_sprites(); - else if (circlewall >= 0) - { - circlewall = -1; - } - else if (!m32_sideview) - { - if (linehighlight >= 0) - { -#if 0 //def YAX_ENABLE - j = linehighlight; - - if (yax_islockedwall(j) || - (wall[j].nextwall >= 0 && yax_islockedwall(wall[j].nextwall))) - printmessage16("Can't make circle in wall constrained by sector extension."); - else -#endif - circlewall = linehighlight; - } - } - - keystatus[sc_C] = 0; - } - - bad = keystatus[sc_Space] && (!m32_sideview || m32_sideelev == 512); //Gotta do this to save lots of 3 spaces! - - if (keystatus[sc_Space] && !bad) - message("Unable to create sectors in angled sideview mode."); - - if (circlewall >= 0) - { - int32_t tempint1, tempint2; - - x1 = wall[circlewall].x; - y1 = wall[circlewall].y; - x2 = POINT2(circlewall).x; - y2 = POINT2(circlewall).y; - x3 = mousxplc; - y3 = mousyplc; - adjustmark(&x3,&y3,newnumwalls); - tempint1 = dmulscale4(x3-x2,x1-x3, y1-y3,y3-y2); - tempint2 = dmulscale4(y1-y2,x1-x3, y1-y3,x2-x1); - - if (tempint2 != 0) - { - int32_t goodtogo, err=0; - - const int32_t centerx = ((x1+x2) + scale(y1-y2,tempint1,tempint2))>>1; - const int32_t centery = ((y1+y2) + scale(x2-x1,tempint1,tempint2))>>1; - const int32_t circlerad = ksqrt(dmulscale4(centerx-x1,centerx-x1, centery-y1,centery-y1))<<2; - - const int32_t circleang1 = getangle(x1-centerx,y1-centery); - const int32_t circleang2 = getangle(x2-centerx,y2-centery); - - const int32_t redw = (int32_t)(wall[circlewall].nextwall >= 0); - int32_t insdpoints = 0; - - draw_cross(centerx, centery, 2, editorcolors[14]); - - k = ((circleang2-circleang1)&2047); - if (mulscale4(x3-x1,y2-y1) < mulscale4(x2-x1,y3-y1)) - { - k = -((circleang1-circleang2)&2047); - } - - // XXX: Still too permissive for TROR insertion - goodtogo = (numwalls+(1+redw)*circlepoints <= MAXWALLS); - - if (bad > 0 && goodtogo) - { - err = backup_drawn_walls(0); - - if (err) - { - message("Error backing up drawn walls (code %d)!", err); - goodtogo = 0; - } - } - - for (i=circlepoints; i>0; i--) - { - const int32_t ps = 2; - - j = (circleang1 + scale(i,k,circlepoints+1))&2047; - dax = centerx + mulscale14(sintable[(j+512)&2047],circlerad); - day = centery + mulscale14(sintable[j],circlerad); - - inpclamp(&dax, -editorgridextent, editorgridextent); - inpclamp(&day, -editorgridextent, editorgridextent); - - if (bad > 0 && goodtogo) - { - int32_t inspts = M32_InsertPoint(circlewall, dax,day, -1, &circlewall); - - if (inspts==0) - { - message("Wall limit exceeded while inserting points."); - goto end_circle_insertion; - } - else if (inspts >= 65536) - { - message("ERR: Inserted %d points for constr. wall (exp. %d; %d already ins'd)", - inspts&65535, inspts>>16, insdpoints); - goto end_circle_insertion; - } - - insdpoints += inspts; - } - - draw_square(dax, day, ps, editorcolors[14]); - } - - if (bad > 0 && goodtogo) - backup_drawn_walls(1); - - if (bad > 0) - { - if (goodtogo) - { - asksave = 1; - printmessage16("Circle points inserted."); -end_circle_insertion: - circlewall = -1; - mkonwinvalid(); - } - else - printmessage16("Inserting circle points would exceed wall limit."); - } - } - - bad = 0; - keystatus[sc_Space] = 0; - } - - if (bad > 0) //Space bar test - { - keystatus[sc_Space] = 0; - adjustmark(&mousxplc,&mousyplc,newnumwalls); - - if (checkautoinsert(mousxplc,mousyplc,newnumwalls) == 1) - { - printmessage16("You must insert a point there first."); - bad = 0; - } - } - - if (bad > 0) //Space - { - if (newnumwalls < numwalls) // starting wall drawing - { - if (numwalls >= MAXWALLS-1) - { - // whatever we do, we will need at least two new walls - printmessage16("Can't start sector drawing: wall limit reached."); - goto end_space_handling; - } - - if (numsectors >= MAXSECTORS) - { - printmessage16("Can't start sector drawing: sector limit reached."); - goto end_space_handling; - } - - firstx = mousxplc; - firsty = mousyplc; //Make first point - newnumwalls = numwalls; - ovh.suckwall = -1; - ovh.split = 0; - - init_new_wall1(&ovh.suckwall, mousxplc, mousyplc); - - printmessage16("Sector drawing started."); - } - else // 2nd point and up... - { - //if not back to first point - if (firstx != mousxplc || firsty != mousyplc) //nextpoint - { - if (newnumwalls>=MAXWALLS) - { - printmessage16("Inserting another point would exceed wall limit."); - goto end_space_handling; - } - - j = 0; - for (i=numwalls; i>1; - day = (wall[numwalls].y+mousyplc)>>1; - - for (i=0; i=0 && (POINT2(k).x != mousxplc || POINT2(k).y != mousyplc)) - if (wall[lastwall(k)].x != mousxplc || wall[lastwall(k)].y != mousyplc) - { - ovh.split = 1; - ovh.splitsect = i; - ovh.splitstartwall = m; - break; - } - } - } - - //make new point - - //make sure not drawing over old red line - bad = 0; - for (i=0; i= 0) - { - int32_t lastwalx = wall[newnumwalls-1].x; - int32_t lastwaly = wall[newnumwalls-1].y; - - YAX_SKIPWALL(wall[i].nextwall); - - if (wall[i].x == mousxplc && wall[i].y == mousyplc) - if (POINT2(i).x == lastwalx && POINT2(i).y == lastwaly) - bad = 1; - if (wall[i].x == lastwalx && wall[i].y == lastwaly) - if (POINT2(i).x == mousxplc && POINT2(i).y == mousyplc) - bad = 1; - } - } - - if (bad == 0) - { - init_new_wall1(&ovh.suckwall, mousxplc, mousyplc); - } - else - { - printmessage16("You can't draw new lines over red lines."); - goto end_space_handling; - } - } - } - - ////////// newnumwalls is at most MAXWALLS here ////////// - - //if not split and back to first point - if (!ovh.split && newnumwalls >= numwalls+3 - && firstx==mousxplc && firsty==mousyplc) - { - wall[newnumwalls-1].point2 = numwalls; - - if (ovh.suckwall == -1) //if no connections to other sectors - { - k = -1; - for (i=0; i 0) - printmessage16("Added inner loop to sector %d and made new inner sector", k); - else -#endif - printmessage16("Added inner loop to sector %d", k); - mkonwinvalid(); - asksave = 1; - } - } - else // if connected to at least one other sector - { - int16_t sucksect; - - //add new sector with connections - - if (clockdir(numwalls) == CLOCKDIR_CCW) - flipwalls(numwalls,newnumwalls); - - for (i=numwalls; i 0) - { - // if new red line, prefer the other-side wall as base - ovh.suckwall = wall[i].nextwall; - } - } - sucksect = sectorofwall(ovh.suckwall); - - if (numsectors != sucksect) - Bmemcpy(§or[numsectors], §or[sucksect], sizeof(sectortype)); - - sector[numsectors].wallptr = numwalls; - sector[numsectors].wallnum = newnumwalls-numwalls; - - sector[numsectors].extra = -1; - sector[numsectors].lotag = sector[numsectors].hitag = 0; - - setslope(numsectors, YAX_CEILING, 0); - setslope(numsectors, YAX_FLOOR, 0); - - sector[numsectors].ceilingpal = sector[numsectors].floorpal = 0; -#ifdef YAX_ENABLE - yax_setbunches(numsectors, -1, -1); -#endif - headspritesect[numsectors] = -1; - numsectors++; - - numwalls = newnumwalls; - newnumwalls = -1; - - message("Created new sector %d based on sector %d", numsectors-1, sucksect); - } - - asksave = 1; -#ifdef YAX_ENABLE - yax_update(0); - yax_updategrays(pos.z); -#endif - - goto end_space_handling; - } - ////////// split sector ////////// - else if (ovh.split == 1) - { - int16_t danumwalls, splitendwall, doSectorSplit; - int16_t secondstartwall=-1; // used only with splitting - int32_t expectedNumwalls = numwalls+2*(newnumwalls-numwalls-1), loopnum; - int32_t firstwallflag; -#ifdef YAX_ENABLE - int16_t cb, fb; -#endif - startwall = sector[ovh.splitsect].wallptr; - endwall = startwall + sector[ovh.splitsect].wallnum - 1; - - firstwallflag = (startwall==ovh.splitstartwall || startwall==lastwall(ovh.splitstartwall)); - -// OSD_Printf("numwalls: %d, newnumwalls: %d\n", numwalls, newnumwalls); - i = -1; - for (k=startwall; k<=endwall; k++) - if (wall[k].x == wall[newnumwalls-1].x && wall[k].y == wall[newnumwalls-1].y) - { - i = k; - break; - } - // vvvv shouldn't happen, but you never know... - if (i==-1 || k==ovh.splitstartwall) - goto end_space_handling; - - splitendwall = k; - doSectorSplit = (loopnumofsector(ovh.splitsect,ovh.splitstartwall) - == loopnumofsector(ovh.splitsect,splitendwall)); - - if (expectedNumwalls > MAXWALLS) - { - printmessage16("%s would exceed wall limit.", bad==0 ? - "Splitting sector" : "Joining sector loops"); - newnumwalls--; - goto end_space_handling; - } -#ifdef YAX_ENABLE - yax_getbunches(ovh.splitsect, &cb, &fb); - - if ((cb>=0 && (sector[ovh.splitsect].ceilingstat&2)) - || (fb>=0 && (sector[ovh.splitsect].floorstat&2))) - { - printmessage16("Sloped extended sectors cannot be split."); - newnumwalls--; - goto end_space_handling; - } -#endif - ////////// common code for splitting/loop joining ////////// - - newnumwalls--; //first fix up the new walls - for (i=numwalls; inumwalls; j--) - { - Bmemcpy(&wall[danumwalls], &wall[j], sizeof(walltype)); - wall[danumwalls].nextwall = -1; - wall[danumwalls].nextsector = -1; - wall[danumwalls].point2 = danumwalls+1; -#ifdef YAX_ENABLE - yax_setnextwall(danumwalls,YAX_CEILING, -1); - yax_setnextwall(danumwalls,YAX_FLOOR, -1); -#endif - danumwalls++; - } - - //copy rest of loop next - if (doSectorSplit) - { - if (do_while_copyloop1(ovh.splitstartwall, splitendwall, &danumwalls, secondstartwall)) - goto split_not_enough_walls; - } - else - { - if (do_while_copyloop1(ovh.splitstartwall, ovh.splitstartwall, &danumwalls, numwalls)) - goto split_not_enough_walls; - } - - //Add other loops for 2nd sector - i = loopnum = loopnumofsector(ovh.splitsect,ovh.splitstartwall); - - for (j=startwall; j<=endwall; j++) - { - k = loopnumofsector(ovh.splitsect, j); - if (k==i) - continue; - - if (doSectorSplit && k==loopnum) - continue; - if (!doSectorSplit && (k == loopnumofsector(ovh.splitsect,ovh.splitstartwall) || - k == loopnumofsector(ovh.splitsect,splitendwall))) - continue; - - i = k; - - // was loopinside(... , secondstartwall) != 1, but this way there are - // no duplicate or left-out loops (can happen with convoluted geometry) - if (doSectorSplit && (loopinside(wall[j].x,wall[j].y, numwalls) != 0)) - continue; - - if (do_while_copyloop1(j, j, &danumwalls, danumwalls)) - goto split_not_enough_walls; - } - - //fix all next pointers on old sector line - for (j=numwalls; j= 0) - { - NEXTWALL(j).nextwall = j; - - if (!doSectorSplit || j < secondstartwall) - NEXTWALL(j).nextsector = numsectors; - else - NEXTWALL(j).nextsector = numsectors+1; - } - } - - //copy sector attributes & fix wall pointers - Bmemcpy(§or[numsectors], §or[ovh.splitsect], sizeof(sectortype)); - sector[numsectors].wallptr = numwalls; - sector[numsectors].wallnum = (doSectorSplit?secondstartwall:danumwalls) - numwalls; - - if (doSectorSplit) - { - //set all next pointers on split - for (j=numwalls; j= 0) - checksectorpointer(wall[j].nextwall, wall[j].nextsector); - checksectorpointer(j, sectorofwall(j)); - } - - //k now safe to use as temp - - if (numwalls==expectedNumwalls) - { - if (doSectorSplit && cb<0 && fb<0) - { - if (firstwallflag) - { - int32_t rhsnew1stwall = sector[numsectors-2].wallptr; - int32_t lhsotherwall = wall[rhsnew1stwall].nextwall; - - Bassert(lhsotherwall >= 0); - - setfirstwall(numsectors-2, lastwall(rhsnew1stwall)); - setfirstwall(numsectors-1, wall[lhsotherwall].point2); - } - } - - message("%s", doSectorSplit ? "Sector split." : "Loops joined."); - } - else - { - message("%s WARNING: CREATED %d MORE WALLS THAN EXPECTED!", - doSectorSplit ? "Sector split." : "Loops joined.", - numwalls-expectedNumwalls); - // this would display 'num* out of bounds' but this corruption - // is almost as bad... (shouldn't happen anymore) - if (numcorruptthings < MAXCORRUPTTHINGS) - corruptthings[numcorruptthings++] = 0; - corruptlevel = 5; - } - - if (0) - { -split_not_enough_walls: - message("%s failed: not enough space beyond wall[]", - doSectorSplit ? "Splitting sectors" : "Joining loops"); - } - - newnumwalls = -1; - asksave = 1; - - mkonwinvalid(); -#ifdef YAX_ENABLE - yax_update(0); - yax_updategrays(pos.z); -#endif - } - } - } -end_space_handling: - - if (keystatus[sc_Enter]) //Left Enter - { - keystatus[sc_Enter] = 0; - if (keystatus[sc_LeftShift] && keystatus[sc_LeftControl]) // LCtrl+LShift - { -#ifdef YAX_ENABLE - if (numyaxbunches == 0 || - (fade_editor_screen(-1), ask_if_sure("Really check all wall pointers in TROR map?", 0))) -#endif - { - printmessage16("CHECKING ALL POINTERS!"); - for (i=0; i wall[j].point2) - startwall = wall[j].point2; - sector[i].wallptr = startwall; - } - for (i=numsectors-2; i>=0; i--) - sector[i].wallnum = sector[i+1].wallptr-sector[i].wallptr; - sector[numsectors-1].wallnum = numwalls-sector[numsectors-1].wallptr; - - for (i=0; i numwalls) // batch insert points - { - const int32_t numdrawnwalls = newnumwalls-numwalls; - vec2_t *point = (vec2_t *)tempxyar; // [MAXWALLS][2] - int32_t insdpoints = 0; - - // back up the points of the line strip - for (i=0; i>3]; - Bmemset(touchedwall, 0, sizeof(touchedwall)); - - for (j=numwalls-1; j>=0; j--) /* j may be modified in loop */ - { - YAX_SKIPWALL(j); - - if ((touchedwall[j >> 3] & pow2char[j & 7]) - || (wall[j].nextwall >= 0 && (touchedwall[wall[j].nextwall >> 3] & pow2char[wall[j].nextwall & 7]))) - continue; - - vec2_t pint; - - if (!lineintersect2v((vec2_t *)&wall[j], (vec2_t *)&POINT2(j), - &point[i], &point[i+1], &pint)) - continue; - - if (vec2eq(&pint, (vec2_t *)&wall[j]) || vec2eq(&pint, (vec2_t *)&POINT2(j))) - continue; - - touchedwall[j>>3] |= (1<<(j&7)); - - if (wall[j].nextwall != -1) - touchedwall[wall[j].nextwall>>3] |= (1<<(wall[j].nextwall&7)); - - int32_t inspts = M32_InsertPoint(j, pint.x, pint.y, -1, &j); /* maybe modify j */ - - if (inspts==0) - { - printmessage16("Wall limit exceeded while inserting points."); - goto end_batch_insert_points; - } - else if (inspts >= 65536) - { - message("ERR: Inserted %d points for constr. wall (exp. %d; %d already ins'd)", - inspts&65535, inspts>>16, insdpoints); - goto end_batch_insert_points; - } - - insdpoints += inspts; - } - } - - message("Batch-inserted %d points in total", insdpoints); -end_batch_insert_points: - - if (insdpoints != 0) - { -#ifdef YAX_ENABLE - yax_updategrays(pos.z); -#endif - mkonwinvalid_keeptempsect(); - asksave = 1; - } - } - else if (linehighlight >= 0) - { - checksectorpointer(linehighlight,sectorofwall(linehighlight)); - printmessage16("Checked pointers of highlighted line."); - asksave = 1; - } - } - } - - static int32_t backspace_last = 0; - - if (keystatus[sc_BackSpace]) //Backspace - { - keystatus[sc_BackSpace] = 0; - - if (newnumwalls >= numwalls) - { - backspace_last = 1; - - if (newnumwalls == numwalls+1 || keystatus[sc_LeftControl]) // LCtrl: delete all newly drawn walls - newnumwalls = -1; - else - newnumwalls--; - } - else if (backspace_last==0) - { - graphicsmode += (1-2*(DOWN_BK(RUN) || keystatus[sc_RightShift]))+3; - graphicsmode %= 3; - printmessage16("2D mode textures %s", - (graphicsmode == 2)?"enabled w/ animation":graphicsmode?"enabled":"disabled"); - } - } - else - backspace_last = 0; - - if ((keystatus[sc_Delete]|keystatus[sc_D]) && eitherCTRL && numwalls > 0) //sector delete - { - int32_t numdelsectors = 0; - char *origframe=NULL; - -#ifdef YAX_ENABLE - int16_t cb, fb; - uint8_t bunchbitmap[YAX_MAXBUNCHES>>3]; - Bmemset(bunchbitmap, 0, sizeof(bunchbitmap)); -#endif - keystatus[sc_Delete] = 0; - keystatus[sc_D] = 0; - - for (i=0; i 0) - { - // LShift: force highlighted sector deleting - if (keystatus[sc_LeftShift] || (hlsectorbitmap[i>>3]&(1<<(i&7)))) - { - for (j=highlightsectorcnt-1; j>=0; j--) - { -#ifdef YAX_ENABLE - yax_getbunches(highlightsector[j], &cb, &fb); - if (cb>=0) bunchbitmap[cb>>3] |= (1<<(cb&7)); - if (fb>=0) bunchbitmap[fb>>3] |= (1<<(fb&7)); -#endif - deletesector(highlightsector[j]); - for (k=j-1; k>=0; k--) - if (highlightsector[k] >= highlightsector[j]) - highlightsector[k]--; - } - - printmessage16("Highlighted sectors deleted."); - mkonwinvalid(); - k = 1; - } - } - - if (k == 0) - { - if (numdelsectors > 1) - { - if (!bakframe_fillandfade(&origframe, i, "Delete this sector? (Y/N)")) - continue; - } - -#ifdef YAX_ENABLE - yax_getbunches(i, &cb, &fb); - if (cb>=0) bunchbitmap[cb>>3] |= (1<<(cb&7)); - if (fb>=0) bunchbitmap[fb>>3] |= (1<<(fb&7)); -#endif - deletesector(i); - mkonwinvalid(); - printmessage16("Sector deleted."); - } - - Bfree(origframe); - -#ifdef YAX_ENABLE - for (j=0; j=0 && (bunchbitmap[cb>>3] & (1<<(cb&7)))) - yax_setbunch(j, YAX_CEILING, -1); - if (fb>=0 && (bunchbitmap[fb>>3] & (1<<(fb&7)))) - yax_setbunch(j, YAX_FLOOR, -1); - } -#endif - reset_highlightsector(); - reset_highlight(); - - newnumwalls = -1; - asksave = 1; -#ifdef YAX_ENABLE - yax_update(0); - yax_updategrays(pos.z); -#endif - break; - } - } - - if ((keystatus[sc_Delete]|keystatus[sc_D]) && (pointhighlight >= 0)) - { - if ((pointhighlight&0xc000) == 16384) //Sprite Delete - { - deletesprite(pointhighlight&16383); - printmessage16("Sprite deleted."); - - update_highlight(); - asksave = 1; - } - else if (eitherSHIFT|keystatus[sc_D]) - { - deletewall(pointhighlight); - asksave = 1; - } - keystatus[sc_Delete] = 0; - keystatus[sc_D] = 0; - } - - if (keystatus[sc_Insert] || keystatus[sc_I]) //InsertPoint - { - if (highlightsectorcnt > 0) - duplicate_selected_sectors(); - else if (highlightcnt > 0) - duplicate_selected_sprites(); - else if (linehighlight2 >= 0) - { - int16_t onewnumwalls = newnumwalls; - int32_t wallis2sided = (wall[linehighlight2].nextwall>=0); - - int32_t err = backup_drawn_walls(0); - - if (err) - { - message("Error backing up drawn walls (code %d)!", err); - } - else if (max(numwalls, onewnumwalls) >= MAXWALLS-wallis2sided) - { - printmessage16("Inserting point would exceed wall limit."); - } - else - { - getclosestpointonwall(m32_sideview?searchx:mousxplc, m32_sideview?searchy:mousyplc, - linehighlight2, &dax,&day, 1); - i = linehighlight2; - if (m32_sideview) - { - int32_t y_p, d, dx, dy, frac; - - dx = dax - m32_wallscreenxy[i][0]; - dy = day - m32_wallscreenxy[i][1]; - d = max(dx, dy); - y_p = (dy>dx); - - if (d==0) - goto point_not_inserted; - - frac = divscale24(d, m32_wallscreenxy[wall[i].point2][y_p]-m32_wallscreenxy[i][y_p]); - dax = POINT2(i).x - wall[i].x; - day = POINT2(i).y - wall[i].y; - dax = wall[i].x + mulscale24(dax,frac); - day = wall[i].y + mulscale24(day,frac); - } - - adjustmark(&dax,&day, newnumwalls); - if ((wall[i].x == dax && wall[i].y == day) || (POINT2(i).x == dax && POINT2(i).y == day)) - { -point_not_inserted: - printmessage16("Point not inserted."); - } - else - { - int32_t insdpoints = M32_InsertPoint(linehighlight2, dax, day, onewnumwalls, NULL); - - if (insdpoints == 0) - { - printmessage16("Inserting points would exceed wall limit."); - goto end_insert_points; - } - else if (insdpoints == 1) - { - printmessage16("Point inserted."); - } - else if (insdpoints > 1 && insdpoints < 65536) - { - message("Inserted %d points for constrained wall.", insdpoints); - } - else // insdpoints >= 65536 - { - message("Inserted %d points for constrained wall (expected %d, WTF?).", - insdpoints&65535, insdpoints>>16); - } - -#ifdef YAX_ENABLE - yax_updategrays(pos.z); -#endif - mkonwinvalid_keeptempsect(); - } - } - -end_insert_points: - backup_drawn_walls(1); - - asksave = 1; - } - keystatus[sc_Insert] = keystatus[sc_I] = 0; - } - - /*j = 0; - for(i=22-1;i>=0;i--) updatecrc16(j,kensig[i]); - if ((j&0xffff) != 0xebf) - { - printf("Don't screw with my name.\n"); - Bexit(0); - }*/ - //printext16(9L,336+9L,4,-1,kensig,0); - //printext16(8L,336+8L,12,-1,kensig,0); - - nokeys: - - videoShowFrame(1); - synctics = totalclock-lockclock; - lockclock += synctics; - - if (keystatus[buildkeys[BK_MODE2D_3D]]) - { - updatesector(pos.x,pos.y,&cursectnum); - if (cursectnum >= 0) - keystatus[buildkeys[BK_MODE2D_3D]] = 2; - else - printmessage16("Arrow must be inside a sector before entering 3D mode."); - } - -// vvv PK ------------------------------------ (LShift) Ctrl-X: (prev) next map -// this is copied from 'L' (load map), but without copying the highlighted sectors - - if (quickmapcycling && keystatus[sc_X]) //X - { - - if (eitherCTRL) //Ctrl - { - if (asksave) - message("You have unsaved changes."); - else - { - int skip = 0; - nextmap: - // bad = 0; - i = menuselect_auto(keystatus[sc_LeftShift] ? 0 : 1, skip); // LShift: prev map - if (i < 0) - { - if (i == -1) - message("No more map files."); - else if (i == -2) - message("No .MAP files found."); - } - else - { - if (LoadBoard(NULL, 4)) - { - skip = 2; - goto nextmap; - } - - RESET_EDITOR_VARS(); - oposz = pos.z; - } - videoShowFrame(1); - keystatus[sc_Enter] = 0; - keystatus[sc_X] = 0; - keystatus[sc_R] = 0; - } - } - } -// ^^^ PK ------------------------------------ - - if (keystatus[sc_Escape] && joinsector[0] >= 0) - { - keystatus[sc_Escape]=0; - joinsector[0]=-1; - printmessage16("No sectors joined."); - } - -CANCEL: - if (keystatus[sc_Escape]) - { - keystatus[sc_Escape] = 0; -#if M32_UNDO - _printmessage16("(N)ew, (L)oad, (S)ave, save (A)s, (T)est map, (U)ndo, (R)edo, (Q)uit"); -#else - _printmessage16("(N)ew, (L)oad, (S)ave, save (A)s, (T)est map, (Q)uit"); -#endif - printext16(16*8, ydim-STATUS2DSIZ2-12, editorcolors[15], -1, GetSaveBoardFilename(NULL), 0); - - videoShowFrame(1); - keyFlushChars(); - bad = 1; - while (bad == 1) - { - char ch; - - if (handleevents()) - { - if (quitevent) - quitevent = 0; - } - idle(); - - ch = keyGetChar(); - - if (keystatus[sc_Escape]) - { - keystatus[sc_Escape] = 0; - bad = 0; - // printmessage16(""); - } - else if (ch == 'n' || ch == 'N') //N - { - bad = 0; - - if (ask_if_sure("Are you sure you want to start a new board? (Y/N)", 0)) - { - int32_t bakstat=-1; - mapinfofull_t bakmap; - - if (highlightsectorcnt > 0) - bakstat = backup_highlighted_map(&bakmap); - -// Bmemset(hlsectorbitmap, 0, sizeof(hlsectorbitmap)); -// highlightsectorcnt = -1; - - highlightcnt = -1; - //Clear all highlights - Bmemset(show2dwall, 0, sizeof(show2dwall)); - Bmemset(show2dsprite, 0, sizeof(show2dsprite)); - - for (i=0; i 0) - bakstat = backup_highlighted_map(&bakmap); - - ret = LoadBoard(NULL, 4); - if (ret) - { - message("^13Invalid map format, nothing loaded (code %d).", ret); - if (bakstat==0) - mapinfofull_free(&bakmap); - } - else - { - RESET_EDITOR_VARS(); - oposz = pos.z; - - if (bakstat==0) - { - bakstat = restore_highlighted_map(&bakmap, 1); - if (bakstat == -1) - { - message("Can't copy highlighted portion of old map: limits exceeded."); - reset_highlightsector(); - } - } - } - } - videoShowFrame(1); - keystatus[sc_Enter] = 0; - } - else if (ch == 'a' || ch == 'A') //A - { - int32_t corrupt = CheckMapCorruption(4, 0); - - bad = 0; - - // Back up full name. - Bstrcpy(selectedboardfilename, boardfilename); - - // Get base name. - { - const char *basefn = getbasefn(boardfilename); - - if (basefn != boardfilename) - Bmemmove(boardfilename, basefn, Bstrlen(basefn)+1); - } - - i = 0; - while (boardfilename[i] != 0 && i < 64) - i++; - if (i >= 4 && boardfilename[i-4] == '.') - i -= 4; - boardfilename[i] = 0; - - keyFlushChars(); - while (bad == 0) - { - _printmessage16("%sSave as: ^011%s%s", corrupt>=4?"(map corrupt) ":"", - boardfilename, (totalclock&32)?"_":""); - videoShowFrame(1); - - if (handleevents()) - quitevent = 0; - - idle(); - - ch = keyGetChar(); - - if (keystatus[sc_Escape]) bad = 1; - else if (ch == 13) bad = 2; - else if (ch > 0) - { - if (i > 0 && (ch == 8 || ch == 127)) - { - i--; - boardfilename[i] = 0; - } - else if (i < 40 && ch > 32 && ch < 128) - { - boardfilename[i++] = ch; - boardfilename[i] = 0; - } - } - } - - if (bad == 1) - { - Bstrcpy(boardfilename, selectedboardfilename); - keystatus[sc_Escape] = 0; - printmessage16("Operation cancelled"); - videoShowFrame(1); - } - else if (bad == 2) - { - char *slash; - - keystatus[sc_Enter] = 0; - - Bstrcpy(&boardfilename[i], ".map"); - - // Update full name with new basename. - slash = Bstrrchr(selectedboardfilename,'/'); - Bstrcpy(slash ? slash+1 : selectedboardfilename, boardfilename); - - SaveBoardAndPrintMessage(selectedboardfilename); - - Bstrcpy(boardfilename, selectedboardfilename); - CallExtSetupMapFilename(boardfilename); - } - bad = 0; - } - else if (ch == 's' || ch == 'S') //S - { - bad = 0; - - if (CheckMapCorruption(4, 0)>=4) - { - fade_editor_screen(-1); - if (!ask_if_sure("Map is corrupt. Are you sure you want to save? (Y/N)", 0)) - break; - } - - SaveBoardAndPrintMessage(NULL); - - videoShowFrame(1); - } - else if (ch == 't' || ch == 'T') - { - bad = 0; - test_map(0); - } -#if M32_UNDO - else if (ch == 'u' || ch == 'U') - { - bad = 0; - if (map_undoredo(0)) printmessage16("Nothing to undo!"); - else printmessage16("Revision %d undone",map_revision); - } - else if (ch == 'r' || ch == 'R') - { - bad = 0; - if (map_undoredo(1)) printmessage16("Nothing to redo!"); - else printmessage16("Restored revision %d",map_revision-1); - } -#endif - else if (ch == 'q' || ch == 'Q') //Q - { - bad = 0; - - if (ask_if_sure("Are you sure you want to quit?", 0)) - { - //QUIT! - - int32_t corrupt = CheckMapCorruption(4, 0); - - if (ask_if_sure(corrupt<4?"Save changes?":"Map corrupt. Save changes?", 2+(corrupt>=4))) - SaveBoard(NULL, M32_SB_ASKOV); - - while (keystatus[sc_Escape] || keystatus[sc_C]) - { - keystatus[sc_Escape] = 0; - keystatus[sc_C] = 0; - quitevent = 0; - printmessage16("Operation cancelled"); - videoShowFrame(1); - goto CANCEL; - } - - CallExtUnInit(); -// clearfilenames(); - engineUnInit(); - - Bexit(0); - } - - // printmessage16(""); - videoShowFrame(1); - } - } - - clearkeys(); - } - - VM_OnEvent(EVENT_KEYS2D, -1); - - //nextpage(); - } - - for (i=0; i= 0) - checksectorpointer(wall[j].nextwall, wall[j].nextsector); - checksectorpointer(j, highlightsector[i]); - } - } - mkonwinvalid_keeptempsect(); - - fixspritesectors(); - - if (videoSetGameMode(fullscreen,xdimgame,ydimgame,bppgame,upscalefactor) < 0) - { - initprintf("%d * %d not supported in this graphics mode\n",xdim,ydim); - CallExtUnInit(); -// clearfilenames(); - engineUnInit(); - Bexit(1); - } - - videoSetPalette(GAMMA_CALC,0,0); - - pos.z = oposz; - - searchx = clamp(scale(searchx,xdimgame,xdim2d), 8, xdimgame-8-1); - searchy = clamp(scale(searchy,ydimgame,ydim2d-STATUS2DSIZ), 8, ydimgame-8-1); - - VM_OnEvent(EVENT_ENTER3DMODE, -1); -} - -// flags: -// 1: quit_is_yes -// 2: don't clear keys on return -int32_t ask_if_sure(const char *query, uint32_t flags) -{ - char ch; - int32_t ret=-1; - - if (!query) - _printmessage16("Are you sure?"); - else - _printmessage16("%s", query); - videoShowFrame(1); - keyFlushChars(); - - while ((keystatus[sc_Escape]|keystatus[sc_C]) == 0 && ret==-1) - { - if (handleevents()) - { - if (quitevent) - { - if (flags&1) - return 1; - else - quitevent = 0; - } - } - idle(); - - ch = keyGetChar(); - - if (ch == 'y' || ch == 'Y') - ret = 1; - else if (ch == 'n' || ch == 'N' || ch == 13 || ch == ' ') - ret = 0; - } - - if ((flags&2)==0) - clearkeys(); - - if (ret >= 0) - return ret; - - return 0; -} - -int32_t editor_ask_function(const char *question, const char *dachars, int32_t numchars) -{ - char ch; - int32_t i, ret=-1; - - _printmessage16("%s", question); - - videoShowFrame(1); - keyFlushChars(); - - // 'c' is cancel too, but can be overridden - while ((keystatus[sc_Escape]|keystatus[sc_C]) == 0 && ret==-1) - { - if (handleevents()) - quitevent = 0; - - idle(); - ch = keyGetChar(); - - for (i=0; i=10 && - g_loadedMapVersion != -1 && g_loadedMapVersion < mapversion) - { - char question[128]; - // XXX: This message is potentially confusing if the user is "Saving - // As" to a new file name. - Bsnprintf(question, sizeof(question), "Are you sure to overwrite a version " - "V%d map with a V%d map-text one?", g_loadedMapVersion, mapversion); - - if (AskIfSure(question)) - { - message("Cancelled saving board"); - saveboard_canceled = 1; - return NULL; - } - } -#endif - - saveboard_savedtags = 0; - saveboard_fixedsprites = CallExtPreSaveMap(); - - ret = saveboard(f, &startpos, startang, startsectnum); - if ((flags&M32_SB_NOEXT)==0) - { - CallExtSaveMap(f); - saveboard_savedtags = !taglab_save(f); - } - - return (ret==0) ? f : NULL; -} - -// flags: 1: for running on Mapster32 init -// 4: passed to loadboard flags (no polymer_loadboard); implies no maphack loading -// returns: -// 0 on success, -// <0 on failure. -int32_t LoadBoard(const char *filename, uint32_t flags) -{ - int32_t i, tagstat; - const int32_t loadingflags = (!pathsearchmode && grponlymode) ? 2 : 0; - - if (!filename) - filename = selectedboardfilename; - - editorzrange[0] = INT32_MIN; - editorzrange[1] = INT32_MAX; - - CallExtPreLoadMap(); - i = engineLoadBoard(filename, (flags&4)|loadingflags, &pos, &ang, &cursectnum); - if (i == -2) - i = engineLoadBoardV5V6(filename,loadingflags, &pos, &ang, &cursectnum); - - if (i < 0) - { -// printmessage16("Invalid map format."); - return i; - } - - // Success, so copy the file name. - if (filename != boardfilename) - Bstrcpy(boardfilename, filename); - - mkonwinvalid(); - - highlightcnt = -1; - Bmemset(show2dwall, 0, sizeof(show2dwall)); //Clear all highlights - Bmemset(show2dsprite, 0, sizeof(show2dsprite)); - - if ((flags&4)==0) - loadmhk(0); - - tagstat = taglab_load(boardfilename, loadingflags); - CallExtLoadMap(boardfilename); - - { - char msgtail[64]; - const int32_t ci = CheckMapCorruption(4, 0); - - if (ci == 5) - Bstrcpy(msgtail, "^12(EXTREME corruption)"); - else if (ci == 4) - Bstrcpy(msgtail, "^12(HEAVY corruption)"); - else if (i > 0) - Bsprintf(msgtail, "^14(removed %d sprites)", i); - else if (ci >= 1 && ci < 4) - Bstrcpy(msgtail, "^14(moderate corruption)"); - else - Bstrcpy(msgtail, "successfully"); - - message("Loaded V%d map %s%s %s", g_loadedMapVersion, - boardfilename, tagstat==0?" w/tags":"", msgtail); - } - - startpos = pos; //this is same - startang = ang; - startsectnum = cursectnum; - asksave = 0; - - return 0; -} - -void getpoint(int32_t searchxe, int32_t searchye, int32_t *x, int32_t *y) -{ - inpclamp(&pos.x, -editorgridextent, editorgridextent); - inpclamp(&pos.y, -editorgridextent, editorgridextent); - - searchxe -= halfxdim16; - searchye -= midydim16; - - vec2_t svec = { searchxe ,searchye }; - - if (m32_sideview) - { - if (m32_sidesin!=0) - svec.y = divscale14(svec.y, m32_sidesin); - rotatepoint(zerovec, svec, -m32_sideang, &svec); - } - - *x = pos.x + divscale14(svec.x,zoom); - *y = pos.y + divscale14(svec.y,zoom); - - inpclamp(x, -editorgridextent, editorgridextent); - inpclamp(y, -editorgridextent, editorgridextent); -} - -static int32_t getlinehighlight(int32_t xplc, int32_t yplc, int32_t line, int8_t ignore_pointhighlight) -{ - int32_t i, j, dst, dist, closest, x1, y1, x2, y2, nx, ny; - int32_t daxplc, dayplc; - - if (numwalls == 0) - return -1; - - if (g_mouseBits & 1 || searchlock) - return line; - - if (!ignore_pointhighlight && (pointhighlight&0xc000) == 16384) - return -1; - - dist = linehighlightdist; - if (m32_sideview) - { - daxplc = searchx; - dayplc = searchy; - dist = mulscale14(dist, zoom); - } - else - { - daxplc = xplc; - dayplc = yplc; - } - - closest = -1; - for (i=0; i=0 && (j = wall[closest].nextwall) >= 0) -#ifdef YAX_ENABLE - if (m32_sideview || ((graywallbitmap[j>>3]&(1<<(j&7)))==0)) -#endif - { - //if red line, allow highlighting of both sides - if (m32_sideview) - { - x1 = m32_wallscreenxy[closest][0]; - y1 = m32_wallscreenxy[closest][1]; - x2 = m32_wallscreenxy[wall[closest].point2][0]; - y2 = m32_wallscreenxy[wall[closest].point2][1]; - } - else - { - x1 = wall[closest].x; - y1 = wall[closest].y; - x2 = POINT2(closest).x; - y2 = POINT2(closest).y; - } - - i = wall[closest].nextwall; - if (!m32_sideview || - ((B_UNBUF64(m32_wallscreenxy[closest]) == B_UNBUF64(m32_wallscreenxy[wall[j].point2])) && - (B_UNBUF64(m32_wallscreenxy[wall[closest].point2]) == B_UNBUF64(m32_wallscreenxy[j])))) - if (dmulscale32(daxplc-x1,y2-y1,-(x2-x1),dayplc-y1) >= 0) - closest = j; - } - - return closest; -} - -int32_t getpointhighlight(int32_t xplc, int32_t yplc, int32_t point) -{ - int32_t i, j, dst, dist = pointhighlightdist, closest = -1; - int32_t dax,day; - int32_t alwaysshowgray = get_alwaysshowgray(); - - if (numwalls == 0) - return -1; - - if (g_mouseBits & 1 || searchlock) - return point; - - if (grid < 1) - dist = 0; - - for (i=0; i= xdim || midydim16+day < 0 || midydim16+day >= ydim) - continue; - - dst = klabs(halfxdim16+dax-searchx) + klabs(midydim16+day-searchy); - } - - if (dst <= dist) - { - // prefer white walls - if (dst=0)-(wall[closest].nextwall>=0) <= 0) - dist = dst, closest = j; - } - } - } - - if (zoom >= 256) - for (i=0; i= 0) - YAX_SKIPSECTOR(sprite[i].sectnum); - - if (!m32_sideview) - { - dst = klabs(xplc-sprite[i].x) + klabs(yplc-sprite[i].y); - } - else - { - editorGet2dScreenCoordinates(&dax,&day, sprite[i].x-pos.x,sprite[i].y-pos.y, zoom); - day += getscreenvdisp(sprite[i].z-pos.z, zoom); - - if (halfxdim16+dax < 0 || halfxdim16+dax >= xdim || midydim16+day < 0 || midydim16+day >= ydim) - continue; - - dst = klabs(halfxdim16+dax-searchx) + klabs(midydim16+day-searchy); - } - - // was (dst <= dist), but this way, when duplicating sprites, - // the selected ones are dragged first - if (dst < dist || (dst == dist && (show2dsprite[i>>3]&(1<<(i&7))))) - dist = dst, closest = i+16384; - } - - return closest; -} - -static void locktogrid(int32_t *dax, int32_t *day) -{ - *dax = ((*dax+(1024>>grid))&(0xffffffff<<(11-grid))); - *day = ((*day+(1024>>grid))&(0xffffffff<<(11-grid))); -} - -static int32_t adjustmark(int32_t *xplc, int32_t *yplc, int16_t danumwalls) -{ - int32_t i, dst, dist, dax, day, pointlockdist; - - if (danumwalls < 0) - danumwalls = numwalls; - - pointlockdist = 0; - if (grid > 0 && gridlock) - pointlockdist = (256>>grid); - - dist = pointlockdist; - dax = *xplc; - day = *yplc; - - for (i=0; i 0) - locktogrid(&dax, &day); - - *xplc = dax; - *yplc = day; - - return 0; -} - -static int32_t checkautoinsert(int32_t dax, int32_t day, int16_t danumwalls) -{ - int32_t i, x1, y1, x2, y2; - - if (danumwalls < 0) - danumwalls = numwalls; - - for (i=0; i has to be the starting (i.e. least index) wall of a loop! -// Returns: CLOCKDIR_CW or CLOCKDIR_CCW. -int32_t clockdir(int32_t wallstart) -{ - int32_t tempint, x0, x1, x2, y0, y1, y2; - - int32_t minx = 0x7fffffff; - int32_t themin = -1; - int32_t i = wallstart-1; - - do - { - i++; - if (POINT2(i).x < minx) - { - minx = POINT2(i).x; - themin = i; - } - } - while (wall[i].point2 != wallstart && i < MAXWALLS-1); - // NOTE: the i < MAXWALLS-1 check is really only safety against either - // - a really corrupt map, or - // - misuse of clockdir() where is not the starting wall of - // the very last loop - - x0 = wall[themin].x; - y0 = wall[themin].y; - x1 = POINT2(themin).x; - y1 = POINT2(themin).y; - x2 = POINT2(wall[themin].point2).x; - y2 = POINT2(wall[themin].point2).y; - - if (y2 <= y1 && y1 <= y0) - return CLOCKDIR_CW; - if (y0 <= y1 && y1 <= y2) - return CLOCKDIR_CCW; - - tempint = (x0-x1)*(y2-y1) - (x2-x1)*(y0-y1); - if (tempint < 0) - return CLOCKDIR_CW; - else - return CLOCKDIR_CCW; -} - -static void flipwalls(int16_t numwalls, int16_t newnumwalls) -{ - int32_t i, j, nume; - - nume = newnumwalls-numwalls; - - for (i=numwalls; i>1); i++) - { - j = numwalls+newnumwalls-i-1; - - swapshort(&onextwall[i], &onextwall[j]); - - swaplong(&wall[i].x, &wall[j].x); - swaplong(&wall[i].y, &wall[j].y); - } -} - -static void do_insertpoint(int32_t w, int32_t dax, int32_t day, int32_t *mapwallnum) -{ - int32_t i; - const int32_t sucksect = sectorofwall(w); - const uint32_t lenbyrep = getlenbyrep(wallength(w), wall[w].xrepeat); - - sector[sucksect].wallnum++; - for (i=sucksect+1; i= w+1) - (*mapwallnum)++; - - movewalls(w+1, +1); - Bmemcpy(&wall[w+1], &wall[w], sizeof(walltype)); -#ifdef YAX_ENABLE - wall[w+1].cstat &= ~(1<<14); -#endif - wall[w].point2 = w+1; - wall[w+1].x = dax; - wall[w+1].y = day; - - fixxrepeat(w, lenbyrep); - AlignWallPoint2(w); - fixxrepeat(w+1, lenbyrep); -} - -// Returns number of points inserted (1; or 2 if wall had a nextwall). -// *mapwallnum is set to the new wallnum of the former (pre-insertpoint) *mapwallnum -// (the new one can only be >= than the old one; ptr may be NULL if we don't care) -static int32_t insertpoint(int16_t linehighlight, int32_t dax, int32_t day, int32_t *mapwallnum) -{ - int32_t j = linehighlight; - - do_insertpoint(j, dax, day, mapwallnum); - - if (wall[j].nextwall >= 0) - { - int32_t k = wall[j].nextwall; - - do_insertpoint(k, dax, day, mapwallnum); - - j = wall[k].nextwall; - wall[j].nextwall = k+1; - wall[j+1].nextwall = k; - wall[k].nextwall = j+1; - wall[k+1].nextwall = j; - - return 2; - } - - return 1; -} - -// runi: 0=check (forbidden), 1=prepare, 2=do! -static void deletepoint(int16_t point, int32_t runi) -{ - int32_t i, j, sucksect; - - Bassert(runi != 0); - - if (runi==1) - { - i = wall[point].nextwall; - if (i >= 0) - { - NEXTWALL(i).nextwall = NEXTWALL(i).nextsector = -1; - wall[i].nextwall = wall[i].nextsector = -1; - } - - return; - } - - sucksect = sectorofwall(point); - - sector[sucksect].wallnum--; - for (i=sucksect+1; i= 0) - { - NEXTWALL(j).nextwall = -1; - NEXTWALL(j).nextsector = -1; - } - if (wall[point].nextwall >= 0) - { - NEXTWALL(point).nextwall = -1; - NEXTWALL(point).nextsector = -1; - } -#endif - movewalls(point, -1); -} - -static int32_t deletesector(int16_t sucksect) -{ - int32_t i, j, k, nextk, startwall, endwall; - - while (headspritesect[sucksect] >= 0) - deletesprite(headspritesect[sucksect]); - - startwall = sector[sucksect].wallptr; - endwall = startwall + sector[sucksect].wallnum - 1; - j = sector[sucksect].wallnum; - -#ifdef YAX_ENABLE - yax_setbunches(sucksect, -1, -1); -#endif - - for (i=sucksect; i= 0) - { - NEXTWALL(i).nextwall = -1; - NEXTWALL(i).nextsector = -1; - } - } - - movewalls(startwall, -j); - for (i=0; i= startwall) - wall[i].nextsector--; - - return 0; -} - -int32_t fixspritesectors(void) -{ - int32_t i; - int32_t numfixedsprites = 0, printfirsttime = 0; - - for (i=numsectors-1; i>=0; i--) - if (sector[i].wallnum <= 0 || sector[i].wallptr >= numwalls) - { - // XXX: This is not the best course of action for - // such great corruption. - deletesector(i); - mkonwinvalid(); - initprintf("NOTE: Deleted sector %d which had corrupt .wallnum or .wallptr\n", i); - } - - if (m32_script_expertmode) - return 0; - - for (i=0; i= numsectors+0u) - { - if (printfirsttime == 0) - { - initprintf("--------------------\n"); - printfirsttime = 1; - } - initprintf("Changed sectnum of sprite #%d from %d to %d\n", - i, TrackerCast(sprite[i].sectnum), j); - - changespritesect(i, j); - numfixedsprites++; - } - break; - } - } - } - } - - return numfixedsprites; -} - -static int32_t movewalls(int32_t start, int32_t offs) -{ - int32_t i; - - if (offs < 0) //Delete - { - for (i=start; i 0) //Insert - { - for (i=numwalls+offs-1; i>=start+offs; i--) - Bmemcpy(&wall[i], &wall[i-offs], sizeof(walltype)); - - if (ovh.bak_wallsdrawn > 0) - { - if (ovh.suckwall >= start) - ovh.suckwall += offs; - if (ovh.splitstartwall >= start) - ovh.splitstartwall += offs; - } - } - - numwalls += offs; - for (i=0; i= start) wall[i].nextwall += offs; - if (wall[i].point2 >= start) wall[i].point2 += offs; - } -#ifdef YAX_ENABLE - yax_tweakwalls(start, offs); -#endif - - return 0; -} - -int32_t wallength(int16_t i) -{ - int64_t dax = POINT2(i).x - wall[i].x; - int64_t day = POINT2(i).y - wall[i].y; -#if 1 //def POLYMOST - int64_t hypsq = dax*dax + day*day; - if (hypsq > (int64_t)INT32_MAX) - return (int32_t)sqrt((double)hypsq); - else - return ksqrt((uint32_t)hypsq); -#else - return ksqrt(dax*dax + day*day); -#endif -} - -void fixrepeats(int16_t i) -{ - int32_t dist = wallength(i); - int32_t day = wall[i].yrepeat; - - wall[i].xrepeat = clamp(mulscale10(dist,day), 1, 255); -} - -uint32_t getlenbyrep(int32_t len, int32_t repeat) -{ - if (repeat <= 0) - return ((uint32_t)len)<<12; - - return divscale12(len, repeat); -} - -void fixxrepeat(int16_t wallnum, uint32_t lenrepquot) // lenrepquot: divscale12(wallength,xrepeat) -{ - if (lenrepquot != 0) - { - uint32_t res = (((wallength(wallnum)<<12)+(1<<11))/lenrepquot); - wall[wallnum].xrepeat = clamp(res, 1, 255); - } -} - - -int32_t overridepm16y = -1; - -void clearmidstatbar16(void) -{ - int32_t y = overridepm16y<0 ? STATUS2DSIZ : overridepm16y; - - videoBeginDrawing(); - CLEARLINES2D(ydim-y+25, STATUS2DSIZ+2-(25<<1), 0); - videoEndDrawing(); -} - -static void clearministatbar16(void) -{ - int32_t i, col = editorcolors[25]; - - videoBeginDrawing(); - - for (i=ydim-STATUS2DSIZ2; i= 800) - { - Bsnprintf(tempbuf, sizeof(tempbuf), "%s %s", AppProperName, CallExtGetVer()); - printext16(xdim2d-(Bstrlen(tempbuf)<<3)-3, ydim2d-STATUS2DSIZ2+10, editorcolors[4],-1, tempbuf, 0); - printext16(xdim2d-(Bstrlen(tempbuf)<<3)-2, ydim2d-STATUS2DSIZ2+9, editorcolors[12],-1, tempbuf, 0); - } - - videoEndDrawing(); -} - -// has to be the starting wall of a loop! -// -// Assuming that indicates a CW (outer) loop, the return value can -// be seen as a boolean of whether (x,y) is inside it. -// -// XXX: this function suffers from asymmetry issues in degenerate cases, -// similar to how inside() did before r3898. -int32_t loopinside(int32_t x, int32_t y, int16_t startwall) -{ - bssize_t cnt = clockdir(startwall); - int32_t i = startwall; - - do - { - int32_t x1 = wall[i].x; - int32_t x2 = POINT2(i).x; - - if (x <= x1 || x <= x2) - { - int32_t y1 = wall[i].y; - int32_t y2 = POINT2(i).y; - - if (y1 > y2) - { - swaplong(&x1, &x2); - swaplong(&y1, &y2); - } - - if (y1 <= y && y < y2) - if ((uint64_t)x1*(y-y2) + (uint64_t)x2*(y1-y) <= (uint64_t)x*(y1-y2)) - cnt ^= 1; - } - - i = wall[i].point2; - } - while (i != startwall); - - return cnt; -} - -#if 0 -static int32_t numloopsofsector(int16_t sectnum) -{ - int32_t i, numloops, startwall, endwall; - - numloops = 0; - startwall = sector[sectnum].wallptr; - endwall = startwall + sector[sectnum].wallnum; - for (i=startwall; i= '0' && ch <= '9') - { - int64_t nbig; - if (danum >= 0) - { - nbig = ((int64_t)danum*10)+(ch-'0'); - if (nbig <= (int64_t)maxnumber) danum = nbig; - } - else if (sign) // this extra check isn't hurting anything - { - nbig = ((int64_t)danum*10)-(ch-'0'); - if (nbig >= (int64_t)(-maxnumber)) danum = nbig; - } - } - else if (ch == 8 || ch == 127) // backspace - { - danum /= 10; - } - else if (ch == 13) - { - return 1; - } - else if (ch == '-' && sign) // negate - { - danum = -danum; - } - - *danumptr = danum; - return 0; -} - -int32_t getnumber_autocomplete(const char *namestart, char ch, int32_t *danum, int32_t flags) -{ - if (flags!=1 && flags!=2) - return 0; - - if (flags==2 && *danum<0) - return 0; - - if (isalpha(ch)) - { - char b[2]; - const char *gotstr; - int32_t i, diddel; - - b[0] = ch; - b[1] = 0; - gotstr = getstring_simple(namestart, b, (flags==1)?sizeof(names[0])-1:TAGLAB_MAX-1, flags); - if (!gotstr || !gotstr[0]) - return 0; - - if (flags==1) - { - for (i=0; i 0) - { - *danum = i; - return 1; - } - else - { - // insert new tag - if (*danum > 0 && *danum<32768) - { - diddel = taglab_add(gotstr, *danum); - message("Added label \"%s\" for tag %d%s%s", gotstr, *danum, - diddel?", deleting old ":"", - (!diddel)?"":(diddel==1?"label":"tag")); - return 1; - } - else if (*danum==0) - { - i = taglab_getnextfreetag(NULL); - if (i >= 1) - { - *danum = i; - diddel = taglab_add(gotstr, *danum); - message("%sadded label \"%s\" for tag %d%s%s", - diddel?"Auto-":"Automatically ", gotstr, *danum, - diddel?", deleting old ":"", - (!diddel)?"":(diddel==1?"label":"tag")); - return 1; - } - } - } - } - } - - return 0; -} - -// sign is now used for more than one flag (also _getnumber256): -// 1: sign -// 2: autocomplete names -// 4: autocomplete taglabels -// 8: return -1 if cancelled -int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t)) -{ - char buffer[80], ournamestart[80-17], ch; - int32_t n, danum, oldnum; - uint8_t flags = (sign&(2|4|8))>>1; - sign &= 1; - - danum = num; - oldnum = danum; - - // need to have 4+11+2==17 chars room at the end - // ("^011", max. string length of an int32, "_ ") - Bstrncpyz(ournamestart, namestart, sizeof(ournamestart)); - - keyFlushChars(); - while (keystatus[sc_Escape] == 0) - { - if (handleevents()) - quitevent = 0; - - idle(); - ch = keyGetChar(); - - Bsprintf(buffer, "%s^011%d", ournamestart, danum); - n = Bstrlen(buffer); // maximum is 62+4+11 == 77 - if (totalclock & 32) - Bstrcat(buffer,"_ "); - // max strlen now 79 - _printmessage16("%s", buffer); - - if (func != NULL) - { - Bsnprintf(buffer, sizeof(buffer), "%s", func(danum)); - // printext16(200L-24, ydim-STATUS2DSIZ+20L, editorcolors[9], editorcolors[0], buffer, 0); - printext16(n<<3, ydim-STATUS2DSIZ+128, editorcolors[11], -1, buffer,0); - } - - videoShowFrame(1); - - n = 0; - if (getnumber_internal1(ch, &danum, maxnumber, sign) || - (n=getnumber_autocomplete(ournamestart, ch, &danum, flags&(1+2)))) - { - if (flags==1 || n==0) - printmessage16("%s", buffer); - if (danum != oldnum) - asksave = 1; - oldnum = danum; - break; - } - } - - if (keystatus[sc_Escape] && (flags&4)) - oldnum = -1; - - clearkeys(); - - return oldnum; -} - -static void getnumber_clearline(void) -{ - char cbuf[128]; - int32_t i; - for (i=0; i>3, (signed)sizeof(cbuf)-1); i++) - cbuf[i] = ' '; - cbuf[i] = 0; - printext256(0, 0, whitecol, 0, cbuf, 0); -} - -// sign: |16: don't draw scene -int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t)) -{ - char buffer[80], ournamestart[80-13], ch; - int32_t danum, oldnum; - uint8_t flags = (sign&(2|4|8|16))>>1; - sign &= 1; - - danum = num; - oldnum = danum; - - // need to have 11+2==13 chars room at the end - // (max. string length of an int32, "_ ") - Bstrncpyz(ournamestart, namestart, sizeof(ournamestart)); - - keyFlushChars(); - while (keystatus[sc_Escape] == 0) - { - if (handleevents()) - quitevent = 0; - - if ((flags&8)==0) - M32_DrawRoomsAndMasks(); - - ch = keyGetChar(); - if (keystatus[sc_Escape]) - break; - clearkeys(); - - g_mouseBits = 0; - searchx = osearchx; - searchy = osearchy; - - inputchecked = 1; - - if ((flags&8)==0) - CallExtCheckKeys(); - - getnumber_clearline(); - - Bsprintf(buffer,"%s%d",ournamestart,danum); - // max strlen now 66+11==77 - if (totalclock & 32) - Bstrcat(buffer,"_ "); - // max strlen now 79 - printmessage256(0, 0, buffer); - if (func != NULL) - { - Bsnprintf(buffer, sizeof(buffer), "%s", func(danum)); - printmessage256(0, 9, buffer); - } - - videoShowFrame(1); - - if (getnumber_internal1(ch, &danum, maxnumber, sign) || - getnumber_autocomplete(ournamestart, ch, &danum, flags&(1+2))) - { - if (danum != oldnum) - asksave = 1; - oldnum = danum; - break; - } - } - - if (keystatus[sc_Escape] && (flags&4)) - oldnum = -1; - - clearkeys(); - - lockclock = totalclock; //Reset timing - - return oldnum; -} - -// querystr: e.g. "Name: ", must be !=NULL -// defaultstr: can be NULL -// NO overflow checks are done when copying them! -// maxlen: maximum length of entry string, if ==1, enter single char -// completion: 0=none, 1=names[][], 2=taglabels -const char *getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen, int32_t completion) -{ - static char buf[128]; - int32_t ei=0, qrylen=0, maxidx, havecompl=0; - char ch; - - keyFlushChars(); - clearkeys(); - - Bmemset(buf, 0, sizeof(buf)); - - qrylen = Bstrlen(querystr); - Bmemcpy(buf, querystr, qrylen); - - if (maxlen==0) - maxlen = 64; - - maxidx = min((signed)sizeof(buf), xdim>>3); - - ei = qrylen; - - if (defaultstr) - { - int32_t deflen = Bstrlen(defaultstr); - Bmemcpy(&buf[ei], defaultstr, deflen); - ei += deflen; - } - - buf[ei] = '_'; - buf[ei+1] = 0; - - while (1) - { - if (in3dmode()) - getnumber_clearline(); - - if (in3dmode()) - printext256(0, 0, whitecol, 0, buf, 0); - else - _printmessage16("%s", buf); - - videoShowFrame(1); - - if (handleevents()) - quitevent = 0; - - idle(); - ch = keyGetChar(); - - if (ch==13) - { - if (maxlen != 1) - buf[ei] = 0; - break; - } - else if (keystatus[sc_Escape]) - { - clearkeys(); - return completion ? NULL : defaultstr; - } - - if (maxlen!=1) - { - // blink... - if (totalclock&32) - { - buf[ei] = '_'; - buf[ei+1] = 0; - } - else - { - buf[ei] = 0; - } - - if (ei>qrylen && (ch==8 || ch==127)) - { - buf[ei--] = 0; - buf[ei] = '_'; - havecompl = 0; - } - else if (eiqrylen && ch==9) || havecompl)) // tab: maybe do auto-completion - { - char cmpbuf[128]; - char completions[3][16]; - const char *cmpstr; - int32_t len=ei-qrylen, i, j, k=len, first=1, numcompl=0; - - Bmemcpy(cmpbuf, &buf[qrylen], len); - cmpbuf[len] = 0; - - for (i=(completion!=1); i<((completion==1)?MAXTILES:32768); i++) - { - cmpstr = (completion==1) ? names[i] : taglab_getlabel(i); - if (!cmpstr) - continue; - - if (Bstrncasecmp(cmpbuf, cmpstr, len) || Bstrlen(cmpstr)==(unsigned)len) // compare the prefix - continue; - - if (ch==9) - { - if (first) - { - Bstrncpy(cmpbuf+len, cmpstr+len, sizeof(cmpbuf)-len); - cmpbuf[sizeof(cmpbuf)-1] = 0; - first = 0; - } - else - { - for (k=len; cmpstr[k] && cmpbuf[k] && Btolower(cmpstr[k])==Btolower(cmpbuf[k]); k++) - /* nop */; - cmpbuf[k] = 0; - } - } - - if (numcompl<3) - { - Bstrncpyz(completions[numcompl], cmpstr+len, sizeof(completions[0])); - - for (k=0; completions[numcompl][k]; k++) - completions[numcompl][k] = Btolower(completions[numcompl][k]); - numcompl++; - } - - for (k=len; cmpbuf[k]; k++) - cmpbuf[k] = Btolower(cmpbuf[k]); - } - - ei = qrylen; - for (i=0; i0) // no chars autocompleted/completion request - { - buf[ei] = '{'; - buf[ei+1] = 0; - - i = ei+1; - for (k=0; knext) - if (!Bstrcmp(findfileshigh->name, boardbasename)) - break; - - if (!findfileshigh) - findfileshigh = fnlist.findfiles; -} - -// vvv PK ------------------------------------ -// copied off menuselect - -static int32_t menuselect_auto(int direction, int skip) // 20080104: jump to next (direction!=0) or prev (direction==0) file -{ - Bstrcpy(selectedboardfilename, g_oldpath); - tweak_sboardfilename(); - - getfilenames(selectedboardfilename, "*.map"); - if (fnlist.numfiles==0) - return -2; - - menuselect_try_findlast(); - - do - { - if (direction) - { - if (findfileshigh->next) - findfileshigh=findfileshigh->next; - else - return -1; - } - else - { - if (findfileshigh->prev) - findfileshigh=findfileshigh->prev; - else - return -1; - } - } while (skip--); - - Bstrcat(selectedboardfilename, findfileshigh->name); - - return 0; -} -// ^^^ PK ------------------------------------ - -static int32_t menuselect(void) -{ - int32_t listsize; - int32_t i; - char ch, buffer[96]; - const int32_t bakpathsearchmode = pathsearchmode; - - Bstrcpy(selectedboardfilename, g_oldpath); - tweak_sboardfilename(); - - getfilenames(selectedboardfilename, "*.map"); - - menuselect_try_findlast(); - - _printmessage16("Select map file with arrow keys and enter."); - - ydim16 = ydim-STATUS2DSIZ2; - listsize = (ydim16-32)/9; - - do - { - videoBeginDrawing(); //{{{ - - CLEARLINES2D(0, ydim16, 0); - - if (pathsearchmode) - Bstrcpy(buffer,"Local filesystem mode. Ctrl-F: game filesystem"); - else - Bsnprintf(buffer, sizeof(buffer), - "Game filesystem %smode. Ctrl-F: local filesystem, Ctrl-G: %s", - grponlymode?"GRP-only ":"", grponlymode?"all files":"GRP contents only"); - - printext16(halfxdim16-(8*Bstrlen(buffer)/2), 4, editorcolors[12],editorcolors[0],buffer,0); - - Bsnprintf(buffer, sizeof(buffer), "(%d dirs, %d files) %s", - fnlist.numdirs, fnlist.numfiles, selectedboardfilename); - - printext16(8,ydim16-8-1,editorcolors[8],editorcolors[0],buffer,0); - - if (finddirshigh) - { - const CACHE1D_FIND_REC *dir = finddirshigh; - - for (i=(listsize/2)-1; i>=0; i--) - { - if (!dir->prev) break; - else dir=dir->prev; - } - for (i=0; ((inext) - { - int32_t c = (dir->type == CACHE1D_FIND_DIR ? 2 : 3); //PK - Bmemset(buffer,0,sizeof(buffer)); - Bstrncpy(buffer,dir->name,25); - if (Bstrlen(buffer) == 25) - buffer[21] = buffer[22] = buffer[23] = '.', buffer[24] = 0; - if (dir == finddirshigh) - { - if (currentlist == 0) printext16(8,16+9*i,editorcolors[c|8],editorcolors[0],"->",0); - printext16(32,16+9*i,editorcolors[c|8],editorcolors[0],buffer,0); - } - else - { - printext16(32,16+9*i,editorcolors[c],editorcolors[0],buffer,0); - } - } - } - - if (findfileshigh) - { - const CACHE1D_FIND_REC *dir = findfileshigh; - - for (i=(listsize/2)-1; i>=0; i--) - { - if (!dir->prev) break; - else dir=dir->prev; - } - for (i=0; (inext) - { - if (dir == findfileshigh) - { - if (currentlist == 1) printext16(240,16+9*i,editorcolors[7|8],editorcolors[0],"->",0); - printext16(240+24,16+9*i,editorcolors[7|8],editorcolors[0],dir->name,0); - } - else - { - printext16(240+24,16+9*i,editorcolors[7],editorcolors[0],dir->name,0); - } - } - } - - videoEndDrawing(); //}}} - videoShowFrame(1); - - keystatus[sc_LeftArrow] = 0; - keystatus[sc_RightArrow] = 0; - keystatus[sc_UpArrow] = 0; - keystatus[sc_DownArrow] = 0; - keystatus[sc_Enter] = 0; - keystatus[sc_BackSpace] = 0; - keystatus[sc_Tab] = 0; - keystatus[sc_Escape] = 0; - - ch = 0; //Interesting fakery of ch = getch() - - while (ch == 0) - { - if (handleevents()) - if (quitevent) - { - keystatus[sc_Escape] = 1; - quitevent = 0; - } - - idle(); - - ch = keyGetChar(); - - { - // JBF 20040208: seek to first name matching pressed character - CACHE1D_FIND_REC *seeker = currentlist ? fnlist.findfiles : fnlist.finddirs; - if (keystatus[sc_Home]||keystatus[sc_End]) // home/end - { - while (keystatus[sc_End] ? seeker->next : seeker->prev) - seeker = keystatus[sc_End] ? seeker->next : seeker->prev; - - if (seeker) - { - if (currentlist) findfileshigh = seeker; - else finddirshigh = seeker; - } - ch = keystatus[sc_End] ? 80 : 72; - keystatus[sc_Home] = keystatus[sc_End] = 0; - } - else if (keystatus[sc_PgUp]|keystatus[sc_PgDn]) // page up/down - { - seeker = currentlist?findfileshigh:finddirshigh; - i = (ydim2d-STATUS2DSIZ2-48)>>5/*3*/; //PK - - while (i>0) - { - if (keystatus[sc_PgDn] ? seeker->next : seeker->prev) - seeker = keystatus[sc_PgDn] ? seeker->next : seeker->prev; - i--; - } - if (seeker) - { - if (currentlist) findfileshigh = seeker; - else finddirshigh = seeker; - } - ch = keystatus[sc_PgDn]?80:72; - keystatus[sc_PgUp] = keystatus[sc_PgDn] = 0; - } - else - { - char ch2; - if (ch > 0 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || (ch=='_'))) - { -#ifdef _WIN32 - if (ch >= 'a') ch -= ('a'-'A'); -#endif - while (seeker) - { - ch2 = seeker->name[0]; -#ifdef _WIN32 - if (ch2 >= 'a' && ch2 <= 'z') ch2 -= ('a'-'A'); -#endif - if (ch2 == ch) break; - seeker = seeker->next; - } - if (seeker) - { - if (currentlist) findfileshigh = seeker; - else finddirshigh = seeker; - continue; - } - } - } - } - if (keystatus[sc_LeftArrow]) ch = 9; // left arr - if (keystatus[sc_RightArrow]) ch = 9; // right arr - if (keystatus[sc_UpArrow]) ch = 72; // up arr - if (keystatus[sc_DownArrow]) ch = 80; // down arr - } - - if (ch==6) // Ctrl-F - { - currentlist = 0; - pathsearchmode = 1-pathsearchmode; - if (pathsearchmode) - { - Bstrcpy(selectedboardfilename, ""); - Bcanonicalisefilename(selectedboardfilename, 0); - } - else Bstrcpy(selectedboardfilename, "/"); - - getfilenames(selectedboardfilename, "*.map"); - Bstrcpy(g_oldpath, selectedboardfilename); - } - else if (ch==7) // Ctrl-G - { - if (!pathsearchmode) - { - grponlymode = 1-grponlymode; - getfilenames(selectedboardfilename, "*.map"); - Bstrcpy(g_oldpath, selectedboardfilename); - } - } - else if (ch == 9) - { - if ((currentlist == 0 && fnlist.findfiles) || (currentlist == 1 && fnlist.finddirs)) - currentlist = 1-currentlist; - } - else if (keystatus[sc_UpArrow] /*(ch == 75) || (ch == 72)*/) - { - if (currentlist == 0) - { - if (finddirshigh && finddirshigh->prev) - finddirshigh = finddirshigh->prev; - } - else - { - if (findfileshigh && findfileshigh->prev) - findfileshigh = findfileshigh->prev; - } - } - else if (keystatus[sc_DownArrow] /*(ch == 77) || (ch == 80)*/) - { - if (currentlist == 0) - { - if (finddirshigh && finddirshigh->next) - finddirshigh = finddirshigh->next; - } - else - { - if (findfileshigh && findfileshigh->next) - findfileshigh = findfileshigh->next; - } - } - else if (keystatus[sc_BackSpace]) // backspace - { - Bstrcat(selectedboardfilename, "../"); - tweak_sboardfilename(); - Bstrcpy(g_oldpath, selectedboardfilename); - getfilenames(selectedboardfilename, "*.map"); - keystatus[sc_BackSpace] = 0; - } - else if (ch == 13 && currentlist == 0) - { - if (finddirshigh->type == CACHE1D_FIND_DRIVE) - Bstrcpy(selectedboardfilename, finddirshigh->name); - else - Bstrcat(selectedboardfilename, finddirshigh->name); - - Bstrcat(selectedboardfilename, "/"); - tweak_sboardfilename(); - - Bstrcpy(g_oldpath, selectedboardfilename); - //printf("Changing directories to: %s\n", selectedboardfilename); - - if (finddirshigh == fnlist.finddirs) - { - getfilenames(selectedboardfilename, "*.map"); - currentlist = 0; - } - else getfilenames(selectedboardfilename, "*.map");; - - - ch = 0; - - videoBeginDrawing(); - CLEARLINES2D(0, ydim16, 0); - videoEndDrawing(); - videoShowFrame(1); - } - - if (ch == 13 && !findfileshigh) ch = 0; - } - while (ch != 13 && ch != 27); - - if (ch == 13) - { - Bstrcat(selectedboardfilename, findfileshigh->name); - //printf("Selected file: %s\n", selectedboardfilename); - - return 0; - } - - pathsearchmode = bakpathsearchmode; - - return -1; -} - -#if 0 -static inline int32_t imod(int32_t a, int32_t b) -{ - if (a >= 0) - return a%b; - - return ((a+1)%b)+b-1; -} -#endif - -int32_t fillsector_maybetrans(int16_t sectnum, int32_t fillcolor, uint8_t dotrans) -{ - if (sectnum == -1) - return 0; - - int32_t x1, x2, y1, y2, sy, y, daminy; - int32_t lborder, rborder, uborder, dborder, miny, maxy, dax; - int16_t z, zz, startwall, endwall, fillcnt; - - char col; - - if (fillcolor == -1) - col = editorcolors[14]-(M32_THROB>>1); - else - col = fillcolor; - - lborder = 0; rborder = xdim; - y = OSD_GetRowsCur(); - uborder = (y>=0)?(y+1)*8:0; dborder = ydim16-STATUS2DSIZ2; - - - miny = dborder-1; - maxy = uborder; - - startwall = sector[sectnum].wallptr; - endwall = startwall + sector[sectnum].wallnum - 1; - for (z=startwall; z<=endwall; z++) - { - editorGet2dScreenCoordinates(&x1,&y1, wall[z].x-pos.x,wall[z].y-pos.y, zoom); - if (m32_sideview) - y1 += getscreenvdisp(getflorzofslope(sectnum,wall[z].x,wall[z].y)-pos.z, zoom); - - x1 += halfxdim16; - y1 += midydim16; - - if (m32_sideview) - { - tempxyar[z][0] = x1; - tempxyar[z][1] = y1; - } - - miny = min(miny, y1); - maxy = max(maxy, y1); - } - - if (miny < uborder) miny = uborder; - if (maxy >= dborder) maxy = dborder-1; - - daminy = miny;// +2 - imod(miny+2, 3); - if (sector[sectnum].floorz > minhlsectorfloorz) - daminy++; - -//+((totalclock>>2)&3) - for (sy=daminy; sy<=maxy; sy++) // JBF 20040116: numframes%3 -> (totalclock>>2)&3 - { - y = pos.y + ((sy-midydim16)<<14)/zoom; - - fillist[0] = lborder; fillcnt = 1; - for (z=startwall; z<=endwall; z++) - { - if (m32_sideview) - { - x1 = tempxyar[z][0]; - y1 = tempxyar[z][1]; - x2 = tempxyar[wall[z].point2][0]; - y2 = tempxyar[wall[z].point2][1]; - - if (y1 > y2) - { - swaplong(&x1, &x2); - swaplong(&y1, &y2); - } - - if (y1 <= sy && sy < y2) - { - if (fillcnt == ARRAY_SIZE(fillist)) - break; - - x1 += scale(sy-y1, x2-x1, y2-y1); - fillist[fillcnt++] = x1; - } - } - else - { - x1 = wall[z].x; x2 = POINT2(z).x; - y1 = wall[z].y; y2 = POINT2(z).y; - - if (y1 > y2) - { - swaplong(&x1, &x2); - swaplong(&y1, &y2); - } - - if (y1 <= y && y < y2) - //if (x1*(y-y2) + x2*(y1-y) <= 0) - { - dax = x1 + scale(y-y1, x2-x1, y2-y1); - dax = halfxdim16 + (((dax-pos.x)*zoom)>>14); - if (dax >= lborder) - { - if (fillcnt == ARRAY_SIZE(fillist)) - break; - - fillist[fillcnt++] = dax; - } - } - } - } - - if (fillcnt > 0) - { - for (z=1; z rborder) - break; - if (fillist[z+1] > rborder) - fillist[z+1] = rborder; - - editorDraw2dLine(fillist[z]+1,sy, fillist[z+1]-1,sy, dotrans ? -col : col); //editorcolors[fillcolor] - } - } - } - - return 0; -} - -static int16_t whitelinescan(int16_t sucksect, int16_t dalinehighlight) -{ - int32_t i, j, k; - int16_t tnewnumwalls; - - if (numsectors >= MAXSECTORS) - return MAXWALLS+1; - - Bmemcpy(§or[numsectors], §or[sucksect], sizeof(sectortype)); - sector[numsectors].wallptr = numwalls; - sector[numsectors].wallnum = 0; - - i = dalinehighlight; - tnewnumwalls = numwalls; - do - { - if (tnewnumwalls >= MAXWALLS) - return MAXWALLS+1; - - j = lastwall(i); - if (wall[j].nextwall >= 0) - { - j = wall[j].point2; - for (k=0; kltextptr; - switch (tokn) - { - case T_INCLUDE: - { - char *fn; - if (scriptfile_getstring(script,&fn)) - { - initprintf("Error: Malformed include on line %s:%d\n", - script->filename,scriptfile_getlinum(script,cmdtokptr)); - break; - } - - scriptfile *included; - - included = scriptfile_fromfile(fn); - if (!included) - { - initprintf("Error: Failed including %s on line %s:%d\n", - fn, script->filename,scriptfile_getlinum(script,cmdtokptr)); - break; - } - - initprintf("Including: %s\n", fn); - - syms += parsenamesfile(included); - scriptfile_close(included); - - break; - } - case T_DEFINE: - { - char *name; - int32_t number; - - if (scriptfile_getstring(script,&name)) - { - initprintf("Error: Malformed define on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - - if (scriptfile_getsymbol(script,&number)) - { - initprintf("Error: No number given for name \"%s\" on line %s:%d\n", - name, script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - - if ((unsigned)number >= MAXTILES) - { - initprintf("Error: Constant %d for name \"%s\" out of range on line %s:%d\n", - number, name, script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - - if (Bstrlen(name) > 24) - initprintf("Warning: Truncating name \"%s\" to 24 characters on line %s:%d\n", - name, script->filename, scriptfile_getlinum(script,cmdtokptr)); - - Bstrncpyz(names[number], name, 25); - name = names[number]; - - ++syms; - - if (scriptfile_addsymbolvalue(name,number) < 0) - initprintf("Warning: Symbol %s was NOT redefined to %d on line %s:%d\n", - name, number, script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - case T_EOF: - return syms; - default: - break; - } - } - - return syms; -} - -static void loadnames(const char *namesfile) -{ - scriptfile *script = scriptfile_fromfile(namesfile); - - if (!script) - return; - - initprintf("Loading names file: %s\n", namesfile); - - int32_t const syms = parsenamesfile(script); - initprintf("Loaded %d names.\n", syms); - - scriptfile_close(script); - - scriptfile_clearsymbols(); -} - - -void printcoords16(int32_t posxe, int32_t posye, int16_t ange) -{ - char snotbuf[128]; - int32_t i, m; - int32_t v8 = (numsectors > MAXSECTORSV7 || numwalls > MAXWALLSV7 || - Numsprites > MAXSPRITESV7 || numyaxbunches > 0); -#if M32_UNDO - Bsprintf(snotbuf,"x:%d y:%d ang:%d r%d",posxe,posye,ange,map_revision-1); -#else - Bsprintf(snotbuf,"x:%d y:%d ang:%d",posxe,posye,ange); -#endif - i = 0; - while ((snotbuf[i] != 0) && (i < 33)) - i++; - while (i < 33) - { - snotbuf[i] = 32; - i++; - } - snotbuf[33] = 0; - - clearministatbar16(); - - printext16(8, ydim-STATUS2DSIZ+128, whitecol, -1, snotbuf,0); - - if (highlightcnt<=0 && highlightsectorcnt<=0) - { - m = Bsprintf(snotbuf,"%d/%d %s. %d", - numsectors, v8?MAXSECTORSV8:MAXSECTORSV7, - numyaxbunches>0 ? "SEC":"sec", numwalls); - if (numyaxbunches > 0) - { - if (xdim >= 800) - Bsprintf(&snotbuf[m], "/%d wal. %d/16k spr. %d/256 bn.", - MAXWALLSV8, Numsprites, numyaxbunches); - else - Bsprintf(&snotbuf[m], " wal. %d spr. %d/256 bn.", - Numsprites, numyaxbunches); - } - else - { - if (xdim >= 800) - Bsprintf(&snotbuf[m], "/%d wal. %d/%d spr.", - v8?MAXWALLSV8:MAXWALLSV7, Numsprites, - v8?MAXSPRITESV8:MAXSPRITESV7); - else - Bsprintf(&snotbuf[m], "/%dk wal. %d/%dk spr.", - (v8?MAXWALLSV8:MAXWALLSV7)/1000, Numsprites, - (v8?MAXSPRITESV8:MAXSPRITESV7)/1000); - } - } - else - { - if (highlightcnt>0) - { - m = 0; - for (i=0; i0) - { - int32_t ii=Bsprintf(snotbuf, "%d sectors with a total of %d walls selected", - highlightsectorcnt, numhlsecwalls); - if (m32_rotateang) - Bsprintf(&snotbuf[ii], " (ang=%d)", m32_rotateang); - } - else - { - snotbuf[0] = 0; - } - - v8 = 1; // yellow color - } - - m = xdim/8 - 264/8; - m = clamp(m, 1, (signed)sizeof(snotbuf)-1); - - i = 0; - while (snotbuf[i] && i < m) - i++; - while (i < m) - { - snotbuf[i] = 32; - i++; - } - snotbuf[m] = 0; - - printext16(264, ydim-STATUS2DSIZ+128, v8?editorcolors[10]:whitecol, -1, snotbuf,0); -} - -#define DOPRINT(Yofs, fmt, ...) do { \ - Bsprintf(snotbuf, fmt, ## __VA_ARGS__); \ - printext16(8+col*200, ydim/*-(row*96)*/-STATUS2DSIZ+Yofs, color, -1, snotbuf, 0); \ - } while (0) - -void showsectordata(int16_t sectnum, int16_t small) -{ - char snotbuf[80]; - int32_t col=0; //,row = 0; - int32_t color = small ? whitecol : editorcolors[11]; - - const sectortype *const sec = §or[sectnum]; - - if (small) - { - _printmessage16("^10Sector %d %s ^O(F7 to edit)", sectnum, CallExtGetSectorCaption(sectnum)); - return; - } - - DOPRINT(32, "^10Sector %d", sectnum); - DOPRINT(48, "Firstwall: %d", TrackerCast(sec->wallptr)); - DOPRINT(56, "Numberofwalls: %d", TrackerCast(sec->wallnum)); - DOPRINT(64, "Firstsprite: %d", headspritesect[sectnum]); - DOPRINT(72, "Tags: %d, %d", TrackerCast(sec->hitag), TrackerCast(sec->lotag)); - DOPRINT(80, " (0x%x), (0x%x)", TrackerCast(sec->hitag), TrackerCast(sec->lotag)); - DOPRINT(88, "Extra: %d", TrackerCast(sec->extra)); - DOPRINT(96, "Visibility: %d", TrackerCast(sec->visibility)); - DOPRINT(104, "Pixel height: %d", (sec->floorz-sec->ceilingz)>>8); - - col++; - - DOPRINT(32, "^10CEILING:^O"); - DOPRINT(48, "Flags (hex): %x", TrackerCast(sec->ceilingstat)); - { - int32_t xp=sec->ceilingxpanning, yp=sec->ceilingypanning; -#ifdef YAX_ENABLE__COMPAT - if (yax_getbunch(sectnum, YAX_CEILING) >= 0) - xp = yp = 0; -#endif - DOPRINT(56, "(X,Y)pan: %d, %d", xp, yp); - } - DOPRINT(64, "Shade byte: %d", TrackerCast(sec->ceilingshade)); - DOPRINT(72, "Z-coordinate: %d", TrackerCast(sec->ceilingz)); - DOPRINT(80, "Tile number: %d", TrackerCast(sec->ceilingpicnum)); - DOPRINT(88, "Ceiling heinum: %d", TrackerCast(sec->ceilingheinum)); - DOPRINT(96, "Palookup number: %d", TrackerCast(sec->ceilingpal)); -#ifdef YAX_ENABLE - DOPRINT(104, "Bunch number: %d", yax_getbunch(sectnum, YAX_CEILING)); -#endif - - col++; - - DOPRINT(32, "^10FLOOR:^O"); - DOPRINT(48, "Flags (hex): %x", TrackerCast(sec->floorstat)); - { - int32_t xp=sec->floorxpanning, yp=sec->floorypanning; -#ifdef YAX_ENABLE__COMPAT - if (yax_getbunch(sectnum, YAX_FLOOR) >= 0) - xp = yp = 0; -#endif - DOPRINT(56, "(X,Y)pan: %d, %d", xp, yp); - } - DOPRINT(64, "Shade byte: %d", TrackerCast(sec->floorshade)); - DOPRINT(72, "Z-coordinate: %d", TrackerCast(sec->floorz)); - DOPRINT(80, "Tile number: %d", TrackerCast(sec->floorpicnum)); - DOPRINT(88, "Floor heinum: %d", TrackerCast(sec->floorheinum)); - DOPRINT(96, "Palookup number: %d", TrackerCast(sec->floorpal)); -#ifdef YAX_ENABLE - DOPRINT(104, "Bunch number: %d", yax_getbunch(sectnum, YAX_FLOOR)); -#endif -} - -void showwalldata(int16_t wallnum, int16_t small) -{ - walltype const * const wal = &wall[wallnum]; - int32_t sec; - char snotbuf[80]; - int32_t col=0; //, row = 0; - int32_t color = small ? whitecol : editorcolors[11]; - - if (small) - { - _printmessage16("^10Wall %d %s ^O(F8 to edit)", wallnum, - CallExtGetWallCaption(wallnum)); - return; - } - - DOPRINT(32, "^10Wall %d", wallnum); - DOPRINT(48, "X-coordinate: %d", TrackerCast(wal->x)); - DOPRINT(56, "Y-coordinate: %d", TrackerCast(wal->y)); - DOPRINT(64, "Point2: %d", TrackerCast(wal->point2)); - DOPRINT(72, "Sector: ^010%d", sectorofwall(wallnum)); - - DOPRINT(88, "Tags: %d, %d", TrackerCast(wal->hitag), TrackerCast(wal->lotag)); - DOPRINT(96, " (0x%x), (0x%x)", TrackerCast(wal->hitag), TrackerCast(wal->lotag)); - - col++; - - DOPRINT(32, "^10%s^O", (wal->picnum>=0 && wal->picnumpicnum] : "!INVALID!"); - DOPRINT(48, "Flags (hex): %x", TrackerCast(wal->cstat)); - DOPRINT(56, "Shade: %d", TrackerCast(wal->shade)); - DOPRINT(64, "Pal: %d", TrackerCast(wal->pal)); - DOPRINT(72, "(X,Y)repeat: %d, %d", TrackerCast(wal->xrepeat), TrackerCast(wal->yrepeat)); - DOPRINT(80, "(X,Y)pan: %d, %d", TrackerCast(wal->xpanning), TrackerCast(wal->ypanning)); - DOPRINT(88, "Tile number: %d", TrackerCast(wal->picnum)); - DOPRINT(96, "OverTile number: %d", TrackerCast(wal->overpicnum)); - - col++; - - DOPRINT(48, "nextsector: %d", TrackerCast(wal->nextsector)); - DOPRINT(56, "nextwall: %d", TrackerCast(wal->nextwall)); - - DOPRINT(72, "Extra: %d", TrackerCast(wal->extra)); - - // TX 20050102 I'm not sure what unit dist<<4 is supposed to be, but dist itself is correct in terms of game coordinates as one would expect - DOPRINT(96, "Wall length: %d", wallength(wallnum)); - - sec = sectorofwall(wallnum); - DOPRINT(104, "Pixel height: %d", (sector[sec].floorz-sector[sec].ceilingz)>>8); -} - -void showspritedata(int16_t spritenum, int16_t small) -{ - spritetype *spr; - char snotbuf[80]; - int32_t col=0; //, row = 0; - int32_t color = small ? whitecol : editorcolors[11]; - - spr = &sprite[spritenum]; - - if (small) - { - _printmessage16("^10Sprite %d %s ^O(F8 to edit)",spritenum, CallExtGetSpriteCaption(spritenum)); - return; - } - - DOPRINT(32, "^10Sprite %d", spritenum); - DOPRINT(48, "X-coordinate: %d", TrackerCast(spr->x)); - DOPRINT(56, "Y-coordinate: %d", TrackerCast(spr->y)); - DOPRINT(64, "Z-coordinate: %d", TrackerCast(spr->z)); - - DOPRINT(72, "Sectnum: ^010%d", TrackerCast(spr->sectnum)); - DOPRINT(80, "Statnum: %d", TrackerCast(spr->statnum)); - - DOPRINT(96, "Tags: %d, %d", TrackerCast(spr->hitag), TrackerCast(spr->lotag)); - DOPRINT(104, " (0x%x), (0x%x)", TrackerCast(spr->hitag), TrackerCast(spr->lotag)); - - col++; - - DOPRINT(32, "^10,0 ^O"); // 24 blanks - DOPRINT(32, "^10%s^O", (spr->picnum>=0 && spr->picnumpicnum] : "!INVALID!"); - DOPRINT(48, "Flags (hex): %x", TrackerCast(spr->cstat)); - DOPRINT(56, "Shade: %d", TrackerCast(spr->shade)); - DOPRINT(64, "Pal: %d", TrackerCast(spr->pal)); - DOPRINT(72, "Blend: %d", TrackerCast(spr->blend)); - DOPRINT(80, "(X,Y)repeat: %d, %d", TrackerCast(spr->xrepeat), TrackerCast(spr->yrepeat)); - DOPRINT(88, "(X,Y)offset: %d, %d", TrackerCast(spr->xoffset), TrackerCast(spr->yoffset)); - DOPRINT(96, "Tile number: %d", TrackerCast(spr->picnum)); - - col++; - - DOPRINT(48, "Angle (2048 degrees): %d", TrackerCast(spr->ang)); - DOPRINT(56, "X-Velocity: %d", TrackerCast(spr->xvel)); - DOPRINT(64, "Y-Velocity: %d", TrackerCast(spr->yvel)); - DOPRINT(72, "Z-Velocity: %d", TrackerCast(spr->zvel)); - DOPRINT(80, "Owner: %d", TrackerCast(spr->owner)); - DOPRINT(88, "Clipdist: %d", TrackerCast(spr->clipdist)); - DOPRINT(96, "Extra: %d", TrackerCast(spr->extra)); -} - -#undef DOPRINT - -// gets called once per totalclock increment since last call -static void keytimerstuff(void) -{ - if (!g_doHardcodedMovement) - return; - - if (DOWN_BK(STRAFE) == 0) - { - if (DOWN_BK(TURNLEFT)) angvel = max(angvel-pk_turnaccel, -127); - if (DOWN_BK(TURNRIGHT)) angvel = min(angvel+pk_turnaccel, 127); - } - else - { - if (DOWN_BK(TURNLEFT)) svel = min(svel+16, 255); // svel and vel aren't even chars... - if (DOWN_BK(TURNRIGHT)) svel = max(svel-16, -255); - } - if (DOWN_BK(MOVEFORWARD)) vel = min(vel+16, 255); - if (DOWN_BK(MOVEBACKWARD)) vel = max(vel-16, -255); - /* if (DOWN_BK(STRAFELEFT)) svel = min(svel+8, 127); - if (DOWN_BK(STRAFERIGHT)) svel = max(svel-8, -128); */ - - if (angvel < 0) angvel = min(angvel+pk_turndecel, 0); - if (angvel > 0) angvel = max(angvel-pk_turndecel, 0); - if (svel < 0) svel = min(svel+6, 0); - if (svel > 0) svel = max(svel-6, 0); - if (vel < 0) vel = min(vel+6, 0); - if (vel > 0) vel = max(vel-6, 0); - /* if(mlook) pos.z -= (horiz-101)*(vel/40); */ -} - -#if 0 -int32_t snfillprintf(char *outbuf, size_t bufsiz, int32_t fill, const char *fmt, ...) -{ - char tmpstr[256]; - int32_t nwritten, ofs; - va_list va; - - va_start(va, fmt); - nwritten = Bvsnprintf(tmpstr, bufsiz, fmt, va); - va_end(va); - - ofs = min(nwritten, (signed)bufsiz-1); - Bmemset(outbuf, fill, bufsiz-ofs); - - return ofs; -} -#endif - -void _printmessage16(const char *fmt, ...) -{ - int32_t i, ybase; - char snotbuf[156]; - char tmpstr[160]; - va_list va; - - va_start(va, fmt); - Bvsnprintf(tmpstr, sizeof(tmpstr), fmt, va); - va_end(va); - - i = 0; - while (tmpstr[i] && i < 146) - { - snotbuf[i] = tmpstr[i]; - i++; - } - snotbuf[i] = 0; - if (lastpm16time == totalclock) - Bstrcpy(lastpm16buf, snotbuf); - - clearministatbar16(); - - ybase = ydim-STATUS2DSIZ+128-8; - - printext16(8, ybase+8, whitecol, -1, snotbuf, 0); -} - -void printmessage256(int32_t x, int32_t y, const char *name) -{ - char snotbuf[80]; - int32_t i; - - i = 0; - while (name[i] && i < 62) - { - snotbuf[i] = name[i]; - i++; - } - while (i < 62) - { - snotbuf[i] = 32; - i++; - } - snotbuf[62] = 0; - printext256(x+2,y+2,0,-1,snotbuf,0); - printext256(x,y,whitecol,-1,snotbuf,0); -} - -//Find closest point (*dax, *day) on wall (dawall) to (x, y) -static void getclosestpointonwall(int32_t x, int32_t y, int32_t dawall, int32_t *nx, int32_t *ny, - int32_t maybe_screen_coord_p) -{ - int64_t i, j, wx,wy, wx2,wy2, dx, dy; - - if (m32_sideview && maybe_screen_coord_p) - { - wx = m32_wallscreenxy[dawall][0]; - wy = m32_wallscreenxy[dawall][1]; - wx2 = m32_wallscreenxy[wall[dawall].point2][0]; - wy2 = m32_wallscreenxy[wall[dawall].point2][1]; - } - else - { - wx = wall[dawall].x; - wy = wall[dawall].y; - wx2 = POINT2(dawall).x; - wy2 = POINT2(dawall).y; - } - - dx = wx2 - wx; - dy = wy2 - wy; - i = dx*(x-wx) + dy*(y-wy); - if (i <= 0) { *nx = wx; *ny = wy; return; } - j = dx*dx + dy*dy; - if (i >= j) { *nx = wx2; *ny = wy2; return; } - i=((i<<15)/j)<<15; - *nx = wx + ((dx*i)>>30); - *ny = wy + ((dy*i)>>30); -} - -static void initcrc(void) -{ - int32_t i, j, k, a; - - for (j=0; j<256; j++) //Calculate CRC table - { - k = (j<<8); a = 0; - for (i=7; i>=0; i--) - { - if (((k^a)&0x8000) > 0) - a = ((a<<1)&65535) ^ 0x1021; //0x1021 = genpoly - else - a = ((a<<1)&65535); - k = ((k<<1)&65535); - } - crctable[j] = (a&65535); - } -} - -static int32_t GetWallBaseZ(int32_t wallnum) -{ - int32_t z=0; - - const int32_t sectnum = sectorofwall(wallnum); - const int32_t nextsec = wall[wallnum].nextsector; - - if (nextsec == -1) //1-sided wall - { - if (wall[wallnum].cstat&4) // floor-aligned - z = sector[sectnum].floorz; - else - z = sector[sectnum].ceilingz; - } - else //2-sided wall - { - if (wall[wallnum].cstat&4) - z = sector[sectnum].ceilingz; - else - { - if (sector[nextsec].ceilingz > sector[sectnum].ceilingz) - z = sector[nextsec].ceilingz; //top step - if (sector[nextsec].floorz < sector[sectnum].floorz) - z = sector[nextsec].floorz; //bottom step - } - } - - return z; -} - - -////////// AUTOMATIC WALL ALIGNMENT ////////// - -static void AlignWalls_(int32_t tilenum, int32_t z0, int32_t z1, int32_t doxpanning, - int32_t w0_pan, int32_t w0_rep, int32_t w1_pan, int32_t w1_rep) -{ - int32_t n; - - if (tilesiz[tilenum].x==0 || tilesiz[tilenum].y==0) - return; - - //do the x alignment - if (doxpanning) - wall[w1_pan].xpanning = (uint8_t)((wall[w0_pan].xpanning + (wall[w0_rep].xrepeat<<3))%tilesiz[tilenum].x); - - for (n=picsiz[tilenum]>>4; (1<>(n+3))); -} - -static void AlignWalls(int32_t w0, int32_t z0, int32_t w1, int32_t z1, int32_t doxpanning) -{ - AlignWalls_(wall[w0].picnum, z0, z1, doxpanning, w0, w0, w1, w1); -} - -void AlignWallPoint2(int32_t w0) -{ - int32_t w1 = wall[w0].point2; - AlignWalls(w0,GetWallBaseZ(w0), w1,GetWallBaseZ(w1), 1); -} - -#define ALIGN_WALLS_CSTAT_MASK (4+8+256) - -static int32_t AlignGetWall(int32_t botswap, int32_t w) -{ - return botswap && (wall[w].cstat&2) && wall[w].nextwall >= 0 ? wall[w].nextwall : w; -} - -// flags: -// 1: more than once -// 2: (unused) -// 4: carry pixel width from first wall over to the rest -// 8: align TROR nextwalls -// 16: iterate lastwall()s (point2 in reverse) -// 32: use special logic for 'bottom-swapped' walls -int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) -{ - static int numaligned, wall0; - static int32_t cstat0; - static uint32_t lenrepquot; - - int const totheleft = flags & 16; - int const botswap = flags & 32; - - int32_t z0 = GetWallBaseZ(w0); - int32_t w1 = totheleft ? lastwall(w0) : wall[w0].point2; - int32_t w0b = AlignGetWall(botswap, w0); - - if (nrecurs == 0) - { - //clear visited bits - Bmemset(visited, 0, sizeof(visited)); - visited[w0>>3] |= (1<<(w0&7)); - numaligned = 0; - lenrepquot = getlenbyrep(wallength(w0), wall[w0].xrepeat); - wall0 = w0; - cstat0 = wall[w0b].cstat & ALIGN_WALLS_CSTAT_MASK; // top/bottom orientation; x/y-flip - } - - int const tilenum = wall[w0b].picnum; - int const rotated = wall[w0b].cstat & CSTAT_WALL_ROTATE_90; - - //loop through walls at this vertex in point2 order - do - { - int const w1b = AlignGetWall(botswap, w1); - - //break if this wall would connect us in a loop - if (visited[w1>>3]&(1<<(w1&7))) - break; - - visited[w1>>3] |= (1<<(w1&7)); - -#ifdef YAX_ENABLE - if (flags&8) - { - for (int cf=0; cf<2; cf++) - { - int const ynw = yax_getnextwall(w0, cf); - - if (ynw >= 0 && wall[ynw].picnum == tilenum && ((wall[ynw].cstat & CSTAT_WALL_ROTATE_90) == rotated) - && (visited[ynw >> 3] & (1 << (ynw & 7))) == 0) - { - wall[ynw].xrepeat = wall[w0].xrepeat; - wall[ynw].xpanning = wall[w0].xpanning; - AlignWalls(w0,z0, ynw,GetWallBaseZ(ynw), 0); // initial vertical alignment - } - } - } -#endif - - //break if reached back of left wall - if (wall[w1].nextwall == w0) - break; - - if (wall[w1b].picnum == tilenum && ((wall[w1b].cstat & CSTAT_WALL_ROTATE_90) == rotated)) - { - bool visible = true; - int const nextsec = wall[w1].nextsector; - - if (nextsec >= 0) - { - int const sectnum = NEXTWALL(w1).nextsector; - - //ignore two sided walls that have no visible face - // TODO: can be more precise (i.e. taking into account the wall face) - // ... needs to be factored out from some engine code maybe... - // as is the whole "z base" determination. - - int32_t cz,fz, czn,fzn; - getzsofslope(sectnum, wall[w1].x,wall[w1].y, &cz, &fz); - getzsofslope(nextsec, wall[w1].x,wall[w1].y, &czn, &fzn); - - if (czn <= cz && fzn >= fz) - visible = false; - } - - if (visible) - { - const int32_t z1 = GetWallBaseZ(w1); - - if ((flags&4) && w1!=wall0) - fixxrepeat(w1, lenrepquot); - - AlignWalls_(tilenum,z0, z1, 1, w0b, w0, w1b, w1); - wall[w1b].cstat &= ~ALIGN_WALLS_CSTAT_MASK; - wall[w1b].cstat |= cstat0; - numaligned++; - - if ((flags&1)==0) - return 1; - - //if wall was 1-sided, no need to recurse - if (wall[w1].nextwall < 0) - { - w0 = w1; - w0b = AlignGetWall(botswap, w0); - z0 = GetWallBaseZ(w0); - w1 = totheleft ? lastwall(w0) : wall[w0].point2; - - continue; - } - - AutoAlignWalls(w1, flags, nrecurs+1); - } - } - - if (wall[w1].nextwall < 0) - break; - w1 = totheleft ? lastwall(wall[w1].nextwall) : NEXTWALL(w1).point2; - } while (1); - - return numaligned; -} - -#define PLAYTEST_MAPNAME "autosave_playtest.map" - -void test_map(int32_t mode) -{ - if (!mode) - updatesector(pos.x, pos.y, &cursectnum); - else - updatesector(startpos.x, startpos.y, &startsectnum); - -#ifdef _WIN32 - if (fullscreen) - { - printmessage16("Must be in windowed mode to test map!"); - return; - } -#endif - - if ((!mode && cursectnum >= 0) || (mode && startsectnum >= 0)) - { - char const *param = " -map " PLAYTEST_MAPNAME " -noinstancechecking"; - char current_cwd[BMAX_PATH]; - int32_t slen = 0; - buildvfs_FILE fp; - - if ((program_origcwd[0] == '\0') || !buildvfs_getcwd(current_cwd, BMAX_PATH)) - current_cwd[0] = '\0'; - else // Before we check if file exists, for the case there's no absolute path. - buildvfs_chdir(program_origcwd); - - fp = buildvfs_fopen_read(game_executable); // File exists? - if (fp != NULL) - buildvfs_fclose(fp); - else - { - char const * lastslash = (char const *)Bstrrchr(mapster32_fullpath, '/'); -#ifdef _WIN32 - char const * lastbackslash = (char const *)Bstrrchr(mapster32_fullpath, '\\'); - lastslash = max(lastslash, lastbackslash); -#endif - if (lastslash) - { - slen = lastslash-mapster32_fullpath+1; - Bstrncpy(game_executable, mapster32_fullpath, slen); - Bstrncpy(game_executable+slen, DefaultGameExec, sizeof(game_executable)-slen); - } - else - Bstrncpy(game_executable, DefaultGameLocalExec, sizeof(game_executable)); - } - - if (current_cwd[0] != '\0') // Temporarily changing back, - buildvfs_chdir(current_cwd); // after checking if file exists. - - if (testplay_addparam) - slen = Bstrlen(testplay_addparam); - - // Considering the NULL character, quatation marks - // and a possible extra space not in testplay_addparam, - // the length should be Bstrlen(game_executable)+Bstrlen(param)+(slen+1)+2+1. - - char *fullparam = (char *)Xmalloc(Bstrlen(game_executable)+Bstrlen(param)+slen+4); - Bsprintf(fullparam,"\"%s\"",game_executable); - - if (testplay_addparam) - { - Bstrcat(fullparam, " "); - Bstrcat(fullparam, testplay_addparam); - } - Bstrcat(fullparam, param); - - CallExtPreSaveMap(); - if (mode) - saveboard(PLAYTEST_MAPNAME, &startpos, startang, startsectnum); - else - saveboard(PLAYTEST_MAPNAME, &pos, ang, cursectnum); - - message("Board saved to " PLAYTEST_MAPNAME ". Starting the game..."); - OSD_Printf("...as `%s'\n", fullparam); - - videoShowFrame(1); - mouseUninit(); -#ifdef _WIN32 - { - STARTUPINFO si; - PROCESS_INFORMATION pi; - - ZeroMemory(&si,sizeof(si)); - ZeroMemory(&pi,sizeof(pi)); - si.cb = sizeof(si); - - if (!CreateProcess(NULL,fullparam,NULL,NULL,0,0,NULL,NULL,&si,&pi)) - message("Error launching the game!"); - else WaitForSingleObject(pi.hProcess,INFINITE); - } -#else - if (current_cwd[0] != '\0') - { - buildvfs_chdir(program_origcwd); - if (system(fullparam)) - message("Error launching the game!"); - buildvfs_chdir(current_cwd); - } - else system(fullparam); -#endif - printmessage16("Game process exited"); - mouseInit(); - clearkeys(); - - Bfree(fullparam); - } - else - printmessage16("Position must be in valid player space to test map!"); -} - -void app_crashhandler(void) -{ - if (levelname[0]) - { - append_ext_UNSAFE(levelname, "_crash.map"); - SaveBoard(levelname, M32_SB_NOEXT); - } -} - -// These will be more useful in the future... -static const char *CallExtGetVer(void) -{ - return ExtGetVer(); -} -static int32_t CallExtInit(void) -{ - return ExtInit(); -} -static int32_t CallExtPreInit(int32_t argc,char const * const * argv) -{ - return ExtPreInit(argc, argv); -} -static int32_t CallExtPostStartupWindow(void) -{ - return ExtPostStartupWindow(); -} -static void CallExtPostInit(void) -{ - return ExtPostInit(); -} -static void CallExtUnInit(void) -{ - ExtUnInit(); -} -static void CallExtPreCheckKeys(void) -{ - ExtPreCheckKeys(); -} -static void CallExtAnalyzeSprites(int32_t ourx, int32_t oury, int32_t oura, int32_t smoothr) -{ - ExtAnalyzeSprites(ourx, oury, oura, smoothr); - VM_OnEvent(EVENT_ANALYZESPRITES, -1); -} -static void CallExtCheckKeys(void) -{ - ExtCheckKeys(); -} -static void CallExtPreLoadMap(void) -{ - VM_OnEvent(EVENT_PRELOADMAP, -1); - ExtPreLoadMap(); -} -static void CallExtSetupMapFilename(const char *mapname) -{ - Bstrncpy(levelname, mapname, sizeof(levelname)); - - Bsnprintf(tempbuf, sizeof(tempbuf), "%s - %s", AppProperName, mapname); - wm_setapptitle(tempbuf); - - ExtSetupMapFilename(mapname); -} -static void CallExtLoadMap(const char *mapname) -{ - CallExtSetupMapFilename(mapname); - ExtLoadMap(mapname); - VM_OnEvent(EVENT_LOADMAP, -1); -} -static int32_t CallExtPreSaveMap(void) -{ - VM_OnEvent(EVENT_PRESAVEMAP, -1); - return ExtPreSaveMap(); -} -static void CallExtSaveMap(const char *mapname) -{ - ExtSaveMap(mapname); - saveboard("backup.map", &pos, ang, cursectnum); - VM_OnEvent(EVENT_SAVEMAP, -1); -} -static void CallExtShowSectorData(int16_t sectnum) -{ - ExtShowSectorData(sectnum); -} -static void CallExtShowWallData(int16_t wallnum) -{ - ExtShowWallData(wallnum); -} -static void CallExtShowSpriteData(int16_t spritenum) -{ - ExtShowSpriteData(spritenum); -} -static void CallExtEditSectorData(int16_t sectnum) -{ - ExtEditSectorData(sectnum); -} -static void CallExtEditWallData(int16_t wallnum) -{ - ExtEditWallData(wallnum); -} -static void CallExtEditSpriteData(int16_t spritenum) -{ - ExtEditSpriteData(spritenum); -} -#if 0 -static const char *CallExtGetSectorType(int32_t lotag) -{ - return ExtGetSectorType(lotag); -} -#endif