From 48e2ce386331d69d95ccdd55cfa134a1e04551b9 Mon Sep 17 00:00:00 2001 From: ac-stef Date: Thu, 25 Aug 2016 11:48:45 +0200 Subject: [PATCH] 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 --- config/menus_edit.cfg | 26 ++++++++++- source/src/audiomanager.cpp | 88 +++++++++++++++++++++++++++++++++++++ source/src/rendermodel.cpp | 33 +++++++++++--- source/src/texture.cpp | 81 ++++++++++++++++++++++++---------- 4 files changed, 195 insertions(+), 33 deletions(-) diff --git a/config/menus_edit.cfg b/config/menus_edit.cfg index 3b05b6c2..48919a8a 100644 --- a/config/menus_edit.cfg +++ b/config/menus_edit.cfg @@ -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 diff --git a/source/src/audiomanager.cpp b/source/src/audiomanager.cpp index 225b7f50..e9f0c8af 100644 --- a/source/src/audiomanager.cpp +++ b/source/src/audiomanager.cpp @@ -968,3 +968,91 @@ void getmapsoundlist() // create a list of mapsound filenames result(res.getbuf()); } COMMAND(getmapsoundlist, ""); + +struct tempmsslot { mapsoundline m; vector 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 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"); + + diff --git a/source/src/rendermodel.cpp b/source/src/rendermodel.cpp index 113bd4de..9a382125 100644 --- a/source/src/rendermodel.cpp +++ b/source/src/rendermodel.cpp @@ -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 oldslot; }; +struct tempmmslot { mapmodelinfo m; vector 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 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 mdlregistry; diff --git a/source/src/texture.cpp b/source/src/texture.cpp index 947dce7f..3db20c58 100644 --- a/source/src/texture.cpp +++ b/source/src/texture.cpp @@ -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 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 oldslot; }; +struct temptexslot { Slot s; vector 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 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