* Support for entering names instead of numbers in various contexts (TAB-autocompletion included): first, when querying for a tile number, and second:

* Tag labeling system for 'link'-type tags, including saving and restoring the tag labels to a separate file '<mapname>.maptags'.  Whether a tag is eligible for linking, is determined by a hardcoded (but extensible via m32script) function.


git-svn-id: https://svn.eduke32.com/eduke32@1867 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-04-17 17:01:20 +00:00
parent a2b3b6006c
commit 64e22b9c6f
7 changed files with 836 additions and 244 deletions

View file

@ -765,9 +765,10 @@ typedef struct
void hash_init(hashtable_t *t);
void hash_free(hashtable_t *t);
int32_t hash_findcase(hashtable_t *t, const char *s);
int32_t hash_find(hashtable_t *t, const char *s);
int32_t hash_findcase(const hashtable_t *t, const char *s);
int32_t hash_find(const hashtable_t *t, const char *s);
void hash_add(hashtable_t *t, const char *s, int32_t key, int32_t replace);
void hash_delete(hashtable_t *t, const char *s);
#ifdef POLYMER
# include "polymer.h"

View file

@ -143,6 +143,10 @@ void editinput(void);
void clearmidstatbar16(void);
void fade_editor_screen(void);
// internal getnumber* helpers:
extern int32_t getnumber_internal1(char ch, int32_t *danumptr, int32_t maxnumber, char sign);
extern int32_t getnumber_autocomplete(const char *namestart, char ch, int32_t *danum, int32_t flags);
int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t));
#define getnumber256(namestart, num, maxnumber, sign) _getnumber256(namestart, num, maxnumber, sign, NULL)
int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t));
@ -150,8 +154,7 @@ int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char
void printmessage256(int32_t x, int32_t y, const char *name);
void message(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
// currently only for 3d mode
const char* getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen);
const char* getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen, int32_t completion);
// like snprintf, but pads the output buffer with 'fill' at the end
//int32_t snfillprintf(char *outbuf, size_t bufsiz, int32_t fill, const char *fmt, ...);
@ -187,6 +190,24 @@ extern uint8_t hlsectorbitmap[MAXSECTORS>>3];
void test_map(int32_t mode);
////////// tag labeling system //////////
// max (strlen+1), i.e. array length to allocate for a tag label:
#define TAGLAB_MAX 40
extern int32_t taglab_load(const char *filename, int32_t flags);
extern int32_t taglab_save(const char *mapname);
extern void taglab_init();
extern int32_t taglab_add(const char *label, int16_t tag);
extern const char *taglab_getlabel(int16_t tag);
extern int32_t taglab_gettag(const char *label);
extern int32_t taglab_linktags(int32_t spritep, int32_t num);
extern int32_t taglab_getnextfreetag(void);
extern int32_t showtags;
#define NEXTWALL(i) (wall[wall[i].nextwall])
#define POINT2(i) (wall[wall[i].point2])
#define SPRITESEC(j) (sector[sprite[j].sectnum])

View file

@ -94,6 +94,7 @@ enum GameEvent_t {
EVENT_KEYS3D,
EVENT_PREKEYS2D,
EVENT_PREKEYS3D,
EVENT_LINKTAGS,
MAXEVENTS
};

View file

