profiles: character/colour select

This commit is contained in:
SinnamonLat 2022-02-18 13:46:32 +01:00
parent 0ac0efda70
commit 5601fa4c22
4 changed files with 158 additions and 64 deletions

View file

@ -658,6 +658,8 @@ void M_EraseData(INT32 choice); // For data erasing
// profile selection menu
void M_ProfileSelectInit(INT32 choice);
void M_HandleProfileSelect(INT32 ch);
void M_HandleProfileEdit(void);
boolean M_ProfileEditInputs(INT32 ch);
// video modes menu (resolution)

View file

@ -438,8 +438,8 @@ menuitem_t OPTIONS_EditProfile[] = {
{IT_STRING | IT_CVAR | IT_CV_STRING, "Player Name", "Name displayed online when using this Profile.",
NULL, &cv_dummyprofileplayername, 0, 0},
{IT_STRING | IT_SUBMENU, "Character", "Default character and color for this Profile.",
NULL, NULL, 0, 0},
{IT_STRING | IT_CALL, "Character", "Default character and color for this Profile.",
NULL, M_CharacterSelect, 0, 0},
{IT_STRING | IT_SUBMENU, "Controls", "Select the button mappings for this Profile.",
NULL, NULL, 0, 0},
@ -454,7 +454,7 @@ menu_t OPTIONS_EditProfileDef = {
SKINCOLOR_ULTRAMARINE, 0,
2, 10,
M_DrawEditProfile,
M_OptionsTick,
M_HandleProfileEdit,
NULL,
NULL,
M_ProfileEditInputs,

View file

@ -834,7 +834,8 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
}
}
static void M_DrawCharacterSprite(INT16 x, INT16 y, SINT8 skin, INT32 addflags, UINT8 *colormap)
// returns false if the character couldn't be rendered
static boolean M_DrawCharacterSprite(INT16 x, INT16 y, SINT8 skin, INT32 addflags, UINT8 *colormap)
{
UINT8 spr;
spritedef_t *sprdef;
@ -848,7 +849,7 @@ static void M_DrawCharacterSprite(INT16 x, INT16 y, SINT8 skin, INT32 addflags,
sprdef = &skins[skin].sprites[spr];
if (!sprdef->numframes) // No frames ??
return; // Can't render!
return false; // Can't render!
frame = states[S_KART_FAST].frame & FF_FRAMEMASK;
if (frame >= sprdef->numframes) // Walking animation missing
@ -869,6 +870,8 @@ static void M_DrawCharacterSprite(INT16 x, INT16 y, SINT8 skin, INT32 addflags,
}
else
V_DrawMappedPatch(x, y, addflags|flags, sprpatch, colormap);
return true;
}
static void M_DrawCharSelectSprite(UINT8 num, INT16 x, INT16 y)
@ -987,8 +990,12 @@ static void M_DrawCharSelectCursor(UINT8 num)
quadx = 4 * (p->gridx / 3);
quady = 4 * (p->gridy / 3);
x = 82 + (p->gridx*16) + quadx - 13,
y = 22 + (p->gridy*16) + quady - 12,
x = 82 + (p->gridx*16) + quadx - 13;
y = 22 + (p->gridy*16) + quady - 12;
// profiles skew the graphic to the right slightly
if (optionsmenu.profile)
x += 64;
colormap = R_GetTranslationColormap(TC_DEFAULT, (p->color != SKINCOLOR_NONE ? p->color : SKINCOLOR_GREY), GTC_MENUCACHE);
@ -1015,12 +1022,77 @@ static void M_DrawCharSelectCursor(UINT8 num)
#undef IDLELEN
#undef SELECTLEN
// Draw character profile card.
// Moved here because in the case of profile edition this is drawn in the charsel menu.
static void M_DrawProfileCard(INT32 x, INT32 y, profile_t *p)
{
setup_player_t *sp = &setup_player[0]; // When editing profile character, we'll always be checking for what P1 is doing.
patch_t *card = W_CachePatchName("PR_CARD", PU_CACHE);
patch_t *cardbot = W_CachePatchName("PR_CARDB", PU_CACHE);
patch_t *pwrlv = W_CachePatchName("PR_PWR", PU_CACHE);
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BLACK, GTC_CACHE);
INT32 skinnum = -1;
INT32 powerlevel = -1;
char pname[PROFILENAMELEN+1] = "empty";
if (p != NULL && p->version)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, p->color, GTC_CACHE);
strcpy(pname, p->profilename);
skinnum = R_SkinAvailable(p->skinname);
powerlevel = 1000; // Test
}
// check setup_player for colormap for the card.
// we'll need to check again for drawing afterwards unfortunately.
if (sp->mdepth >= CSSTEP_CHARS)
colormap = R_GetTranslationColormap(skinnum, sp->color, GTC_MENUCACHE);
// Card
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, 0, card, colormap);
// Draw pwlv if we can
if (powerlevel > -1)
{
V_DrawFixedPatch((x+30)*FRACUNIT, (y+84)*FRACUNIT, FRACUNIT, 0, pwrlv, colormap);
V_DrawCenteredKartString(x+30, y+87, 0, va("%d\n", powerlevel));
}
// check what setup_player is doing in priority.
if (sp->mdepth >= CSSTEP_CHARS)
{
skinnum = setup_chargrid[sp->gridx][sp->gridy].skinlist[sp->clonenum];
if (M_DrawCharacterSprite(x-22, y+119, skinnum, V_FLIP, colormap))
V_DrawMappedPatch(x+14, y+66, 0, faceprefix[skinnum][FACE_RANK], colormap);
if (sp->mdepth == CSSTEP_ALTS || sp->mdepth == CSSTEP_COLORS)
{
M_DrawCharSelectCircle(sp, x-22, y+104);
}
}
else if (skinnum > -1) // otherwise, read from profile.
{
if (M_DrawCharacterSprite(x-22, y+119, skinnum, V_FLIP, colormap))
V_DrawMappedPatch(x+14, y+66, 0, faceprefix[skinnum][FACE_RANK], colormap);
}
V_DrawCenteredGamemodeString(x, y+24, 0, 0, pname);
// Card bottom to overlay the skin preview
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, 0, cardbot, colormap);
}
void M_DrawCharacterSelect(void)
{
UINT8 i, j, k;
UINT8 priority = 0;
INT16 quadx, quady;
SINT8 skin;
INT32 basex = optionsmenu.profile != NULL ? 64 : 0;
if (setup_numplayers > 0)
{
@ -1047,12 +1119,12 @@ void M_DrawCharacterSelect(void)
}
if (skin != -1)
V_DrawScaledPatch(82 + (i*16) + quadx + 1, 22 + (j*16) + quady + 1, 0, W_CachePatchName("ICONBACK", PU_CACHE));
V_DrawScaledPatch(basex+ 82 + (i*16) + quadx + 1, 22 + (j*16) + quady + 1, 0, W_CachePatchName("ICONBACK", PU_CACHE));
}
}
// Draw this inbetween. These drop shadows should be covered by the stat graph, but the icons shouldn't.
V_DrawScaledPatch(3, 2, 0, W_CachePatchName("STATGRPH", PU_CACHE));
V_DrawScaledPatch(basex+ 3, 2, 0, W_CachePatchName((optionsmenu.profile ? "PR_STGRPH" : "STATGRPH"), PU_CACHE));
// Draw the icons now
for (i = 0; i < 9; i++)
@ -1078,10 +1150,10 @@ void M_DrawCharacterSelect(void)
else
colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE);
V_DrawMappedPatch(82 + (i*16) + quadx, 22 + (j*16) + quady, 0, faceprefix[skin][FACE_RANK], colormap);
V_DrawMappedPatch(basex + 82 + (i*16) + quadx, 22 + (j*16) + quady, 0, faceprefix[skin][FACE_RANK], colormap);
if (setup_chargrid[i][j].numskins > 1)
V_DrawScaledPatch(82 + (i*16) + quadx, 22 + (j*16) + quady + 11, 0, W_CachePatchName("ALTSDOT", PU_CACHE));
V_DrawScaledPatch(basex + 82 + (i*16) + quadx, 22 + (j*16) + quady + 11, 0, W_CachePatchName("ALTSDOT", PU_CACHE));
}
}
}
@ -1092,7 +1164,10 @@ void M_DrawCharacterSelect(void)
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
// Draw a preview for each player
M_DrawCharSelectPreview(i);
if (optionsmenu.profile == NULL)
M_DrawCharSelectPreview(i);
else if (i == 0)
M_DrawProfileCard(optionsmenu.optx, optionsmenu.opty, optionsmenu.profile);
if (i >= setup_numplayers)
continue;
@ -2094,49 +2169,6 @@ void M_DrawGenericOptions(void)
}
}
static void M_DrawProfileCard(INT32 x, INT32 y, profile_t *p)
{
patch_t *card = W_CachePatchName("PR_CARD", PU_CACHE);
patch_t *cardbot = W_CachePatchName("PR_CARDB", PU_CACHE);
patch_t *pwrlv = W_CachePatchName("PR_PWR", PU_CACHE);
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BLACK, GTC_CACHE);
INT32 skinnum = -1;
INT32 powerlevel = -1;
char pname[PROFILENAMELEN+1] = "empty";
if (p != NULL && p->version)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, p->color, GTC_CACHE);
strcpy(pname, p->profilename);
skinnum = R_SkinAvailable(p->skinname);
powerlevel = 1000; // Test
}
// Card
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, 0, card, colormap);
// Draw pwlv if we can
if (powerlevel > -1)
{
V_DrawFixedPatch((x+30)*FRACUNIT, (y+84)*FRACUNIT, FRACUNIT, 0, pwrlv, colormap);
V_DrawCenteredKartString(x+30, y+87, 0, va("%d\n", powerlevel));
}
if (skinnum > -1)
{
M_DrawCharacterSprite(x-22, y+119, skinnum, V_FLIP, colormap);
V_DrawMappedPatch(x+14, y+66, 0, faceprefix[skinnum][FACE_RANK], colormap);
}
V_DrawCenteredGamemodeString(x, y+24, 0, 0, pname);
// Card bottom to overlay the skin preview
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, 0, cardbot, colormap);
}
// Draws profile selection
void M_DrawProfileSelect(void)
{

View file

@ -1990,10 +1990,13 @@ void M_CharacterSelectInit(void)
{
UINT8 i, j;
// While we're editing profiles, don't unset the devices for p1
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
// Un-set devices for other players.
CV_SetValue(&cv_usejoystick[i], -1);
if (i != 0 || optionsmenu.profile)
CV_SetValue(&cv_usejoystick[i], -1);
CONS_Printf("Device for %d set to %d\n", i, -1);
}
CONS_Printf("========\n");
@ -2031,6 +2034,11 @@ void M_CharacterSelectInit(void)
setup_player[j].gridx = x;
setup_player[j].gridy = y;
setup_player[j].color = skins[i].prefcolor;
// If we're on prpfile select, skip straight to CSSTEP_CHARS
if (optionsmenu.profile && j == 0)
setup_player[j].mdepth = CSSTEP_CHARS;
}
}
}
@ -2243,8 +2251,18 @@ static boolean M_HandleCharacterGrid(setup_player_t *p, UINT8 num)
{
if (num == setup_numplayers-1)
{
p->mdepth = CSSTEP_NONE;
S_StartSound(NULL, sfx_s3k5b);
// for profiles, exit out of the menu instantly,
// we don't want to go to the input detection menu.
if (optionsmenu.profile)
{
M_GoBack(0);
return true;
}
else // for the actual player select, go back to device detection.
{
p->mdepth = CSSTEP_NONE;
S_StartSound(NULL, sfx_s3k5b);
}
// Prevent quick presses for multiple players
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
@ -2490,14 +2508,29 @@ void M_CharacterSelectTick(void)
// Selecting from the menu
if (gamestate == GS_MENU)
{
for (i = 0; i < setup_numplayers; i++)
// in a profile; update the selected profile and then go back to the profile menu.
if (optionsmenu.profile)
{
CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name);
CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color);
}
strcpy(optionsmenu.profile->skinname, skins[setup_player[0].skin].name);
optionsmenu.profile->color = setup_player[0].color;
CV_StealthSetValue(&cv_splitplayers, setup_numplayers);
M_SetupNextMenu(&PLAY_MainDef, false);
// reset setup_player
memset(setup_player, 0, sizeof(setup_player));
M_GoBack(0);
return;
}
else // in a normal menu, stealthset the cvars and then go to the play menu.
{
for (i = 0; i < setup_numplayers; i++)
{
CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name);
CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color);
}
CV_StealthSetValue(&cv_splitplayers, setup_numplayers);
M_SetupNextMenu(&PLAY_MainDef, false);
}
}
else // In a game
{
@ -3557,6 +3590,18 @@ void M_HandleProfileSelect(INT32 ch)
optionsmenu.toptx = 130/2;
optionsmenu.topty = 0;
// setup cvars
if (optionsmenu.profile->version)
{
CV_StealthSet(&cv_dummyprofilename, optionsmenu.profile->profilename);
CV_StealthSet(&cv_dummyprofileplayername, optionsmenu.profile->playername);
}
else
{
CV_StealthSet(&cv_dummyprofilename, "");
CV_StealthSet(&cv_dummyprofileplayername, "");
}
M_SetupNextMenu(&OPTIONS_EditProfileDef, false);
}
@ -3592,6 +3637,21 @@ boolean M_ProfileEditInputs(INT32 ch)
return false;
}
// Handle some actions in profile editing
void M_HandleProfileEdit(void)
{
M_OptionsTick(); // Keep running that ticker normally.
// Always copy the profile name and player name in the profile.
// Copy the first 6 chars for profile name
if (strlen(cv_dummyprofilename.string))
strncpy(optionsmenu.profile->profilename, cv_dummyprofilename.string, PROFILENAMELEN);
if (strlen(cv_dummyprofileplayername.string))
strcpy(optionsmenu.profile->playername, cv_dummyprofileplayername.string);
}
// special menuitem key handler for video mode list
void M_HandleVideoModes(INT32 ch)
{