From aa8113cf06f030eebbdb680097d2ff20f005b3e1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Aug 2020 15:29:47 +0200 Subject: [PATCH] - ported the level summary screens. Not hooked up yet. --- source/sw/src/2d.cpp | 356 ++++++++++++++++++++++++++++++++ source/sw/src/draw.cpp | 4 +- source/sw/src/game.cpp | 435 +--------------------------------------- source/sw/src/game.h | 5 + source/sw/src/menus.cpp | 229 --------------------- source/sw/src/menus.h | 2 +- source/sw/src/misc.h | 2 +- source/sw/src/save.cpp | 4 - source/sw/src/sbar.cpp | 1 - source/sw/src/text.cpp | 242 +++++++++++++++++++++- 10 files changed, 611 insertions(+), 669 deletions(-) diff --git a/source/sw/src/2d.cpp b/source/sw/src/2d.cpp index 809d92e10..f1278ff7c 100644 --- a/source/sw/src/2d.cpp +++ b/source/sw/src/2d.cpp @@ -30,7 +30,12 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "sounds.h" #include "v_draw.h" #include "network.h" +#include "menus.h" #include "gamecontrol.h" +#include "mapinfo.h" +#include "misc.h" +#include "network.h" +#include "pal.h" BEGIN_SW_NS @@ -90,6 +95,357 @@ void Logo(const CompletionFunc& completion) else completion(false); } +//--------------------------------------------------------------------------- +// +// Summary screen +// +//--------------------------------------------------------------------------- +static int BonusPunchSound(short) +{ + PlaySound(DIGI_PLAYERYELL3, v3df_none); + return 0; +} + +static int BonusKickSound(short) +{ + PlaySound(DIGI_PLAYERYELL2, v3df_none); + return 0; +} + +static int BonusGrabSound(short) +{ + PlaySound(DIGI_BONUS_GRAB, v3df_none); + return 0; +} + + +enum +{ + BONUS_SCREEN_PIC = 5120, + BONUS_ANIM = 5121, + BONUS_ANIM_FRAMES = (5159 - 5121), + + BREAK_LIGHT_RATE = 18, + + BONUS_PUNCH = 5121, + BONUS_KICK = 5136, + BONUS_GRAB = 5151, + BONUS_REST = 5121, + + BONUS_TICS = 8, + BONUS_GRAB_TICS = 20, + BONUS_REST_TICS = 50, +}; + +static STATE s_BonusPunch[] = +{ + {BONUS_PUNCH + 0, BONUS_TICS, NULL, &s_BonusPunch[1]}, + {BONUS_PUNCH + 1, BONUS_TICS, NULL, &s_BonusPunch[2]}, + {BONUS_PUNCH + 2, BONUS_TICS, NULL, &s_BonusPunch[3]}, + {BONUS_PUNCH + 2, 0 | SF_QUICK_CALL, BonusPunchSound, &s_BonusPunch[4]}, + {BONUS_PUNCH + 3, BONUS_TICS, NULL, &s_BonusPunch[5]}, + {BONUS_PUNCH + 4, BONUS_TICS, NULL, &s_BonusPunch[6]}, + {BONUS_PUNCH + 5, BONUS_TICS, NULL, &s_BonusPunch[7]}, + {BONUS_PUNCH + 6, BONUS_TICS, NULL, &s_BonusPunch[8]}, + {BONUS_PUNCH + 7, BONUS_TICS, NULL, &s_BonusPunch[9]}, + {BONUS_PUNCH + 8, BONUS_TICS, NULL, &s_BonusPunch[10]}, + {BONUS_PUNCH + 9, BONUS_TICS, NULL, &s_BonusPunch[11]}, + {BONUS_PUNCH + 10, BONUS_TICS, NULL, &s_BonusPunch[12]}, + {BONUS_PUNCH + 11, BONUS_TICS, NULL, &s_BonusPunch[13]}, + {BONUS_PUNCH + 12, BONUS_TICS, NULL, &s_BonusPunch[14]}, + {BONUS_PUNCH + 14, 90, NULL, &s_BonusPunch[15]}, + {BONUS_PUNCH + 14, BONUS_TICS, NULL, &s_BonusPunch[15]}, +}; + +static STATE s_BonusKick[] = +{ + {BONUS_KICK + 0, BONUS_TICS, NULL, &s_BonusKick[1]}, + {BONUS_KICK + 1, BONUS_TICS, NULL, &s_BonusKick[2]}, + {BONUS_KICK + 2, BONUS_TICS, NULL, &s_BonusKick[3]}, + {BONUS_KICK + 2, 0 | SF_QUICK_CALL, BonusKickSound, &s_BonusKick[4]}, + {BONUS_KICK + 3, BONUS_TICS, NULL, &s_BonusKick[5]}, + {BONUS_KICK + 4, BONUS_TICS, NULL, &s_BonusKick[6]}, + {BONUS_KICK + 5, BONUS_TICS, NULL, &s_BonusKick[7]}, + {BONUS_KICK + 6, BONUS_TICS, NULL, &s_BonusKick[8]}, + {BONUS_KICK + 7, BONUS_TICS, NULL, &s_BonusKick[9]}, + {BONUS_KICK + 8, BONUS_TICS, NULL, &s_BonusKick[10]}, + {BONUS_KICK + 9, BONUS_TICS, NULL, &s_BonusKick[11]}, + {BONUS_KICK + 10, BONUS_TICS, NULL, &s_BonusKick[12]}, + {BONUS_KICK + 11, BONUS_TICS, NULL, &s_BonusKick[13]}, + {BONUS_KICK + 12, BONUS_TICS, NULL, &s_BonusKick[14]}, + {BONUS_KICK + 14, 90, NULL, &s_BonusKick[15]}, + {BONUS_KICK + 14, BONUS_TICS, NULL, &s_BonusKick[15]}, +}; + +static STATE s_BonusGrab[] = +{ + {BONUS_GRAB + 0, BONUS_GRAB_TICS, NULL, &s_BonusGrab[1]}, + {BONUS_GRAB + 1, BONUS_GRAB_TICS, NULL, &s_BonusGrab[2]}, + {BONUS_GRAB + 2, BONUS_GRAB_TICS, NULL, &s_BonusGrab[3]}, + {BONUS_GRAB + 2, 0 | SF_QUICK_CALL, BonusGrabSound, &s_BonusGrab[4]}, + {BONUS_GRAB + 3, BONUS_GRAB_TICS, NULL, &s_BonusGrab[5]}, + {BONUS_GRAB + 4, BONUS_GRAB_TICS, NULL, &s_BonusGrab[6]}, + {BONUS_GRAB + 5, BONUS_GRAB_TICS, NULL, &s_BonusGrab[7]}, + {BONUS_GRAB + 6, BONUS_GRAB_TICS, NULL, &s_BonusGrab[8]}, + {BONUS_GRAB + 7, BONUS_GRAB_TICS, NULL, &s_BonusGrab[9]}, + {BONUS_GRAB + 8, BONUS_GRAB_TICS, NULL, &s_BonusGrab[10]}, + {BONUS_GRAB + 9, 90, NULL, &s_BonusGrab[11]}, + {BONUS_GRAB + 9, BONUS_GRAB_TICS, NULL, &s_BonusGrab[11]}, +}; + +static STATE s_BonusRest[] = +{ + {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]}, + {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[2]}, + {BONUS_REST + 2, BONUS_REST_TICS, NULL, &s_BonusRest[3]}, + {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[0]}, +}; + +static STATE * s_BonusAnim[] = +{ + s_BonusPunch, + s_BonusKick, + s_BonusGrab +}; + +class DSWLevelSummaryScreen : public DScreenJob +{ + int minutes, seconds, second_tics; + int nextclock = synctics; + STATE * State = s_BonusRest; + int Tics = 0; + + DSWLevelSummaryScreen() + { + second_tics = (PlayClock / 120); + minutes = (second_tics / 60); + seconds = (second_tics % 60); + } + + static void gNextState(STATE** State) + { + // Transition to the next state + *State = (*State)->NextState; + + if (TEST((*State)->Tics, SF_QUICK_CALL)) + { + (*(*State)->Animator)(0); + *State = (*State)->NextState; + } + } + + + // Generic state control + static void gStateControl(STATE** State, int* tics) + { + *tics += synctics; + + // Skip states if too much time has passed + while (*tics >= (*State)->Tics) + { + // Set Tics + *tics -= (*State)->Tics; + gNextState(State); + } + + // Call the correct animator + if ((*State)->Animator) + (*(*State)->Animator)(0); + } + + int Frame(uint64_t clock, bool skiprequest) + { + twod->ClearScreen(); + int totalclock = int(clock * 120 / 1'000'000'000); + + while (totalclock > nextclock) + { + nextclock += synctics; + + if (State >= s_BonusRest && State < &s_BonusRest[countof(s_BonusRest)]) + { + State = s_BonusAnim[STD_RANDOM_RANGE(countof(s_BonusAnim))]; + Tics = 0; + } + gStateControl(&State, &Tics); + } + twod->ClearScreen(); + DrawTexture(twod, tileGetTexture(BONUS_SCREEN_PIC, true), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); + MNU_DrawString(160, 20, currentLevel->DisplayName(), 1, 19, 0); + MNU_DrawString(170, 30, GStrings("COMPLETED"), 1, 19, 0); + + DrawTexture(twod, tileGetTexture(State->Pic), 158, 86, DTA_FullscreenScale, FSMode_ScaleToFit43, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, + DTA_TopLeft, true, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); + + auto BONUS_LINE = [](int i) { return (50 + ((i) * 20)); }; + + int line = 0; + FString ds; + ds.Format("%s %2d : %02d", GStrings("TXT_YOURTIME"), minutes, seconds); + MNU_DrawString(60, BONUS_LINE(line++), ds, 1, 16); + + if (currentLevel->designerTime > 0) + { + ds.Format("%s %d:%02d", GStrings("TXT_3DRTIME"), currentLevel->designerTime / 60, currentLevel->designerTime % 60); + MNU_DrawString(40, BONUS_LINE(line++), ds, 1, 16); + } + + if (currentLevel->parTime > 0) + { + ds.Format("%s %d:%02d", GStrings("TXT_PARTIME"), currentLevel->parTime / 60, currentLevel->parTime % 60); + MNU_DrawString(40, BONUS_LINE(line++), ds, 1, 16); + } + + // always read secrets and kills from the first player + ds.Format("%s: %d / %d", GStrings("SECRETS"), Player->SecretsFound, LevelSecrets); + MNU_DrawString(60, BONUS_LINE(line++), ds, 1, 16); + + ds.Format("%s: %d / %d", GStrings("KILLS"), Player->Kills, TotalKillable); + MNU_DrawString(60, BONUS_LINE(line), ds, 1, 16); + + MNU_DrawString(160, 185, GStrings("PRESSKEY"), 1, 19, 0); + + int ret = (State == State->NextState)? 0 : skiprequest ? -1 : 1; + if (ret != 1) StopSound(); + return ret; + } + +}; + +//--------------------------------------------------------------------------- +// +// Deathmatch summary screen +// +//--------------------------------------------------------------------------- + +static constexpr int SM_SIZ(int num) { return (num * 4); } + +enum +{ + STAT_SCREEN_PIC = 5114, + + STAT_START_X = 20, + STAT_START_Y = 85, + STAT_OFF_Y = 9, + STAT_HEADER_Y = 14, + STAT_TABLE_X = (STAT_START_X + SM_SIZ(15)), + STAT_TABLE_XOFF = SM_SIZ(6) +}; + + +class DSWMultiSummaryScreen : public DScreenJob +{ + short death_total[MAX_SW_PLAYERS_REG]{}; + short kills[MAX_SW_PLAYERS_REG]{}; + + DSWMultiSummaryScreen() + { + } + + int Frame(uint64_t clock, bool skiprequest) + { + if (clock == 0) PlaySong(nullptr, ThemeSongs[1], ThemeTrack[1]); + + twod->ClearScreen(); + DrawTexture(twod, tileGetTexture(STAT_SCREEN_PIC, true), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); + MNU_DrawString(160, 68, GStrings("MULTIPLAYER TOTALS"), 0, 0); + MNU_DrawString(160, 189, GStrings("PRESSKEY"), 0, 0, 0); + + int x = STAT_START_X; + int y = STAT_START_Y; + + // Hm.... how to translate this without messing up the formatting? + DisplayMiniBarSmString(x, y, 0, " NAME 1 2 3 4 5 6 7 8 KILLS"); + int rows = OrigCommPlayers; + int cols = OrigCommPlayers; + + y += STAT_HEADER_Y; + + FString ds; + for (int i = 0; i < rows; i++) + { + x = STAT_START_X; + auto pp = Player + i; + + ds.Format("%d", i + 1); + DisplayMiniBarSmString(x, y, 0, ds); + + ds.Format(" %-13s", pp->PlayerName); + DisplayMiniBarSmString(x, y, User[pp->PlayerSprite]->spal, ds); + + x = STAT_TABLE_X; + for (int j = 0; j < cols; j++) + { + int pal = 0; + death_total[j] += pp->KilledPlayer[j]; + + if (i == j) + { + // don't add kill for self or team player + pal = PALETTE_PLAYER0 + 4; + kills[i] -= pp->KilledPlayer[j]; // subtract self kills + } + else if (gNet.TeamPlay) + { + if (User[pp->PlayerSprite]->spal == User[Player[j].PlayerSprite]->spal) + { + // don't add kill for self or team player + pal = PALETTE_PLAYER0 + 4; + kills[i] -= pp->KilledPlayer[j]; // subtract self kills + } + else + kills[i] += pp->KilledPlayer[j]; // kills added here + } + else + { + kills[i] += pp->KilledPlayer[j]; // kills added here + } + + ds.Format("%d", pp->KilledPlayer[j]); + DisplayMiniBarSmString(x, y, pal, ds); + x += STAT_TABLE_XOFF; + } + + y += STAT_OFF_Y; + } + + + // Deaths + + x = STAT_START_X; + y += STAT_OFF_Y; + + ds.Format(" %s", GStrings("DEATHS")); + DisplayMiniBarSmString(x, y, 0, ds); + x = STAT_TABLE_X; + + for (int j = 0; j < cols; j++) + { + ds.Format("%d", death_total[j]); + DisplayMiniBarSmString(x, y, 0, ds); + x += STAT_TABLE_XOFF; + } + + x = STAT_START_X; + y += STAT_OFF_Y; + + // Kills + x = STAT_TABLE_X + SM_SIZ(50); + y = STAT_START_Y + STAT_HEADER_Y; + + for (int i = 0; i < rows; i++) + { + auto pp = Player + i; + + ds.Format("%d", kills[i]); //pp->Kills); + DisplayMiniBarSmString(x, y, 0, ds); + + y += STAT_OFF_Y; + } + if (skiprequest) StopSound(); + return skiprequest ? -1 : 1; + } +}; END_SW_NS diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 4fb0b99f1..bfba360ca 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -1376,10 +1376,10 @@ void SecretInfo(PLAYERp pp) if (hud_stats) { sprintf(ds, "Kills %d/%d", Player->Kills, TotalKillable); - DisplayMiniBarSmString(pp, x, y, PAL_XLAT_BROWN, ds); + DisplayMiniBarSmString(x, y, PAL_XLAT_BROWN, ds); sprintf(ds, "Secrets %d/%d", Player->SecretsFound, LevelSecrets); - DisplayMiniBarSmString(pp, x, y+10, PAL_XLAT_BROWN, ds); + DisplayMiniBarSmString(x, y+10, PAL_XLAT_BROWN, ds); } } diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 88b85ee2a..4af13b50e 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -124,7 +124,6 @@ extern int sw_snd_scratch; #define BETA 0 #endif -#define STAT_SCREEN_PIC 5114 #define TITLE_PIC 2324 #define TITLE_ROT_FLAGS (RS_TOPLEFT|ROTATE_SPRITE_SCREEN_CLIP|ROTATE_SPRITE_NON_MASK) #define PAL_SIZE (256*3) @@ -148,7 +147,6 @@ int DemoTextYstart = 0; int Follow_posx=0,Follow_posy=0; SWBOOL NoMeters = FALSE; -short PlayingLevel = -1; SWBOOL GraphicsMode = FALSE; char CacheLastLevel[32] = ""; char PlayerNameArg[32] = ""; @@ -236,7 +234,7 @@ int totalsynctics; short Level = 0; SWBOOL ExitLevel = FALSE; -int16_t OrigCommPlayers=0; +int OrigCommPlayers=0; extern uint8_t CommPlayers; extern SWBOOL CommEnabled; extern int bufferjitter; @@ -804,8 +802,6 @@ InitLevel(void) } } - PlayingLevel = Level; - if (NewGame) InitNewGame(); @@ -1180,12 +1176,6 @@ void DrawMenuLevelScreen(void) rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1); } -void DrawStatScreen(void) -{ - twod->ClearScreen(); - rotatesprite(0, 0, RS_SCALE, 0, STAT_SCREEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1); -} - void DrawLoadLevelScreen(void) { twod->ClearScreen(); @@ -1345,300 +1335,16 @@ LoadingLevelScreen(void) videoNextPage(); } -void gNextState(STATEp *State) -{ - // Transition to the next state - *State = (*State)->NextState; - - if (TEST((*State)->Tics, SF_QUICK_CALL)) - { - (*(*State)->Animator)(0); - *State = (*State)->NextState; - } -} - -// Generic state control -void gStateControl(STATEp *State, int *tics) -{ - *tics += synctics; - - // Skip states if too much time has passed - while (*tics >= (*State)->Tics) - { - // Set Tics - *tics -= (*State)->Tics; - gNextState(State); - } - - // Call the correct animator - if ((*State)->Animator) - (*(*State)->Animator)(0); -} - -int BonusPunchSound(short UNUSED(SpriteNum)) -{ - PLAYERp pp = Player + myconnectindex; - PlaySound(DIGI_PLAYERYELL3, pp, v3df_none); - return 0; -} - -int BonusKickSound(short UNUSED(SpriteNum)) -{ - PLAYERp pp = Player + myconnectindex; - PlaySound(DIGI_PLAYERYELL2, pp, v3df_none); - return 0; -} - -int BonusGrabSound(short UNUSED(SpriteNum)) -{ - PLAYERp pp = Player + myconnectindex; - PlaySound(DIGI_BONUS_GRAB, pp, v3df_none); - return 0; -} - extern SWBOOL FinishedLevel; -extern int PlayClock; -extern short LevelSecrets; -extern short TotalKillable; -void BonusScreen() -{ - int minutes,seconds,second_tics; - - short w,h; - short limit; - - -#define BONUS_SCREEN_PIC 5120 -#define BONUS_ANIM 5121 -#define BONUS_ANIM_FRAMES (5159-5121) - -#define BREAK_LIGHT_RATE 18 - -#define BONUS_PUNCH 5121 -#define BONUS_KICK 5136 -#define BONUS_GRAB 5151 -#define BONUS_REST 5121 - -#define BONUS_TICS 8 -#define BONUS_GRAB_TICS 20 -#define BONUS_REST_TICS 50 - - static STATE s_BonusPunch[] = - { - {BONUS_PUNCH + 0, BONUS_TICS, NULL, &s_BonusPunch[1]}, - {BONUS_PUNCH + 1, BONUS_TICS, NULL, &s_BonusPunch[2]}, - {BONUS_PUNCH + 2, BONUS_TICS, NULL, &s_BonusPunch[3]}, - {BONUS_PUNCH + 2, 0|SF_QUICK_CALL, BonusPunchSound, &s_BonusPunch[4]}, - {BONUS_PUNCH + 3, BONUS_TICS, NULL, &s_BonusPunch[5]}, - {BONUS_PUNCH + 4, BONUS_TICS, NULL, &s_BonusPunch[6]}, - {BONUS_PUNCH + 5, BONUS_TICS, NULL, &s_BonusPunch[7]}, - {BONUS_PUNCH + 6, BONUS_TICS, NULL, &s_BonusPunch[8]}, - {BONUS_PUNCH + 7, BONUS_TICS, NULL, &s_BonusPunch[9]}, - {BONUS_PUNCH + 8, BONUS_TICS, NULL, &s_BonusPunch[10]}, - {BONUS_PUNCH + 9, BONUS_TICS, NULL, &s_BonusPunch[11]}, - {BONUS_PUNCH + 10, BONUS_TICS, NULL, &s_BonusPunch[12]}, - {BONUS_PUNCH + 11, BONUS_TICS, NULL, &s_BonusPunch[13]}, - {BONUS_PUNCH + 12, BONUS_TICS, NULL, &s_BonusPunch[14]}, - {BONUS_PUNCH + 14, 90, NULL, &s_BonusPunch[15]}, - {BONUS_PUNCH + 14, BONUS_TICS, NULL, &s_BonusPunch[15]}, - }; - - static STATE s_BonusKick[] = - { - {BONUS_KICK + 0, BONUS_TICS, NULL, &s_BonusKick[1]}, - {BONUS_KICK + 1, BONUS_TICS, NULL, &s_BonusKick[2]}, - {BONUS_KICK + 2, BONUS_TICS, NULL, &s_BonusKick[3]}, - {BONUS_KICK + 2, 0|SF_QUICK_CALL, BonusKickSound, &s_BonusKick[4]}, - {BONUS_KICK + 3, BONUS_TICS, NULL, &s_BonusKick[5]}, - {BONUS_KICK + 4, BONUS_TICS, NULL, &s_BonusKick[6]}, - {BONUS_KICK + 5, BONUS_TICS, NULL, &s_BonusKick[7]}, - {BONUS_KICK + 6, BONUS_TICS, NULL, &s_BonusKick[8]}, - {BONUS_KICK + 7, BONUS_TICS, NULL, &s_BonusKick[9]}, - {BONUS_KICK + 8, BONUS_TICS, NULL, &s_BonusKick[10]}, - {BONUS_KICK + 9, BONUS_TICS, NULL, &s_BonusKick[11]}, - {BONUS_KICK + 10, BONUS_TICS, NULL, &s_BonusKick[12]}, - {BONUS_KICK + 11, BONUS_TICS, NULL, &s_BonusKick[13]}, - {BONUS_KICK + 12, BONUS_TICS, NULL, &s_BonusKick[14]}, - {BONUS_KICK + 14, 90, NULL, &s_BonusKick[15]}, - {BONUS_KICK + 14, BONUS_TICS, NULL, &s_BonusKick[15]}, - }; - - static STATE s_BonusGrab[] = - { - {BONUS_GRAB + 0, BONUS_GRAB_TICS, NULL, &s_BonusGrab[1]}, - {BONUS_GRAB + 1, BONUS_GRAB_TICS, NULL, &s_BonusGrab[2]}, - {BONUS_GRAB + 2, BONUS_GRAB_TICS, NULL, &s_BonusGrab[3]}, - {BONUS_GRAB + 2, 0|SF_QUICK_CALL, BonusGrabSound, &s_BonusGrab[4]}, - {BONUS_GRAB + 3, BONUS_GRAB_TICS, NULL, &s_BonusGrab[5]}, - {BONUS_GRAB + 4, BONUS_GRAB_TICS, NULL, &s_BonusGrab[6]}, - {BONUS_GRAB + 5, BONUS_GRAB_TICS, NULL, &s_BonusGrab[7]}, - {BONUS_GRAB + 6, BONUS_GRAB_TICS, NULL, &s_BonusGrab[8]}, - {BONUS_GRAB + 7, BONUS_GRAB_TICS, NULL, &s_BonusGrab[9]}, - {BONUS_GRAB + 8, BONUS_GRAB_TICS, NULL, &s_BonusGrab[10]}, - {BONUS_GRAB + 9, 90, NULL, &s_BonusGrab[11]}, - {BONUS_GRAB + 9, BONUS_GRAB_TICS, NULL, &s_BonusGrab[11]}, - }; - -#if 1 // Turned off the standing animate because he looks like a FAG! - static STATE s_BonusRest[] = - { - {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]}, - {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[2]}, - {BONUS_REST + 2, BONUS_REST_TICS, NULL, &s_BonusRest[3]}, - {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[0]}, - }; -#else - static STATE s_BonusRest[] = - { - {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]}, - {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[0]}, - }; -#endif - - static STATEp s_BonusAnim[] = - { - s_BonusPunch, - s_BonusKick, - s_BonusGrab - }; - - STATEp State = s_BonusRest; - - int Tics = 0; - int line = 0; - SWBOOL BonusDone; - - if (Level < 0) Level = 0; - - twod->ClearScreen(); - videoNextPage(); - - inputState.ClearAllInput(); - - totalclock = ototalclock = 0; - limit = synctics; - - PlaySong(nullptr, ThemeSongs[1], ThemeTrack[1]); - - // special case code because I don't care any more! - if (FinishAnim) - { - renderFlushPerms(); - rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1); - rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1); - videoNextPage(); - //FadeIn(0,0); - } - - BonusDone = FALSE; - while (!BonusDone) - { - handleevents(); - - if (totalclock < ototalclock + limit) - { - continue; - } - ototalclock += limit; - - if (inputState.CheckAllInput()) - { - if (State >= s_BonusRest && State < &s_BonusRest[SIZ(s_BonusRest)]) - { - State = s_BonusAnim[STD_RANDOM_RANGE(SIZ(s_BonusAnim))]; - Tics = 0; - } - } - - gStateControl(&State, &Tics); - - twod->ClearScreen(); - rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1); - - if (UserMapName[0]) - { - sprintf(ds,"%s",UserMapName); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19); - } - else - { - if (PlayingLevel <= 1) - PlayingLevel = 1; - auto ds = currentLevel->DisplayName(); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19); - } - - sprintf(ds,"Completed"); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(TEXT_TEST_COL(w), 30, ds,1,19); - - rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1); - -#define BONUS_LINE(i) (50 + ((i)*20)) - - line = 0; - second_tics = (PlayClock/120); - minutes = (second_tics/60); - seconds = (second_tics%60); - sprintf(ds,"Your Time: %2d : %02d", minutes, seconds); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(60, BONUS_LINE(line), ds,1,16); - - if (!UserMapName[0]) - { - line++; - sprintf(ds,"3D Realms Best Time: %d:%02d", currentLevel->designerTime/60, currentLevel->designerTime%60); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(40, BONUS_LINE(line), ds,1,16); - - line++; - sprintf(ds,"Par Time: %d:%02d", currentLevel->parTime/ 60, currentLevel->parTime%60); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(40, BONUS_LINE(line), ds,1,16); - } - - - // always read secrets and kills from the first player - line++; - sprintf(ds,"Secrets: %d / %d", Player->SecretsFound, LevelSecrets); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(60, BONUS_LINE(line), ds,1,16); - - line++; - sprintf(ds,"Kills: %d / %d", Player->Kills, TotalKillable); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(60, BONUS_LINE(line), ds,1,16); - - - sprintf(ds,"Press SPACE to continue"); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(TEXT_TEST_COL(w), 185, ds,1,19); - - videoNextPage(); - - if (State == State->NextState) - BonusDone = TRUE; - } - - StopSound(); -} void EndGameSequence(void) { - SWBOOL anim_ok = TRUE; - //FadeOut(0, 5); StopSound(); - if ((adult_lockout || Global_PLock) && FinishAnim == ANIM_SUMO) - anim_ok = FALSE; + playanm(FinishAnim); - if (anim_ok) - playanm(FinishAnim); - - BonusScreen(); + //BonusScreen(); ExitLevel = FALSE; QuitFlag = FALSE; @@ -1674,20 +1380,8 @@ void StatScreen(PLAYERp mpp) short rows,cols,i,j; PLAYERp pp = NULL; int x,y; - short death_total[MAX_SW_PLAYERS_REG]; - short kills[MAX_SW_PLAYERS_REG]; short pal; -#define STAT_START_X 20 -#define STAT_START_Y 85 -#define STAT_OFF_Y 9 -#define STAT_HEADER_Y 14 - -#define SM_SIZ(num) ((num)*4) - -#define STAT_TABLE_X (STAT_START_X + SM_SIZ(15)) -#define STAT_TABLE_XOFF SM_SIZ(6) - //ResetPalette(mpp); COVER_SetReverb(0); // Reset reverb mpp->Reverb = 0; @@ -1704,129 +1398,10 @@ void StatScreen(PLAYERp mpp) { if (!FinishedLevel) return; - BonusScreen(); + //BonusScreen(); return; } - - renderFlushPerms(); - DrawStatScreen(); - - memset(death_total,0,sizeof(death_total)); - memset(kills,0,sizeof(kills)); - - auto c = GStrings("MULTIPLAYER TOTALS"); - MNU_MeasureString(c, &w, &h); - MNU_DrawString(TEXT_TEST_COL(w), 68, c, 0, 0); - - c = GStrings("TXTS_PRESSSPACE"); - MNU_MeasureString(c, &w, &h); - MNU_DrawString(TEXT_TEST_COL(w), 189, c, 0, 0); - - x = STAT_START_X; - y = STAT_START_Y; - - // Hm.... how to translate this without messing up the formatting? - sprintf(ds," NAME 1 2 3 4 5 6 7 8 KILLS"); - DisplayMiniBarSmString(mpp, x, y, 0, ds); - rows = OrigCommPlayers; - cols = OrigCommPlayers; - mpp = Player + myconnectindex; - - y += STAT_HEADER_Y; - - for (i = 0; i < rows; i++) - { - x = STAT_START_X; - pp = Player + i; - - sprintf(ds,"%d", i+1); - DisplayMiniBarSmString(mpp, x, y, 0, ds); - - sprintf(ds," %-13s", pp->PlayerName); - DisplayMiniBarSmString(mpp, x, y, User[pp->PlayerSprite]->spal, ds); - - x = STAT_TABLE_X; - for (j = 0; j < cols; j++) - { - pal = 0; - death_total[j] += pp->KilledPlayer[j]; - - if (i == j) - { - // don't add kill for self or team player - pal = PALETTE_PLAYER0 + 4; - kills[i] -= pp->KilledPlayer[j]; // subtract self kills - } - else if (gNet.TeamPlay) - { - if (User[pp->PlayerSprite]->spal == User[Player[j].PlayerSprite]->spal) - { - // don't add kill for self or team player - pal = PALETTE_PLAYER0 + 4; - kills[i] -= pp->KilledPlayer[j]; // subtract self kills - } - else - kills[i] += pp->KilledPlayer[j]; // kills added here - } - else - { - kills[i] += pp->KilledPlayer[j]; // kills added here - } - - sprintf(ds,"%d", pp->KilledPlayer[j]); - DisplayMiniBarSmString(mpp, x, y, pal, ds); - x += STAT_TABLE_XOFF; - } - - y += STAT_OFF_Y; - } - - - // Deaths - - x = STAT_START_X; - y += STAT_OFF_Y; - - sprintf(ds," %s", GStrings("DEATHS")); - DisplayMiniBarSmString(mpp, x, y, 0, ds); - x = STAT_TABLE_X; - - for (j = 0; j < cols; j++) - { - sprintf(ds,"%d",death_total[j]); - DisplayMiniBarSmString(mpp, x, y, 0, ds); - x += STAT_TABLE_XOFF; - } - - x = STAT_START_X; - y += STAT_OFF_Y; - - // Kills - x = STAT_TABLE_X + SM_SIZ(50); - y = STAT_START_Y + STAT_HEADER_Y; - - for (i = 0; i < rows; i++) - { - pp = Player + i; - - sprintf(ds,"%d", kills[i]); //pp->Kills); - DisplayMiniBarSmString(mpp, x, y, 0, ds); - - y += STAT_OFF_Y; - } - - videoNextPage(); - - inputState.ClearAllInput(); - - PlaySong(nullptr, ThemeSongs[1], ThemeTrack[1]); - - while (!inputState.CheckAllInput()) - { - handleevents(); - } - - StopSound(); + //MPBonusScreen(); } void GameIntro(void) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index fa87df0e4..1ffa8a022 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2427,6 +2427,11 @@ void LoadSaveMsg(const char *msg); void UpdateStatusBar(ClockTicks arg); +extern int PlayClock; +extern short LevelSecrets; +extern short TotalKillable; +extern int OrigCommPlayers; + struct GameInterface : ::GameInterface { const char* Name() override { return "ShadowWarrior"; } diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index 430e57af0..338a0d39c 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -140,235 +140,6 @@ MNU_StartNetGame(void) } -//////////////////////////////////////////////// -// Measure the pixel width of a graphic string -//////////////////////////////////////////////// -static char lg_xlat_num[] = { 0,1,2,3,4,5,6,7,8,9 }; -#define FONT_LARGE_ALPHA 3706 -#define FONT_LARGE_DIGIT 3732 -#define MenuDrawFlags (ROTATE_SPRITE_SCREEN_CLIP) -#define MZ 65536 -#define MENU_SHADE_DEFAULT 0 -#define MENU_SHADE_INACTIVE 20 - -void MNU_MeasureStringLarge(const char *string, short *w, short *h) -{ - short ndx, width, height; - char c; - short pic; - - width = 0; - height = *h; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - if (isalpha(c)) - { - c = toupper(c); - pic = FONT_LARGE_ALPHA + (c - 'A'); - } - else if (isdigit(c)) - { - pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')]; - } - else if (c == ' ') - { - width += 10; // Special case for space char - continue; - } - else - { - continue; - } - - width += tilesiz[pic].x+1; - if (height < tilesiz[pic].y) - height = tilesiz[pic].y; - } - - *w = width; - *h = height; -} - -//////////////////////////////////////////////// -// Draw a string using a graphic font -//////////////////////////////////////////////// -void MNU_DrawStringLarge(short x, short y, const char *string, int shade) -{ - int ndx, offset; - char c; - short pic; - - offset = x; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - if (isalpha(c)) - { - c = toupper(c); - pic = FONT_LARGE_ALPHA + (c - 'A'); - } - else if (isdigit(c)) - { - pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')]; - } - else if (c == ' ') - { - offset += 10; - continue; - } - else - { - continue; - } - - rotatesprite(offset << 16, y << 16, MZ, 0, pic, shade, 0, MenuDrawFlags|RS_TOPLEFT, 0, 0, xdim - 1, ydim - 1); - offset += tilesiz[pic].x + 1; - } - -} - - -//////////////////////////////////////////////// -// Measure the pixel width of a graphic string -//////////////////////////////////////////////// -void MNU_MeasureString(const char *string, short *w, short *h) -{ - short ndx, width, height; - char c; - short ac; - - if (string[0] == '^') - { - MNU_MeasureStringLarge(&string[1], w, h); - return; - } - - width = 0; - height = *h; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - ac = c - '!' + STARTALPHANUM; - if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space) - break; - - if (c > asc_Space && c < 127) - { - width += tilesiz[ac].x; - if (height < tilesiz[ac].y) - height = tilesiz[ac].y; - } - else if (c == asc_Space) - width += 4; // Special case for space char - } - - *w = width; - *h = height; -} - -//////////////////////////////////////////////// -// Draw a string using a graphic font -// -// MenuTextShade and MenuDrawFlags -//////////////////////////////////////////////// -void MNU_DrawString(short x, short y, const char *string, short shade, short pal) -{ - int ndx, offset; - char c; - short ac; - - if (string[0] == '^') - { - MNU_DrawStringLarge(x,y, &string[1]); - return; - } - - offset = x; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - ac = c - '!' + STARTALPHANUM; - if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space) - break; - - if (c > asc_Space && c < 127) - { - rotatesprite(offset<<16,y<<16,MZ,0,ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - offset += tilesiz[ac].x; - } - else if (c == asc_Space) - offset += 4; // Special case for space char - } - -} - -//////////////////////////////////////////////// -// Measure the pixel width of a small font string -//////////////////////////////////////////////// -void MNU_MeasureSmallString(const char *string, short *w, short *h) -{ - short ndx, width, height; - char c; - short ac; - - width = 0; - height = *h; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - ac = (c - '!') + 2930; - if ((ac < 2930 || ac > 3023) && c != asc_Space) - break; - - if (c > asc_Space && c < 127) - { - width += tilesiz[ac].x; - if (height < tilesiz[ac].y) - height = tilesiz[ac].y; - } - else if (c == asc_Space) - width += 4; // Special case for space char - } - - *w = width; - *h = height; -} - -//////////////////////////////////////////////// -// Draw a string using a small graphic font -//////////////////////////////////////////////// -void MNU_DrawSmallString(short x, short y, const char *string, short shade, short pal) -{ - int ndx; - char c; - short ac,offset; - - - offset = x; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - ac = c - '!' + 2930; - if ((ac < 2930 || ac > 3023) && c != asc_Space) - break; - - if (c > asc_Space && c < 127) - { - rotatesprite(offset<<16,y<<16,MZ,0,ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - - offset += tilesiz[ac].x; - - } - else if (c == asc_Space) - { - offset += 4; // Special case for space char - } - } - -} - - ////////////////////////////////////////////////////////////////////////////// #define FADE_DAMAGE_FACTOR 3 // 100 health / 32 shade cycles = 3.125 diff --git a/source/sw/src/menus.h b/source/sw/src/menus.h index 6a1289569..c62427b80 100644 --- a/source/sw/src/menus.h +++ b/source/sw/src/menus.h @@ -33,7 +33,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS void MNU_MeasureString(const char* string, short* w, short* h); -void MNU_DrawString(short x, short y, const char* string, short shade, short pal); +void MNU_DrawString(short x, short y, const char* string, short shade, short pal, int align = -1); void MNU_MeasureSmallString(const char* string, short* w, short* h); void MNU_DrawSmallString(short x, short y, const char* string, short shade, short pal); void MNU_MeasureStringLarge(const char* string, short* w, short* h); diff --git a/source/sw/src/misc.h b/source/sw/src/misc.h index 87d70e393..3ee281ba9 100644 --- a/source/sw/src/misc.h +++ b/source/sw/src/misc.h @@ -53,7 +53,7 @@ void MoveSectorObjects(SECTOR_OBJECTp sop, short locktics); #define TEXT_INFO_YOFF (10) inline int TEXT_INFO_LINE(int line) { return (TEXT_INFO_Y + ((line)*TEXT_INFO_YOFF)); } -void DisplayMiniBarSmString(PLAYERp pp, short xs, short ys, short pal, const char* buffer); +void DisplayMiniBarSmString(short xs, short ys, short pal, const char* buffer); void PutStringInfo(PLAYERp pp, const char* string); void PutStringInfoLine(PLAYERp pp, const char* string); void PutStringInfoLine2(PLAYERp pp, const char* string); diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index 08162ab2b..d81d0d158 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -71,12 +71,9 @@ extern int lastUpdate; extern char UserMapName[80]; extern char SaveGameDescr[10][80]; extern int PlayClock; -extern short TotalKillable; -extern short LevelSecrets; extern short Bunny_Count; extern SWBOOL NewGame; extern char CacheLastLevel[]; -extern short PlayingLevel; extern int GodMode; extern int FinishTimer; extern SWBOOL FinishAnim; @@ -1115,7 +1112,6 @@ bool GameInterface::LoadGame(FSaveGameNode* sv) InitNetVars(); screenpeek = myconnectindex; - PlayingLevel = Level; Mus_ResumeSaved(); if (snd_ambience) diff --git a/source/sw/src/sbar.cpp b/source/sw/src/sbar.cpp index c9e2098d0..9c007c7f5 100644 --- a/source/sw/src/sbar.cpp +++ b/source/sw/src/sbar.cpp @@ -326,7 +326,6 @@ class DSWStatusBar : public DBaseStatusBar // must draw this in HUD mode and align to the top center short i, num_frag_bars; int y; - extern int16_t OrigCommPlayers; if (numplayers <= 1) return; diff --git a/source/sw/src/text.cpp b/source/sw/src/text.cpp index 23e5f6797..0e7912d8c 100644 --- a/source/sw/src/text.cpp +++ b/source/sw/src/text.cpp @@ -184,7 +184,7 @@ PANEL_SPRITEp pClearSpriteID(PLAYERp pp, short id) void -DisplayMiniBarSmString(PLAYERp UNUSED(pp), short xs, short ys, short pal, const char *buffer) +DisplayMiniBarSmString(short xs, short ys, short pal, const char *buffer) { short size=4,x; const char *ptr; @@ -208,6 +208,246 @@ DisplayMiniBarSmString(PLAYERp UNUSED(pp), short xs, short ys, short pal, const } } + +//////////////////////////////////////////////// +// Measure the pixel width of a graphic string +//////////////////////////////////////////////// +static char lg_xlat_num[] = { 0,1,2,3,4,5,6,7,8,9 }; +#define FONT_LARGE_ALPHA 3706 +#define FONT_LARGE_DIGIT 3732 +#define MenuDrawFlags (ROTATE_SPRITE_SCREEN_CLIP) +#define MZ 65536 +#define MENU_SHADE_DEFAULT 0 +#define MENU_SHADE_INACTIVE 20 + +void MNU_MeasureStringLarge(const char* string, short* w, short* h) +{ + short ndx, width, height; + char c; + short pic; + + width = 0; + height = *h; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + if (isalpha(c)) + { + c = toupper(c); + pic = FONT_LARGE_ALPHA + (c - 'A'); + } + else if (isdigit(c)) + { + pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')]; + } + else if (c == ' ') + { + width += 10; // Special case for space char + continue; + } + else + { + continue; + } + + width += tilesiz[pic].x + 1; + if (height < tilesiz[pic].y) + height = tilesiz[pic].y; + } + + *w = width; + *h = height; +} + +//////////////////////////////////////////////// +// Draw a string using a graphic font +//////////////////////////////////////////////// +void MNU_DrawStringLarge(short x, short y, const char* string, int shade) +{ + int ndx, offset; + char c; + short pic; + + offset = x; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + if (isalpha(c)) + { + c = toupper(c); + pic = FONT_LARGE_ALPHA + (c - 'A'); + } + else if (isdigit(c)) + { + pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')]; + } + else if (c == ' ') + { + offset += 10; + continue; + } + else + { + continue; + } + + rotatesprite(offset << 16, y << 16, MZ, 0, pic, shade, 0, MenuDrawFlags | RS_TOPLEFT, 0, 0, xdim - 1, ydim - 1); + offset += tilesiz[pic].x + 1; + } + +} + + +//////////////////////////////////////////////// +// Measure the pixel width of a graphic string +//////////////////////////////////////////////// +void MNU_MeasureString(const char* string, short* w, short* h) +{ + short ndx, width, height; + char c; + short ac; + + if (string[0] == '^') + { + MNU_MeasureStringLarge(&string[1], w, h); + return; + } + + width = 0; + height = *h; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + ac = c - '!' + STARTALPHANUM; + if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space) + break; + + if (c > asc_Space && c < 127) + { + width += tilesiz[ac].x; + if (height < tilesiz[ac].y) + height = tilesiz[ac].y; + } + else if (c == asc_Space) + width += 4; // Special case for space char + } + + *w = width; + *h = height; +} + +//////////////////////////////////////////////// +// Draw a string using a graphic font +// +// MenuTextShade and MenuDrawFlags +//////////////////////////////////////////////// +void MNU_DrawString(short x, short y, const char* string, short shade, short pal, int align) +{ + int ndx, offset; + char c; + short ac; + + if (string[0] == '^') + { + MNU_DrawStringLarge(x, y, &string[1]); + return; + } + + if (align > -1) + { + short w, h; + MNU_MeasureString(string, &w, &h); + if (align == 0) x -= w / 2; + else x -= w; + } + + offset = x; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + ac = c - '!' + STARTALPHANUM; + if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space) + break; + + if (c > asc_Space && c < 127) + { + rotatesprite(offset << 16, y << 16, MZ, 0, ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); + offset += tilesiz[ac].x; + } + else if (c == asc_Space) + offset += 4; // Special case for space char + } + +} + +//////////////////////////////////////////////// +// Measure the pixel width of a small font string +//////////////////////////////////////////////// +void MNU_MeasureSmallString(const char* string, short* w, short* h) +{ + short ndx, width, height; + char c; + short ac; + + width = 0; + height = *h; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + ac = (c - '!') + 2930; + if ((ac < 2930 || ac > 3023) && c != asc_Space) + break; + + if (c > asc_Space && c < 127) + { + width += tilesiz[ac].x; + if (height < tilesiz[ac].y) + height = tilesiz[ac].y; + } + else if (c == asc_Space) + width += 4; // Special case for space char + } + + *w = width; + *h = height; +} + +//////////////////////////////////////////////// +// Draw a string using a small graphic font +//////////////////////////////////////////////// +void MNU_DrawSmallString(short x, short y, const char* string, short shade, short pal) +{ + int ndx; + char c; + short ac, offset; + + + offset = x; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + ac = c - '!' + 2930; + if ((ac < 2930 || ac > 3023) && c != asc_Space) + break; + + if (c > asc_Space && c < 127) + { + rotatesprite(offset << 16, y << 16, MZ, 0, ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); + + offset += tilesiz[ac].x; + + } + else if (c == asc_Space) + { + offset += 4; // Special case for space char + } + } + +} + + + + short GlobInfoStringTime = TEXT_INFO_TIME; void PutStringInfo(PLAYERp pp, const char *string) {