implement sorting for grid CSS
This commit is contained in:
parent
be8e46506a
commit
7f12437c76
5 changed files with 209 additions and 25 deletions
16
.vscode/settings.json
vendored
Normal file
16
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"charconv": "c",
|
||||
"chrono": "c",
|
||||
"optional": "c",
|
||||
"format": "c",
|
||||
"ranges": "c",
|
||||
"ratio": "c",
|
||||
"system_error": "c",
|
||||
"array": "c",
|
||||
"functional": "c",
|
||||
"tuple": "c",
|
||||
"type_traits": "c",
|
||||
"utility": "c"
|
||||
}
|
||||
}
|
||||
78
src/m_menu.c
78
src/m_menu.c
|
|
@ -381,6 +381,17 @@ consvar_t cv_chooseskin = CVAR_INIT ("chooseskin", "0", CV_HIDEN|CV_CALL|CV_NOIN
|
|||
static CV_PossibleValue_t skinselectstyle_cons_t[] = {{0, "Bar"}, {1, "Grid"}, {0, NULL}};
|
||||
consvar_t cv_skinselectstyle = CVAR_INIT ("skinselectstyle", "Grid", CV_SAVE, skinselectstyle_cons_t, NULL);
|
||||
|
||||
static CV_PossibleValue_t skinselectsort_cons_t[] = {
|
||||
{SKINMENUSORT_ID, "Order Added"},
|
||||
{SKINMENUSORT_NAME, "Name"},
|
||||
{SKINMENUSORT_SPEED, "Speed"},
|
||||
{SKINMENUSORT_WEIGHT, "Weight"},
|
||||
{SKINMENUSORT_ACCEL, "Accel"},
|
||||
{SKINMENUSORT_HANDLING, "Handling"},
|
||||
{0, NULL}
|
||||
};
|
||||
consvar_t cv_skinselectsort = CVAR_INIT ("skinselectsort", "Order Added", CV_SAVE|CV_CALL|CV_NOINIT, skinselectsort_cons_t, Skinsort_option_Onchange);
|
||||
|
||||
// This gametype list is integral for many different reasons.
|
||||
// When you add gametypes here, don't forget to update them in dehacked.c and doomstat.h!
|
||||
CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1];
|
||||
|
|
@ -821,6 +832,26 @@ void Moviemode_option_Onchange(void)
|
|||
;
|
||||
}
|
||||
|
||||
|
||||
//width now 9 so we can make moe's "2D" grid just an option in the normal grid
|
||||
#define SKINGRIDWIDTH 9
|
||||
#define SKINGRIDHEIGHT 6
|
||||
|
||||
static INT32 gridcss_skinydrag;
|
||||
static INT32 gridcss_skinmemory;
|
||||
static INT32 gridcss_row;
|
||||
static INT32 gridcss_column;
|
||||
|
||||
void Skinsort_option_Onchange(void)
|
||||
{
|
||||
SortSkins();
|
||||
INT32 sortedIndex = FindSortedSkinIndex(cv_chooseskin.value);
|
||||
gridcss_row = sortedIndex % SKINGRIDWIDTH;
|
||||
gridcss_column = sortedIndex / SKINGRIDWIDTH;
|
||||
|
||||
gridcss_skinydrag = CLAMP(gridcss_column - SKINGRIDHEIGHT + 1, 0, ((numskins - 1) / SKINGRIDWIDTH) - SKINGRIDHEIGHT - 1);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// END ORGANIZATION STUFF.
|
||||
// ==========================================================================
|
||||
|
|
@ -2082,6 +2113,8 @@ void M_Init(void)
|
|||
CV_RegisterVar(&cv_nextmap);
|
||||
CV_RegisterVar(&cv_newgametype);
|
||||
CV_RegisterVar(&cv_chooseskin);
|
||||
CV_RegisterVar(&cv_skinselectstyle);
|
||||
CV_RegisterVar(&cv_skinselectsort);
|
||||
CV_RegisterVar(&cv_autorecord);
|
||||
|
||||
if (dedicated)
|
||||
|
|
@ -6723,11 +6756,6 @@ INT32 MR_ConnectIP(INT32 choice)
|
|||
static fixed_t multi_tics;
|
||||
static state_t *multi_state;
|
||||
|
||||
static INT32 gridcss_skinydrag;
|
||||
static INT32 gridcss_skinmemory;
|
||||
static INT32 gridcss_row;
|
||||
static INT32 gridcss_column;
|
||||
|
||||
// used for follower display on player setup menu
|
||||
static fixed_t follower_tics;
|
||||
static UINT32 follower_frame; // used for FF_ANIMATE garbo
|
||||
|
|
@ -7030,10 +7058,6 @@ void MD_DrawBarCssSelector(void)
|
|||
// minenice's grid style CSS from an unfinished moe mansion pull request
|
||||
// originally based on callmore's skin select
|
||||
|
||||
//width now 9 so we can make moe's "2D" grid just an option in the normal grid
|
||||
#define SKINGRIDWIDTH 9
|
||||
#define SKINGRIDHEIGHT 6
|
||||
|
||||
#define SKINXSHIFT 33
|
||||
#define SKINYSHIFT 28
|
||||
|
||||
|
|
@ -7105,8 +7129,8 @@ void MD_DrawGridCssSelector(void)
|
|||
calcs = gridslot + (gridcss_skinydrag * SKINGRIDWIDTH);
|
||||
|
||||
if (calcs < numskins)
|
||||
// skinn = skinsorted[calcs];
|
||||
skinn = calcs;
|
||||
skinn = skinsorted[calcs];
|
||||
// skinn = calcs;
|
||||
else if (gridslot % SKINGRIDWIDTH == 0)
|
||||
break; //really conveniant (sic) place to break out here
|
||||
else
|
||||
|
|
@ -7169,6 +7193,7 @@ INT32 MapGridSelectToSkin(INT32 row, INT32 column)
|
|||
|
||||
INT32 MR_HandleSetupMultiPlayerMenu(INT32 choice)
|
||||
{
|
||||
INT32 sortedIndex;
|
||||
// don't consume input if we're not interacting with the grid CSS
|
||||
if (!(M_IsItemOn(MN_MP_PLAYERSETUP, "SKIN") && cv_skinselectstyle.value))
|
||||
{
|
||||
|
|
@ -7182,8 +7207,9 @@ INT32 MR_HandleSetupMultiPlayerMenu(INT32 choice)
|
|||
{
|
||||
M_SetItemOn(MN_MP_PLAYERSETUP, "FOLLOWER");
|
||||
CV_SetValue(&cv_chooseskin, gridcss_skinmemory);
|
||||
gridcss_row = cv_chooseskin.value % SKINGRIDWIDTH;
|
||||
gridcss_column = cv_chooseskin.value / SKINGRIDWIDTH;
|
||||
sortedIndex = FindSortedSkinIndex(cv_chooseskin.value);
|
||||
gridcss_row = sortedIndex % SKINGRIDWIDTH;
|
||||
gridcss_column = sortedIndex / SKINGRIDWIDTH;
|
||||
|
||||
gridcss_skinydrag = CLAMP(gridcss_column - SKINGRIDHEIGHT + 1, 0, ((numskins - 1) / SKINGRIDWIDTH) - SKINGRIDHEIGHT - 1);
|
||||
}
|
||||
|
|
@ -7207,8 +7233,9 @@ INT32 MR_HandleSetupMultiPlayerMenu(INT32 choice)
|
|||
{
|
||||
M_SetItemOn(MN_MP_PLAYERSETUP, "NAME");
|
||||
CV_SetValue(&cv_chooseskin, gridcss_skinmemory);
|
||||
gridcss_row = cv_chooseskin.value % SKINGRIDWIDTH;
|
||||
gridcss_column = cv_chooseskin.value / SKINGRIDWIDTH;
|
||||
sortedIndex = FindSortedSkinIndex(cv_chooseskin.value);
|
||||
gridcss_row = sortedIndex % SKINGRIDWIDTH;
|
||||
gridcss_column = sortedIndex / SKINGRIDWIDTH;
|
||||
|
||||
gridcss_skinydrag = CLAMP(gridcss_column - SKINGRIDHEIGHT + 1, 0, ((numskins - 1) / SKINGRIDWIDTH) - SKINGRIDHEIGHT - 1);
|
||||
}
|
||||
|
|
@ -7288,8 +7315,9 @@ INT32 MR_HandleSetupMultiPlayerMenu(INT32 choice)
|
|||
case KEY_TAB:
|
||||
M_SetItemOn(MN_MP_PLAYERSETUP, "FOLLOWER");
|
||||
CV_SetValue(&cv_chooseskin, gridcss_skinmemory);
|
||||
gridcss_row = cv_chooseskin.value % SKINGRIDWIDTH;
|
||||
gridcss_column = cv_chooseskin.value / SKINGRIDWIDTH;
|
||||
sortedIndex = FindSortedSkinIndex(cv_chooseskin.value);
|
||||
gridcss_row = sortedIndex % SKINGRIDWIDTH;
|
||||
gridcss_column = sortedIndex / SKINGRIDWIDTH;
|
||||
|
||||
gridcss_skinydrag = CLAMP(gridcss_column - SKINGRIDHEIGHT + 1, 0, ((numskins - 1) / SKINGRIDWIDTH) - SKINGRIDHEIGHT - 1);
|
||||
|
||||
|
|
@ -7306,7 +7334,7 @@ INT32 MR_HandleSetupMultiPlayerMenu(INT32 choice)
|
|||
return false;
|
||||
}
|
||||
|
||||
CV_SetValue(&cv_chooseskin, MapGridSelectToSkin(gridcss_row, gridcss_column));
|
||||
CV_SetValue(&cv_chooseskin, skinsorted[MapGridSelectToSkin(gridcss_row, gridcss_column)]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -7333,6 +7361,7 @@ static void M_GetFollowerState(void)
|
|||
// start the multiplayer setup menu
|
||||
INT32 MR_SetupMultiPlayer(INT32 arg)
|
||||
{
|
||||
INT32 sortedIndex;
|
||||
if (arg < 0 || arg >= MAXSPLITSCREENPLAYERS)
|
||||
return false;
|
||||
|
||||
|
|
@ -7348,8 +7377,9 @@ INT32 MR_SetupMultiPlayer(INT32 arg)
|
|||
CV_SetValue(&cv_dummyfollower, cv_follower[arg].value);
|
||||
CV_SetValue(&cv_dummycolor, cv_playercolor[arg].value);
|
||||
|
||||
gridcss_row = gridcss_skinmemory % SKINGRIDWIDTH;
|
||||
gridcss_column = gridcss_skinmemory / SKINGRIDWIDTH;
|
||||
sortedIndex = FindSortedSkinIndex(gridcss_skinmemory);
|
||||
gridcss_row = sortedIndex % SKINGRIDWIDTH;
|
||||
gridcss_column = sortedIndex / SKINGRIDWIDTH;
|
||||
gridcss_skinydrag = CLAMP(gridcss_column - SKINGRIDHEIGHT + 1, 0, ((numskins - 1) / SKINGRIDWIDTH) - SKINGRIDHEIGHT - 1);
|
||||
|
||||
M_GetFollowerState(); // update follower state
|
||||
|
|
@ -7364,7 +7394,8 @@ INT32 MR_QuitMultiPlayerMenu(INT32 choice)
|
|||
{
|
||||
(void)choice;
|
||||
|
||||
CV_SetValue(&cv_chooseskin, gridcss_skinmemory);
|
||||
if (cv_skinselectstyle.value == 1)
|
||||
CV_SetValue(&cv_chooseskin, gridcss_skinmemory);
|
||||
|
||||
const char *followername = cv_dummyfollower.value == -1 ?
|
||||
"None" : followers[cv_dummyfollower.value].skinname;
|
||||
|
|
@ -7377,11 +7408,12 @@ INT32 MR_QuitMultiPlayerMenu(INT32 choice)
|
|||
));
|
||||
return true;
|
||||
}
|
||||
#undef SKINGRIDWIDTH
|
||||
#undef SKINGRIDHEIGHT
|
||||
#undef SKINXSHIFT
|
||||
#undef SKINYSHIFT
|
||||
|
||||
#undef SKINGRIDWIDTH
|
||||
#undef SKINGRIDHEIGH
|
||||
|
||||
void M_AddMenuColor(UINT16 color) {
|
||||
menucolor_t *c;
|
||||
|
||||
|
|
|
|||
|
|
@ -425,8 +425,6 @@ extern consvar_t cv_dummystaff;
|
|||
extern consvar_t cv_dummymultiplayer, cv_dummyip, cv_dummyname, cv_dummyfollower, cv_dummycolor;
|
||||
extern consvar_t cv_dummyserverpage;
|
||||
|
||||
extern consvar_t cv_skinselectstyle;
|
||||
|
||||
extern consvar_t cv_menucaps;
|
||||
// allow menu text to be displayed in lowercase
|
||||
#define MENUCAPS (!cv_menucaps.value ? V_ALLOWLOWERCASE : 0)
|
||||
|
|
@ -471,6 +469,8 @@ fixed_t M_GetMapThumbnail(INT16 mapnum, patch_t **out);
|
|||
// Moviemode menu updating
|
||||
void Moviemode_option_Onchange(void);
|
||||
|
||||
void Skinsort_option_Onchange(void);
|
||||
|
||||
// Player Setup menu colors linked list
|
||||
struct menucolor_t {
|
||||
menucolor_t *next;
|
||||
|
|
|
|||
120
src/r_skins.c
120
src/r_skins.c
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
INT32 numskins = 0;
|
||||
skin_t skins[MAXSKINS];
|
||||
INT32 skinsorted[MAXSKINS];
|
||||
|
||||
// FIXTHIS: don't work because it must be inistilised before the config load
|
||||
//#define SKINVALUES
|
||||
|
|
@ -214,6 +215,8 @@ void R_InitSkins(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
// doesn't seem right but it's what the original did
|
||||
memset(skinsorted, 0, sizeof(skinsorted));
|
||||
// yes default skin!
|
||||
numskins = 1;
|
||||
|
||||
|
|
@ -246,6 +249,121 @@ UINT32 R_GetSkinAvailabilities(void)
|
|||
return response;
|
||||
}
|
||||
|
||||
//
|
||||
// From callmore's skin select
|
||||
// Sort function(s) for sorting skin names
|
||||
//
|
||||
static int CompareSkinIds(const void *a, const void *b)
|
||||
{
|
||||
const INT32 val_a = *((const INT32 *)a);
|
||||
const INT32 val_b = *((const INT32 *)b);
|
||||
if (val_a > val_b)
|
||||
return 1;
|
||||
else if (val_a < val_b)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CompareSkinNames(const void *a, const void *b)
|
||||
{
|
||||
const skin_t *in1 = &skins[*(const INT32 *)a];
|
||||
const skin_t *in2 = &skins[*(const INT32 *)b];
|
||||
return strcmp(in1->realname, in2->realname);
|
||||
}
|
||||
|
||||
static int CompareSkinSpeeds(const void *a, const void *b)
|
||||
{
|
||||
const skin_t *in1 = &skins[*(const INT32 *)a];
|
||||
const skin_t *in2 = &skins[*(const INT32 *)b];
|
||||
INT32 temp = 0;
|
||||
// check speed
|
||||
if (in1->kartspeed < in2->kartspeed)
|
||||
return -1;
|
||||
else if (in2->kartspeed < in1->kartspeed)
|
||||
return 1;
|
||||
// then check weight
|
||||
if (in1->kartweight < in2->kartweight)
|
||||
return -1;
|
||||
else if (in2->kartweight < in1->kartweight)
|
||||
return 1;
|
||||
// then check name
|
||||
if ((temp = strcmp(in1->realname, in2->realname)))
|
||||
return temp;
|
||||
// sort by internal name
|
||||
return strcmp(in1->name, in2->name);
|
||||
}
|
||||
|
||||
static int CompareSkinWeights(const void *a, const void *b)
|
||||
{
|
||||
const skin_t *in1 = &skins[*(const INT32 *)a];
|
||||
const skin_t *in2 = &skins[*(const INT32 *)b];
|
||||
INT32 temp = 0;
|
||||
// check weight
|
||||
if (in1->kartweight < in2->kartweight)
|
||||
return -1;
|
||||
else if (in2->kartweight < in1->kartweight)
|
||||
return 1;
|
||||
// then check speed
|
||||
if (in1->kartspeed < in2->kartspeed)
|
||||
return -1;
|
||||
else if (in2->kartspeed < in1->kartspeed)
|
||||
return 1;
|
||||
// then check name
|
||||
if ((temp = strcmp(in1->realname, in2->realname)))
|
||||
return temp;
|
||||
// sort by internal name
|
||||
return strcmp(in1->name, in2->name);
|
||||
}
|
||||
|
||||
static int CompareSkinAccels(const void *a, const void *b)
|
||||
{
|
||||
return CompareSkinSpeeds(b, a);
|
||||
}
|
||||
|
||||
static int CompareSkinHandlings(const void *a, const void *b)
|
||||
{
|
||||
return CompareSkinWeights(b, a);
|
||||
}
|
||||
|
||||
void SortSkins(void)
|
||||
{
|
||||
CONS_Printf("Sorting skin list (sort type %d)...\n", cv_skinselectsort.value);
|
||||
|
||||
int (*_sortingFunc)(const void *, const void *);
|
||||
switch (cv_skinselectsort.value)
|
||||
{
|
||||
case SKINMENUSORT_NAME:
|
||||
_sortingFunc = CompareSkinNames;
|
||||
break;
|
||||
case SKINMENUSORT_SPEED:
|
||||
_sortingFunc = CompareSkinSpeeds;
|
||||
break;
|
||||
case SKINMENUSORT_WEIGHT:
|
||||
_sortingFunc = CompareSkinWeights;
|
||||
break;
|
||||
case SKINMENUSORT_ACCEL:
|
||||
_sortingFunc = CompareSkinAccels;
|
||||
break;
|
||||
case SKINMENUSORT_HANDLING:
|
||||
_sortingFunc = CompareSkinHandlings;
|
||||
break;
|
||||
default:
|
||||
_sortingFunc = CompareSkinIds;
|
||||
break;
|
||||
}
|
||||
qsort(skinsorted, numskins, sizeof(INT32), _sortingFunc);
|
||||
}
|
||||
|
||||
INT32 FindSortedSkinIndex(INT32 skinnum)
|
||||
{
|
||||
for (INT32 i = 0; i < numskins; i++)
|
||||
{
|
||||
if (skinsorted[i] == skinnum) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// returns true if available in circumstances, otherwise nope
|
||||
// warning don't use with an invalid skinnum other than -1 which always returns true
|
||||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
|
||||
|
|
@ -911,8 +1029,10 @@ next_token:
|
|||
HWR_AddPlayerModel(numskins);
|
||||
#endif
|
||||
|
||||
skinsorted[numskins] = numskins;
|
||||
numskins++;
|
||||
}
|
||||
SortSkins();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ extern "C" {
|
|||
#define DEFAULTSKIN3 "knuckles" // third player
|
||||
#define DEFAULTSKIN4 "eggman" // fourth player
|
||||
|
||||
extern consvar_t cv_skinselectstyle, cv_skinselectsort;
|
||||
|
||||
/// The skin_t struct
|
||||
struct skin_t
|
||||
{
|
||||
|
|
@ -76,9 +78,21 @@ enum facepatches {
|
|||
NUMFACES
|
||||
};
|
||||
|
||||
enum skinmenusortoption
|
||||
{
|
||||
SKINMENUSORT_ID = 0,
|
||||
SKINMENUSORT_NAME,
|
||||
SKINMENUSORT_SPEED,
|
||||
SKINMENUSORT_WEIGHT,
|
||||
SKINMENUSORT_ACCEL,
|
||||
SKINMENUSORT_HANDLING,
|
||||
NUMSKINMENUSORT,
|
||||
};
|
||||
|
||||
/// Externs
|
||||
extern INT32 numskins;
|
||||
extern skin_t skins[MAXSKINS];
|
||||
extern INT32 skinsorted[MAXSKINS];
|
||||
|
||||
extern CV_PossibleValue_t Forceskin_cons_t[];
|
||||
|
||||
|
|
@ -86,6 +100,8 @@ extern const UINT8 kart2spr2[26][2];
|
|||
|
||||
/// Function prototypes
|
||||
void R_InitSkins(void);
|
||||
void SortSkins(void);
|
||||
INT32 FindSortedSkinIndex(INT32 skinnum);
|
||||
|
||||
void SetPlayerSkin(INT32 playernum,const char *skinname);
|
||||
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
||||
|
|
|
|||
Loading…
Reference in a new issue