diff --git a/src/g_game.c b/src/g_game.c index fcb815d3a..89987a29f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -524,22 +524,22 @@ player_t *seenplayer; // player we're aiming at right now char player_names[MAXPLAYERS][MAXPLAYERNAME+1] = { - "Player 1", - "Player 2", - "Player 3", - "Player 4", - "Player 5", - "Player 6", - "Player 7", - "Player 8", - "Player 9", - "Player 10", - "Player 11", - "Player 12", - "Player 13", - "Player 14", - "Player 15", - "Player 16" + "A Player", + "B Player", + "C Player", + "D Player", + "E Player", + "F Player", + "G Player", + "H Player", + "I Player", + "J Player", + "K Player", + "L Player", + "M Player", + "N Player", + "O Player", + "P Player" }; // SRB2kart - removed Players 17 through 32 INT16 rw_maximums[NUM_WEAPONS] = diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 44ed3ae81..3be1d6473 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -65,12 +65,14 @@ // heads up font //------------------------------------------- patch_t *hu_font[HU_FONTSIZE]; -patch_t *kart_font[KART_FONTSIZE]; // SRB2kart -patch_t *gamemode_font[AZ_FONTSIZE]; patch_t *tny_font[HU_FONTSIZE]; patch_t *tallnum[10]; // 0-9 patch_t *nightsnum[10]; // 0-9 +patch_t *kart_font[KART_FONTSIZE]; // SRB2kart +patch_t *gamemode_font[AZ_FONTSIZE]; +patch_t *file_font[AZ_FONTSIZE]; + // Level title and credits fonts patch_t *lt_font[LT_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE]; @@ -248,6 +250,13 @@ void HU_LoadGraphics(void) gamemode_font[i] = NULL; else gamemode_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); + + // File select font + sprintf(buffer, "FILEF%.3d", j); + if (W_CheckNumForName(buffer) == LUMPERROR) + file_font[i] = NULL; + else + file_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } // diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 2c5fcbb29..9c9206f83 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -84,7 +84,8 @@ void HU_AddChatText(const char *text, boolean playsound); extern boolean chat_on; extern patch_t *hu_font[HU_FONTSIZE], *tny_font[HU_FONTSIZE]; -extern patch_t *kart_font[KART_FONTSIZE], *gamemode_font[AZ_FONTSIZE]; // SRB2kart +extern patch_t *kart_font[KART_FONTSIZE]; // SRB2kart +extern patch_t *gamemode_font[AZ_FONTSIZE], *file_font[AZ_FONTSIZE]; extern patch_t *tallnum[10]; extern patch_t *pingnum[10]; extern patch_t *pinggfx[5]; diff --git a/src/k_menu.h b/src/k_menu.h index 863838127..d57618a4a 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -111,6 +111,7 @@ typedef struct menu_s INT16 transitionInTics; // tics for transitions in INT16 transitionOutTics; // tics for transitions out void (*drawroutine)(void); // draw routine + void (*tickroutine)(void); // ticker routine boolean (*quitroutine)(void); // called before quit a menu return true if we can } menu_t; @@ -227,11 +228,19 @@ extern struct setup_chargrid_s { UINT8 numskins; } setup_chargrid[9][9]; +#define CSSTEP_NONE 0 +#define CSSTEP_CHARS 1 +#define CSSTEP_ALTS 2 +#define CSSTEP_COLORS 3 +#define CSSTEP_READY 4 + typedef struct setup_player_s { SINT8 gridx, gridy; SINT8 skin; SINT8 clonenum; + SINT8 rotate; + UINT8 delay; UINT8 color; UINT8 mdepth; } setup_player_t; @@ -239,6 +248,18 @@ typedef struct setup_player_s extern setup_player_t setup_player[MAXSPLITSCREENPLAYERS]; extern UINT8 setup_numplayers; +extern UINT16 setup_animcounter; + +// The selection spawns 3 explosions in 4 directions, and there's 4 players -- 3 * 4 * 4 = 48 +#define CSEXPLOSIONS 48 + +#define CSROTATETICS 6 + +extern struct setup_explosions_s { + UINT8 x, y; + UINT8 tics; + UINT8 color; +} setup_explosions[CSEXPLOSIONS]; typedef enum { @@ -251,6 +272,7 @@ consvar_t *setup_playercvars[MAXSPLITSCREENPLAYERS][SPLITCV_MAX]; void M_CharacterSelectInit(INT32 choice); void M_CharacterSelectHandler(INT32 choice); +void M_CharacterSelectTick(void); boolean M_CharacterSelectQuit(void); void M_EndModeAttackRun(void); @@ -288,6 +310,7 @@ void M_DrawPlaybackMenu(void); x, y,\ 0, 0,\ M_DrawGenericMenu,\ + NULL,\ NULL\ } @@ -301,6 +324,7 @@ void M_DrawPlaybackMenu(void); 0, 0,\ 10, 10,\ M_DrawKartGamemodeMenu,\ + NULL,\ NULL\ } diff --git a/src/k_menudef.c b/src/k_menudef.c index 07cd413b9..5dc155fd0 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -18,7 +18,7 @@ // --------- menuitem_t MainMenu[] = { - {IT_STRING | IT_CALL, "Play", "Cut to the chase and start playing!", + {IT_STRING | IT_CALL, "Play", "Cut to the chase and start the race!", NULL, M_CharacterSelectInit, 48, 0}, {IT_STRING, "Extra", "Check out some bonus features.", @@ -50,6 +50,7 @@ menu_t PLAY_CharSelectDef = { 0, 0, 0, 0, M_DrawCharacterSelect, + M_CharacterSelectTick, M_CharacterSelectQuit }; @@ -128,5 +129,6 @@ menu_t PAUSE_PlaybackMenuDef = { BASEVIDWIDTH/2 - 88, 2, 0, 0, M_DrawPlaybackMenu, + NULL, NULL }; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index abf696764..556955d42 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -518,54 +518,91 @@ void M_DrawImageDef(void) static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y) { - const fixed_t rad = 32<mdepth == 2) + if (p->mdepth == CSSTEP_ALTS) numoptions = setup_chargrid[p->gridx][p->gridy].numskins; else - { - numoptions = 16; - patch = W_CachePatchName("COLORSPH", PU_CACHE); - } + numoptions = MAXSKINCOLORS-1; - angamt /= numoptions*2; + angamt /= numoptions; for (i = 0; i < numoptions; i++) { fixed_t cx = x << FRACBITS, cy = y << FRACBITS; - fixed_t ang = -(angamt * i); + boolean subtract = (i & 1); + angle_t ang = ((i+1)/2) * angamt; + patch_t *patch = NULL; UINT8 *colormap; + fixed_t radius = 24<> ANGLETOFINESHIFT)); - cy += FixedMul(rad, FINESINE(FixedAngle(ang << FRACBITS) >> ANGLETOFINESHIFT)) >> 2; - - if (p->mdepth == 2) + if (p->mdepth == CSSTEP_ALTS) { SINT8 skin; - cx -= 8<clonenum + i) % setup_chargrid[p->gridx][p->gridy].numskins; + n = (p->clonenum) + numoptions/2; + if (subtract) + n -= ((i+1)/2); + else + n += ((i+1)/2); + n %= numoptions; skin = setup_chargrid[p->gridx][p->gridy].skinlist[n]; - - colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); patch = facerankprefix[skin]; + colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); } else { - cx -= 4<color + i) % (MAXSKINCOLORS-1)); + INT16 diff; + + n = (p->color-1) + numoptions/2; + if (subtract) + n -= ((i+1)/2); + else + n += ((i+1)/2); + n %= numoptions; + n++; + colormap = R_GetTranslationColormap(TC_DEFAULT, n, GTC_MENUCACHE); + + if (n > p->color) + diff = n - p->color; + else + diff = p->color - n; + + if (diff == 0) + patch = W_CachePatchName("COLORSP2", PU_CACHE); + else if (abs(diff) < 25) + patch = W_CachePatchName("COLORSP1", PU_CACHE); + else + patch = W_CachePatchName("COLORSP0", PU_CACHE); + + radius -= SHORT(patch->width) << FRACBITS; } + cx -= (SHORT(patch->width) << FRACBITS) >> 1; + cy -= (SHORT(patch->height) << FRACBITS) >> 1; + + if (subtract) + ang = (signed)(ANGLE_90 - ang); + else + ang = ANGLE_90 + ang; + + if (numoptions % 2) + ang = (signed)(ang - (angamt/2)); + + if (p->rotate) + ang = (signed)(ang + ((angamt / CSROTATETICS) * p->rotate)); + + cx += FixedMul(radius, FINECOSINE(ang >> ANGLETOFINESHIFT)); + cy -= FixedMul(radius, FINESINE(ang >> ANGLETOFINESHIFT)) / 3; + V_DrawFixedPatch(cx, cy, FRACUNIT, 0, patch, colormap); + if (p->mdepth == CSSTEP_ALTS && n != p->clonenum) + V_DrawFixedPatch(cx, cy, FRACUNIT, V_TRANSLUCENT, W_CachePatchName("ICONDARK", PU_CACHE), NULL); } } @@ -589,7 +626,7 @@ static void M_DrawCharSelectPreview(UINT8 num) V_DrawScaledPatch(x, y+6, V_TRANSLUCENT, W_CachePatchName("PREVBACK", PU_CACHE)); - if (p->mdepth > 0) + if (p->mdepth >= CSSTEP_CHARS) { skin = setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]; @@ -634,21 +671,117 @@ static void M_DrawCharSelectPreview(UINT8 num) } } - if (p->mdepth == 2 || p->mdepth == 3) - M_DrawCharSelectCircle(p, x+32, y+48); + if (p->mdepth == CSSTEP_ALTS || p->mdepth == CSSTEP_COLORS) + M_DrawCharSelectCircle(p, x+32, y+64); + } + + if ((setup_animcounter/10) & 1) + { + if (p->mdepth == CSSTEP_NONE) + V_DrawScaledPatch(x+1, y+36, 0, W_CachePatchName("4PSTART", PU_CACHE)); + //else if (p->mdepth >= CSSTEP_READY) + // V_DrawScaledPatch(x+1, y+36, 0, W_CachePatchName("4PREADY", PU_CACHE)); } V_DrawScaledPatch(x+9, y+2, 0, W_CachePatchName("FILEBACK", PU_CACHE)); - V_DrawScaledPatch(x, y, 0, W_CachePatchName(va("CHARSEL%c", letter), PU_CACHE)); - - if (p->mdepth == 0 && (skullAnimCounter/5)) - V_DrawScaledPatch(x+1, y+36, 0, W_CachePatchName("4PSTART", PU_CACHE)); + V_DrawScaledPatch(x, y+2, 0, W_CachePatchName(va("CHARSEL%c", letter), PU_CACHE)); + V_DrawFileString(x+16, y+2, 0, "PLAYER"); } +static void M_DrawCharSelectExplosions(void) +{ + UINT8 i; + + for (i = 0; i < CSEXPLOSIONS; i++) + { + INT16 quadx, quady; + UINT8 *colormap; + UINT8 frame; + + if (setup_explosions[i].tics == 0 || setup_explosions[i].tics > 5) + continue; + + frame = 6 - setup_explosions[i].tics; + + quadx = 4 * (setup_explosions[i].x / 3); + quady = 4 * (setup_explosions[i].y / 3); + + colormap = R_GetTranslationColormap(TC_DEFAULT, setup_explosions[i].color, GTC_MENUCACHE); + + V_DrawMappedPatch( + 82 + (setup_explosions[i].x*16) + quadx - 6, + 22 + (setup_explosions[i].y*16) + quady - 6, + 0, W_CachePatchName(va("CHCNFRM%d", frame), PU_CACHE), + colormap + ); + } +} + +#define IDLELEN 8 +#define SELECTLEN (8 + IDLELEN + 7 + IDLELEN) + +static void M_DrawCharSelectCursors(void) +{ + UINT8 i; + static const char *idleframes[IDLELEN] = { + "CHHOV1", "CHHOV1", "CHHOV1", "CHHOV2", "CHHOV1", "CHHOV3", "CHHOV1", "CHHOV2" + }; + static const char *selectframesa[SELECTLEN] = { + "CHHOV1", "CHPIKA1", "CHHOV2", "CHPIKA2", "CHHOV3", "CHPIKA3", "CHHOV2", "CHPIKA4", + "CHHOV1", "CHHOV1", "CHHOV1", "CHHOV2", "CHHOV1", "CHHOV3", "CHHOV1", "CHHOV2", + "CHPIKA5", "CHHOV2", "CHPIKA6", "CHHOV3", "CHPIKA7", "CHHOV2", "CHPIKA8", + "CHHOV1", "CHHOV1", "CHHOV1", "CHHOV2", "CHHOV1", "CHHOV3", "CHHOV1", "CHHOV2" + }; + static const char *selectframesb[SELECTLEN] = { + "CHHOV1", "CHPIKB1", "CHHOV2", "CHPIKB2", "CHHOV3", "CHPIKB3", "CHHOV2", "CHPIKB4", + "CHHOV1", "CHHOV1", "CHHOV1", "CHHOV2", "CHHOV1", "CHHOV3", "CHHOV1", "CHHOV2", + "CHPIKB5", "CHHOV2", "CHPIKB6", "CHHOV3", "CHPIKB7", "CHHOV2", "CHPIKB8", + "CHHOV1", "CHHOV1", "CHHOV1", "CHHOV2", "CHHOV1", "CHHOV3", "CHHOV1", "CHHOV2" + }; + + for (i = 0; i < setup_numplayers; i++) + { + setup_player_t *p = &setup_player[i]; + char letter = 'A' + i; + UINT8 *colormap; + INT16 x, y; + INT16 quadx, quady; + + quadx = 4 * (p->gridx / 3); + quady = 4 * (p->gridy / 3); + + x = 82 + (p->gridx*16) + quadx - 13, + y = 22 + (p->gridy*16) + quady - 12, + + colormap = R_GetTranslationColormap(TC_DEFAULT, (p->color != SKINCOLOR_NONE ? p->color : SKINCOLOR_GREY), GTC_MENUCACHE); + + if (p->mdepth >= CSSTEP_READY) + { + V_DrawMappedPatch(x, y, 0, W_CachePatchName("CHCNFRM0", PU_CACHE), colormap); + } + else if (p->mdepth > CSSTEP_CHARS) + { + V_DrawMappedPatch(x, y, 0, W_CachePatchName(selectframesa[setup_animcounter % SELECTLEN], PU_CACHE), colormap); + V_DrawMappedPatch(x, y, V_TRANSLUCENT, W_CachePatchName(selectframesb[(setup_animcounter-1) % SELECTLEN], PU_CACHE), colormap); + } + else + { + V_DrawMappedPatch(x, y, 0, W_CachePatchName(idleframes[setup_animcounter % IDLELEN], PU_CACHE), colormap); + } + + if (p->mdepth < CSSTEP_READY) + V_DrawMappedPatch(x, y, 0, W_CachePatchName(va("CSELH%c", letter), PU_CACHE), colormap); + } +} + +#undef IDLE +#undef IDLELEN +#undef SELECTLEN + void M_DrawCharacterSelect(void) { UINT8 i, j, k; - UINT16 quadx, quady; + INT16 quadx, quady; SINT8 skin; // We have to loop twice -- first time to draw the drop shadows, a second time to draw the icons. @@ -703,10 +836,19 @@ void M_DrawCharacterSelect(void) colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); V_DrawMappedPatch(82 + (i*16) + quadx, 22 + (j*16) + quady, 0, facerankprefix[skin], 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)); } } } + // Explosions when you've made your final selection + M_DrawCharSelectExplosions(); + + // Draw the cursors + M_DrawCharSelectCursors(); + // Draw a preview for each player for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) M_DrawCharSelectPreview(i); diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 10dd84f2b..22c064f32 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -1290,6 +1290,9 @@ void M_Ticker(void) noFurtherInput = false; } + if (currentMenu->tickroutine) + currentMenu->tickroutine(); + if (dedicated) return; @@ -1374,7 +1377,8 @@ menu_t MessageDef = 0, 0, // x, y (TO HACK) 0, 0, // transition tics M_DrawMessageMenu, // drawing routine -> - NULL + NULL, // ticker routine + NULL // quit routine }; // @@ -1622,7 +1626,11 @@ void M_QuitSRB2(INT32 choice) // Character Select! struct setup_chargrid_s setup_chargrid[9][9]; setup_player_t setup_player[MAXSPLITSCREENPLAYERS]; +struct setup_explosions_s setup_explosions[48]; + UINT8 setup_numplayers = 0; +UINT16 setup_animcounter = 0; + consvar_t *setup_playercvars[MAXSPLITSCREENPLAYERS][SPLITCV_MAX]; void M_CharacterSelectInit(INT32 choice) @@ -1632,14 +1640,19 @@ void M_CharacterSelectInit(INT32 choice) (void)choice; memset(setup_chargrid, -1, sizeof(setup_chargrid)); - memset(setup_player, 0, sizeof(setup_player)); - for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) setup_chargrid[i][j].numskins = 0; } + memset(setup_player, 0, sizeof(setup_player)); + setup_player[0].mdepth = CSSTEP_CHARS; + setup_numplayers = 1; + + memset(setup_explosions, 0, sizeof(setup_explosions)); + setup_animcounter = 0; + // Keep these in a table for the sake of my sanity later setup_playercvars[0][SPLITCV_SKIN] = &cv_skin; setup_playercvars[1][SPLITCV_SKIN] = &cv_skin2; @@ -1680,12 +1693,56 @@ void M_CharacterSelectInit(INT32 choice) } } - setup_player[0].mdepth = 1; - setup_numplayers = 1; - M_SetupNextMenu(&PLAY_CharSelectDef, false); } +static void M_SetupReadyExplosions(setup_player_t *p) +{ + UINT8 i, j; + UINT8 e = 0; + + while (setup_explosions[e].tics) + { + e++; + if (e == CSEXPLOSIONS) + return; + } + + for (i = 0; i < 3; i++) + { + UINT8 t = 5 + (i*2); + UINT8 offset = (i+1); + + for (j = 0; j < 4; j++) + { + SINT8 x = p->gridx, y = p->gridy; + + switch (j) + { + case 0: x += offset; break; + case 1: x -= offset; break; + case 2: y += offset; break; + case 3: y -= offset; break; + } + + if ((x < 0 || x > 8) || (y < 0 || y > 8)) + continue; + + setup_explosions[e].tics = t; + setup_explosions[e].color = p->color; + setup_explosions[e].x = x; + setup_explosions[e].y = y; + + while (setup_explosions[e].tics) + { + e++; + if (e == CSEXPLOSIONS) + return; + } + } + } +} + static void M_HandleCharacterGrid(INT32 choice, setup_player_t *p) { switch (choice) @@ -1716,17 +1773,19 @@ static void M_HandleCharacterGrid(INT32 choice, setup_player_t *p) break; case KEY_ENTER: if (setup_chargrid[p->gridx][p->gridy].numskins == 0) - S_StartSound(NULL, sfx_s3k5b); + S_StartSound(NULL, sfx_s3k7b); //sfx_s3kb2 else { - p->mdepth++; if (setup_chargrid[p->gridx][p->gridy].numskins == 1) - p->mdepth++; // Skip clones menu + p->mdepth = CSSTEP_COLORS; // Skip clones menu + else + p->mdepth = CSSTEP_ALTS; + S_StartSound(NULL, sfx_s3k5b); } break; case KEY_ESCAPE: - p->mdepth--; + p->mdepth = CSSTEP_NONE; S_StartSound(NULL, sfx_s3k5b); break; default: @@ -1744,24 +1803,24 @@ static void M_HandleCharRotate(INT32 choice, setup_player_t *p) p->clonenum++; if (p->clonenum >= numclones) p->clonenum = 0; - - //p->skin = setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]; - S_StartSound(NULL, sfx_s3k5b); + p->rotate = CSROTATETICS; + p->delay = CSROTATETICS; + S_StartSound(NULL, sfx_s3kc3s); break; case KEY_LEFTARROW: p->clonenum--; if (p->clonenum < 0) p->clonenum = numclones-1; - - //p->skin = setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]; - S_StartSound(NULL, sfx_s3k5b); + p->rotate = -CSROTATETICS; + p->delay = CSROTATETICS; + S_StartSound(NULL, sfx_s3kc3s); break; case KEY_ENTER: - p->mdepth++; + p->mdepth = CSSTEP_COLORS; S_StartSound(NULL, sfx_s3k5b); break; case KEY_ESCAPE: - p->mdepth--; + p->mdepth = CSSTEP_CHARS; S_StartSound(NULL, sfx_s3k5b); break; default: @@ -1777,22 +1836,29 @@ static void M_HandleColorRotate(INT32 choice, setup_player_t *p) p->color++; if (p->color >= MAXSKINCOLORS) p->color = 1; - S_StartSound(NULL, sfx_s3k5b); + p->rotate = CSROTATETICS; + //p->delay = CSROTATETICS; + S_StartSound(NULL, sfx_s3kc3s); break; case KEY_LEFTARROW: p->color--; if (p->color < 1) p->color = MAXSKINCOLORS-1; - S_StartSound(NULL, sfx_s3k5b); + p->rotate = -CSROTATETICS; + //p->delay = CSROTATETICS; + S_StartSound(NULL, sfx_s3kc3s); break; case KEY_ENTER: - p->mdepth++; - S_StartSound(NULL, sfx_s3k5b); + p->mdepth = CSSTEP_READY; + p->delay = TICRATE; + M_SetupReadyExplosions(p); + S_StartSound(NULL, sfx_s3k4e); break; case KEY_ESCAPE: - p->mdepth--; - if (setup_chargrid[p->gridx][p->gridy].numskins <= 1) - p->mdepth--; // Skip clones menu + if (setup_chargrid[p->gridx][p->gridy].numskins == 1) + p->mdepth = CSSTEP_CHARS; // Skip clones menu + else + p->mdepth = CSSTEP_ALTS; S_StartSound(NULL, sfx_s3k5b); break; default: @@ -1811,76 +1877,98 @@ void M_CharacterSelectHandler(INT32 choice) if (i > 0) break; // temp - switch (p->mdepth) + if (p->delay == 0) { - case 0: // Enter Game - if (choice == KEY_ENTER) - setup_player[i].mdepth++; - break; - case 1: // Character Select grid - M_HandleCharacterGrid(choice, p); - break; - case 2: // Select clone - M_HandleCharRotate(choice, p); - break; - case 3: // Select color - M_HandleColorRotate(choice, p); - break; - default: // Unready - if (choice == KEY_ESCAPE) - setup_player[i].mdepth--; - break; + switch (p->mdepth) + { + case CSSTEP_NONE: // Enter Game + if (choice == KEY_ENTER) + p->mdepth = CSSTEP_CHARS; + break; + case CSSTEP_CHARS: // Character Select grid + M_HandleCharacterGrid(choice, p); + break; + case CSSTEP_ALTS: // Select clone + M_HandleCharRotate(choice, p); + break; + case CSSTEP_COLORS: // Select color + M_HandleColorRotate(choice, p); + break; + case CSSTEP_READY: + default: // Unready + if (choice == KEY_ESCAPE) + p->mdepth = CSSTEP_COLORS; + break; + } } - if (p->mdepth < 2) + if (p->mdepth < CSSTEP_ALTS) p->clonenum = 0; // Just makes it easier to access later p->skin = setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]; - if (p->mdepth < 3) + if (p->mdepth < CSSTEP_COLORS) p->color = skins[p->skin].prefcolor; - if (p->mdepth == 0) + if (p->mdepth == CSSTEP_NONE) break; else setup_numplayers = i+1; } // If the first player unjoins, then we get outta here - if (setup_player[0].mdepth == 0) + if (setup_player[0].mdepth == CSSTEP_NONE) { if (currentMenu->prevMenu) M_SetupNextMenu(currentMenu->prevMenu, false); else M_ClearMenus(true); } - else - { - boolean setupnext = false; +} +void M_CharacterSelectTick(void) +{ + UINT8 i; + boolean setupnext = true; + + setup_animcounter++; + + for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) + { + if (setup_player[i].delay) + setup_player[i].delay--; + + if (setup_player[i].rotate > 0) + setup_player[i].rotate--; + else if (setup_player[i].rotate < 0) + setup_player[i].rotate++; + + if (i >= setup_numplayers) + continue; + + if (setup_player[i].mdepth < CSSTEP_READY || setup_player[i].delay > 0) + { + // Someone's not ready yet. + setupnext = false; + } + } + + for (i = 0; i < CSEXPLOSIONS; i++) + { + if (setup_explosions[i].tics > 0) + setup_explosions[i].tics--; + } + + if (setupnext) + { for (i = 0; i < setup_numplayers; i++) { - if (setup_player[i].mdepth >= 4) - setupnext = true; - else - { - // Someone's not ready yet. - setupnext = false; - break; - } + CV_StealthSetValue(setup_playercvars[i][SPLITCV_SKIN], setup_player[i].skin); + CV_StealthSetValue(setup_playercvars[i][SPLITCV_COLOR], setup_player[i].color); } - if (setupnext) - { - for (i = 0; i < setup_numplayers; i++) - { - CV_StealthSetValue(setup_playercvars[i][SPLITCV_SKIN], setup_player[i].skin); - CV_StealthSetValue(setup_playercvars[i][SPLITCV_COLOR], setup_player[i].color); - } - - M_SetupNextMenu(&PLAY_MainDef, false); - } + M_SetupNextMenu(&PLAY_MainDef, false); } } diff --git a/src/v_video.c b/src/v_video.c index 8cb0751f7..c85fea3c7 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1792,6 +1792,74 @@ void V_DrawRightAlignedGamemodeString(INT32 x, INT32 y, INT32 option, const char x -= V_GamemodeStringWidth(string, option); V_DrawGamemodeString(x, y, option, string, color); } + +void V_DrawFileString(INT32 x, INT32 y, INT32 option, const char *string) +{ + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; + const char *ch = string; + + option &= ~V_FLIP; + + if (option & V_NOSCALESTART) + { + dupx = vid.dupx; + dupy = vid.dupy; + scrwidth = vid.width; + } + else + { + dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } + + for (;;ch++) + { + if (!*ch) + break; + + if (*ch == '\n') + { + cx = x; + cy += 14*dupy; + + continue; + } + + c = toupper(*ch) - AZ_FONTSTART; + + // character does not exist or is a space + if (c < 0 || c >= AZ_FONTSIZE || !file_font[c]) + continue; + + w = (SHORT(file_font[c]->width) - 3) * dupx; + + if (cx > scrwidth) + break; + + if (cx+left + w < 0) //left boundary check + { + cx += w; + continue; + } + + V_DrawFixedPatch(cx<= AZ_FONTSIZE || !file_font[c]) + continue; + else + w += SHORT(file_font[c]->width) - 3; + } + + return w; +} + boolean *heatshifter = NULL; INT32 lastheight = 0; INT32 heatindex[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0}; diff --git a/src/v_video.h b/src/v_video.h index 3c2ee8478..18968b77b 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -183,6 +183,9 @@ void V_DrawKartString(INT32 x, INT32 y, INT32 option, const char *string); void V_DrawGamemodeString(INT32 x, INT32 y, INT32 option, const char *string, UINT8 color); void V_DrawCenteredGamemodeString(INT32 x, INT32 y, INT32 option, const char *string, UINT8 color); void V_DrawRightAlignedGamemodeString(INT32 x, INT32 y, INT32 option, const char *string, UINT8 color); +void V_DrawFileString(INT32 x, INT32 y, INT32 option, const char *string); +void V_DrawCenteredFileString(INT32 x, INT32 y, INT32 option, const char *string); +void V_DrawRightAlignedFileString(INT32 x, INT32 y, INT32 option, const char *string); // draw a string using the hu_font, 0.5x scale void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string); @@ -219,6 +222,7 @@ INT32 V_ThinStringWidth(const char *string, INT32 option); // SRB2Kart INT32 V_GamemodeStringWidth(const char *string, INT32 option); +INT32 V_FileStringWidth(const char *string, INT32 option); void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param);