* 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_init(hashtable_t *t);
void hash_free(hashtable_t *t); void hash_free(hashtable_t *t);
int32_t hash_findcase(hashtable_t *t, const char *s); int32_t hash_findcase(const hashtable_t *t, const char *s);
int32_t hash_find(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_add(hashtable_t *t, const char *s, int32_t key, int32_t replace);
void hash_delete(hashtable_t *t, const char *s);
#ifdef POLYMER #ifdef POLYMER
# include "polymer.h" # include "polymer.h"

View file

@ -143,6 +143,10 @@ void editinput(void);
void clearmidstatbar16(void); void clearmidstatbar16(void);
void fade_editor_screen(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)); 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) #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)); 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 printmessage256(int32_t x, int32_t y, const char *name);
void message(const char *fmt, ...) ATTRIBUTE((format(printf,1,2))); 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, int32_t completion);
const char* getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen);
// like snprintf, but pads the output buffer with 'fill' at the end // 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, ...); //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); 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 NEXTWALL(i) (wall[wall[i].nextwall])
#define POINT2(i) (wall[wall[i].point2]) #define POINT2(i) (wall[wall[i].point2])
#define SPRITESEC(j) (sector[sprite[j].sectnum]) #define SPRITESEC(j) (sector[sprite[j].sectnum])

View file

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

View file

