new command sortmapsoundslots

...and some options for sortmapmodelslots and sorttextureslots

All three commands now accept three modifier keywords as arguments:
  nosort     do not sort the list alphabetically
  nomerge    do not merge any slots
  mergeused  merge used and unused (identical) slots freely
By default, the list is sorted and only unused identical slots are merged.
The keywords can be combined in any order. "nomerge" takes priority over
"mergeused".

Examples:

  sortmapmodelslots
    Sort the mapmodel slot list alphabetically and merge unused identical
    slots. Merging an unused slot is pretty much the same as deleting it,
    so this command sorts the list and removes unneeded double entries.

  sortmapmodelslots nosort
    Merges (deletes) unused double entries in the mapmodel slot list.

  sorttextureslots nosort mergeused
    Merges double entries in the texture slot list. If two identical
    entries are used in the map, all uses are mapped to the new combined
    slot. This leaves no visual changes on the map. Should be avoided, if
    texture slots have been renamed manually - and the the renaming isn't
    finished yet.

  sortmapsoundslots mergeused
    Sorts the mapsound slot list and merges all double entries.

DOCREF sortmapmodelslots sorttextureslots sortmapsoundslots
This commit is contained in:
ac-stef
2016-08-25 11:48:45 +02:00
parent 2ebf328bb8
commit 48e2ce3863
4 changed files with 195 additions and 33 deletions
+24 -2
View File
@@ -179,8 +179,9 @@ menuitem "Delete ALL unused mapmodel slots" [loop ii 256 [ push i (- 255 $ii) ;
menuitem "Delete ALL unused texture slots" [loop ii 251 [ push i (- 255 $ii) ; if (&& (strlen (edittextureslot $i)) (strcmp "" (textureslotusage $i))) [deletetextureslot $i] ; pop i]]
menuitem "Delete ALL unused mapsound slots" [loop ii 256 [ push i (- 255 $ii) ; if (&& (strlen (editmapsoundslot $i)) (strcmp "" (mapsoundslotusage $i))) [deletemapsoundslot $i] ; pop i]]
menuitem "" -1
menuitem "Sort all mapmodel slots and merge duplicates" sortmapmodelslots
menuitem "Sort all texture slots and merge duplicates" sorttextureslots
menuitem "Sort mapmodel slots..." [ showmenu [Sort mapmodel slots] ]
menuitem "Sort texture slots..." [ showmenu [Sort texture slots] ]
menuitem "Sort mapsound slots..." [ showmenu [Sort mapsound slots] ]
menuitem "" -1
menuitem "Update mapmodel menus" "mapmodelchanged 1"
@@ -525,6 +526,27 @@ menuinit [
]
]
// sort config slots
looplist [__mmsort __mmmerge __texsort __texmerge __sndsort __sndmerge] i [tempalias $i 1]
newmenu [Sort mapmodel slots]
menuitemcheckbox "Sort slots alphabetically" "$__mmsort" [ __mmsort = $arg1 ]
menuitemslider "Merge " 0 2 "$__mmmerge" 1 ["no slots" "unused identical slots" "all identical slots"] [ __mmmerge = $arg1 ]
menuitem "" -1
menuitem "\t\t\f0[Start]" [sortmapmodelslots (at [nosort ""] $__mmsort) (at [nomerge "" mergeused] $__mmmerge)]
newmenu [Sort texture slots]
menuitemcheckbox "Sort slots alphabetically" "$__texsort" [ __texsort = $arg1 ]
menuitemslider "Merge " 0 2 "$__texmerge" 1 ["no slots" "unused identical slots" "all identical slots"] [ __texmerge = $arg1 ]
menuitem "" -1
menuitem "\t\t\f0[Start]" [sorttextureslots (at [nosort ""] $__texsort) (at [nomerge "" mergeused] $__texmerge)]
newmenu [Sort mapsound slots]
menuitemcheckbox "Sort slots alphabetically" "$__sndsort" [ __sndsort = $arg1 ]
menuitemslider "Merge " 0 2 "$__sndmerge" 1 ["no slots" "unused identical slots" "all identical slots"] [ __sndmerge = $arg1 ]
menuitem "" -1
menuitem "\t\t\f0[Start]" [sortmapsoundslots (at [nosort ""] $__sndsort) (at [nomerge "" mergeused] $__sndmerge)]
//Mapmodels
newmenu Mapmodels
menuinit __rebuildmapmodelmenus
+88
View File
@@ -968,3 +968,91 @@ void getmapsoundlist() // create a list of mapsound filenames
result(res.getbuf());
}
COMMAND(getmapsoundlist, "");
struct tempmsslot { mapsoundline m; vector<int> oldslot; bool used; };
int tempmscmp(tempmsslot *a, tempmsslot *b)
{
int n = strcmp(a->m.name, b->m.name);
if(n) return n;
return a->m.maxuses - b->m.maxuses;
}
int tempmssort(tempmsslot *a, tempmsslot *b)
{
int n = tempmscmp(a, b);
return n ? n : a->oldslot[0] - b->oldslot[0];
}
int tempmsunsort(tempmsslot *a, tempmsslot *b)
{
return a->oldslot[0] - b->oldslot[0];
}
void sortmapsoundslots(char **args, int numargs)
{
bool nomerge = false, mergeused = false, nosort = false, unknownarg = false;
loopi(numargs) if(args[i][0])
{
if(!strcasecmp(args[i], "nomerge")) nomerge = true;
else if(!strcasecmp(args[i], "nosort")) nosort = true;
else if(!strcasecmp(args[i], "mergeused")) mergeused = true;
else { conoutf("sortmapsoundslots: unknown argument \"%s\"", args[i]); unknownarg = true; }
}
if(noteditmode("sortmapsoundslots") || multiplayer(true) || unknownarg || mapconfigdata.mapsoundlines.length() < 3) return;
vector<tempmsslot> tempslots;
loopv(mapconfigdata.mapsoundlines)
{
tempslots.add().m = mapconfigdata.mapsoundlines[i];
tempslots.last().oldslot.add(i);
tempslots.last().used = false;
}
loopv(ents) if(ents[i].type == SOUND) tempslots[ents[i].attr1 & 255].used = true;
tempslots.sort(tempmssort);
// remove double entries
if(!nomerge) loopvrev(tempslots) if(i > 0)
{
tempmsslot &s1 = tempslots[i], &s0 = tempslots[i - 1];
if(!tempmscmp(&s0, &s1) && (mergeused || !s0.used || !s1.used))
{
if(s1.used) s0.used = true;
loopvj(s1.oldslot) s0.oldslot.add(s1.oldslot[j]);
tempslots.remove(i);
}
}
if(nosort) tempslots.sort(tempmsunsort);
// create translation table
uchar newslot[256];
loopk(256) newslot[k] = k;
loopv(tempslots)
{
tempmsslot &t = tempslots[i];
loopvj(t.oldslot)
{
if(t.oldslot[j] < 256) newslot[t.oldslot[j]] = i;
}
}
// translate all mapsound entities
loopv(ents) if(ents[i].type == SOUND) ents[i].attr1 = newslot[ents[i].attr1 & 255];
conoutf("%d mapsound slots%s, %d %sslots merged", tempslots.length(), nosort ? "" : " sorted", mapconfigdata.mapsoundlines.length() - tempslots.length(), mergeused ? "" : "unused ");
// rewrite mapmodel slot list
mapconfigdata.mapsoundlines.shrink(tempslots.length());
loopv(tempslots)
{
mapconfigdata.mapsoundlines[i] = tempslots[i].m;
}
reloadmapsoundconfig();
unsavededits++;
mapsoundchanged = 1;
hdr.flags |= MHF_AUTOMAPCONFIG; // requires automapcfg
}
COMMAND(sortmapsoundslots, "v");
+26 -7
View File
@@ -211,7 +211,7 @@ void editmapmodelslot(int *n, char *rad, char *h, char *zoff, char *scale, char
}
COMMAND(editmapmodelslot, "isssss");
struct tempmmslot { mapmodelinfo m; vector<int> oldslot; };
struct tempmmslot { mapmodelinfo m; vector<int> oldslot; bool used; };
int tempmmcmp(tempmmslot *a, tempmmslot *b)
{
@@ -230,27 +230,46 @@ int tempmmsort(tempmmslot *a, tempmmslot *b)
return n ? n : a->oldslot[0] - b->oldslot[0];
}
void sortmapmodelslots()
int tempmmunsort(tempmmslot *a, tempmmslot *b)
{
if(noteditmode("sortmapmodelslots") || multiplayer(true) || mapmodels.length() < 5) return;
return a->oldslot[0] - b->oldslot[0];
}
void sortmapmodelslots(char **args, int numargs)
{
bool nomerge = false, mergeused = false, nosort = false, unknownarg = false;
loopi(numargs) if(args[i][0])
{
if(!strcasecmp(args[i], "nomerge")) nomerge = true;
else if(!strcasecmp(args[i], "nosort")) nosort = true;
else if(!strcasecmp(args[i], "mergeused")) mergeused = true;
else { conoutf("sortmapmodelslots: unknown argument \"%s\"", args[i]); unknownarg = true; }
}
if(noteditmode("sortmapmodelslots") || multiplayer(true) || unknownarg || mapmodels.length() < 3) return;
vector<tempmmslot> tempslots;
loopv(mapmodels)
{
tempslots.add().m = mapmodels[i];
tempslots.last().oldslot.add(i);
tempslots.last().used = false;
}
loopv(ents) if(ents[i].type == MAPMODEL) tempslots[ents[i].attr2].used = true;
tempslots.sort(tempmmsort);
// remove double entries
loopvrev(tempslots) if(i > 0)
if(!nomerge) loopvrev(tempslots) if(i > 0)
{
tempmmslot &s1 = tempslots[i], &s0 = tempslots[i - 1];
if(!tempmmcmp(&s0, &s1))
if(!tempmmcmp(&s0, &s1) && (mergeused || !s0.used || !s1.used))
{
if(s1.used) s0.used = true;
loopvj(s1.oldslot) s0.oldslot.add(s1.oldslot[j]);
tempslots.remove(i);
}
}
if(nosort) tempslots.sort(tempmmunsort);
// create translation table
uchar newslot[256];
@@ -267,7 +286,7 @@ void sortmapmodelslots()
// translate all mapmodel entities
loopv(ents) if(ents[i].type == MAPMODEL) ents[i].attr2 = newslot[ents[i].attr2];
conoutf("%d mapmodel slots sorted, %d slots merged", tempslots.length(), mapmodels.length() - tempslots.length());
conoutf("%d mapmodel slots%s, %d %sslots merged", tempslots.length(), nosort ? "" : " sorted", mapmodels.length() - tempslots.length(), mergeused ? "" : "unused ");
// rewrite mapmodel slot list
mapmodels.shrink(tempslots.length());
@@ -280,7 +299,7 @@ void sortmapmodelslots()
mapmodelchanged = 1;
hdr.flags |= MHF_AUTOMAPCONFIG; // requires automapcfg
}
COMMAND(sortmapmodelslots, "");
COMMAND(sortmapmodelslots, "v");
hashtable<const char *, mapmodelattributes *> mdlregistry;
+57 -24
View File
@@ -955,28 +955,39 @@ void gettexturelist(char *_filter, char *_exclude, char *_exts) // create a list
}
COMMAND(gettexturelist, "sss");
void textureslotusagemapmodels(int *used)
{
int old0 = used[0];
loopv(ents) if(ents[i].type == MAPMODEL) used[ents[i].attr4]++;
used[0] = old0;
}
void textureslotusagegeometry(int *used)
{
sqr *s = world;
loopirev(cubicsize)
{
used[s->wtex]++;
if(s->type != SOLID)
{
used[s->ctex]++;
used[s->ftex]++;
used[s->utex]++;
}
s++;
}
}
void textureslotusagelist(char *what)
{
int used[256] = { 0 };
if(strcmp(what, "onlygeometry"))
{ // if not only geometry, cound map model usage
loopv(ents) if(ents[i].type == MAPMODEL) used[ents[i].attr4]++;
used[0] = 0;
{ // if not only geometry, count map model usage
textureslotusagemapmodels(used);
}
if(strcmp(what, "onlymodels"))
{ // if not only models, count map geometry
sqr *s = world;
loopirev(cubicsize)
{
used[s->wtex]++;
if(s->type != SOLID)
{
used[s->ctex]++;
used[s->ftex]++;
used[s->utex]++;
}
s++;
}
textureslotusagegeometry(used);
}
vector<char> res;
loopi(256) cvecprintf(res, "%d ", used[i]);
@@ -1158,7 +1169,7 @@ uchar *texconfig_paste(void *_s, uchar *usedslots) // create mapping table to tr
return res;
}
struct temptexslot { Slot s; vector<int> oldslot; };
struct temptexslot { Slot s; vector<int> oldslot; bool used; };
int tempslotsort(temptexslot *a, temptexslot *b)
{
@@ -1169,29 +1180,51 @@ int tempslotsort(temptexslot *a, temptexslot *b)
return a->oldslot[0] - b->oldslot[0];
}
void sorttextureslots()
int tempslotunsort(temptexslot *a, temptexslot *b)
{
if(noteditmode("sorttextureslots") || multiplayer(true) || slots.length() < 5) return;
return a->oldslot[0] - b->oldslot[0];
}
void sorttextureslots(char **args, int numargs)
{
bool nomerge = false, mergeused = false, nosort = false, unknownarg = false;
loopi(numargs) if(args[i][0])
{
if(!strcasecmp(args[i], "nomerge")) nomerge = true;
else if(!strcasecmp(args[i], "nosort")) nosort = true;
else if(!strcasecmp(args[i], "mergeused")) mergeused = true;
else { conoutf("sorttextureslots: unknown argument \"%s\"", args[i]); unknownarg = true; }
}
if(noteditmode("sorttextureslots") || multiplayer(true) || unknownarg || slots.length() < 5) return;
int used[256] = { 0 };
textureslotusagemapmodels(used);
textureslotusagegeometry(used);
vector<temptexslot> tempslots;
loopv(slots)
{
tempslots.add().s = slots[i];
tempslots.last().oldslot.add(i);
tempslots.last().used = used[i] > 0;
}
tempslots.sort(tempslotsort);
// remove double entries
loopvrev(tempslots) if(i > 0)
// remove double entries (if requested)
if(!nomerge) loopvrev(tempslots) if(i > 0)
{
temptexslot &s1 = tempslots[i], &s0 = tempslots[i - 1];
if(s1.oldslot[0] > 4 && !strcmp(s0.s.name, s1.s.name) && s0.s.scale == s1.s.scale)
if(s1.oldslot[0] > 4 && !strcmp(s0.s.name, s1.s.name) && s0.s.scale == s1.s.scale && (mergeused || !s0.used || !s1.used))
{
if(s1.used) s0.used = true;
loopvj(s1.oldslot) s0.oldslot.add(s1.oldslot[j]);
tempslots.remove(i);
}
}
// sort special textures (like skymap) back front
// sort special textures (like skymap) back front - also, revert sorting, if it's unwanted
if(nosort) tempslots.sort(tempslotunsort);
loopk(5)
{
loopv(tempslots)
@@ -1252,7 +1285,7 @@ void sorttextureslots()
loopi(256) if(d[i]) *pd++ = i;
}
conoutf("%d texture slots sorted, %d slots merged", tempslots.length(), slots.length() - tempslots.length());
conoutf("%d texture slots%s, %d %sslots merged", tempslots.length(), nosort ? "" : " sorted", slots.length() - tempslots.length(), mergeused ? "" : "unused ");
// rewrite texture slot list
slots.shrink(tempslots.length());
@@ -1264,7 +1297,7 @@ void sorttextureslots()
unsavededits++;
hdr.flags |= MHF_AUTOMAPCONFIG; // requires automapcfg
}
COMMAND(sorttextureslots, "");
COMMAND(sorttextureslots, "v");
#ifdef _DEBUG