@ -97,7 +97,7 @@ extern int16_t searchsector, searchwall, searchstat; //search output
int32_t osearchx, osearchy; //old search input
extern int16_t pointhighlight, linehighlight, highlightcnt;
int32_t grid = 3, autogrid = 0, gridlock = 1, showtags = 1;
int32_t grid = 3, autogrid = 0, gridlock = 1, showtags = 2;
int32_t zoom = 768, gettilezoom = 1;
int32_t lastpm16time = 0;
@ -190,6 +190,7 @@ int8_t sideview_reversehrot = 0;
char lastpm16buf[156];
//static int32_t checksectorpointer_warn = 0;
static int32_t saveboard_savedtags=0;
char changechar(char dachar, int32_t dadir, char smooshyalign, char boundcheck);
static int32_t adjustmark(int32_t *xplc, int32_t *yplc, int16_t danumwalls);
@ -405,6 +406,8 @@ static void reset_default_mapstate(void)
numsprites = 0;
initspritelists();
taglab_init();
#ifdef YAX_ENABLE
yax_resetbunchnums();
#endif
@ -516,6 +519,8 @@ int32_t app_main(int32_t argc, const char **argv)
if (k>0)
initprintf("There was an error loading the sprite clipping map (status %d).\n", k);
taglab_init();
if (LoadBoard(boardfilename, 1))
reset_default_mapstate();
@ -2257,7 +2262,7 @@ void overheadeditor(void)
draw2dscreen(&pos,cursectnum,ang,zoom,grid);
begindrawing(); //{{{
if (showtags == 1)
if (showtags)
{
if (zoom >= 768)
{
@ -2799,14 +2804,18 @@ void overheadeditor(void)
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);
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);
wall[i].hitag = getnumber16(buffer, wall[i].hitag, BTAG_MAX, 0+j);
}
}
else
@ -5366,7 +5375,8 @@ CANCEL:
f = SaveBoard(selectedboardfilename, 0);
if (f)
printmessage16("Saved board to %s.", f);
printmessage16("Saved board %sto %s.",
saveboard_savedtags?"and tags ":"", f);
else
printmessage16("Saving board failed.");
@ -5390,7 +5400,8 @@ CANCEL:
f = SaveBoard(NULL, 0);
if (f)
printmessage16("Saved board to %s.", f);
printmessage16("Saved board %sto %s.",
saveboard_savedtags?"and tags ":"", f);
else
printmessage16("Saving board failed.");
@ -5571,12 +5582,14 @@ static int32_t ask_above_or_below(void)
}
#endif
// flags: 1:no ExSaveMap (backup.map)
// flags: 1:no ExSaveMap (backup.map) and no taglabels saving
const char *SaveBoard(const char *fn, uint32_t flags)
{
const char *f;
int32_t ret;
saveboard_savedtags = 0;
if (!fn)
fn = boardfilename;
@ -5598,7 +5611,10 @@ const char *SaveBoard(const char *fn, uint32_t flags)
ExtPreSaveMap();
ret = saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum);
if ((flags&1)==0)
{
ExtSaveMap(f);
saveboard_savedtags = !taglab_save(f);
}
if (!ret)
return f;
@ -5610,7 +5626,7 @@ const char *SaveBoard(const char *fn, uint32_t flags)
// 4: passed to loadboard flags (no polymer_loadboard); implies no maphack loading
int32_t LoadBoard(const char *filename, uint32_t flags)
{
int32_t i;
int32_t i, tagstat, loadingflags=(!pathsearchmode&&grponlymode?2:0);
if (!filename)
filename = selectedboardfilename;
@ -5630,29 +5646,29 @@ int32_t LoadBoard(const char *filename, uint32_t flags)
for (i=0; i<MAXSPRITES; i++) sprite[i].extra = -1;
ExtPreLoadMap();
i = loadboard(boardfilename,(flags&4)|(!pathsearchmode&&grponlymode?2:0),
&pos.x,&pos.y,&pos.z,&ang,&cursectnum);
if (i == -2) i = loadoldboard(boardfilename,(!pathsearchmode&&grponlymode?2:0),
&pos.x,&pos.y,&pos.z,&ang,&cursectnum);
i = loadboard(boardfilename,(flags&4)|loadingflags, &pos.x,&pos.y,&pos.z,&ang,&cursectnum);
if (i == -2)
i = loadoldboard(boardfilename,loadingflags, &pos.x,&pos.y,&pos.z,&ang,&cursectnum);
if (i < 0)
{
// printmessage16("Invalid map format.");
return i;
}
if ((flags&4)==0)
loadmhk(0);
tagstat = taglab_load(boardfilename, loadingflags);
ExtLoadMap(boardfilename);
if (mapversion < 7)
message("Map %s loaded successfully and autoconverted to V7!",boardfilename);
else
{
if ((flags&4)==0)
loadmhk(0);
ExtLoadMap(boardfilename);
if (mapversion < 7) message("Map %s loaded successfully and autoconverted to V7!",boardfilename);
else
{
i = CheckMapCorruption(4, 0);
message("Loaded map %s %s",boardfilename, i==0?"successfully":
(i<4 ? "(moderate corruption)" : "(HEAVY corruption)"));
}
i = CheckMapCorruption(4, 0);
message("Loaded map %s%s %s", boardfilename, tagstat==0?" w/tags":"",
i==0?"successfully": (i<4 ? "(moderate corruption)" : "(HEAVY corruption)"));
}
updatenumsprites();
@ -6247,7 +6263,7 @@ static int32_t numloopsofsector(int16_t sectnum)
}
#endif
static int32_t getnumber_internal1(char ch, const char *buffer, int32_t *danumptr, int32_t *oldnum, int32_t maxnumber, char sign)
int32_t getnumber_internal1(char ch, int32_t *danumptr, int32_t maxnumber, char sign)
{
int32_t danum = *danumptr;
@ -6271,10 +6287,6 @@ static int32_t getnumber_internal1(char ch, const char *buffer, int32_t *danumpt
}
else if (ch == 13)
{
*oldnum = danum;
asksave = 1;
if (qsetmode!=200)
printmessage16("%s", buffer);
return 1;
}
else if (ch == '-' && sign) // negate
@ -6286,10 +6298,86 @@ static int32_t getnumber_internal1(char ch, const char *buffer, int32_t *danumpt
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<MAXTILES; i++)
if (!Bstrcasecmp(names[i], gotstr))
{
*danum = i;
return 1;
}
}
else
{
i = taglab_gettag(gotstr);
//initprintf("taglab: s=%s, i=%d\n",gotstr,i);
if (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();
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:
// 1: sign
// 2: autocomplete names
// 4: autocomplete taglabels
int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t))
{
char buffer[80], ch;
int32_t n, danum, oldnum;
uint8_t flags = (sign>>1)&3;
sign &= 1;
danum = num;
oldnum = danum;
@ -6310,15 +6398,24 @@ int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char
if (func != NULL)
{
Bsprintf(buffer, "^011%s", (char *)func(danum));
Bsprintf(buffer, "%s", (char *)func(danum));
// printext16(200L-24, ydim-STATUS2DSIZ+20L, editorcolors[9], editorcolors[0], buffer, 0);
printext16(n<<3, ydim-STATUS2DSIZ+128, editorcolors[9], -1, buffer,0);
printext16(n<<3, ydim-STATUS2DSIZ+128, editorcolors[11], -1, buffer,0);
}
showframe(1);
if (getnumber_internal1(ch, buffer, &danum, &oldnum, maxnumber, sign))
n = 0;
if (getnumber_internal1(ch, &danum, maxnumber, sign) ||
(n=getnumber_autocomplete(namestart, ch, &danum, flags)))
{
if (flags==1 || n==0)
printmessage16("%s", buffer);
if (danum != oldnum)
asksave = 1;
oldnum = danum;
break;
}
}
clearkeys();
@ -6330,6 +6427,8 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
{
char buffer[80], ch;
int32_t danum, oldnum;
uint8_t flags = (sign>>1)&3;
sign &= 1;
danum = num;
oldnum = danum;
@ -6376,8 +6475,14 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
showframe(1);
if (getnumber_internal1(ch, buffer, &danum, &oldnum, maxnumber, sign))
if (getnumber_internal1(ch, &danum, maxnumber, sign) ||
getnumber_autocomplete(namestart, ch, &danum, flags))
{
if (danum != oldnum)
asksave = 1;
oldnum = danum;
break;
}
}
clearkeys();
@ -6391,23 +6496,26 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
// defaultstr: can be NULL
// NO overflow checks are done when copying them!
// maxlen: maximum length of entry string, if ==1, enter single char
const char *getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen)
// 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;
int32_t ei=0, qrylen=0, maxidx, havecompl=0;
char ch;
bflushchars();
clearkeys();
if (maxlen==0)
maxlen = 1000;
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)
@ -6417,25 +6525,32 @@ const char *getstring_simple(const char *querystr, const char *defaultstr, int32
ei += deflen;
}
buf[ei] = 0;
if (maxlen==1)
{
ei = qrylen;
buf[ei] = '_';
buf[ei+1] = 0;
}
buf[ei] = '_';
buf[ei+1] = 0;
while (1)
{
printext256(0, 0, whitecol, 0, buf, 0);
if (qsetmode==200)
{
char cbuf[128];
int32_t i;
for (i=0; i<min(xdim>>3, (signed)sizeof(cbuf)-1); i++)
cbuf[i] = ' ';
cbuf[i] = 0;
printext256(0, 0, whitecol, 0, cbuf, 0);
}
if (qsetmode==200)
printext256(0, 0, whitecol, 0, buf, 0);
else
_printmessage16("%s", buf);
showframe(1);
if (handleevents())
quitevent = 0;
idle_waitevent();
idle();
ch = bgetchar();
if (ch==13)
@ -6447,22 +6562,113 @@ const char *getstring_simple(const char *querystr, const char *defaultstr, int32
else if (keystatus[1])
{
clearkeys();
return defaultstr;
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] = ' ';
buf[--ei] = '_';
buf[ei--] = 0;
buf[ei] = '_';
havecompl = 0;
}
else if ((unsigned)ei<sizeof(buf)-2 && ei-qrylen<maxlen && isprint(ch))
else if (ei<maxidx-2 && ei-qrylen<maxlen && isprint(ch))
{
if (completion==2 && ch==' ')
ch = '_';
buf[ei++] = ch;
buf[ei] = '_';
buf[ei+1] = 0;
}
if (completion && ((ei>qrylen && 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)
{
Bstrncpy(completions[numcompl], cmpstr+len, sizeof(completions[0]));
completions[numcompl][sizeof(completions[0])-1] = 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; i<k && i<maxlen && ei<maxidx-2; i++)
buf[ei++] = cmpbuf[i];
if (k==len && numcompl>0) // no chars autocompleted/completion request
{
buf[ei] = '{';
buf[ei+1] = 0;
i = ei+1;
for (k=0; k<numcompl; k++)
{
j = 0;
while (i<maxidx-1 && completions[k][j])
buf[i++] = completions[k][j++];
if (i<maxidx-1)
buf[i++] = (k==numcompl-1) ? '}' : ',';
}
buf[i] = 0;
havecompl = 1;
}
else
{
buf[ei] = '_';
buf[ei+1] = 0;
}
}
}
else
{
@ -7481,6 +7687,7 @@ void showspritedata(int16_t spritenum, int16_t small)
col++;
DOPRINT(32, "^10,0 ^O"); // 24 blanks
DOPRINT(32, "^10%s^O", (spr->picnum>=0 && spr->picnum<MAXTILES) ? names[spr->picnum] : "!INVALID!");
DOPRINT(48, "Flags (hex): %x", spr->cstat);
DOPRINT(56, "Shade: %d", spr->shade);

View file

@ -7521,7 +7521,7 @@ int32_t loadboard(char *filename, char flags, int32_t *daposx, int32_t *daposy,
flags &= 3;
i = strlen(filename)-1;
i = Bstrlen(filename)-1;
if (filename[i] == 255) { filename[i] = 0; flags = 1; } // JBF 20040119: "compatibility"
if ((fil = kopen4load(filename,flags)) == -1)
{ mapversion = 7L; return(-1); }
@ -7981,7 +7981,7 @@ int32_t loadoldboard(char *filename, char fromwhere, int32_t *daposx, int32_t *d
struct walltypev6 v6wall;
struct spritetypev6 v6spr;
i = strlen(filename)-1;
i = Bstrlen(filename)-1;
if (filename[i] == 255) { filename[i] = 0; fromwhere = 1; } // JBF 20040119: "compatibility"
if ((fil = kopen4load(filename,fromwhere)) == -1)
{ mapversion = 5L; return(-1); }
@ -9422,6 +9422,8 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, in
return(0);
}
static int32_t hitscan_hitsectcf=-1;
// stat, heinum, z: either ceiling- or floor-
// how: -1: behave like ceiling, 1: behave like floor
static int32_t hitscan_trysector(const vec3_t *sv, const sectortype *sec, hitdata_t *hitinfo,
@ -9472,6 +9474,7 @@ static int32_t hitscan_trysector(const vec3_t *sv, const sectortype *sec, hitdat
{
hitinfo->hitsect = sec-sector; hitinfo->hitwall = -1; hitinfo->hitsprite = -1;
hitinfo->pos.x = x1; hitinfo->pos.y = y1; hitinfo->pos.z = z1;
hitscan_hitsectcf = (how+1)>>1;
}
}
else
@ -9531,14 +9534,19 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
int32_t clipspritecnt, curidx=-1;
// tmp: { (int32_t)curidx, (spritetype *)curspr, (!=0 if outer sector) }
intptr_t tmp[3], *tmpptr=NULL;
#ifdef YAX_ENABLE
vec3_t newsv;
int32_t oldhitsect = -1;
#endif
hitinfo->hitsect = -1; hitinfo->hitwall = -1; hitinfo->hitsprite = -1;
if (sectnum < 0) return(-1);
hitinfo->pos.x = hitscangoalx; hitinfo->pos.y = hitscangoaly;
dawalclipmask = (cliptype&65535);
dasprclipmask = (cliptype>>16);
#ifdef TAX_ENABLE
restart_grand:
#endif
hitinfo->pos.x = hitscangoalx; hitinfo->pos.y = hitscangoaly;
clipsectorlist[0] = sectnum;
tempshortcnt = 0; tempshortnum = 1;
@ -9806,6 +9814,47 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
if (curspr)
mapinfo_set(NULL, &origmapinfo);
#ifdef YAX_ENABLE
if (numyaxbunches == 0 || editstatus)
return 0;
if (hitinfo->hitsprite==-1 && hitinfo->hitwall==-1 && hitinfo->hitsect!=oldhitsect)
{
if (hitinfo->hitsect == -1 && oldhitsect >= 0)
{
// this is bad: we didn't hit anything after going through a ceiling/floor
Bmemcpy(&hitinfo->pos, &newsv, sizeof(vec3_t));
hitinfo->hitsect = oldhitsect;
return 0;
}
{
// 1st, 2nd, ... ceil/floor hit
// hitinfo->hitsect is >=0 because if oldhitsect's init and check above
int32_t hitfloor = hitscan_hitsectcf;
int16_t bunchnum = yax_getbunch(hitinfo->hitsect, hitfloor);
if (bunchnum >= 0) // todo: check against cstat
{
for (i=headsectbunch[!hitfloor][bunchnum]; i!=-1; i=nextsectbunch[!hitfloor][i])
if (inside(hitinfo->pos.x, hitinfo->pos.y, i) != 1)
continue;
Bmemcpy(&newsv, &hitinfo->pos, sizeof(vec3_t));
sectnum = i;
sv = &newsv;
oldhitsect = hitinfo->hitsect;
hitinfo->hitsect = -1;
goto restart_grand;
}
}
}
#endif
return(0);
}
@ -11008,10 +11057,6 @@ int32_t krand(void)
//
// getzrange
//
//extern char m32_debugstr[64][128];
//extern int32_t m32_numdebuglines;
void getzrange(const vec3_t *pos, int16_t sectnum,
int32_t *ceilz, int32_t *ceilhit, int32_t *florz, int32_t *florhit,
int32_t walldist, uint32_t cliptype)
@ -14422,7 +14467,7 @@ void hash_add(hashtable_t *t, const char *s, int32_t key, int32_t replace)
if (t->items == NULL)
{
initprintf("hash_replace(): table not initialized!\n");
initprintf("hash_add(): table not initialized!\n");
return;
}
@ -14457,7 +14502,45 @@ void hash_add(hashtable_t *t, const char *s, int32_t key, int32_t replace)
prev->next = cur;
}
int32_t hash_find(hashtable_t *t, const char *s)
// delete at most once
void hash_delete(hashtable_t *t, const char *s)
{
hashitem_t *cur, *prev=NULL;
int32_t code;
if (t->items == NULL)
{
initprintf("hash_delete(): table not initialized!\n");
return;
}
code = hash_getcode(s) % t->size;
cur = t->items[code];
if (!cur)
return;
do
{
if (Bstrcmp(s,cur->string) == 0)
{
Bfree(cur->string);
if (!prev)
t->items[code] = cur->next;
else
prev->next = cur->next;
Bfree(cur);
return;
}
prev = cur;
}
while ((cur = cur->next));
}
int32_t hash_find(const hashtable_t *t, const char *s)
{
hashitem_t *cur;
@ -14477,7 +14560,7 @@ int32_t hash_find(hashtable_t *t, const char *s)
return -1;
}
int32_t hash_findcase(hashtable_t *t, const char *s)
int32_t hash_findcase(const hashtable_t *t, const char *s)
{
hashitem_t *cur;

View file

@ -165,6 +165,12 @@ static const char *Typestr_wss[] = { "Wall", "Sector", "Sector", "Sprite", "Wall
static const char *ONOFF_[] = {"OFF","ON"};
#define ONOFF(b) (ONOFF_[!!(b)])
// always CRLF for us
#ifdef _WIN32
# define OURNEWL "\n"
#else
# define OURNEWL "\r\n"
#endif
static CACHE1D_FIND_REC *finddirs=NULL, *findfiles=NULL, *finddirshigh=NULL, *findfileshigh=NULL;
static int32_t numdirs=0, numfiles=0;
@ -211,7 +217,7 @@ static int32_t yax_invalidop()
#endif
// tile marking in tile selector for custom creation of tile groups
static int16_t tilemarked[(MAXTILES+7)>>3];
static uint8_t tilemarked[(MAXTILES+7)>>3];
#ifdef POLYMER
static int16_t spritelightid[MAXSPRITES];
@ -756,7 +762,241 @@ void ExtSaveMap(const char *mapname)
////////// tag labeling system //////////
#define TLCHR(Cond) ((Cond)?"+":"")
typedef struct
{
hashtable_t hashtab;
char *label[32768];
int32_t numlabels;
} taglab_t;
static taglab_t g_taglab;
static void tstrtoupper(char *s)
{
int32_t i;
for (i=0; s[i]; i++)
s[i] = Btoupper(s[i]);
}
void taglab_init()
{
int32_t i;
g_taglab.numlabels = 0;
g_taglab.hashtab.size = 16384;
hash_init(&g_taglab.hashtab);
for (i=0; i<32768; i++)
{
if (g_taglab.label[i])
Bfree(g_taglab.label[i]);
g_taglab.label[i] = NULL;
}
}
int32_t taglab_load(const char *filename, int32_t flags)
{
int32_t fil, len, i;
char buf[BMAX_PATH], *dot, *filebuf;
taglab_init();
len = Bstrlen(filename);
if (len >= BMAX_PATH)
return -1;
Bmemcpy(buf, filename, len);
//
dot = Bstrrchr(buf, '.');
if (!dot)
dot = &buf[len];
if (dot-buf+8 >= BMAX_PATH)
return -1;
Bmemcpy(dot, ".maptags", 9);
//
if ((fil = kopen4load(buf,flags)) == -1)
return -1;
len = kfilelength(fil);
filebuf = Bmalloc(len+1);
if (!filebuf)
{
kclose(fil);
return -1;
}
kread(fil, filebuf, len);
filebuf[len] = 0;
kclose(fil);
// ----
{
int32_t tag;
char *cp=filebuf, *bp, *ep;
while (1)
{
#define XTAGLAB_STRINGIFY(X) TAGLAB_STRINGIFY(X)
#define TAGLAB_STRINGIFY(X) #X
i = sscanf(cp, "%d %" XTAGLAB_STRINGIFY(TAGLAB_MAX) "s", &tag, buf);
#undef XTAGLAB_STRINGIFY
#undef TAGLAB_STRINGIFY
if (i != 2 || !buf[0] || tag<0 || tag>=32768)
goto nextline;
buf[TAGLAB_MAX-1] = 0;
i = Bstrlen(buf);
bp = buf; while (*bp && isspace(*bp)) bp++;
ep = &buf[i-1]; while (ep>buf && isspace(*ep)) ep--;
ep++;
if (!(ep > bp))
goto nextline;
*ep = 0;
taglab_add(bp, tag);
//initprintf("add tag %s:%d\n", bp, tag);
nextline:
while (*cp && *cp!='\n')
cp++;
while (*cp=='\r' || *cp=='\n')
cp++;
if (*cp == 0)
break;
}
}
// ----
Bfree(filebuf);
return 0;
}
int32_t taglab_save(const char *mapname)
{
int32_t fil, len, i;
char buf[BMAX_PATH], *dot;
const char *label;
if (g_taglab.numlabels==0)
return 1;
Bstrncpy(buf, mapname, BMAX_PATH);
buf[BMAX_PATH-1] = 0;
len = Bstrlen(buf);
//
dot = Bstrrchr(buf, '.');
if (!dot)
dot = &buf[len];
if (dot-buf+8 >= BMAX_PATH)
return -1;
Bmemcpy(dot, ".maptags", 9);
//
if ((fil = Bopen(buf,BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1)
{
initprintf("Couldn't open \"%s\" for writing: %s\n", buf, strerror(errno));
return -1;
}
for (i=0; i<32768; i++)
{
label = taglab_getlabel(i);
if (!label)
continue;
len = Bsprintf(buf, "%d %s"OURNEWL, i, label);
if (Bwrite(fil, buf, len)!=len)
break;
}
Bclose(fil);
return (i!=32768);
}
int32_t taglab_add(const char *label, int16_t tag)
{
const char *otaglabel;
char buf[TAGLAB_MAX];
int32_t olabeltag, diddel=0;
if (tag < 0)
return -1;
Bstrncpy(buf, label, sizeof(buf));
buf[sizeof(buf)-1] = 0;
// upcase the tag for storage and comparison
tstrtoupper(buf);
otaglabel = g_taglab.label[tag];
if (otaglabel)
{
if (!Bstrcasecmp(otaglabel, buf))
return 0;
// hash_delete(&g_taglab.hashtab, g_taglab.label[tag]);
// a label having the same tag number as 'tag' is deleted
Bfree(g_taglab.label[tag]);
g_taglab.label[tag] = NULL;
diddel |= 1;
}
else
{
olabeltag = hash_findcase(&g_taglab.hashtab, buf);
if (olabeltag==tag)
return 0;
if (olabeltag>=0)
{
// the label gets assigned to a new tag number ('tag deleted')
Bfree(g_taglab.label[olabeltag]);
g_taglab.label[olabeltag] = NULL;
diddel |= 2;
}
}
if (!diddel)
g_taglab.numlabels++;
g_taglab.label[tag] = Bstrdup(buf);
//initprintf("added %s %d to hash\n", g_taglab.label[tag], tag);
hash_add(&g_taglab.hashtab, g_taglab.label[tag], tag, 1);
return diddel;
}
const char *taglab_getlabel(int16_t tag)
{
if (tag < 0) // || tag>=32768 implicitly
return NULL;
return g_taglab.label[tag];
}
int32_t taglab_gettag(const char *label)
{
char buf[TAGLAB_MAX];
Bstrncpy(buf, label, TAGLAB_MAX);
buf[sizeof(buf)-1] = 0;
// need to upcase since hash_findcase doesn't work as expected:
// getting the code is still (necessarily) case-sensitive...
tstrtoupper(buf);
return hash_findcase(&g_taglab.hashtab, buf);
}
#define TLCHAR "+"
#define TLCHR(Cond) ((Cond)?TLCHAR:"")
static uint64_t taglab_nolink_SEs = (1ull<<10)|(1ull<<27)|(1ull<<28)|(1ull<<29)|(1ull<<49)|(1ull<<50);
// Whether the individual tags have linking semantics. Based on
@ -769,6 +1009,8 @@ static uint64_t taglab_nolink_SEs = (1ull<<10)|(1ull<<27)|(1ull<<28)|(1ull<<29)|
// 16: yvel
// 32: zvel
// 64: owner
// The caller is responsible for checking bounds (usually tag>0), because
// this function is supposed to say something about the potential of a tag
int32_t taglab_linktags(int32_t spritep, int32_t num)
{
int32_t picnum;
@ -788,7 +1030,7 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
l = sprite[num].lotag;
if (l>=0 && l<=63 && (taglab_nolink_SEs&(1ull<<l)))
break;
if (sprite[num].hitag > 0)
// if (sprite[num].hitag > 0)
link = 2;
break;
@ -800,7 +1042,7 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
case DIPSWITCH: case TECHSWITCH: case ALIENSWITCH: case TARGET: case DUCK:
case REACTOR:
case CAMERA1:
if (sprite[num].lotag > 0)
// if (sprite[num].lotag > 0)
link = 1;
break;
@ -812,7 +1054,7 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
case SEENINE: case OOZFILTER:
case CRANEPOLE: case CRANE:
case NATURALLIGHTNING:
if (sprite[num].hitag > 0)
// if (sprite[num].hitag > 0)
link = 2;
break;
}
@ -824,7 +1066,7 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
case TECHLIGHT2: case TECHLIGHT4: case WALLLIGHT4:
case WALLLIGHT3: case WALLLIGHT1: case WALLLIGHT2:
case BIGFORCE: case W_FORCEFIELD:
if (sprite[num].lotag > 0)
// if (sprite[num].lotag > 0)
link = 1;
break;
}
@ -845,15 +1087,70 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
case DOORTILE22: case DOORTILE18: case DOORTILE19: case DOORTILE20:
case DOORTILE14: case DOORTILE16: case DOORTILE15: case DOORTILE21:
case DOORTILE17: case DOORTILE11: case DOORTILE12: case DOORTILE23: // ---
if ((!spritep && wall[num].lotag>0) || (spritep && sprite[num].lotag>0))
// if ((!spritep && wall[num].lotag>0) || (spritep && sprite[num].lotag>0))
link = 1;
break;
}
}
// TODO: link up with m32script to make custom defs possible
g_iReturnVar = link;
VM_OnEvent(EVENT_LINKTAGS, spritep?num:-1);
link = g_iReturnVar;
return link;
}
int32_t taglab_getnextfreetag(void)
{
int32_t i, lt, nextfreetag=1;
for (i=0; i<MAXSPRITES; i++)
{
if (sprite[i].statnum == MAXSTATUS)
continue;
if (sprite[i].picnum==MULTISWITCH)
{
// MULTISWITCH needs special care
int32_t endtag = sprite[i].lotag+3;
if (nextfreetag <= endtag)
nextfreetag = endtag+1;
continue;
}
lt = taglab_linktags(1, i);
if ((lt&1) && nextfreetag <= sprite[i].lotag)
nextfreetag = sprite[i].lotag+1;
if ((lt&2) && nextfreetag <= sprite[i].hitag)
nextfreetag = sprite[i].hitag+1;
}
for (i=0; i<numwalls; i++)
{
lt = taglab_linktags(0, i);
if ((lt&1) && nextfreetag <= wall[i].lotag)
nextfreetag = wall[i].lotag+1;
if ((lt&2) && nextfreetag <= wall[i].hitag)
nextfreetag = wall[i].hitag+1;
}
if (nextfreetag < 32768)
return nextfreetag;
return 0;
}
static void taglab_handle1(int32_t linktagp, int32_t tagnum, char *buf)
{
const char *label = NULL;
if (linktagp && showtags==2)
label = taglab_getlabel(tagnum);
if (label)
Bsprintf(buf, "%hu<%s>", tagnum, label);
else
Bsprintf(buf, "%hu%s", tagnum, TLCHR(linktagp));
}
////////// end tag labeling system //////////
@ -968,18 +1265,27 @@ const char *ExtGetWallCaption(int16_t wallnum)
else
{
int32_t lt = taglab_linktags(0, wallnum);
char histr[TAGLAB_MAX+16], lostr[TAGLAB_MAX+16];
lt &= ~(wall[wallnum].lotag<=0);
lt &= ~((wall[wallnum].hitag<=0)<<1);
taglab_handle1(lt&2, wall[wallnum].hitag, histr);
#ifdef YAX_ENABLE
if (yax_getnextwall(wallnum, YAX_CEILING) >= 0) // ceiling nextwall: lotag
{
if (wall[wallnum].hitag == 0)
tempbuf[0] = 0;
else
Bsprintf(tempbuf, "%hu%s,*", wall[wallnum].hitag, TLCHR(lt&2));
Bsprintf(tempbuf, "%s,*", histr);
}
else
#endif
Bsprintf(tempbuf, "%hu%s,%hu%s", wall[wallnum].hitag, TLCHR(lt&2),
wall[wallnum].lotag, TLCHR(lt&1));
{
taglab_handle1(lt&1, wall[wallnum].lotag, lostr);
Bsprintf(tempbuf, "%s,%s", histr, lostr);
}
}
return(tempbuf);
@ -1099,9 +1405,11 @@ const char *ExtGetSpriteCaption(int16_t spritenum)
retfast = 1;
if (retfast)
return(tempbuf);
return tempbuf;
lt = taglab_linktags(1, spritenum);
lt &= ~(sprite[spritenum].lotag<=0);
lt &= ~((sprite[spritenum].hitag<=0)<<1);
if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0)
{
@ -1113,28 +1421,36 @@ const char *ExtGetSpriteCaption(int16_t spritenum)
else
Bsprintf(tempbuf,"%s",lo);
}
}
else if (sprite[spritenum].picnum==SECTOREFFECTOR)
{
if (onnames!=8)
{
Bsprintf(lo,"%s",SectorEffectorText(spritenum));
Bsprintf(tempbuf,"%s, %hu%s",lo,sprite[spritenum].hitag, TLCHR(lt&2));
}
}
else
{
SpriteName(spritenum,lo);
if (sprite[spritenum].extra != -1)
Bsprintf(tempbuf,"%hu%s,%hu%s,%d %s", sprite[spritenum].hitag, TLCHR(lt&2),
sprite[spritenum].lotag, TLCHR(lt&1),
sprite[spritenum].extra,lo);
else
Bsprintf(tempbuf,"%hu%s,%hu%s %s", sprite[spritenum].hitag, TLCHR(lt&2),
sprite[spritenum].lotag, TLCHR(lt&1), lo);
return tempbuf;
}
return(tempbuf);
{
char histr[TAGLAB_MAX+16], lostr[TAGLAB_MAX+16];
taglab_handle1(lt&2, sprite[spritenum].hitag, histr);
if (sprite[spritenum].picnum==SECTOREFFECTOR)
{
if (onnames!=8)
{
Bsprintf(lo,"%s",SectorEffectorText(spritenum));
Bsprintf(tempbuf,"%s, %s",lo, histr);
}
}
else
{
taglab_handle1(lt&1, sprite[spritenum].lotag, lostr);
SpriteName(spritenum,lo);
if (sprite[spritenum].extra != -1)
Bsprintf(tempbuf,"%s,%s,%d %s", histr, lostr, sprite[spritenum].extra, lo);
else
Bsprintf(tempbuf,"%s,%s %s", histr, lostr, lo);
}
}
return tempbuf;
} //end
@ -1210,7 +1526,7 @@ void ExtShowSectorData(int16_t sectnum) //F5
drawgradient();
ydim += 8;
printmessage16("Level %s",levelname);
printmessage16("Level %s next tag %d", levelname, taglab_getnextfreetag());
#define PRSTAT(Str, Tiledef) \
PrintStatus(Str, numsprite[Tiledef], x, y+yi, numsprite[Tiledef]?11:7); \
@ -1286,71 +1602,21 @@ void ExtShowSectorData(int16_t sectnum) //F5
enddrawing(); //}}}
ydim += 8; // ^^^^^^ see above!
}// end ExtShowSectorData
}
void ExtShowWallData(int16_t wallnum) //F6
{
int32_t i, runi, nextfreetag=0, total=0, x, y, yi, l;
int32_t i, runi, total=0, x, y, yi;
UNREFERENCED_PARAMETER(wallnum);
if (qsetmode==200)
return;
for (i=0; i<MAXSPRITES; i++)
{
if (sprite[i].statnum!=0)
continue;
switch (sprite[i].picnum)
{
//LOTAG
case ACTIVATOR:
case ACTIVATORLOCKED:
case TOUCHPLATE:
case MASTERSWITCH:
case RESPAWN:
case ACCESSSWITCH:
case SLOTDOOR:
case LIGHTSWITCH:
case SPACEDOORSWITCH:
case SPACELIGHTSWITCH:
case FRANKENSTINESWITCH:
case MULTISWITCH:
case DIPSWITCH:
case DIPSWITCH2:
case TECHSWITCH:
case DIPSWITCH3:
case ACCESSSWITCH2:
case POWERSWITCH1:
case LOCKSWITCH1:
case POWERSWITCH2:
case PULLSWITCH:
case ALIENSWITCH:
if (sprite[i].lotag > nextfreetag)
nextfreetag = sprite[i].lotag+1;
break;
//HITAG
case SEENINE:
case OOZFILTER:
case SECTOREFFECTOR:
l = sprite[i].lotag;
if (l>=0 && l<=63 && (taglab_nolink_SEs&(1ull<<l)))
break;
if (sprite[i].hitag > nextfreetag)
nextfreetag=sprite[i].hitag+1;
break;
default:
break;
}
} // end sprite loop
clearmidstatbar16();
drawgradient();
printmessage16("Level %s next tag %d", levelname, nextfreetag);
printmessage16("Level %s next tag %d", levelname, taglab_getnextfreetag());
#define CASES_LIZTROOP \
@ -1485,7 +1751,7 @@ void ExtShowWallData(int16_t wallnum) //F6
enddrawing(); //}}}
}
}// end ExtShowWallData
}
// formerly Show2dText and Show3dText
static void ShowFileText(const char *name, int32_t do3d)
@ -1545,7 +1811,7 @@ static void ShowFileText(const char *name, int32_t do3d)
kclose(fp);
}// end ShowFileText
}
// PK_ vvvv
typedef struct helppage_
@ -3275,7 +3541,7 @@ static int32_t m32gettile(int32_t idInitialTile)
if (PRESSED_KEYSC(S))
{
static char laststr[25] = "";
const char *searchstr = getstring_simple("Search for tile name: ", laststr, MAXTILES-1);
const char *searchstr = getstring_simple("Search for tile name: ", laststr, sizeof(names[0])-1, 1);
static char buf[2][25];
if (searchstr && searchstr[0])
@ -3339,7 +3605,8 @@ static int32_t m32gettile(int32_t idInitialTile)
if (noTilesMarked)
{
noTilesMarked = 0;
TMPERRMSG_PRINT("Beginning marking tiles. To group, press Ctrl-G. To reset, press LCtrl-RShift-SPACE.");
TMPERRMSG_PRINT("Beginning marking tiles. To group, press Ctrl-G."
" To reset, press LCtrl-RShift-SPACE.");
}
if (mark_lastk>=0 && eitherCTRL)
@ -3424,7 +3691,7 @@ static int32_t OnSaveTileGroup(void)
TMPERRMSG_RETURN("Cannot save tile group: too many tiles in group. Have %d, max is %d.",
n, MAX_TILE_GROUP_ENTRIES);
cp = getstring_simple("Hotkey for new group: ", "", 1);
cp = getstring_simple("Hotkey for new group: ", "", 1, 0);
if (!cp || !*cp)
return 1;
@ -3436,7 +3703,7 @@ static int32_t OnSaveTileGroup(void)
if (s_TileGroups[i].key1==hotkey || s_TileGroups[i].key2==Btolower(hotkey))
TMPERRMSG_RETURN("Hotkey '%c' already in use by tile group `%s'.", hotkey, s_TileGroups[i].szText);
name = getstring_simple("Name for new tile group: ", "", 0);
name = getstring_simple("Name for new tile group: ", "", 63, 0);
if (!name || !*name)
return 1;
@ -3458,9 +3725,9 @@ static int32_t OnSaveTileGroup(void)
#define TTAB "\t"
#define TBITCHK(i) ((i)<MAXTILES && (tilemarked[(i)>>3]&(1<<((i)&7))))
Bfprintf(fp, "\n");
Bfprintf(fp, "tilegroup \"%s\"\n{\n", name);
Bfprintf(fp, TTAB "hotkey \"%c\"\n\n", hotkey);
Bfprintf(fp, OURNEWL);
Bfprintf(fp, "tilegroup \"%s\""OURNEWL"{"OURNEWL, name);
Bfprintf(fp, TTAB "hotkey \"%c\""OURNEWL OURNEWL, hotkey);
if (!(s_TileGroups[tile_groups].pIds = Bmalloc(n * sizeof(s_TileGroups[tile_groups].pIds[0]))))
TMPERRMSG_RETURN("Out of memory.");
@ -3472,9 +3739,9 @@ static int32_t OnSaveTileGroup(void)
if (lasti>=0 && !TBITCHK(i))
{
if (names[lasti][0] && names[i-1][0])
Bfprintf(fp, TTAB "tilerange %s %s\n", names[lasti], names[i-1]);
Bfprintf(fp, TTAB "tilerange %s %s"OURNEWL, names[lasti], names[i-1]);
else
Bfprintf(fp, TTAB "tilerange %d %d\n", lasti, i-1);
Bfprintf(fp, TTAB "tilerange %d %d"OURNEWL, lasti, i-1);
for (k=lasti; k<i; k++)
{
@ -3500,39 +3767,50 @@ static int32_t OnSaveTileGroup(void)
s_TileGroups[tile_groups].pIds[j++] = k;
tilemarked[k>>3] &= ~(1<<(k&7));
}
Bfprintf(fp, TTAB "tilerange %d %d\n", lasti, MAXTILES-1);
Bfprintf(fp, TTAB "tilerange %d %d"OURNEWL, lasti, MAXTILES-1);
}
Bfprintf(fp, "\n");
Bfprintf(fp, OURNEWL);
// throw them all in a tiles{...} group else
Bfprintf(fp, TTAB "tiles\n" TTAB "{\n");
k = 0;
for (i=0; i<MAXTILES; i++)
{
if (TBITCHK(i))
if (tilemarked[i>>3]&(1<<(i&7)))
{
s_TileGroups[tile_groups].pIds[j++] = i;
k = 1;
break;
}
if (col==0)
Bfprintf(fp, TTAB TTAB), col+=8;
if (names[i][0])
col+=Bfprintf(fp, "%s ", names[i]);
else
col+=Bfprintf(fp, "%d ", i);
if (col>80)
if (k)
{
// throw them all in a tiles{...} group else
Bfprintf(fp, TTAB "tiles\n" TTAB "{"OURNEWL);
for (i=0; i<MAXTILES; i++)
{
if (TBITCHK(i))
{
Bfprintf(fp, "\n");
col = 0;
s_TileGroups[tile_groups].pIds[j++] = i;
if (col==0)
Bfprintf(fp, TTAB TTAB), col+=8;
if (names[i][0])
col+=Bfprintf(fp, "%s ", names[i]);
else
col+=Bfprintf(fp, "%d ", i);
if (col>80)
{
Bfprintf(fp, OURNEWL);
col = 0;
}
}
}
if (col>0)
Bfprintf(fp, OURNEWL);
Bfprintf(fp, TTAB "}"OURNEWL);
}
if (col>0)
Bfprintf(fp, "\n");
Bfprintf(fp, TTAB "}\n");
#undef TBITCHK
#undef TTAB
Bfprintf(fp, "}\n");
Bfprintf(fp, "}"OURNEWL);
Bfclose(fp);
@ -4053,7 +4331,9 @@ static inline void getnumber_doint64(int64_t *ptr, int32_t num)
static void getnumberptr256(const char *namestart, void *num, int32_t bytes, int32_t maxnumber, char sign, void *(func)(int32_t))
{
char buffer[80], ch;
int32_t n, danum = 0, oldnum;
int32_t danum = 0, oldnum;
uint8_t flags = (sign>>1)&3;
sign &= 1;
switch (bytes)
{
@ -4113,34 +4393,15 @@ static void getnumberptr256(const char *namestart, void *num, int32_t bytes, int
}
showframe(1);
if (ch >= '0' && ch <= '9')
{
if (danum >= 0)
{
n = (danum*10)+(ch-'0');
if (n <= maxnumber) danum = n;
}
else if (sign)
{
n = (danum*10)-(ch-'0');
if (n >= -maxnumber) danum = n;
}
}
else if (ch == 8 || ch == 127) // backspace
{
danum /= 10;
}
else if (ch == 13)
if (getnumber_internal1(ch, &danum, maxnumber, sign) ||
getnumber_autocomplete(namestart, ch, &danum, flags))
{
if (danum != oldnum)
asksave = 1;
oldnum = danum;
break;
}
else if (ch == '-' && sign) // negate
{
danum = -danum;
}
switch (bytes)
{
case 1:
@ -4157,6 +4418,7 @@ static void getnumberptr256(const char *namestart, void *num, int32_t bytes, int
break;
}
}
clearkeys();
lockclock = totalclock; //Reset timing
@ -4887,15 +5149,8 @@ static void Keys3d(void)
if (pal[3] > -1)
{
for (k=0; k<highlightsectorcnt; k++)
{
w = headspritesect[highlightsector[k]];
while (w >= 0)
{
j = nextspritesect[w];
for (w=headspritesect[highlightsector[k]]; w >= 0; w=nextspritesect[w])
sprite[w].pal = pal[3];
w = j;
}
}
}
}
@ -5144,8 +5399,15 @@ static void Keys3d(void)
{
if (ASSERT_AIMING)
{
j = 0;
if (AIMING_AT_WALL || AIMING_AT_SPRITE)
{
j = taglab_linktags(AIMING_AT_SPRITE, searchwall);
j = 2*(j&2);
}
Bsprintf(tempbuf, "%s hitag: ", Typestr_wss[searchstat]);
getnumberptr256(tempbuf, &AIMED(hitag), sizeof(int16_t), BTAG_MAX, 0, NULL);
getnumberptr256(tempbuf, &AIMED(hitag), sizeof(int16_t), BTAG_MAX, 0+j, NULL);
}
}
else
@ -5858,6 +6120,13 @@ static void Keys3d(void)
if (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(T)) // ' T
{
j = 0;
if (AIMING_AT_WALL || AIMING_AT_SPRITE)
{
j = taglab_linktags(AIMING_AT_SPRITE, searchwall);
j = 4*(j&1);
}
if (AIMING_AT_WALL_OR_MASK)
{
#ifdef YAX_ENABLE
@ -5865,7 +6134,7 @@ static void Keys3d(void)
message("Can't change lotag in protected wall");
else
#endif
wall[searchwall].lotag = getnumber256("Wall lotag: ", wall[searchwall].lotag, BTAG_MAX, 0);
wall[searchwall].lotag = getnumber256("Wall lotag: ", wall[searchwall].lotag, BTAG_MAX, 0+j);
}
else if (AIMING_AT_CEILING_OR_FLOOR)
{
@ -5877,14 +6146,14 @@ static void Keys3d(void)
if (sprite[searchwall].picnum == SECTOREFFECTOR)
{
sprite[searchwall].lotag =
_getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0, (void *)SectorEffectorTagText);
_getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0+j, (void *)SectorEffectorTagText);
}
else if (sprite[searchwall].picnum == MUSICANDSFX)
{
int16_t oldtag = sprite[searchwall].lotag;
sprite[searchwall].lotag =
_getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0, (void *)MusicAndSFXTagText);
_getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0+j, (void *)MusicAndSFXTagText);
if ((sprite[searchwall].filler&1) && sprite[searchwall].lotag != oldtag)
{
@ -5893,10 +6162,10 @@ static void Keys3d(void)
}
}
else
sprite[searchwall].lotag = getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0);
sprite[searchwall].lotag = getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0+j);
}
}
#if 0
if (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(H)) // ' H
{
if (ASSERT_AIMING)
@ -5908,7 +6177,7 @@ static void Keys3d(void)
asksave = 1;
}
}
#endif
if (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(S)) // ' S
{
if (ASSERT_AIMING)
@ -5974,7 +6243,7 @@ static void Keys3d(void)
int16_t opicnum = AIMED_CF_SEL(picnum), aimspr=AIMING_AT_SPRITE, osearchwall=searchwall;
static const char *Typestr_tmp[5] = { "Wall", "Sector ceiling", "Sector floor", "Sprite", "Masked wall" };
Bsprintf(tempbuf, "%s picnum: ", Typestr_tmp[searchstat]);
getnumberptr256(tempbuf, &AIMED_CF_SEL(picnum), sizeof(int16_t), MAXTILES-1, 0, NULL);
getnumberptr256(tempbuf, &AIMED_CF_SEL(picnum), sizeof(int16_t), MAXTILES-1, 0+2, NULL);
if (opicnum != AIMED_CF_SEL(picnum))
asksave = 1;
@ -7172,18 +7441,23 @@ static void Keys2d(void)
if (eitherCTRL) //Ctrl-T
{
extern int32_t showtags;
showtags ^= 1;
printmessage16("Show tags %s", ONOFF(showtags));
if (eitherSHIFT)
showtags--;
else
showtags++;
showtags += 3;
showtags %= 3;
printmessage16("Show tags %s", showtags<2?ONOFF(showtags):"LABELED");
}
else if (eitherALT) //ALT
{
if (pointhighlight >= 16384)
{
i = pointhighlight-16384;
j = taglab_linktags(1, i);
j = 4*(j&1);
Bsprintf(buffer,"Sprite (%d) Lo-tag: ", i);
sprite[i].lotag = _getnumber16(buffer, sprite[i].lotag, BTAG_MAX, 0, sprite[i].picnum==SECTOREFFECTOR ?
sprite[i].lotag = _getnumber16(buffer, sprite[i].lotag, BTAG_MAX, 0+j, sprite[i].picnum==SECTOREFFECTOR ?
(void *)SectorEffectorTagText : NULL);
}
else if (linehighlight >= 0)
@ -7195,8 +7469,10 @@ static void Keys2d(void)
#endif
{
i = linehighlight;
j = taglab_linktags(1, i);
j = 4*(j&1);
Bsprintf(buffer,"Wall (%d) Lo-tag: ", i);
wall[i].lotag = getnumber16(buffer, wall[i].lotag, BTAG_MAX, 0);
wall[i].lotag = getnumber16(buffer, wall[i].lotag, BTAG_MAX, 0+j);
}
}
}
@ -10776,6 +11052,8 @@ static void handlemed(int32_t dohex, const char *disp_membername, const char *ed
void *themember, int32_t thesizeof, int32_t themax, int32_t sign)
{
int32_t i, val;
int32_t flags = sign;
sign &= 1;
if (thesizeof==sizeof(int8_t))
{
@ -10801,7 +11079,7 @@ static void handlemed(int32_t dohex, const char *disp_membername, const char *ed
if (med_editval)
{
printmessage16("%s", med_edittext);
val = getnumber16(med_edittext, val, themax, sign);
val = getnumber16(med_edittext, val, themax, flags);
if (thesizeof==sizeof(int8_t))
{
@ -11126,10 +11404,10 @@ static void EditSpriteData(int16_t spritenum)
// clearmidstatbar16();
showspritedata(spritenum, 0);
while (keystatus[KEYSC_ESC] == 0)
{
showspritedata(spritenum, 0);
med_handlecommon(xpos, ypos, &row, rowmax);
if (PRESSED_KEYSC(LEFT))
@ -11276,7 +11554,7 @@ static void EditSpriteData(int16_t spritenum)
break;
case 5:
handlemed(0, "Tile number", "Tile number", &sprite[spritenum].picnum,
sizeof(sprite[spritenum].picnum), MAXTILES-1, 0);
sizeof(sprite[spritenum].picnum), MAXTILES-1, 0+2);
break;
}
}
@ -11369,13 +11647,13 @@ static void GenericSpriteSearch(void)
static char sign[7][3] =
{
{1, 0, 1},
{1, 1, 1},
{1, 0, 1},
{0, 0, 1},
{0, 1, 0},
{0, 0, 0},
{0, 0, 1}
{1, 0, 1},
{1, 1, 1},
{1, 0, 1},
{0, 0, 1},
{0, 1, 0},
{0+4, 0+2, 0},
{0+4, 0, 1}
};
clearmidstatbar16();

View file

@ -3491,6 +3491,7 @@ static void C_AddDefaultDefinitions(void)
C_AddDefinition("EVENT_KEYS3D", EVENT_KEYS3D, LABEL_EVENT);
C_AddDefinition("EVENT_PREKEYS2D", EVENT_PREKEYS2D, LABEL_EVENT);
C_AddDefinition("EVENT_PREKEYS3D", EVENT_PREKEYS3D, LABEL_EVENT);
C_AddDefinition("EVENT_LINKTAGS", EVENT_LINKTAGS, LABEL_EVENT);
C_AddDefinition("CLIPMASK0", CLIPMASK0, LABEL_DEFINE);
C_AddDefinition("CLIPMASK1", CLIPMASK1, LABEL_DEFINE);