@ -97,7 +97,7 @@ extern int16_t searchsector, searchwall, searchstat; //search output
int32_t osearchx, osearchy; //old search input int32_t osearchx, osearchy; //old search input
extern int16_t pointhighlight, linehighlight, highlightcnt; 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 zoom = 768, gettilezoom = 1;
int32_t lastpm16time = 0; int32_t lastpm16time = 0;
@ -190,6 +190,7 @@ int8_t sideview_reversehrot = 0;
char lastpm16buf[156]; char lastpm16buf[156];
//static int32_t checksectorpointer_warn = 0; //static int32_t checksectorpointer_warn = 0;
static int32_t saveboard_savedtags=0;
char changechar(char dachar, int32_t dadir, char smooshyalign, char boundcheck); char changechar(char dachar, int32_t dadir, char smooshyalign, char boundcheck);
static int32_t adjustmark(int32_t *xplc, int32_t *yplc, int16_t danumwalls); 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; numsprites = 0;
initspritelists(); initspritelists();
taglab_init();
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
yax_resetbunchnums(); yax_resetbunchnums();
#endif #endif
@ -516,6 +519,8 @@ int32_t app_main(int32_t argc, const char **argv)
if (k>0) if (k>0)
initprintf("There was an error loading the sprite clipping map (status %d).\n", k); initprintf("There was an error loading the sprite clipping map (status %d).\n", k);
taglab_init();
if (LoadBoard(boardfilename, 1)) if (LoadBoard(boardfilename, 1))
reset_default_mapstate(); reset_default_mapstate();
@ -2257,7 +2262,7 @@ void overheadeditor(void)
draw2dscreen(&pos,cursectnum,ang,zoom,grid); draw2dscreen(&pos,cursectnum,ang,zoom,grid);
begindrawing(); //{{{ begindrawing(); //{{{
if (showtags == 1) if (showtags)
{ {
if (zoom >= 768) if (zoom >= 768)
{ {
@ -2799,14 +2804,18 @@ void overheadeditor(void)
if (pointhighlight >= 16384) if (pointhighlight >= 16384)
{ {
i = pointhighlight-16384; i = pointhighlight-16384;
j = taglab_linktags(1, i);
j = 2*(j&2);
Bsprintf(buffer, "Sprite (%d) Hi-tag: ", i); 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) else if (linehighlight >= 0)
{ {
i = linehighlight; i = linehighlight;
j = taglab_linktags(1, i);
j = 2*(j&2);
Bsprintf(buffer, "Wall (%d) Hi-tag: ", i); 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 else
@ -5366,7 +5375,8 @@ CANCEL:
f = SaveBoard(selectedboardfilename, 0); f = SaveBoard(selectedboardfilename, 0);
if (f) if (f)
printmessage16("Saved board to %s.", f); printmessage16("Saved board %sto %s.",
saveboard_savedtags?"and tags ":"", f);
else else
printmessage16("Saving board failed."); printmessage16("Saving board failed.");
@ -5390,7 +5400,8 @@ CANCEL:
f = SaveBoard(NULL, 0); f = SaveBoard(NULL, 0);
if (f) if (f)
printmessage16("Saved board to %s.", f); printmessage16("Saved board %sto %s.",
saveboard_savedtags?"and tags ":"", f);
else else
printmessage16("Saving board failed."); printmessage16("Saving board failed.");
@ -5571,12 +5582,14 @@ static int32_t ask_above_or_below(void)
} }
#endif #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 *SaveBoard(const char *fn, uint32_t flags)
{ {
const char *f; const char *f;
int32_t ret; int32_t ret;
saveboard_savedtags = 0;
if (!fn) if (!fn)
fn = boardfilename; fn = boardfilename;
@ -5598,7 +5611,10 @@ const char *SaveBoard(const char *fn, uint32_t flags)
ExtPreSaveMap(); ExtPreSaveMap();
ret = saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum); ret = saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum);
if ((flags&1)==0) if ((flags&1)==0)
{
ExtSaveMap(f); ExtSaveMap(f);
saveboard_savedtags = !taglab_save(f);
}
if (!ret) if (!ret)
return f; 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 // 4: passed to loadboard flags (no polymer_loadboard); implies no maphack loading
int32_t LoadBoard(const char *filename, uint32_t flags) int32_t LoadBoard(const char *filename, uint32_t flags)
{ {
int32_t i; int32_t i, tagstat, loadingflags=(!pathsearchmode&&grponlymode?2:0);
if (!filename) if (!filename)
filename = selectedboardfilename; 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; for (i=0; i<MAXSPRITES; i++) sprite[i].extra = -1;
ExtPreLoadMap(); ExtPreLoadMap();
i = loadboard(boardfilename,(flags&4)|(!pathsearchmode&&grponlymode?2:0), i = loadboard(boardfilename,(flags&4)|loadingflags, &pos.x,&pos.y,&pos.z,&ang,&cursectnum);
&pos.x,&pos.y,&pos.z,&ang,&cursectnum); if (i == -2)
if (i == -2) i = loadoldboard(boardfilename,(!pathsearchmode&&grponlymode?2:0), i = loadoldboard(boardfilename,loadingflags, &pos.x,&pos.y,&pos.z,&ang,&cursectnum);
&pos.x,&pos.y,&pos.z,&ang,&cursectnum);
if (i < 0) if (i < 0)
{ {
// printmessage16("Invalid map format."); // printmessage16("Invalid map format.");
return i; return i;
} }
else
{
if ((flags&4)==0) if ((flags&4)==0)
loadmhk(0); loadmhk(0);
tagstat = taglab_load(boardfilename, loadingflags);
ExtLoadMap(boardfilename); ExtLoadMap(boardfilename);
if (mapversion < 7) message("Map %s loaded successfully and autoconverted to V7!",boardfilename); if (mapversion < 7)
message("Map %s loaded successfully and autoconverted to V7!",boardfilename);
else else
{ {
i = CheckMapCorruption(4, 0); i = CheckMapCorruption(4, 0);
message("Loaded map %s %s",boardfilename, i==0?"successfully": message("Loaded map %s%s %s", boardfilename, tagstat==0?" w/tags":"",
(i<4 ? "(moderate corruption)" : "(HEAVY corruption)")); i==0?"successfully": (i<4 ? "(moderate corruption)" : "(HEAVY corruption)"));
}
} }
updatenumsprites(); updatenumsprites();
@ -6247,7 +6263,7 @@ static int32_t numloopsofsector(int16_t sectnum)
} }
#endif #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; 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) else if (ch == 13)
{ {
*oldnum = danum;
asksave = 1;
if (qsetmode!=200)
printmessage16("%s", buffer);
return 1; return 1;
} }
else if (ch == '-' && sign) // negate else if (ch == '-' && sign) // negate
@ -6286,10 +6298,86 @@ static int32_t getnumber_internal1(char ch, const char *buffer, int32_t *danumpt
return 0; 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)) int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t))
{ {
char buffer[80], ch; char buffer[80], ch;
int32_t n, danum, oldnum; int32_t n, danum, oldnum;
uint8_t flags = (sign>>1)&3;
sign &= 1;
danum = num; danum = num;
oldnum = danum; oldnum = danum;
@ -6310,16 +6398,25 @@ int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char
if (func != NULL) 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(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); 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; break;
} }
}
clearkeys(); clearkeys();
@ -6330,6 +6427,8 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
{ {
char buffer[80], ch; char buffer[80], ch;
int32_t danum, oldnum; int32_t danum, oldnum;
uint8_t flags = (sign>>1)&3;
sign &= 1;
danum = num; danum = num;
oldnum = danum; oldnum = danum;
@ -6376,9 +6475,15 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
showframe(1); 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; break;
} }
}
clearkeys(); clearkeys();
@ -6391,23 +6496,26 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
// defaultstr: can be NULL // defaultstr: can be NULL
// NO overflow checks are done when copying them! // NO overflow checks are done when copying them!
// maxlen: maximum length of entry string, if ==1, enter single char // 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]; static char buf[128];
int32_t ei=0, qrylen=0; int32_t ei=0, qrylen=0, maxidx, havecompl=0;
char ch; char ch;
bflushchars(); bflushchars();
clearkeys(); clearkeys();
if (maxlen==0)
maxlen = 1000;
Bmemset(buf, 0, sizeof(buf)); Bmemset(buf, 0, sizeof(buf));
qrylen = Bstrlen(querystr); qrylen = Bstrlen(querystr);
Bmemcpy(buf, querystr, qrylen); Bmemcpy(buf, querystr, qrylen);
if (maxlen==0)
maxlen = 64;
maxidx = min((signed)sizeof(buf), xdim>>3);
ei = qrylen; ei = qrylen;
if (defaultstr) if (defaultstr)
@ -6417,25 +6525,32 @@ const char *getstring_simple(const char *querystr, const char *defaultstr, int32
ei += deflen; ei += deflen;
} }
buf[ei] = 0;
if (maxlen==1)
{
ei = qrylen;
buf[ei] = '_'; buf[ei] = '_';
buf[ei+1] = 0; buf[ei+1] = 0;
}
while (1) while (1)
{ {
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); printext256(0, 0, whitecol, 0, buf, 0);
else
_printmessage16("%s", buf);
showframe(1); showframe(1);
if (handleevents()) if (handleevents())
quitevent = 0; quitevent = 0;
idle_waitevent(); idle();
ch = bgetchar(); ch = bgetchar();
if (ch==13) if (ch==13)
@ -6447,22 +6562,113 @@ const char *getstring_simple(const char *querystr, const char *defaultstr, int32
else if (keystatus[1]) else if (keystatus[1])
{ {
clearkeys(); clearkeys();
return defaultstr; return completion ? NULL : defaultstr;
} }
if (maxlen!=1) if (maxlen!=1)
{ {
// blink...
if (totalclock&32)
{
buf[ei] = '_';
buf[ei+1] = 0;
}
else
{
buf[ei] = 0;
}
if (ei>qrylen && (ch==8 || ch==127)) if (ei>qrylen && (ch==8 || ch==127))
{ {
buf[ei] = ' '; buf[ei--] = 0;
buf[--ei] = '_'; 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++] = ch;
buf[ei] = '_'; buf[ei] = '_';
buf[ei+1] = 0; 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 else
{ {
@ -7481,6 +7687,7 @@ void showspritedata(int16_t spritenum, int16_t small)
col++; col++;
DOPRINT(32, "^10,0 ^O"); // 24 blanks
DOPRINT(32, "^10%s^O", (spr->picnum>=0 && spr->picnum<MAXTILES) ? names[spr->picnum] : "!INVALID!"); DOPRINT(32, "^10%s^O", (spr->picnum>=0 && spr->picnum<MAXTILES) ? names[spr->picnum] : "!INVALID!");
DOPRINT(48, "Flags (hex): %x", spr->cstat); DOPRINT(48, "Flags (hex): %x", spr->cstat);
DOPRINT(56, "Shade: %d", spr->shade); 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; flags &= 3;
i = strlen(filename)-1; i = Bstrlen(filename)-1;
if (filename[i] == 255) { filename[i] = 0; flags = 1; } // JBF 20040119: "compatibility" if (filename[i] == 255) { filename[i] = 0; flags = 1; } // JBF 20040119: "compatibility"
if ((fil = kopen4load(filename,flags)) == -1) if ((fil = kopen4load(filename,flags)) == -1)
{ mapversion = 7L; return(-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 walltypev6 v6wall;
struct spritetypev6 v6spr; struct spritetypev6 v6spr;
i = strlen(filename)-1; i = Bstrlen(filename)-1;
if (filename[i] == 255) { filename[i] = 0; fromwhere = 1; } // JBF 20040119: "compatibility" if (filename[i] == 255) { filename[i] = 0; fromwhere = 1; } // JBF 20040119: "compatibility"
if ((fil = kopen4load(filename,fromwhere)) == -1) if ((fil = kopen4load(filename,fromwhere)) == -1)
{ mapversion = 5L; return(-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); return(0);
} }
static int32_t hitscan_hitsectcf=-1;
// stat, heinum, z: either ceiling- or floor- // stat, heinum, z: either ceiling- or floor-
// how: -1: behave like ceiling, 1: behave like 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, 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->hitsect = sec-sector; hitinfo->hitwall = -1; hitinfo->hitsprite = -1;
hitinfo->pos.x = x1; hitinfo->pos.y = y1; hitinfo->pos.z = z1; hitinfo->pos.x = x1; hitinfo->pos.y = y1; hitinfo->pos.z = z1;
hitscan_hitsectcf = (how+1)>>1;
} }
} }
else 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; int32_t clipspritecnt, curidx=-1;
// tmp: { (int32_t)curidx, (spritetype *)curspr, (!=0 if outer sector) } // tmp: { (int32_t)curidx, (spritetype *)curspr, (!=0 if outer sector) }
intptr_t tmp[3], *tmpptr=NULL; 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; hitinfo->hitsect = -1; hitinfo->hitwall = -1; hitinfo->hitsprite = -1;
if (sectnum < 0) return(-1); if (sectnum < 0) return(-1);
hitinfo->pos.x = hitscangoalx; hitinfo->pos.y = hitscangoaly;
dawalclipmask = (cliptype&65535); dawalclipmask = (cliptype&65535);
dasprclipmask = (cliptype>>16); dasprclipmask = (cliptype>>16);
#ifdef TAX_ENABLE
restart_grand:
#endif
hitinfo->pos.x = hitscangoalx; hitinfo->pos.y = hitscangoaly;
clipsectorlist[0] = sectnum; clipsectorlist[0] = sectnum;
tempshortcnt = 0; tempshortnum = 1; 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) if (curspr)
mapinfo_set(NULL, &origmapinfo); 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); return(0);
} }
@ -11008,10 +11057,6 @@ int32_t krand(void)
// //
// getzrange // getzrange
// //
//extern char m32_debugstr[64][128];
//extern int32_t m32_numdebuglines;
void getzrange(const vec3_t *pos, int16_t sectnum, void getzrange(const vec3_t *pos, int16_t sectnum,
int32_t *ceilz, int32_t *ceilhit, int32_t *florz, int32_t *florhit, int32_t *ceilz, int32_t *ceilhit, int32_t *florz, int32_t *florhit,
int32_t walldist, uint32_t cliptype) 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) if (t->items == NULL)
{ {
initprintf("hash_replace(): table not initialized!\n"); initprintf("hash_add(): table not initialized!\n");
return; return;
} }
@ -14457,7 +14502,45 @@ void hash_add(hashtable_t *t, const char *s, int32_t key, int32_t replace)
prev->next = cur; 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; hashitem_t *cur;
@ -14477,7 +14560,7 @@ int32_t hash_find(hashtable_t *t, const char *s)
return -1; 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; 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"}; static const char *ONOFF_[] = {"OFF","ON"};
#define ONOFF(b) (ONOFF_[!!(b)]) #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 CACHE1D_FIND_REC *finddirs=NULL, *findfiles=NULL, *finddirshigh=NULL, *findfileshigh=NULL;
static int32_t numdirs=0, numfiles=0; static int32_t numdirs=0, numfiles=0;
@ -211,7 +217,7 @@ static int32_t yax_invalidop()
#endif #endif
// tile marking in tile selector for custom creation of tile groups // 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 #ifdef POLYMER
static int16_t spritelightid[MAXSPRITES]; static int16_t spritelightid[MAXSPRITES];
@ -756,7 +762,241 @@ void ExtSaveMap(const char *mapname)
////////// tag labeling system ////////// ////////// 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); 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 // 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 // 16: yvel
// 32: zvel // 32: zvel
// 64: owner // 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 taglab_linktags(int32_t spritep, int32_t num)
{ {
int32_t picnum; int32_t picnum;
@ -788,7 +1030,7 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
l = sprite[num].lotag; l = sprite[num].lotag;
if (l>=0 && l<=63 && (taglab_nolink_SEs&(1ull<<l))) if (l>=0 && l<=63 && (taglab_nolink_SEs&(1ull<<l)))
break; break;
if (sprite[num].hitag > 0) // if (sprite[num].hitag > 0)
link = 2; link = 2;
break; 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 DIPSWITCH: case TECHSWITCH: case ALIENSWITCH: case TARGET: case DUCK:
case REACTOR: case REACTOR:
case CAMERA1: case CAMERA1:
if (sprite[num].lotag > 0) // if (sprite[num].lotag > 0)
link = 1; link = 1;
break; break;
@ -812,7 +1054,7 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
case SEENINE: case OOZFILTER: case SEENINE: case OOZFILTER:
case CRANEPOLE: case CRANE: case CRANEPOLE: case CRANE:
case NATURALLIGHTNING: case NATURALLIGHTNING:
if (sprite[num].hitag > 0) // if (sprite[num].hitag > 0)
link = 2; link = 2;
break; break;
} }
@ -824,7 +1066,7 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
case TECHLIGHT2: case TECHLIGHT4: case WALLLIGHT4: case TECHLIGHT2: case TECHLIGHT4: case WALLLIGHT4:
case WALLLIGHT3: case WALLLIGHT1: case WALLLIGHT2: case WALLLIGHT3: case WALLLIGHT1: case WALLLIGHT2:
case BIGFORCE: case W_FORCEFIELD: case BIGFORCE: case W_FORCEFIELD:
if (sprite[num].lotag > 0) // if (sprite[num].lotag > 0)
link = 1; link = 1;
break; break;
} }
@ -845,15 +1087,70 @@ int32_t taglab_linktags(int32_t spritep, int32_t num)
case DOORTILE22: case DOORTILE18: case DOORTILE19: case DOORTILE20: case DOORTILE22: case DOORTILE18: case DOORTILE19: case DOORTILE20:
case DOORTILE14: case DOORTILE16: case DOORTILE15: case DOORTILE21: case DOORTILE14: case DOORTILE16: case DOORTILE15: case DOORTILE21:
case DOORTILE17: case DOORTILE11: case DOORTILE12: case DOORTILE23: // --- 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; link = 1;
break; 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; 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 ////////// ////////// end tag labeling system //////////
@ -968,18 +1265,27 @@ const char *ExtGetWallCaption(int16_t wallnum)
else else
{ {
int32_t lt = taglab_linktags(0, wallnum); 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 #ifdef YAX_ENABLE
if (yax_getnextwall(wallnum, YAX_CEILING) >= 0) // ceiling nextwall: lotag if (yax_getnextwall(wallnum, YAX_CEILING) >= 0) // ceiling nextwall: lotag
{ {
if (wall[wallnum].hitag == 0) if (wall[wallnum].hitag == 0)
tempbuf[0] = 0; tempbuf[0] = 0;
else else
Bsprintf(tempbuf, "%hu%s,*", wall[wallnum].hitag, TLCHR(lt&2)); Bsprintf(tempbuf, "%s,*", histr);
} }
else else
#endif #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); return(tempbuf);
@ -1099,9 +1405,11 @@ const char *ExtGetSpriteCaption(int16_t spritenum)
retfast = 1; retfast = 1;
if (retfast) if (retfast)
return(tempbuf); return tempbuf;
lt = taglab_linktags(1, spritenum); lt = taglab_linktags(1, spritenum);
lt &= ~(sprite[spritenum].lotag<=0);
lt &= ~((sprite[spritenum].hitag<=0)<<1);
if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0) if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0)
{ {
@ -1113,28 +1421,36 @@ const char *ExtGetSpriteCaption(int16_t spritenum)
else else
Bsprintf(tempbuf,"%s",lo); Bsprintf(tempbuf,"%s",lo);
} }
return tempbuf;
} }
else if (sprite[spritenum].picnum==SECTOREFFECTOR)
{
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) if (onnames!=8)
{ {
Bsprintf(lo,"%s",SectorEffectorText(spritenum)); Bsprintf(lo,"%s",SectorEffectorText(spritenum));
Bsprintf(tempbuf,"%s, %hu%s",lo,sprite[spritenum].hitag, TLCHR(lt&2)); Bsprintf(tempbuf,"%s, %s",lo, histr);
} }
} }
else else
{ {
taglab_handle1(lt&1, sprite[spritenum].lotag, lostr);
SpriteName(spritenum,lo); SpriteName(spritenum,lo);
if (sprite[spritenum].extra != -1) if (sprite[spritenum].extra != -1)
Bsprintf(tempbuf,"%hu%s,%hu%s,%d %s", sprite[spritenum].hitag, TLCHR(lt&2), Bsprintf(tempbuf,"%s,%s,%d %s", histr, lostr, sprite[spritenum].extra, lo);
sprite[spritenum].lotag, TLCHR(lt&1),
sprite[spritenum].extra,lo);
else else
Bsprintf(tempbuf,"%hu%s,%hu%s %s", sprite[spritenum].hitag, TLCHR(lt&2), Bsprintf(tempbuf,"%s,%s %s", histr, lostr, lo);
sprite[spritenum].lotag, TLCHR(lt&1), lo); }
} }
return(tempbuf); return tempbuf;
} //end } //end
@ -1210,7 +1526,7 @@ void ExtShowSectorData(int16_t sectnum) //F5
drawgradient(); drawgradient();
ydim += 8; ydim += 8;
printmessage16("Level %s",levelname); printmessage16("Level %s next tag %d", levelname, taglab_getnextfreetag());
#define PRSTAT(Str, Tiledef) \ #define PRSTAT(Str, Tiledef) \
PrintStatus(Str, numsprite[Tiledef], x, y+yi, numsprite[Tiledef]?11:7); \ PrintStatus(Str, numsprite[Tiledef], x, y+yi, numsprite[Tiledef]?11:7); \
@ -1286,71 +1602,21 @@ void ExtShowSectorData(int16_t sectnum) //F5
enddrawing(); //}}} enddrawing(); //}}}
ydim += 8; // ^^^^^^ see above! ydim += 8; // ^^^^^^ see above!
}
}// end ExtShowSectorData
void ExtShowWallData(int16_t wallnum) //F6 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); UNREFERENCED_PARAMETER(wallnum);
if (qsetmode==200) if (qsetmode==200)
return; 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(); clearmidstatbar16();
drawgradient(); drawgradient();
printmessage16("Level %s next tag %d", levelname, nextfreetag); printmessage16("Level %s next tag %d", levelname, taglab_getnextfreetag());
#define CASES_LIZTROOP \ #define CASES_LIZTROOP \
@ -1485,7 +1751,7 @@ void ExtShowWallData(int16_t wallnum) //F6
enddrawing(); //}}} enddrawing(); //}}}
} }
}// end ExtShowWallData }
// formerly Show2dText and Show3dText // formerly Show2dText and Show3dText
static void ShowFileText(const char *name, int32_t do3d) static void ShowFileText(const char *name, int32_t do3d)
@ -1545,7 +1811,7 @@ static void ShowFileText(const char *name, int32_t do3d)
kclose(fp); kclose(fp);
}// end ShowFileText }
// PK_ vvvv // PK_ vvvv
typedef struct helppage_ typedef struct helppage_
@ -3275,7 +3541,7 @@ static int32_t m32gettile(int32_t idInitialTile)
if (PRESSED_KEYSC(S)) if (PRESSED_KEYSC(S))
{ {
static char laststr[25] = ""; 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]; static char buf[2][25];
if (searchstr && searchstr[0]) if (searchstr && searchstr[0])
@ -3339,7 +3605,8 @@ static int32_t m32gettile(int32_t idInitialTile)
if (noTilesMarked) if (noTilesMarked)
{ {
noTilesMarked = 0; 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) 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.", TMPERRMSG_RETURN("Cannot save tile group: too many tiles in group. Have %d, max is %d.",
n, MAX_TILE_GROUP_ENTRIES); 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) if (!cp || !*cp)
return 1; return 1;
@ -3436,7 +3703,7 @@ static int32_t OnSaveTileGroup(void)
if (s_TileGroups[i].key1==hotkey || s_TileGroups[i].key2==Btolower(hotkey)) 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); 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) if (!name || !*name)
return 1; return 1;
@ -3458,9 +3725,9 @@ static int32_t OnSaveTileGroup(void)
#define TTAB "\t" #define TTAB "\t"
#define TBITCHK(i) ((i)<MAXTILES && (tilemarked[(i)>>3]&(1<<((i)&7)))) #define TBITCHK(i) ((i)<MAXTILES && (tilemarked[(i)>>3]&(1<<((i)&7))))
Bfprintf(fp, "\n"); Bfprintf(fp, OURNEWL);
Bfprintf(fp, "tilegroup \"%s\"\n{\n", name); Bfprintf(fp, "tilegroup \"%s\""OURNEWL"{"OURNEWL, name);
Bfprintf(fp, TTAB "hotkey \"%c\"\n\n", hotkey); Bfprintf(fp, TTAB "hotkey \"%c\""OURNEWL OURNEWL, hotkey);
if (!(s_TileGroups[tile_groups].pIds = Bmalloc(n * sizeof(s_TileGroups[tile_groups].pIds[0])))) if (!(s_TileGroups[tile_groups].pIds = Bmalloc(n * sizeof(s_TileGroups[tile_groups].pIds[0]))))
TMPERRMSG_RETURN("Out of memory."); TMPERRMSG_RETURN("Out of memory.");
@ -3472,9 +3739,9 @@ static int32_t OnSaveTileGroup(void)
if (lasti>=0 && !TBITCHK(i)) if (lasti>=0 && !TBITCHK(i))
{ {
if (names[lasti][0] && names[i-1][0]) 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 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++) for (k=lasti; k<i; k++)
{ {
@ -3500,12 +3767,22 @@ static int32_t OnSaveTileGroup(void)
s_TileGroups[tile_groups].pIds[j++] = k; s_TileGroups[tile_groups].pIds[j++] = k;
tilemarked[k>>3] &= ~(1<<(k&7)); 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);
k = 0;
for (i=0; i<MAXTILES; i++)
if (tilemarked[i>>3]&(1<<(i&7)))
{
k = 1;
break;
}
if (k)
{
// throw them all in a tiles{...} group else // throw them all in a tiles{...} group else
Bfprintf(fp, TTAB "tiles\n" TTAB "{\n"); Bfprintf(fp, TTAB "tiles\n" TTAB "{"OURNEWL);
for (i=0; i<MAXTILES; i++) for (i=0; i<MAXTILES; i++)
{ {
if (TBITCHK(i)) if (TBITCHK(i))
@ -3522,17 +3799,18 @@ static int32_t OnSaveTileGroup(void)
if (col>80) if (col>80)
{ {
Bfprintf(fp, "\n"); Bfprintf(fp, OURNEWL);
col = 0; col = 0;
} }
} }
} }
if (col>0) if (col>0)
Bfprintf(fp, "\n"); Bfprintf(fp, OURNEWL);
Bfprintf(fp, TTAB "}\n"); Bfprintf(fp, TTAB "}"OURNEWL);
}
#undef TBITCHK #undef TBITCHK
#undef TTAB #undef TTAB
Bfprintf(fp, "}\n"); Bfprintf(fp, "}"OURNEWL);
Bfclose(fp); 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)) static void getnumberptr256(const char *namestart, void *num, int32_t bytes, int32_t maxnumber, char sign, void *(func)(int32_t))
{ {
char buffer[80], ch; 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) switch (bytes)
{ {
@ -4113,34 +4393,15 @@ static void getnumberptr256(const char *namestart, void *num, int32_t bytes, int
} }
showframe(1); showframe(1);
if (ch >= '0' && ch <= '9') if (getnumber_internal1(ch, &danum, maxnumber, sign) ||
{ getnumber_autocomplete(namestart, ch, &danum, flags))
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 (danum != oldnum) if (danum != oldnum)
asksave = 1; asksave = 1;
oldnum = danum; oldnum = danum;
break; break;
} }
else if (ch == '-' && sign) // negate
{
danum = -danum;
}
switch (bytes) switch (bytes)
{ {
case 1: case 1:
@ -4157,6 +4418,7 @@ static void getnumberptr256(const char *namestart, void *num, int32_t bytes, int
break; break;
} }
} }
clearkeys(); clearkeys();
lockclock = totalclock; //Reset timing lockclock = totalclock; //Reset timing
@ -4887,15 +5149,8 @@ static void Keys3d(void)
if (pal[3] > -1) if (pal[3] > -1)
{ {
for (k=0; k<highlightsectorcnt; k++) for (k=0; k<highlightsectorcnt; k++)
{ for (w=headspritesect[highlightsector[k]]; w >= 0; w=nextspritesect[w])
w = headspritesect[highlightsector[k]];
while (w >= 0)
{
j = nextspritesect[w];
sprite[w].pal = pal[3]; sprite[w].pal = pal[3];
w = j;
}
}
} }
} }
@ -5144,8 +5399,15 @@ static void Keys3d(void)
{ {
if (ASSERT_AIMING) 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]); 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 else
@ -5858,6 +6120,13 @@ static void Keys3d(void)
if (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(T)) // ' T 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) if (AIMING_AT_WALL_OR_MASK)
{ {
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
@ -5865,7 +6134,7 @@ static void Keys3d(void)
message("Can't change lotag in protected wall"); message("Can't change lotag in protected wall");
else else
#endif #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) else if (AIMING_AT_CEILING_OR_FLOOR)
{ {
@ -5877,14 +6146,14 @@ static void Keys3d(void)
if (sprite[searchwall].picnum == SECTOREFFECTOR) if (sprite[searchwall].picnum == SECTOREFFECTOR)
{ {
sprite[searchwall].lotag = 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) else if (sprite[searchwall].picnum == MUSICANDSFX)
{ {
int16_t oldtag = sprite[searchwall].lotag; int16_t oldtag = sprite[searchwall].lotag;
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) if ((sprite[searchwall].filler&1) && sprite[searchwall].lotag != oldtag)
{ {
@ -5893,10 +6162,10 @@ static void Keys3d(void)
} }
} }
else 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 (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(H)) // ' H
{ {
if (ASSERT_AIMING) if (ASSERT_AIMING)
@ -5908,7 +6177,7 @@ static void Keys3d(void)
asksave = 1; asksave = 1;
} }
} }
#endif
if (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(S)) // ' S if (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(S)) // ' S
{ {
if (ASSERT_AIMING) if (ASSERT_AIMING)
@ -5974,7 +6243,7 @@ static void Keys3d(void)
int16_t opicnum = AIMED_CF_SEL(picnum), aimspr=AIMING_AT_SPRITE, osearchwall=searchwall; 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" }; static const char *Typestr_tmp[5] = { "Wall", "Sector ceiling", "Sector floor", "Sprite", "Masked wall" };
Bsprintf(tempbuf, "%s picnum: ", Typestr_tmp[searchstat]); 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)) if (opicnum != AIMED_CF_SEL(picnum))
asksave = 1; asksave = 1;
@ -7172,18 +7441,23 @@ static void Keys2d(void)
if (eitherCTRL) //Ctrl-T if (eitherCTRL) //Ctrl-T
{ {
extern int32_t showtags; if (eitherSHIFT)
showtags--;
showtags ^= 1; else
printmessage16("Show tags %s", ONOFF(showtags)); showtags++;
showtags += 3;
showtags %= 3;
printmessage16("Show tags %s", showtags<2?ONOFF(showtags):"LABELED");
} }
else if (eitherALT) //ALT else if (eitherALT) //ALT
{ {
if (pointhighlight >= 16384) if (pointhighlight >= 16384)
{ {
i = pointhighlight-16384; i = pointhighlight-16384;
j = taglab_linktags(1, i);
j = 4*(j&1);
Bsprintf(buffer,"Sprite (%d) Lo-tag: ", i); 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); (void *)SectorEffectorTagText : NULL);
} }
else if (linehighlight >= 0) else if (linehighlight >= 0)
@ -7195,8 +7469,10 @@ static void Keys2d(void)
#endif #endif
{ {
i = linehighlight; i = linehighlight;
j = taglab_linktags(1, i);
j = 4*(j&1);
Bsprintf(buffer,"Wall (%d) Lo-tag: ", i); 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) void *themember, int32_t thesizeof, int32_t themax, int32_t sign)
{ {
int32_t i, val; int32_t i, val;
int32_t flags = sign;
sign &= 1;
if (thesizeof==sizeof(int8_t)) 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) if (med_editval)
{ {
printmessage16("%s", med_edittext); printmessage16("%s", med_edittext);
val = getnumber16(med_edittext, val, themax, sign); val = getnumber16(med_edittext, val, themax, flags);
if (thesizeof==sizeof(int8_t)) if (thesizeof==sizeof(int8_t))
{ {
@ -11126,10 +11404,10 @@ static void EditSpriteData(int16_t spritenum)
// clearmidstatbar16(); // clearmidstatbar16();
showspritedata(spritenum, 0);
while (keystatus[KEYSC_ESC] == 0) while (keystatus[KEYSC_ESC] == 0)
{ {
showspritedata(spritenum, 0);
med_handlecommon(xpos, ypos, &row, rowmax); med_handlecommon(xpos, ypos, &row, rowmax);
if (PRESSED_KEYSC(LEFT)) if (PRESSED_KEYSC(LEFT))
@ -11276,7 +11554,7 @@ static void EditSpriteData(int16_t spritenum)
break; break;
case 5: case 5:
handlemed(0, "Tile number", "Tile number", &sprite[spritenum].picnum, 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; break;
} }
} }
@ -11374,8 +11652,8 @@ static void GenericSpriteSearch(void)
{1, 0, 1}, {1, 0, 1},
{0, 0, 1}, {0, 0, 1},
{0, 1, 0}, {0, 1, 0},
{0, 0, 0}, {0+4, 0+2, 0},
{0, 0, 1} {0+4, 0, 1}
}; };
clearmidstatbar16(); clearmidstatbar16();

View file

@ -3491,6 +3491,7 @@ static void C_AddDefaultDefinitions(void)
C_AddDefinition("EVENT_KEYS3D", EVENT_KEYS3D, LABEL_EVENT); C_AddDefinition("EVENT_KEYS3D", EVENT_KEYS3D, LABEL_EVENT);
C_AddDefinition("EVENT_PREKEYS2D", EVENT_PREKEYS2D, LABEL_EVENT); C_AddDefinition("EVENT_PREKEYS2D", EVENT_PREKEYS2D, LABEL_EVENT);
C_AddDefinition("EVENT_PREKEYS3D", EVENT_PREKEYS3D, 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("CLIPMASK0", CLIPMASK0, LABEL_DEFINE);
C_AddDefinition("CLIPMASK1", CLIPMASK1, LABEL_DEFINE); C_AddDefinition("CLIPMASK1", CLIPMASK1, LABEL_DEFINE);