Merge branch 'continue_startinglives' into 'master'
Save cards and continue startinglives-balancing See merge request !114
This commit is contained in:
commit
6d03c50966
|
@ -45,6 +45,10 @@ extern INT32 cursaveslot;
|
||||||
extern INT16 lastmaploaded;
|
extern INT16 lastmaploaded;
|
||||||
extern boolean gamecomplete;
|
extern boolean gamecomplete;
|
||||||
|
|
||||||
|
#define maxgameovers 13
|
||||||
|
extern UINT8 numgameovers;
|
||||||
|
extern SINT8 startinglivesbalance[maxgameovers+1];
|
||||||
|
|
||||||
#define PRECIP_NONE 0
|
#define PRECIP_NONE 0
|
||||||
#define PRECIP_STORM 1
|
#define PRECIP_STORM 1
|
||||||
#define PRECIP_SNOW 2
|
#define PRECIP_SNOW 2
|
||||||
|
|
|
@ -1125,7 +1125,7 @@ void F_StartCredits(void)
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
|
|
||||||
// Save the second we enter the credits
|
// Save the second we enter the credits
|
||||||
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot >= 0)
|
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
|
||||||
G_SaveGame((UINT32)cursaveslot);
|
G_SaveGame((UINT32)cursaveslot);
|
||||||
|
|
||||||
if (creditscutscene)
|
if (creditscutscene)
|
||||||
|
@ -1263,7 +1263,7 @@ static boolean drawemblem = false, drawchaosemblem = false;
|
||||||
void F_StartGameEvaluation(void)
|
void F_StartGameEvaluation(void)
|
||||||
{
|
{
|
||||||
// Credits option in secrets menu
|
// Credits option in secrets menu
|
||||||
if (cursaveslot == -2)
|
if (cursaveslot == -1)
|
||||||
{
|
{
|
||||||
F_StartGameEnd();
|
F_StartGameEnd();
|
||||||
return;
|
return;
|
||||||
|
@ -1277,7 +1277,7 @@ void F_StartGameEvaluation(void)
|
||||||
// Save the second we enter the evaluation
|
// Save the second we enter the evaluation
|
||||||
// We need to do this again! Remember, it's possible a mod designed skipped
|
// We need to do this again! Remember, it's possible a mod designed skipped
|
||||||
// the credits sequence!
|
// the credits sequence!
|
||||||
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot >= 0)
|
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
|
||||||
G_SaveGame((UINT32)cursaveslot);
|
G_SaveGame((UINT32)cursaveslot);
|
||||||
|
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
|
|
173
src/g_game.c
173
src/g_game.c
|
@ -76,11 +76,14 @@ INT16 gamemap = 1;
|
||||||
INT16 maptol;
|
INT16 maptol;
|
||||||
UINT8 globalweather = 0;
|
UINT8 globalweather = 0;
|
||||||
INT32 curWeather = PRECIP_NONE;
|
INT32 curWeather = PRECIP_NONE;
|
||||||
INT32 cursaveslot = -1; // Auto-save 1p savegame slot
|
INT32 cursaveslot = 0; // Auto-save 1p savegame slot
|
||||||
//INT16 lastmapsaved = 0; // Last map we auto-saved at
|
//INT16 lastmapsaved = 0; // Last map we auto-saved at
|
||||||
INT16 lastmaploaded = 0; // Last map the game loaded
|
INT16 lastmaploaded = 0; // Last map the game loaded
|
||||||
boolean gamecomplete = false;
|
boolean gamecomplete = false;
|
||||||
|
|
||||||
|
UINT8 numgameovers = 0; // for startinglives balance
|
||||||
|
SINT8 startinglivesbalance[maxgameovers+1] = {3, 5, 7, 9, 12, 15, 20, 25, 30, 40, 50, 75, 99, 0x7F};
|
||||||
|
|
||||||
UINT16 mainwads = 0;
|
UINT16 mainwads = 0;
|
||||||
boolean modifiedgame; // Set if homebrew PWAD stuff has been added.
|
boolean modifiedgame; // Set if homebrew PWAD stuff has been added.
|
||||||
boolean savemoddata = false;
|
boolean savemoddata = false;
|
||||||
|
@ -3149,8 +3152,11 @@ static void G_DoContinued(void)
|
||||||
tokenlist = 0;
|
tokenlist = 0;
|
||||||
token = 0;
|
token = 0;
|
||||||
|
|
||||||
|
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && (!modifiedgame || savemoddata) && cursaveslot > 0)
|
||||||
|
G_SaveGameOver((UINT32)cursaveslot, true);
|
||||||
|
|
||||||
// Reset # of lives
|
// Reset # of lives
|
||||||
pl->lives = (ultimatemode) ? 1 : 3;
|
pl->lives = (ultimatemode) ? 1 : startinglivesbalance[numgameovers];
|
||||||
|
|
||||||
D_MapChange(gamemap, gametype, ultimatemode, false, 0, false, false);
|
D_MapChange(gamemap, gametype, ultimatemode, false, 0, false, false);
|
||||||
|
|
||||||
|
@ -3489,59 +3495,6 @@ void G_SaveGameData(void)
|
||||||
|
|
||||||
#define VERSIONSIZE 16
|
#define VERSIONSIZE 16
|
||||||
|
|
||||||
#ifdef SAVEGAMES_OTHERVERSIONS
|
|
||||||
static INT16 startonmapnum = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// User wants to load a savegame from a different version?
|
|
||||||
//
|
|
||||||
static void M_ForceLoadGameResponse(INT32 ch)
|
|
||||||
{
|
|
||||||
if (ch != 'y' && ch != KEY_ENTER)
|
|
||||||
{
|
|
||||||
//refused
|
|
||||||
Z_Free(savebuffer);
|
|
||||||
save_p = savebuffer = NULL;
|
|
||||||
startonmapnum = 0;
|
|
||||||
M_SetupNextMenu(&SP_LoadDef);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pick up where we left off.
|
|
||||||
save_p += VERSIONSIZE;
|
|
||||||
if (!P_LoadGame(startonmapnum))
|
|
||||||
{
|
|
||||||
M_ClearMenus(true); // so ESC backs out to title
|
|
||||||
M_StartMessage(M_GetText("Savegame file corrupted\n\nPress ESC\n"), NULL, MM_NOTHING);
|
|
||||||
Command_ExitGame_f();
|
|
||||||
Z_Free(savebuffer);
|
|
||||||
save_p = savebuffer = NULL;
|
|
||||||
startonmapnum = 0;
|
|
||||||
|
|
||||||
// no cheating!
|
|
||||||
memset(&savedata, 0, sizeof(savedata));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// done
|
|
||||||
Z_Free(savebuffer);
|
|
||||||
save_p = savebuffer = NULL;
|
|
||||||
startonmapnum = 0;
|
|
||||||
|
|
||||||
//set cursaveslot to -1 so nothing gets saved.
|
|
||||||
cursaveslot = -1;
|
|
||||||
|
|
||||||
displayplayer = consoleplayer;
|
|
||||||
multiplayer = splitscreen = false;
|
|
||||||
|
|
||||||
if (setsizeneeded)
|
|
||||||
R_ExecuteSetViewSize();
|
|
||||||
|
|
||||||
M_ClearMenus(true);
|
|
||||||
CON_ToggleOff();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// G_InitFromSavegame
|
// G_InitFromSavegame
|
||||||
// Can be called by the startup code or the menu task.
|
// Can be called by the startup code or the menu task.
|
||||||
|
@ -3634,13 +3587,13 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
||||||
// G_SaveGame
|
// G_SaveGame
|
||||||
// Saves your game.
|
// Saves your game.
|
||||||
//
|
//
|
||||||
void G_SaveGame(UINT32 savegameslot)
|
void G_SaveGame(UINT32 slot)
|
||||||
{
|
{
|
||||||
boolean saved;
|
boolean saved;
|
||||||
char savename[256] = "";
|
char savename[256] = "";
|
||||||
const char *backup;
|
const char *backup;
|
||||||
|
|
||||||
sprintf(savename, savegamename, savegameslot);
|
sprintf(savename, savegamename, slot);
|
||||||
backup = va("%s",savename);
|
backup = va("%s",savename);
|
||||||
|
|
||||||
// save during evaluation or credits? game's over, folks!
|
// save during evaluation or credits? game's over, folks!
|
||||||
|
@ -3676,9 +3629,91 @@ void G_SaveGame(UINT32 savegameslot)
|
||||||
if (cv_debug && saved)
|
if (cv_debug && saved)
|
||||||
CONS_Printf(M_GetText("Game saved.\n"));
|
CONS_Printf(M_GetText("Game saved.\n"));
|
||||||
else if (!saved)
|
else if (!saved)
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, savegameslot, savegamename);
|
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BADSAVE goto cleanup;
|
||||||
|
#define CHECKPOS if (save_p >= end_p) BADSAVE
|
||||||
|
void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
||||||
|
{
|
||||||
|
boolean saved = false;
|
||||||
|
size_t length;
|
||||||
|
char vcheck[VERSIONSIZE];
|
||||||
|
char savename[255];
|
||||||
|
const char *backup;
|
||||||
|
|
||||||
|
sprintf(savename, savegamename, slot);
|
||||||
|
backup = va("%s",savename);
|
||||||
|
|
||||||
|
length = FIL_ReadFile(savename, &savebuffer);
|
||||||
|
if (!length)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("Couldn't read file %s\n"), savename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char temp[sizeof(timeattackfolder)];
|
||||||
|
UINT8 *end_p = savebuffer + length;
|
||||||
|
UINT8 *lives_p;
|
||||||
|
SINT8 pllives;
|
||||||
|
|
||||||
|
save_p = savebuffer;
|
||||||
|
// Version check
|
||||||
|
memset(vcheck, 0, sizeof (vcheck));
|
||||||
|
sprintf(vcheck, "version %d", VERSION);
|
||||||
|
if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE
|
||||||
|
save_p += VERSIONSIZE;
|
||||||
|
|
||||||
|
// P_UnArchiveMisc()
|
||||||
|
(void)READINT16(save_p);
|
||||||
|
CHECKPOS
|
||||||
|
(void)READUINT16(save_p); // emeralds
|
||||||
|
CHECKPOS
|
||||||
|
READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to
|
||||||
|
if (strcmp(temp, timeattackfolder)) BADSAVE
|
||||||
|
|
||||||
|
// P_UnArchivePlayer()
|
||||||
|
CHECKPOS
|
||||||
|
(void)READUINT16(save_p);
|
||||||
|
CHECKPOS
|
||||||
|
|
||||||
|
WRITEUINT8(save_p, numgameovers);
|
||||||
|
CHECKPOS
|
||||||
|
|
||||||
|
lives_p = save_p;
|
||||||
|
pllives = READSINT8(save_p); // lives
|
||||||
|
CHECKPOS
|
||||||
|
if (modifylives && pllives < startinglivesbalance[numgameovers])
|
||||||
|
{
|
||||||
|
pllives = startinglivesbalance[numgameovers];
|
||||||
|
WRITESINT8(lives_p, pllives);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)READINT32(save_p); // Score
|
||||||
|
CHECKPOS
|
||||||
|
(void)READINT32(save_p); // continues
|
||||||
|
|
||||||
|
// File end marker check
|
||||||
|
CHECKPOS
|
||||||
|
if (READUINT8(save_p) != 0x1d) BADSAVE;
|
||||||
|
|
||||||
|
// done
|
||||||
|
saved = FIL_WriteFile(backup, savebuffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (cv_debug && saved)
|
||||||
|
CONS_Printf(M_GetText("Game saved.\n"));
|
||||||
|
else if (!saved)
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename);
|
||||||
|
Z_Free(savebuffer);
|
||||||
|
save_p = savebuffer = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
#undef CHECKPOS
|
||||||
|
#undef BADSAVE
|
||||||
|
|
||||||
//
|
//
|
||||||
// G_DeferedInitNew
|
// G_DeferedInitNew
|
||||||
// Can be called by the startup code or the menu task,
|
// Can be called by the startup code or the menu task,
|
||||||
|
@ -3686,7 +3721,7 @@ void G_SaveGame(UINT32 savegameslot)
|
||||||
//
|
//
|
||||||
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS)
|
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS)
|
||||||
{
|
{
|
||||||
UINT8 color = 0;
|
UINT8 color = skins[pickedchar].prefcolor;
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
if (demoplayback)
|
if (demoplayback)
|
||||||
|
@ -3698,10 +3733,8 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b
|
||||||
|
|
||||||
if (savedata.lives > 0)
|
if (savedata.lives > 0)
|
||||||
{
|
{
|
||||||
color = savedata.skincolor;
|
if ((botingame = ((botskin = savedata.botskin) != 0)))
|
||||||
botskin = savedata.botskin;
|
botcolor = skins[botskin-1].prefcolor;
|
||||||
botcolor = savedata.botcolor;
|
|
||||||
botingame = (botskin != 0);
|
|
||||||
}
|
}
|
||||||
else if (splitscreen != SSSG)
|
else if (splitscreen != SSSG)
|
||||||
{
|
{
|
||||||
|
@ -3709,8 +3742,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b
|
||||||
SplitScreen_OnChange();
|
SplitScreen_OnChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!color)
|
color = skins[pickedchar].prefcolor;
|
||||||
color = skins[pickedchar].prefcolor;
|
|
||||||
SetPlayerSkinByNum(consoleplayer, pickedchar);
|
SetPlayerSkinByNum(consoleplayer, pickedchar);
|
||||||
CV_StealthSet(&cv_skin, skins[pickedchar].name);
|
CV_StealthSet(&cv_skin, skins[pickedchar].name);
|
||||||
CV_StealthSetValue(&cv_playercolor, color);
|
CV_StealthSetValue(&cv_playercolor, color);
|
||||||
|
@ -3742,7 +3774,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
||||||
if (resetplayer)
|
if (resetplayer)
|
||||||
{
|
{
|
||||||
// Clear a bunch of variables
|
// Clear a bunch of variables
|
||||||
tokenlist = token = sstimer = redscore = bluescore = lastmap = 0;
|
numgameovers = tokenlist = token = sstimer = redscore = bluescore = lastmap = 0;
|
||||||
countdown = countdown2 = 0;
|
countdown = countdown2 = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
@ -3757,15 +3789,10 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
||||||
players[i].lives = cv_startinglives.value;
|
players[i].lives = cv_startinglives.value;
|
||||||
players[i].continues = 0;
|
players[i].continues = 0;
|
||||||
}
|
}
|
||||||
else if (pultmode)
|
|
||||||
{
|
|
||||||
players[i].lives = 1;
|
|
||||||
players[i].continues = 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
players[i].lives = 3;
|
players[i].lives = (pultmode) ? 1 : startinglivesbalance[0];
|
||||||
players[i].continues = 1;
|
players[i].continues = (pultmode) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((netgame || multiplayer) && (FLS)))
|
if (!((netgame || multiplayer) && (FLS)))
|
||||||
|
|
|
@ -116,6 +116,8 @@ void G_SaveGameData(void);
|
||||||
|
|
||||||
void G_SaveGame(UINT32 slot);
|
void G_SaveGame(UINT32 slot);
|
||||||
|
|
||||||
|
void G_SaveGameOver(UINT32 slot, boolean modifylives);
|
||||||
|
|
||||||
// Only called by startup code.
|
// Only called by startup code.
|
||||||
void G_RecordDemo(const char *name);
|
void G_RecordDemo(const char *name);
|
||||||
void G_RecordMetal(void);
|
void G_RecordMetal(void);
|
||||||
|
|
|
@ -83,6 +83,7 @@ patch_t *rmatcico;
|
||||||
patch_t *bmatcico;
|
patch_t *bmatcico;
|
||||||
patch_t *tagico;
|
patch_t *tagico;
|
||||||
patch_t *tallminus;
|
patch_t *tallminus;
|
||||||
|
patch_t *tallinfin;
|
||||||
|
|
||||||
//-------------------------------------------
|
//-------------------------------------------
|
||||||
// coop hud
|
// coop hud
|
||||||
|
@ -235,6 +236,7 @@ void HU_LoadGraphics(void)
|
||||||
|
|
||||||
// minus for negative tallnums
|
// minus for negative tallnums
|
||||||
tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX);
|
tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX);
|
||||||
|
tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX);
|
||||||
|
|
||||||
// cache the crosshairs, don't bother to know which one is being used,
|
// cache the crosshairs, don't bother to know which one is being used,
|
||||||
// just cache all 3, they're so small anyway.
|
// just cache all 3, they're so small anyway.
|
||||||
|
@ -1250,7 +1252,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3))) //show lives
|
if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != 0x7f)) //show lives
|
||||||
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives));
|
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives));
|
||||||
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
||||||
{
|
{
|
||||||
|
@ -1388,7 +1390,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
||||||
| (greycheck ? V_TRANSLUCENT : 0)
|
| (greycheck ? V_TRANSLUCENT : 0)
|
||||||
| V_ALLOWLOWERCASE, name);
|
| V_ALLOWLOWERCASE, name);
|
||||||
|
|
||||||
if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3))) //show lives
|
if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != 0x7f)) //show lives
|
||||||
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives));
|
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives));
|
||||||
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
||||||
V_DrawSmallScaledPatch(x-28, y-4, 0, tagico);
|
V_DrawSmallScaledPatch(x-28, y-4, 0, tagico);
|
||||||
|
|
|
@ -71,6 +71,7 @@ extern patch_t *rmatcico;
|
||||||
extern patch_t *bmatcico;
|
extern patch_t *bmatcico;
|
||||||
extern patch_t *tagico;
|
extern patch_t *tagico;
|
||||||
extern patch_t *tallminus;
|
extern patch_t *tallminus;
|
||||||
|
extern patch_t *tallinfin;
|
||||||
extern patch_t *tokenicon;
|
extern patch_t *tokenicon;
|
||||||
|
|
||||||
// set true when entering a chat message
|
// set true when entering a chat message
|
||||||
|
|
|
@ -61,7 +61,7 @@ static UINT8 cheatf_ultimate(void)
|
||||||
if (menuactive && (currentMenu != &MainDef && currentMenu != &SP_LoadDef))
|
if (menuactive && (currentMenu != &MainDef && currentMenu != &SP_LoadDef))
|
||||||
return 0; // Only on the main menu, or the save select!
|
return 0; // Only on the main menu, or the save select!
|
||||||
|
|
||||||
S_StartSound(0, sfx_itemup);
|
BwehHehHe();
|
||||||
ultimate_selectable = (!ultimate_selectable);
|
ultimate_selectable = (!ultimate_selectable);
|
||||||
|
|
||||||
// If on the save select, move to what is now Ultimate Mode!
|
// If on the save select, move to what is now Ultimate Mode!
|
||||||
|
|
724
src/m_menu.c
724
src/m_menu.c
|
@ -172,7 +172,9 @@ static char joystickInfo[8][25];
|
||||||
static UINT32 serverlistpage;
|
static UINT32 serverlistpage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games.
|
static UINT8 numsaves = 0;
|
||||||
|
static saveinfo_t* savegameinfo = NULL; // Extra info about the save games.
|
||||||
|
static patch_t *savselp[7];
|
||||||
|
|
||||||
INT16 startmap; // Mario, NiGHTS, or just a plain old normal game?
|
INT16 startmap; // Mario, NiGHTS, or just a plain old normal game?
|
||||||
|
|
||||||
|
@ -222,7 +224,7 @@ static INT32 lsoffs[2];
|
||||||
#define lshli levelselectselect[2]
|
#define lshli levelselectselect[2]
|
||||||
|
|
||||||
#define lshseperation 101
|
#define lshseperation 101
|
||||||
#define lsbasevseperation 62
|
#define lsbasevseperation (62*vid.height)/(BASEVIDHEIGHT*vid.dupy) //62
|
||||||
#define lsheadingheight 16
|
#define lsheadingheight 16
|
||||||
#define getheadingoffset(row) (levelselect.rows[row].header[0] ? lsheadingheight : 0)
|
#define getheadingoffset(row) (levelselect.rows[row].header[0] ? lsheadingheight : 0)
|
||||||
#define lsvseperation(row) lsbasevseperation + getheadingoffset(row)
|
#define lsvseperation(row) lsbasevseperation + getheadingoffset(row)
|
||||||
|
@ -2580,7 +2582,7 @@ boolean M_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata)
|
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata)
|
||||||
{
|
{
|
||||||
S_StartSound(NULL, sfx_menu1);
|
S_StartSound(NULL, sfx_skid);
|
||||||
M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4061,10 +4063,10 @@ static boolean M_PrepareLevelPlatter(INT32 gt)
|
||||||
if (actnum)
|
if (actnum)
|
||||||
sprintf(mapname, "%s %d", mapheaderinfo[mapnum]->lvlttl, actnum);
|
sprintf(mapname, "%s %d", mapheaderinfo[mapnum]->lvlttl, actnum);
|
||||||
else
|
else
|
||||||
sprintf(mapname, "%s", mapheaderinfo[mapnum]->lvlttl);
|
strcpy(mapname, mapheaderinfo[mapnum]->lvlttl);
|
||||||
|
|
||||||
if (strlen(mapname) >= 17)
|
if (strlen(mapname) >= 17)
|
||||||
sprintf(mapname+17-3, "...");
|
strcpy(mapname+17-3, "...");
|
||||||
|
|
||||||
strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname);
|
strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname);
|
||||||
}
|
}
|
||||||
|
@ -4093,6 +4095,24 @@ static boolean M_PrepareLevelPlatter(INT32 gt)
|
||||||
mapnum++;
|
mapnum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SYMMETRICAL_PLATTER
|
||||||
|
// horizontally space out rows with missing right sides
|
||||||
|
for (; row >= 0; row--)
|
||||||
|
{
|
||||||
|
if (!levelselect.rows[row].maplist[2] // no right side
|
||||||
|
&& levelselect.rows[row].maplist[0] && levelselect.rows[row].maplist[1]) // all the left filled in
|
||||||
|
{
|
||||||
|
levelselect.rows[row].maplist[2] = levelselect.rows[row].maplist[1];
|
||||||
|
STRBUFCPY(levelselect.rows[row].mapnames[2], levelselect.rows[row].mapnames[1]);
|
||||||
|
levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1];
|
||||||
|
|
||||||
|
levelselect.rows[row].maplist[1] = -1; // diamond
|
||||||
|
levelselect.rows[row].mapnames[1][0] = '\0';
|
||||||
|
levelselect.rows[row].mapavailable[1] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (levselp[0][0]) // never going to have some provided but not all, saves individually checking
|
if (levselp[0][0]) // never going to have some provided but not all, saves individually checking
|
||||||
{
|
{
|
||||||
W_UnlockCachedPatch(levselp[0][0]);
|
W_UnlockCachedPatch(levselp[0][0]);
|
||||||
|
@ -4230,7 +4250,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
||||||
else if (!lsoffs[0]) // prevent sound spam
|
else if (!lsoffs[0]) // prevent sound spam
|
||||||
{
|
{
|
||||||
lsoffs[0] = -8;
|
lsoffs[0] = -8;
|
||||||
S_StartSound(NULL,sfx_s3kb2);
|
S_StartSound(NULL,sfx_lose);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -4261,14 +4281,10 @@ void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlig
|
||||||
y += lsheadingheight - 12;
|
y += lsheadingheight - 12;
|
||||||
V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0)|(allowlowercase ? V_ALLOWLOWERCASE : 0), header);
|
V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0)|(allowlowercase ? V_ALLOWLOWERCASE : 0), header);
|
||||||
y += 9;
|
y += 9;
|
||||||
if ((y >= 0) && (y < 200))
|
V_DrawFill(19, y, 281, 1, (headerhighlight ? yellowmap[3] : 3));
|
||||||
{
|
V_DrawFill(300, y, 1, 1, 26);
|
||||||
V_DrawFill(19, y, 281, 1, (headerhighlight ? yellowmap[3] : 3));
|
|
||||||
V_DrawFill(300, y, 1, 1, 26);
|
|
||||||
}
|
|
||||||
y++;
|
y++;
|
||||||
if ((y >= 0) && (y < 200))
|
V_DrawFill(19, y, 282, 1, 26);
|
||||||
V_DrawFill(19, y, 282, 1, 26);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight)
|
static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight)
|
||||||
|
@ -4276,7 +4292,7 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo
|
||||||
patch_t *patch;
|
patch_t *patch;
|
||||||
|
|
||||||
INT32 map = levelselect.rows[row].maplist[col];
|
INT32 map = levelselect.rows[row].maplist[col];
|
||||||
if (!map)
|
if (map <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// A 564x100 image of the level as entry MAPxxW
|
// A 564x100 image of the level as entry MAPxxW
|
||||||
|
@ -4292,22 +4308,9 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo
|
||||||
V_DrawSmallScaledPatch(x, y, 0, patch);
|
V_DrawSmallScaledPatch(x, y, 0, patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((y+50) < 200)
|
V_DrawFill(x, y+50, 282, 8,
|
||||||
{
|
((mapheaderinfo[map-1]->unlockrequired < 0)
|
||||||
INT32 topy = (y+50), h = 8;
|
? 159 : 63));
|
||||||
|
|
||||||
if (topy < 0)
|
|
||||||
{
|
|
||||||
h += topy;
|
|
||||||
topy = 0;
|
|
||||||
}
|
|
||||||
else if (topy + h >= 200)
|
|
||||||
h = 200 - y;
|
|
||||||
if (h > 0)
|
|
||||||
V_DrawFill(x, topy, 282, h,
|
|
||||||
((mapheaderinfo[map-1]->unlockrequired < 0)
|
|
||||||
? 159 : 63));
|
|
||||||
}
|
|
||||||
|
|
||||||
V_DrawString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
|
V_DrawString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
|
||||||
}
|
}
|
||||||
|
@ -4317,7 +4320,7 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea
|
||||||
patch_t *patch;
|
patch_t *patch;
|
||||||
|
|
||||||
INT32 map = levelselect.rows[row].maplist[col];
|
INT32 map = levelselect.rows[row].maplist[col];
|
||||||
if (!map)
|
if (map <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// A 160x100 image of the level as entry MAPxxP
|
// A 160x100 image of the level as entry MAPxxP
|
||||||
|
@ -4333,22 +4336,9 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea
|
||||||
V_DrawSmallScaledPatch(x, y, 0, patch);
|
V_DrawSmallScaledPatch(x, y, 0, patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((y+50) < 200)
|
V_DrawFill(x, y+50, 80, 8,
|
||||||
{
|
((mapheaderinfo[map-1]->unlockrequired < 0)
|
||||||
INT32 topy = (y+50), h = 8;
|
? 159 : 63));
|
||||||
|
|
||||||
if (topy < 0)
|
|
||||||
{
|
|
||||||
h += topy;
|
|
||||||
topy = 0;
|
|
||||||
}
|
|
||||||
else if (topy + h >= 200)
|
|
||||||
h = 200 - y;
|
|
||||||
if (h > 0)
|
|
||||||
V_DrawFill(x, topy, 80, h,
|
|
||||||
((mapheaderinfo[map-1]->unlockrequired < 0)
|
|
||||||
? 159 : 63));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(levelselect.rows[row].mapnames[col]) > 6) // "AERIAL GARDEN" vs "ACT 18" - "THE ACT" intentionally compressed
|
if (strlen(levelselect.rows[row].mapnames[col]) > 6) // "AERIAL GARDEN" vs "ACT 18" - "THE ACT" intentionally compressed
|
||||||
V_DrawThinString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
|
V_DrawThinString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
|
||||||
|
@ -4402,16 +4392,16 @@ static void M_DrawLevelPlatterMenu(void)
|
||||||
// draw cursor box
|
// draw cursor box
|
||||||
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)]));
|
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)]));
|
||||||
|
|
||||||
if (levelselect.rows[lsrow].maplist[lscol])
|
if (levelselect.rows[lsrow].maplist[lscol] > 0)
|
||||||
V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
||||||
|
|
||||||
// handle movement of cursor box
|
// handle movement of cursor box
|
||||||
if (abs(lsoffs[0]) > 1)
|
if (lsoffs[0] > 1 || lsoffs[0] < -1)
|
||||||
lsoffs[0] = 2*lsoffs[0]/3;
|
lsoffs[0] = 2*lsoffs[0]/3;
|
||||||
else
|
else
|
||||||
lsoffs[0] = 0;
|
lsoffs[0] = 0;
|
||||||
|
|
||||||
if (abs(lsoffs[1]) > 1)
|
if (lsoffs[1] > 1 || lsoffs[1] < -1)
|
||||||
lsoffs[1] = 2*lsoffs[1]/3;
|
lsoffs[1] = 2*lsoffs[1]/3;
|
||||||
else
|
else
|
||||||
lsoffs[1] = 0;
|
lsoffs[1] = 0;
|
||||||
|
@ -5395,7 +5385,7 @@ static void M_LevelSelectWarp(INT32 choice)
|
||||||
G_LoadGame((UINT32)cursaveslot, startmap);
|
G_LoadGame((UINT32)cursaveslot, startmap);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cursaveslot = -1;
|
cursaveslot = 0;
|
||||||
M_SetupChoosePlayer(0);
|
M_SetupChoosePlayer(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5970,7 +5960,7 @@ static void M_CustomWarp(INT32 choice)
|
||||||
static void M_Credits(INT32 choice)
|
static void M_Credits(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
cursaveslot = -2;
|
cursaveslot = -1;
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
F_StartCredits();
|
F_StartCredits();
|
||||||
}
|
}
|
||||||
|
@ -6028,149 +6018,285 @@ static void M_LoadGameLevelSelect(INT32 choice)
|
||||||
// LOAD GAME MENU
|
// LOAD GAME MENU
|
||||||
// ==============
|
// ==============
|
||||||
|
|
||||||
static INT32 saveSlotSelected = 0;
|
static INT32 saveSlotSelected = 1;
|
||||||
static short menumovedir = 0;
|
static INT32 loadgamescroll = 0;
|
||||||
|
static UINT8 loadgameoffset = 0;
|
||||||
|
|
||||||
static void M_DrawLoadGameData(void)
|
static void M_DrawLoadGameData(void)
|
||||||
{
|
{
|
||||||
INT32 ecks;
|
INT32 i, savetodraw, x, y, hsep = 90;
|
||||||
INT32 i;
|
skin_t *charskin = NULL;
|
||||||
|
|
||||||
ecks = SP_LoadDef.x + 24;
|
if (vid.width != BASEVIDWIDTH*vid.dupx)
|
||||||
M_DrawTextBox(SP_LoadDef.x-12,144, 24, 4);
|
hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx);
|
||||||
|
|
||||||
if (saveSlotSelected == NOSAVESLOT) // last slot is play without saving
|
for (i = -2; i <= 2; i++)
|
||||||
{
|
{
|
||||||
if (ultimate_selectable)
|
savetodraw = (saveSlotSelected + i + numsaves)%numsaves;
|
||||||
|
x = (BASEVIDWIDTH/2 - 42 + loadgamescroll) + (i*hsep);
|
||||||
|
y = 33 + 9;
|
||||||
|
|
||||||
{
|
{
|
||||||
V_DrawCenteredString(ecks + 68, 144, V_ORANGEMAP, "ULTIMATE MODE");
|
INT32 diff = x - (BASEVIDWIDTH/2 - 42);
|
||||||
V_DrawCenteredString(ecks + 68, 156, 0, "NO RINGS, NO ONE-UPS,");
|
if (diff < 0)
|
||||||
V_DrawCenteredString(ecks + 68, 164, 0, "NO CONTINUES, ONE LIFE,");
|
diff = -diff;
|
||||||
V_DrawCenteredString(ecks + 68, 172, 0, "FINAL DESTINATION.");
|
diff = (42 - diff)/3 - loadgameoffset;
|
||||||
|
if (diff < 0)
|
||||||
|
diff = 0;
|
||||||
|
y -= diff;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (savetodraw == 0)
|
||||||
V_DrawCenteredString(ecks + 68, 144, V_ORANGEMAP, "PLAY WITHOUT SAVING");
|
|
||||||
V_DrawCenteredString(ecks + 68, 156, 0, "THIS GAME WILL NOT BE");
|
|
||||||
V_DrawCenteredString(ecks + 68, 164, 0, "SAVED, BUT YOU CAN STILL");
|
|
||||||
V_DrawCenteredString(ecks + 68, 172, 0, "GET EMBLEMS AND SECRETS.");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (savegameinfo[saveSlotSelected].lives == -42) // Empty
|
|
||||||
{
|
|
||||||
V_DrawCenteredString(ecks + 68, 160, 0, "NO DATA");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (savegameinfo[saveSlotSelected].lives == -666) // savegame is bad
|
|
||||||
{
|
|
||||||
V_DrawCenteredString(ecks + 68, 144, V_REDMAP, "CORRUPT SAVE FILE");
|
|
||||||
V_DrawCenteredString(ecks + 68, 156, 0, "THIS SAVE FILE");
|
|
||||||
V_DrawCenteredString(ecks + 68, 164, 0, "CAN NOT BE LOADED.");
|
|
||||||
V_DrawCenteredString(ecks + 68, 172, 0, "DELETE USING BACKSPACE.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the back sprite, it looks ugly if we don't
|
|
||||||
V_DrawScaledPatch(SP_LoadDef.x, 144+8, 0, livesback);
|
|
||||||
if (savegameinfo[saveSlotSelected].skincolor == 0)
|
|
||||||
V_DrawScaledPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UINT8 *colormap = R_GetTranslationColormap(savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor, 0);
|
|
||||||
V_DrawMappedPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE), colormap);
|
|
||||||
}
|
|
||||||
|
|
||||||
V_DrawString(ecks + 12, 152, 0, savegameinfo[saveSlotSelected].playername);
|
|
||||||
|
|
||||||
#ifdef SAVEGAMES_OTHERVERSIONS
|
|
||||||
if (savegameinfo[saveSlotSelected].gamemap & 16384)
|
|
||||||
V_DrawCenteredString(ecks + 68, 144, V_REDMAP, "OUTDATED SAVE FILE!");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (savegameinfo[saveSlotSelected].gamemap & 8192)
|
|
||||||
V_DrawString(ecks + 12, 160, V_GREENMAP, "CLEAR!");
|
|
||||||
else
|
|
||||||
V_DrawString(ecks + 12, 160, 0, va("%s", savegameinfo[saveSlotSelected].levelname));
|
|
||||||
|
|
||||||
// Use the big face pic for lives, duh. :3
|
|
||||||
V_DrawScaledPatch(ecks + 12, 175, 0, W_CachePatchName("STLIVEX", PU_HUDGFX));
|
|
||||||
V_DrawTallNum(ecks + 40, 172, 0, savegameinfo[saveSlotSelected].lives);
|
|
||||||
|
|
||||||
// Absolute ridiculousness, condensed into another function.
|
|
||||||
V_DrawContinueIcon(ecks + 58, 182, 0, savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor);
|
|
||||||
V_DrawScaledPatch(ecks + 68, 175, 0, W_CachePatchName("STLIVEX", PU_HUDGFX));
|
|
||||||
V_DrawTallNum(ecks + 96, 172, 0, savegameinfo[saveSlotSelected].continues);
|
|
||||||
|
|
||||||
for (i = 0; i < 7; ++i)
|
|
||||||
{
|
|
||||||
if (savegameinfo[saveSlotSelected].numemeralds & (1 << i))
|
|
||||||
V_DrawScaledPatch(ecks + 104 + (i * 8), 172, 0, tinyemeraldpics[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOADBARHEIGHT SP_LoadDef.y + (LINEHEIGHT * (j+1)) + ymod
|
|
||||||
#define CURSORHEIGHT SP_LoadDef.y + (LINEHEIGHT*3) - 1
|
|
||||||
static void M_DrawLoad(void)
|
|
||||||
{
|
|
||||||
INT32 i, j;
|
|
||||||
INT32 ymod = 0, offset = 0;
|
|
||||||
|
|
||||||
M_DrawMenuTitle();
|
|
||||||
|
|
||||||
if (menumovedir != 0) //movement illusion
|
|
||||||
{
|
|
||||||
ymod = (-(LINEHEIGHT/4))*menumovedir;
|
|
||||||
offset = ((menumovedir > 0) ? -1 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, 40, 0, "Press backspace to delete a save.");
|
|
||||||
|
|
||||||
for (i = MAXSAVEGAMES + saveSlotSelected - 2 + offset, j = 0;i <= MAXSAVEGAMES + saveSlotSelected + 2 + offset; i++, j++)
|
|
||||||
{
|
|
||||||
if ((menumovedir < 0 && j == 4) || (menumovedir > 0 && j == 0))
|
|
||||||
continue; //this helps give the illusion of movement
|
|
||||||
|
|
||||||
M_DrawSaveLoadBorder(SP_LoadDef.x, LOADBARHEIGHT);
|
|
||||||
|
|
||||||
if ((i%MAXSAVEGAMES) == NOSAVESLOT) // play without saving
|
|
||||||
{
|
{
|
||||||
|
V_DrawSmallScaledPatch(x, y, 0,
|
||||||
|
savselp[((ultimate_selectable) ? 2 : 1)]);
|
||||||
|
x += 2;
|
||||||
|
y += 1;
|
||||||
|
V_DrawString(x, y,
|
||||||
|
((savetodraw == saveSlotSelected) ? V_YELLOWMAP : 0),
|
||||||
|
"NO FILE");
|
||||||
|
if (savetodraw == saveSlotSelected)
|
||||||
|
V_DrawFill(x, y+9, 80, 1, yellowmap[3]);
|
||||||
|
y += 11;
|
||||||
|
V_DrawSmallScaledPatch(x, y, V_STATIC, savselp[4]);
|
||||||
|
y += 41;
|
||||||
if (ultimate_selectable)
|
if (ultimate_selectable)
|
||||||
V_DrawCenteredString(SP_LoadDef.x+92, LOADBARHEIGHT - 1, V_ORANGEMAP, "ULTIMATE MODE");
|
V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "ULTIMATE.");
|
||||||
else
|
else
|
||||||
V_DrawCenteredString(SP_LoadDef.x+92, LOADBARHEIGHT - 1, V_ORANGEMAP, "PLAY WITHOUT SAVING");
|
V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "DON'T SAVE!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savegameinfo[i%MAXSAVEGAMES].lives == -42)
|
savetodraw--;
|
||||||
V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_TRANSLUCENT, "NO DATA");
|
|
||||||
else if (savegameinfo[i%MAXSAVEGAMES].lives == -666)
|
|
||||||
V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_REDMAP, "CORRUPT SAVE FILE");
|
|
||||||
else if (savegameinfo[i%MAXSAVEGAMES].gamemap & 8192)
|
|
||||||
V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_GREENMAP, "CLEAR!");
|
|
||||||
else
|
|
||||||
V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, 0, va("%s", savegameinfo[i%MAXSAVEGAMES].levelname));
|
|
||||||
|
|
||||||
//Draw the save slot number on the right side
|
if (savegameinfo[savetodraw].lives > 0)
|
||||||
V_DrawRightAlignedString(SP_LoadDef.x+192, LOADBARHEIGHT - 1, 0, va("%d",(i%MAXSAVEGAMES) + 1));
|
charskin = &skins[savegameinfo[savetodraw].skinnum];
|
||||||
|
|
||||||
|
// signpost background
|
||||||
|
{
|
||||||
|
UINT8 col;
|
||||||
|
if (savegameinfo[savetodraw].lives == -666)
|
||||||
|
{
|
||||||
|
V_DrawSmallScaledPatch(x+2, y+64, 0, savselp[5]);
|
||||||
|
}
|
||||||
|
#ifndef PERFECTSAVE // disabled, don't touch
|
||||||
|
else if ((savegameinfo[savetodraw].skinnum == 1)
|
||||||
|
&& (savegameinfo[savetodraw].lives == 99)
|
||||||
|
&& (savegameinfo[savetodraw].gamemap & 8192)
|
||||||
|
&& (savegameinfo[savetodraw].numgameovers == 0)
|
||||||
|
&& (savegameinfo[savetodraw].numemeralds == ((1<<7) - 1))) // perfect save
|
||||||
|
{
|
||||||
|
V_DrawFill(x+6, y+64, 72, 50, 134);
|
||||||
|
V_DrawFill(x+6, y+74, 72, 30, 201);
|
||||||
|
V_DrawFill(x+6, y+84, 72, 10, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (savegameinfo[savetodraw].lives == -42)
|
||||||
|
col = 26;
|
||||||
|
else if (savegameinfo[savetodraw].botskin == 3) // & knuckles
|
||||||
|
col = 105;
|
||||||
|
else if (savegameinfo[savetodraw].botskin) // tailsbot or custom
|
||||||
|
col = 134;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
col = (charskin->prefcolor - 1)*2;
|
||||||
|
col = Color_Index[Color_Opposite[col]-1][Color_Opposite[col+1]];
|
||||||
|
}
|
||||||
|
|
||||||
|
V_DrawFill(x+6, y+64, 72, 50, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
V_DrawSmallScaledPatch(x, y, 0, savselp[0]);
|
||||||
|
x += 2;
|
||||||
|
y += 1;
|
||||||
|
V_DrawString(x, y,
|
||||||
|
((savetodraw == saveSlotSelected-1) ? V_YELLOWMAP : 0),
|
||||||
|
va("FILE %d", savetodraw+1));
|
||||||
|
if (savetodraw == saveSlotSelected-1)
|
||||||
|
V_DrawFill(x, y+9, 80, 1, yellowmap[3]);
|
||||||
|
y += 11;
|
||||||
|
|
||||||
|
// level image area
|
||||||
|
{
|
||||||
|
patch_t *patch;
|
||||||
|
INT32 flags = 0;
|
||||||
|
|
||||||
|
if ((savegameinfo[savetodraw].lives == -42)
|
||||||
|
|| (savegameinfo[savetodraw].lives == -666))
|
||||||
|
{
|
||||||
|
patch = savselp[3];
|
||||||
|
flags = V_STATIC;
|
||||||
|
}
|
||||||
|
else if (savegameinfo[savetodraw].gamemap & 8192)
|
||||||
|
patch = savselp[6];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lumpnum_t lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName((savegameinfo[savetodraw].gamemap) & 8191)));
|
||||||
|
if (lumpnum != LUMPERROR)
|
||||||
|
patch = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||||
|
else
|
||||||
|
patch = savselp[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
V_DrawSmallScaledPatch(x, y, flags, patch);
|
||||||
|
|
||||||
|
y += 41;
|
||||||
|
|
||||||
|
if (savegameinfo[savetodraw].lives == -42)
|
||||||
|
V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "NEW GAME");
|
||||||
|
else if (savegameinfo[savetodraw].lives == -666)
|
||||||
|
V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "CAN'T LOAD!");
|
||||||
|
else if (savegameinfo[savetodraw].gamemap & 8192)
|
||||||
|
V_DrawRightAlignedThinString(x + 79, y, V_GREENMAP, "CLEAR!");
|
||||||
|
else
|
||||||
|
V_DrawRightAlignedThinString(x + 79, y, V_YELLOWMAP, savegameinfo[savetodraw].levelname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((savegameinfo[savetodraw].lives == -42)
|
||||||
|
|| (savegameinfo[savetodraw].lives == -666))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
y += 64;
|
||||||
|
|
||||||
|
// tiny emeralds
|
||||||
|
{
|
||||||
|
INT32 j, workx = x + 6;
|
||||||
|
for (j = 0; j < 7; ++j)
|
||||||
|
{
|
||||||
|
if (savegameinfo[savetodraw].numemeralds & (1 << j))
|
||||||
|
V_DrawScaledPatch(workx, y, 0, tinyemeraldpics[j]);
|
||||||
|
workx += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
y -= 13;
|
||||||
|
|
||||||
|
// character heads, lives, and continues
|
||||||
|
{
|
||||||
|
spritedef_t *sprdef;
|
||||||
|
spriteframe_t *sprframe;
|
||||||
|
patch_t *patch;
|
||||||
|
UINT8 *colormap = NULL;
|
||||||
|
|
||||||
|
INT32 tempx = (x+40)<<FRACBITS, tempy = y<<FRACBITS, flip = 0, calc;
|
||||||
|
|
||||||
|
// botskin first
|
||||||
|
if (savegameinfo[savetodraw].botskin)
|
||||||
|
{
|
||||||
|
skin_t *charbotskin = &skins[savegameinfo[savetodraw].botskin-1];
|
||||||
|
sprdef = &charbotskin->sprites[SPR2_SIGN];
|
||||||
|
if (!sprdef->numframes)
|
||||||
|
goto skipbot;
|
||||||
|
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin, charbotskin->prefcolor, 0);
|
||||||
|
sprframe = &sprdef->spriteframes[0];
|
||||||
|
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||||
|
|
||||||
|
V_DrawFixedPatch(
|
||||||
|
tempx + (18<<FRACBITS),
|
||||||
|
tempy - (4<<FRACBITS),
|
||||||
|
charbotskin->highresscale,
|
||||||
|
0, patch, colormap);
|
||||||
|
|
||||||
|
Z_Free(colormap);
|
||||||
|
|
||||||
|
tempx -= (15<<FRACBITS);
|
||||||
|
flip = V_FLIP;
|
||||||
|
}
|
||||||
|
skipbot:
|
||||||
|
// signpost image
|
||||||
|
if (!charskin) // shut up compiler
|
||||||
|
goto skipsign;
|
||||||
|
sprdef = &charskin->sprites[SPR2_SIGN];
|
||||||
|
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, 0);
|
||||||
|
if (!sprdef->numframes)
|
||||||
|
goto skipsign;
|
||||||
|
sprframe = &sprdef->spriteframes[0];
|
||||||
|
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||||
|
if ((calc = SHORT(patch->topoffset) - 42) > 0)
|
||||||
|
tempy += ((4+calc)<<FRACBITS);
|
||||||
|
|
||||||
|
V_DrawFixedPatch(
|
||||||
|
tempx,
|
||||||
|
tempy,
|
||||||
|
charskin->highresscale,
|
||||||
|
flip, patch, colormap);
|
||||||
|
|
||||||
|
skipsign:
|
||||||
|
y += 25;
|
||||||
|
|
||||||
|
tempx = x + 10;
|
||||||
|
if (savegameinfo[savetodraw].lives != 0x7f
|
||||||
|
&& savegameinfo[savetodraw].lives > 9)
|
||||||
|
tempx -= 4;
|
||||||
|
|
||||||
|
if (!charskin) // shut up compiler
|
||||||
|
goto skiplife;
|
||||||
|
|
||||||
|
// lives
|
||||||
|
sprdef = &charskin->sprites[SPR2_LIFE];
|
||||||
|
if (!sprdef->numframes)
|
||||||
|
goto skiplife;
|
||||||
|
sprframe = &sprdef->spriteframes[0];
|
||||||
|
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||||
|
|
||||||
|
V_DrawFixedPatch(
|
||||||
|
(tempx + 4)<<FRACBITS,
|
||||||
|
(y + 6)<<FRACBITS,
|
||||||
|
charskin->highresscale/2,
|
||||||
|
0, patch, colormap);
|
||||||
|
skiplife:
|
||||||
|
if (colormap)
|
||||||
|
Z_Free(colormap);
|
||||||
|
|
||||||
|
patch = W_CachePatchName("STLIVEX", PU_CACHE);
|
||||||
|
|
||||||
|
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch);
|
||||||
|
tempx += 16;
|
||||||
|
if (savegameinfo[savetodraw].lives == 0x7f)
|
||||||
|
V_DrawCharacter(tempx, y + 1, '\x16', false);
|
||||||
|
else
|
||||||
|
V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives));
|
||||||
|
|
||||||
|
tempx = x + 47;
|
||||||
|
if (savegameinfo[savetodraw].continues > 9)
|
||||||
|
tempx -= 4;
|
||||||
|
|
||||||
|
// continues
|
||||||
|
if (savegameinfo[savetodraw].continues > 0)
|
||||||
|
{
|
||||||
|
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_CACHE));
|
||||||
|
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch);
|
||||||
|
V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continues));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_CACHE));
|
||||||
|
V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_CACHE));
|
||||||
|
V_DrawString(tempx + 16, y, V_GRAYMAP, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Draw cursors on both sides.
|
static void M_DrawLoad(void)
|
||||||
V_DrawScaledPatch( 32, CURSORHEIGHT, 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
{
|
||||||
V_DrawScaledPatch(274, CURSORHEIGHT, 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
M_DrawMenuTitle();
|
||||||
|
|
||||||
|
if (loadgamescroll > 1 || loadgamescroll < -1)
|
||||||
|
loadgamescroll = 2*loadgamescroll/3;
|
||||||
|
else
|
||||||
|
loadgamescroll = 0;
|
||||||
|
|
||||||
|
if (loadgameoffset > 1)
|
||||||
|
loadgameoffset = 2*loadgameoffset/3;
|
||||||
|
else
|
||||||
|
loadgameoffset = 0;
|
||||||
|
|
||||||
M_DrawLoadGameData();
|
M_DrawLoadGameData();
|
||||||
|
|
||||||
//finishing the movement illusion
|
|
||||||
if (menumovedir)
|
|
||||||
menumovedir += ((menumovedir > 0) ? 1 : -1);
|
|
||||||
if (abs(menumovedir) > 3)
|
|
||||||
menumovedir = 0;
|
|
||||||
}
|
}
|
||||||
#undef LOADBARHEIGHT
|
|
||||||
#undef CURSORHEIGHT
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// User wants to load this game
|
// User wants to load this game
|
||||||
|
@ -6182,7 +6308,7 @@ static void M_LoadSelect(INT32 choice)
|
||||||
if (saveSlotSelected == NOSAVESLOT) //last slot is play without saving
|
if (saveSlotSelected == NOSAVESLOT) //last slot is play without saving
|
||||||
{
|
{
|
||||||
M_NewGame();
|
M_NewGame();
|
||||||
cursaveslot = -1;
|
cursaveslot = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6191,8 +6317,8 @@ static void M_LoadSelect(INT32 choice)
|
||||||
// This slot is empty, so start a new game here.
|
// This slot is empty, so start a new game here.
|
||||||
M_NewGame();
|
M_NewGame();
|
||||||
}
|
}
|
||||||
else if (savegameinfo[saveSlotSelected].gamemap & 8192) // Completed
|
else if (savegameinfo[saveSlotSelected-1].gamemap & 8192) // Completed
|
||||||
M_LoadGameLevelSelect(saveSlotSelected + 1);
|
M_LoadGameLevelSelect(0);
|
||||||
else
|
else
|
||||||
G_LoadGame((UINT32)saveSlotSelected, 0);
|
G_LoadGame((UINT32)saveSlotSelected, 0);
|
||||||
|
|
||||||
|
@ -6214,12 +6340,11 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
||||||
INT32 fake; // Dummy variable
|
INT32 fake; // Dummy variable
|
||||||
char temp[sizeof(timeattackfolder)];
|
char temp[sizeof(timeattackfolder)];
|
||||||
char vcheck[VERSIONSIZE];
|
char vcheck[VERSIONSIZE];
|
||||||
#ifdef SAVEGAMES_OTHERVERSIONS
|
|
||||||
boolean oldversion = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sprintf(savename, savegamename, slot);
|
sprintf(savename, savegamename, slot);
|
||||||
|
|
||||||
|
slot--;
|
||||||
|
|
||||||
length = FIL_ReadFile(savename, &savebuffer);
|
length = FIL_ReadFile(savename, &savebuffer);
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
{
|
{
|
||||||
|
@ -6235,14 +6360,7 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
||||||
// Version check
|
// Version check
|
||||||
memset(vcheck, 0, sizeof (vcheck));
|
memset(vcheck, 0, sizeof (vcheck));
|
||||||
sprintf(vcheck, "version %d", VERSION);
|
sprintf(vcheck, "version %d", VERSION);
|
||||||
if (strcmp((const char *)save_p, (const char *)vcheck))
|
if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE
|
||||||
{
|
|
||||||
#ifdef SAVEGAMES_OTHERVERSIONS
|
|
||||||
oldversion = true;
|
|
||||||
#else
|
|
||||||
BADSAVE // Incompatible versions?
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
save_p += VERSIONSIZE;
|
save_p += VERSIONSIZE;
|
||||||
|
|
||||||
// dearchive all the modifications
|
// dearchive all the modifications
|
||||||
|
@ -6254,30 +6372,19 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
||||||
if (((fake-1) & 8191) >= NUMMAPS) BADSAVE
|
if (((fake-1) & 8191) >= NUMMAPS) BADSAVE
|
||||||
|
|
||||||
if(!mapheaderinfo[(fake-1) & 8191])
|
if(!mapheaderinfo[(fake-1) & 8191])
|
||||||
{
|
|
||||||
savegameinfo[slot].levelname[0] = '\0';
|
savegameinfo[slot].levelname[0] = '\0';
|
||||||
savegameinfo[slot].actnum = 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl);
|
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 17+1);
|
||||||
savegameinfo[slot].actnum = mapheaderinfo[(fake-1) & 8191]->actnum;
|
|
||||||
|
if (strlen(mapheaderinfo[(fake-1) & 8191]->lvlttl) >= 17)
|
||||||
|
strcpy(savegameinfo[slot].levelname+17-3, "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SAVEGAMES_OTHERVERSIONS
|
|
||||||
if (oldversion)
|
|
||||||
{
|
|
||||||
if (fake == 24) //meh, let's count old Clear! saves too
|
|
||||||
fake |= 8192;
|
|
||||||
fake |= 16384; // marker for outdated version
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
savegameinfo[slot].gamemap = fake;
|
savegameinfo[slot].gamemap = fake;
|
||||||
|
|
||||||
CHECKPOS
|
CHECKPOS
|
||||||
fake = READUINT16(save_p)-357; // emeralds
|
savegameinfo[slot].numemeralds = READUINT16(save_p)-357; // emeralds
|
||||||
|
|
||||||
savegameinfo[slot].numemeralds = (UINT8)fake;
|
|
||||||
|
|
||||||
CHECKPOS
|
CHECKPOS
|
||||||
READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to
|
READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to
|
||||||
|
@ -6286,39 +6393,25 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
||||||
|
|
||||||
// P_UnArchivePlayer()
|
// P_UnArchivePlayer()
|
||||||
CHECKPOS
|
CHECKPOS
|
||||||
savegameinfo[slot].skincolor = READUINT8(save_p);
|
fake = READUINT16(save_p);
|
||||||
CHECKPOS
|
savegameinfo[slot].skinnum = fake & ((1<<5) - 1);
|
||||||
savegameinfo[slot].skinnum = READUINT8(save_p);
|
if (savegameinfo[slot].skinnum >= numskins
|
||||||
|
|| !R_SkinUsable(-1, savegameinfo[slot].skinnum))
|
||||||
|
BADSAVE
|
||||||
|
savegameinfo[slot].botskin = fake >> 5;
|
||||||
|
if (savegameinfo[slot].botskin-1 >= numskins
|
||||||
|
|| !R_SkinUsable(-1, savegameinfo[slot].botskin-1))
|
||||||
|
BADSAVE
|
||||||
|
|
||||||
|
CHECKPOS
|
||||||
|
savegameinfo[slot].numgameovers = READUINT8(save_p); // numgameovers
|
||||||
|
CHECKPOS
|
||||||
|
savegameinfo[slot].lives = READSINT8(save_p); // lives
|
||||||
CHECKPOS
|
CHECKPOS
|
||||||
(void)READINT32(save_p); // Score
|
(void)READINT32(save_p); // Score
|
||||||
|
|
||||||
CHECKPOS
|
|
||||||
savegameinfo[slot].lives = READINT32(save_p); // lives
|
|
||||||
CHECKPOS
|
CHECKPOS
|
||||||
savegameinfo[slot].continues = READINT32(save_p); // continues
|
savegameinfo[slot].continues = READINT32(save_p); // continues
|
||||||
|
|
||||||
if (fake & (1<<10))
|
|
||||||
{
|
|
||||||
CHECKPOS
|
|
||||||
savegameinfo[slot].botskin = READUINT8(save_p);
|
|
||||||
if (savegameinfo[slot].botskin-1 >= numskins)
|
|
||||||
savegameinfo[slot].botskin = 0;
|
|
||||||
CHECKPOS
|
|
||||||
savegameinfo[slot].botcolor = READUINT8(save_p); // because why not.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
savegameinfo[slot].botskin = 0;
|
|
||||||
|
|
||||||
if (savegameinfo[slot].botskin)
|
|
||||||
snprintf(savegameinfo[slot].playername, 32, "%s & %s",
|
|
||||||
skins[savegameinfo[slot].skinnum].realname,
|
|
||||||
skins[savegameinfo[slot].botskin-1].realname);
|
|
||||||
else
|
|
||||||
strcpy(savegameinfo[slot].playername, skins[savegameinfo[slot].skinnum].realname);
|
|
||||||
|
|
||||||
savegameinfo[slot].playername[31] = 0;
|
|
||||||
|
|
||||||
// File end marker check
|
// File end marker check
|
||||||
CHECKPOS
|
CHECKPOS
|
||||||
if (READUINT8(save_p) != 0x1d) BADSAVE;
|
if (READUINT8(save_p) != 0x1d) BADSAVE;
|
||||||
|
@ -6337,23 +6430,80 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
||||||
static void M_ReadSaveStrings(void)
|
static void M_ReadSaveStrings(void)
|
||||||
{
|
{
|
||||||
FILE *handle;
|
FILE *handle;
|
||||||
UINT32 i;
|
SINT8 i;
|
||||||
char name[256];
|
char name[256];
|
||||||
|
boolean nofile[MAXSAVEGAMES-1];
|
||||||
|
SINT8 tolerance = 3; // empty slots at any time
|
||||||
|
UINT8 lastseen = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAXSAVEGAMES; i++)
|
loadgamescroll = 0;
|
||||||
|
loadgameoffset = 14;
|
||||||
|
|
||||||
|
for (i = 1; (i < MAXSAVEGAMES); i++) // slot 0 is no save
|
||||||
{
|
{
|
||||||
snprintf(name, sizeof name, savegamename, i);
|
snprintf(name, sizeof name, savegamename, i);
|
||||||
name[sizeof name - 1] = '\0';
|
name[sizeof name - 1] = '\0';
|
||||||
|
|
||||||
handle = fopen(name, "rb");
|
handle = fopen(name, "rb");
|
||||||
if (handle == NULL)
|
if ((nofile[i-1] = (handle == NULL)))
|
||||||
|
continue;
|
||||||
|
fclose(handle);
|
||||||
|
lastseen = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savegameinfo)
|
||||||
|
Z_Free(savegameinfo);
|
||||||
|
savegameinfo = NULL;
|
||||||
|
|
||||||
|
if (lastseen < saveSlotSelected)
|
||||||
|
lastseen = saveSlotSelected;
|
||||||
|
|
||||||
|
i = lastseen;
|
||||||
|
|
||||||
|
for (; (lastseen > 0 && tolerance); lastseen--)
|
||||||
|
{
|
||||||
|
if (nofile[lastseen-1])
|
||||||
|
tolerance--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i += tolerance+1) > MAXSAVEGAMES) // show 3 empty slots at minimum
|
||||||
|
i = MAXSAVEGAMES;
|
||||||
|
|
||||||
|
numsaves = i;
|
||||||
|
savegameinfo = Z_Realloc(savegameinfo, numsaves*sizeof(saveinfo_t), PU_STATIC, NULL);
|
||||||
|
if (!savegameinfo)
|
||||||
|
I_Error("Insufficient memory to prepare save platter");
|
||||||
|
|
||||||
|
for (; i > 0; i--)
|
||||||
|
{
|
||||||
|
if (nofile[i-1] == true)
|
||||||
{
|
{
|
||||||
savegameinfo[i].lives = -42;
|
savegameinfo[i-1].lives = -42;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fclose(handle);
|
|
||||||
M_ReadSavegameInfo(i);
|
M_ReadSavegameInfo(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (savselp[0]) // never going to have some provided but not all, saves individually checking
|
||||||
|
{
|
||||||
|
W_UnlockCachedPatch(savselp[0]);
|
||||||
|
W_UnlockCachedPatch(savselp[1]);
|
||||||
|
W_UnlockCachedPatch(savselp[2]);
|
||||||
|
|
||||||
|
W_UnlockCachedPatch(savselp[3]);
|
||||||
|
W_UnlockCachedPatch(savselp[4]);
|
||||||
|
W_UnlockCachedPatch(savselp[5]);
|
||||||
|
W_UnlockCachedPatch(savselp[6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
savselp[0] = W_CachePatchName("SAVEBACK", PU_STATIC);
|
||||||
|
savselp[1] = W_CachePatchName("SAVENONE", PU_STATIC);
|
||||||
|
savselp[2] = W_CachePatchName("ULTIMATE", PU_STATIC);
|
||||||
|
|
||||||
|
savselp[3] = W_CachePatchName("BLACKLVL", PU_STATIC);
|
||||||
|
savselp[4] = W_CachePatchName("BLACXLVL", PU_STATIC);
|
||||||
|
savselp[5] = W_CachePatchName("BLANKLVL", PU_STATIC);
|
||||||
|
savselp[6] = W_CachePatchName("GAMEDONE", PU_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -6371,8 +6521,19 @@ static void M_SaveGameDeleteResponse(INT32 ch)
|
||||||
name[sizeof name - 1] = '\0';
|
name[sizeof name - 1] = '\0';
|
||||||
remove(name);
|
remove(name);
|
||||||
|
|
||||||
// Refresh savegame menu info
|
BwehHehHe();
|
||||||
M_ReadSaveStrings();
|
M_ReadSaveStrings(); // reload the menu
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M_SaveGameUltimateResponse(INT32 ch)
|
||||||
|
{
|
||||||
|
if (ch != 'y' && ch != KEY_ENTER)
|
||||||
|
return;
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
M_LoadSelect(saveSlotSelected);
|
||||||
|
SP_PlayerDef.prevMenu = MessageDef.prevMenu;
|
||||||
|
MessageDef.prevMenu = &SP_PlayerDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_HandleLoadSave(INT32 choice)
|
static void M_HandleLoadSave(INT32 choice)
|
||||||
|
@ -6381,26 +6542,46 @@ static void M_HandleLoadSave(INT32 choice)
|
||||||
|
|
||||||
switch (choice)
|
switch (choice)
|
||||||
{
|
{
|
||||||
case KEY_DOWNARROW:
|
case KEY_RIGHTARROW:
|
||||||
S_StartSound(NULL, sfx_menu1);
|
S_StartSound(NULL, sfx_s3kb7);
|
||||||
++saveSlotSelected;
|
++saveSlotSelected;
|
||||||
if (saveSlotSelected >= MAXSAVEGAMES)
|
if (saveSlotSelected >= numsaves)
|
||||||
saveSlotSelected -= MAXSAVEGAMES;
|
saveSlotSelected -= numsaves;
|
||||||
menumovedir = 1;
|
loadgamescroll = 90;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_UPARROW:
|
case KEY_LEFTARROW:
|
||||||
S_StartSound(NULL, sfx_menu1);
|
S_StartSound(NULL, sfx_s3kb7);
|
||||||
--saveSlotSelected;
|
--saveSlotSelected;
|
||||||
if (saveSlotSelected < 0)
|
if (saveSlotSelected < 0)
|
||||||
saveSlotSelected += MAXSAVEGAMES;
|
saveSlotSelected += numsaves;
|
||||||
menumovedir = -1;
|
loadgamescroll = -90;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_ENTER:
|
case KEY_ENTER:
|
||||||
S_StartSound(NULL, sfx_menu1);
|
if (ultimate_selectable && saveSlotSelected == NOSAVESLOT)
|
||||||
if (savegameinfo[saveSlotSelected].lives != -666) // don't allow loading of "bad saves"
|
{
|
||||||
|
loadgamescroll = 0;
|
||||||
|
S_StartSound(NULL, sfx_skid);
|
||||||
|
M_StartMessage("Are you sure you want to play\n\x85ultimate mode\x80? It isn't remotely fair,\nand you don't even get an emblem for it.\n\n(Press 'Y' to confirm)\n",M_SaveGameUltimateResponse,MM_YESNO);
|
||||||
|
}
|
||||||
|
else if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected-1].lives == -42 && !(!modifiedgame || savemoddata))
|
||||||
|
{
|
||||||
|
loadgamescroll = 0;
|
||||||
|
S_StartSound(NULL, sfx_skid);
|
||||||
|
M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
|
||||||
|
}
|
||||||
|
else if (saveSlotSelected == NOSAVESLOT || savegameinfo[saveSlotSelected-1].lives != -666) // don't allow loading of "bad saves"
|
||||||
|
{
|
||||||
|
loadgamescroll = 0;
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
M_LoadSelect(saveSlotSelected);
|
M_LoadSelect(saveSlotSelected);
|
||||||
|
}
|
||||||
|
else if (!loadgameoffset)
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
loadgameoffset = 14;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_ESCAPE:
|
case KEY_ESCAPE:
|
||||||
|
@ -6408,11 +6589,25 @@ static void M_HandleLoadSave(INT32 choice)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_BACKSPACE:
|
case KEY_BACKSPACE:
|
||||||
S_StartSound(NULL, sfx_menu1);
|
|
||||||
// Don't allow people to 'delete' "Play without Saving."
|
// Don't allow people to 'delete' "Play without Saving."
|
||||||
// Nor allow people to 'delete' slots with no saves in them.
|
// Nor allow people to 'delete' slots with no saves in them.
|
||||||
if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected].lives != -42)
|
if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected-1].lives != -42)
|
||||||
M_StartMessage(M_GetText("Are you sure you want to delete\nthis save game?\n\n(Press 'Y' to confirm)\n"),M_SaveGameDeleteResponse,MM_YESNO);
|
{
|
||||||
|
loadgamescroll = 0;
|
||||||
|
S_StartSound(NULL, sfx_skid);
|
||||||
|
M_StartMessage(va("Are you sure you want to delete\nsave file %d?\n\n(Press 'Y' to confirm)\n", saveSlotSelected),M_SaveGameDeleteResponse,MM_YESNO);
|
||||||
|
}
|
||||||
|
else if (!loadgameoffset)
|
||||||
|
{
|
||||||
|
if (saveSlotSelected == NOSAVESLOT && ultimate_selectable)
|
||||||
|
{
|
||||||
|
ultimate_selectable = false;
|
||||||
|
S_StartSound(NULL, sfx_strpst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
loadgameoffset = 14;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (exitmenu)
|
if (exitmenu)
|
||||||
|
@ -6421,6 +6616,8 @@ static void M_HandleLoadSave(INT32 choice)
|
||||||
M_SetupNextMenu(currentMenu->prevMenu);
|
M_SetupNextMenu(currentMenu->prevMenu);
|
||||||
else
|
else
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
|
Z_Free(savegameinfo);
|
||||||
|
savegameinfo = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6440,14 +6637,15 @@ static void M_LoadGame(INT32 choice)
|
||||||
//
|
//
|
||||||
void M_ForceSaveSlotSelected(INT32 sslot)
|
void M_ForceSaveSlotSelected(INT32 sslot)
|
||||||
{
|
{
|
||||||
// Already there? Out of bounds? Whatever, then!
|
loadgameoffset = 14;
|
||||||
if (sslot == saveSlotSelected || sslot >= MAXSAVEGAMES)
|
|
||||||
|
// Already there? Whatever, then!
|
||||||
|
if (sslot == saveSlotSelected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Figure out whether to display up movement or down movement
|
loadgamescroll = 90;
|
||||||
menumovedir = (saveSlotSelected - sslot) > 0 ? -1 : 1;
|
if (saveSlotSelected <= numsaves/2)
|
||||||
if (abs(saveSlotSelected - sslot) > (MAXSAVEGAMES>>1))
|
loadgamescroll = -loadgamescroll;
|
||||||
menumovedir *= -1;
|
|
||||||
|
|
||||||
saveSlotSelected = sslot;
|
saveSlotSelected = sslot;
|
||||||
}
|
}
|
||||||
|
@ -6718,7 +6916,7 @@ static void M_ChoosePlayer(INT32 choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startmap != spstage_start)
|
if (startmap != spstage_start)
|
||||||
cursaveslot = -1;
|
cursaveslot = 0;
|
||||||
|
|
||||||
//lastmapsaved = 0;
|
//lastmapsaved = 0;
|
||||||
gamecomplete = false;
|
gamecomplete = false;
|
||||||
|
@ -6729,6 +6927,10 @@ static void M_ChoosePlayer(INT32 choice)
|
||||||
if (levelselect.rows)
|
if (levelselect.rows)
|
||||||
Z_Free(levelselect.rows);
|
Z_Free(levelselect.rows);
|
||||||
levelselect.rows = NULL;
|
levelselect.rows = NULL;
|
||||||
|
|
||||||
|
if (savegameinfo)
|
||||||
|
Z_Free(savegameinfo);
|
||||||
|
savegameinfo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===============
|
// ===============
|
||||||
|
@ -8687,7 +8889,7 @@ static void M_EraseDataResponse(INT32 ch)
|
||||||
totalplaytime = 0;
|
totalplaytime = 0;
|
||||||
F_StartIntro();
|
F_StartIntro();
|
||||||
}
|
}
|
||||||
S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)); // Bweh heh he
|
BwehHehHe();
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/m_menu.h
10
src/m_menu.h
|
@ -215,18 +215,14 @@ typedef struct
|
||||||
// savegame struct for save game menu
|
// savegame struct for save game menu
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char playername[32];
|
|
||||||
char levelname[32];
|
char levelname[32];
|
||||||
UINT8 actnum;
|
|
||||||
UINT8 skincolor;
|
|
||||||
UINT8 skinnum;
|
UINT8 skinnum;
|
||||||
UINT8 botskin;
|
UINT8 botskin;
|
||||||
UINT8 botcolor;
|
|
||||||
UINT8 numemeralds;
|
UINT8 numemeralds;
|
||||||
|
UINT8 numgameovers;
|
||||||
INT32 lives;
|
INT32 lives;
|
||||||
INT32 continues;
|
INT32 continues;
|
||||||
INT32 gamemap;
|
INT32 gamemap;
|
||||||
UINT8 netgame;
|
|
||||||
} saveinfo_t;
|
} saveinfo_t;
|
||||||
|
|
||||||
extern description_t description[32];
|
extern description_t description[32];
|
||||||
|
@ -238,7 +234,9 @@ extern INT16 startmap;
|
||||||
extern INT32 ultimate_selectable;
|
extern INT32 ultimate_selectable;
|
||||||
|
|
||||||
#define MAXSAVEGAMES 31 //note: last save game is "no save"
|
#define MAXSAVEGAMES 31 //note: last save game is "no save"
|
||||||
#define NOSAVESLOT MAXSAVEGAMES-1 //slot where Play Without Saving appears
|
#define NOSAVESLOT 0 //slot where Play Without Saving appears
|
||||||
|
|
||||||
|
#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he
|
||||||
|
|
||||||
void M_ForceSaveSlotSelected(INT32 sslot);
|
void M_ForceSaveSlotSelected(INT32 sslot);
|
||||||
|
|
||||||
|
|
|
@ -2239,7 +2239,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
|
|
||||||
if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0))
|
if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0))
|
||||||
;
|
;
|
||||||
else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap)
|
else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && (target->player->lives != 0x7f)
|
||||||
&& G_GametypeUsesLives())
|
&& G_GametypeUsesLives())
|
||||||
{
|
{
|
||||||
target->player->lives -= 1; // Lose a life Tails 03-11-2000
|
target->player->lives -= 1; // Lose a life Tails 03-11-2000
|
||||||
|
@ -2269,6 +2269,13 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
S_StopMusic(); // Stop the Music! Tails 03-14-2000
|
S_StopMusic(); // Stop the Music! Tails 03-14-2000
|
||||||
S_ChangeMusicInternal("_gover", false); // Yousa dead now, Okieday? Tails 03-14-2000
|
S_ChangeMusicInternal("_gover", false); // Yousa dead now, Okieday? Tails 03-14-2000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers)
|
||||||
|
{
|
||||||
|
numgameovers++;
|
||||||
|
if ((!modifiedgame || savemoddata) && cursaveslot > 0)
|
||||||
|
G_SaveGameOver((UINT32)cursaveslot, (target->player->continues <= 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target->player->playerstate = PST_DEAD;
|
target->player->playerstate = PST_DEAD;
|
||||||
|
|
|
@ -64,22 +64,16 @@ typedef enum
|
||||||
static inline void P_ArchivePlayer(void)
|
static inline void P_ArchivePlayer(void)
|
||||||
{
|
{
|
||||||
const player_t *player = &players[consoleplayer];
|
const player_t *player = &players[consoleplayer];
|
||||||
INT32 pllives = player->lives;
|
INT16 skininfo = player->skin + (botskin<<5);
|
||||||
if (pllives < 3) // Bump up to 3 lives if the player
|
SINT8 pllives = player->lives;
|
||||||
pllives = 3; // has less than that.
|
if (pllives < startinglivesbalance[numgameovers]) // Bump up to 3 lives if the player
|
||||||
|
pllives = startinglivesbalance[numgameovers]; // has less than that.
|
||||||
WRITEUINT8(save_p, player->skincolor);
|
|
||||||
WRITEUINT8(save_p, player->skin);
|
|
||||||
|
|
||||||
|
WRITEUINT16(save_p, skininfo);
|
||||||
|
WRITEUINT8(save_p, numgameovers);
|
||||||
|
WRITESINT8(save_p, pllives);
|
||||||
WRITEUINT32(save_p, player->score);
|
WRITEUINT32(save_p, player->score);
|
||||||
WRITEINT32(save_p, pllives);
|
|
||||||
WRITEINT32(save_p, player->continues);
|
WRITEINT32(save_p, player->continues);
|
||||||
|
|
||||||
if (botskin)
|
|
||||||
{
|
|
||||||
WRITEUINT8(save_p, botskin);
|
|
||||||
WRITEUINT8(save_p, botcolor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -87,22 +81,14 @@ static inline void P_ArchivePlayer(void)
|
||||||
//
|
//
|
||||||
static inline void P_UnArchivePlayer(void)
|
static inline void P_UnArchivePlayer(void)
|
||||||
{
|
{
|
||||||
savedata.skincolor = READUINT8(save_p);
|
INT16 skininfo = READUINT16(save_p);
|
||||||
savedata.skin = READUINT8(save_p);
|
savedata.skin = skininfo & ((1<<5) - 1);
|
||||||
|
savedata.botskin = skininfo >> 5;
|
||||||
|
|
||||||
savedata.score = READINT32(save_p);
|
savedata.numgameovers = READUINT8(save_p);
|
||||||
savedata.lives = READINT32(save_p);
|
savedata.lives = READSINT8(save_p);
|
||||||
|
savedata.score = READUINT32(save_p);
|
||||||
savedata.continues = READINT32(save_p);
|
savedata.continues = READINT32(save_p);
|
||||||
|
|
||||||
if (savedata.botcolor)
|
|
||||||
{
|
|
||||||
savedata.botskin = READUINT8(save_p);
|
|
||||||
if (savedata.botskin-1 >= numskins)
|
|
||||||
savedata.botskin = 0;
|
|
||||||
savedata.botcolor = READUINT8(save_p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
savedata.botskin = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -3162,7 +3148,7 @@ static inline void P_ArchiveMisc(void)
|
||||||
//lastmapsaved = gamemap;
|
//lastmapsaved = gamemap;
|
||||||
lastmaploaded = gamemap;
|
lastmaploaded = gamemap;
|
||||||
|
|
||||||
WRITEUINT16(save_p, (botskin ? (emeralds|(1<<10)) : emeralds)+357);
|
WRITEUINT16(save_p, emeralds+357);
|
||||||
WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder));
|
WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3192,9 +3178,6 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
|
||||||
token = 0;
|
token = 0;
|
||||||
|
|
||||||
savedata.emeralds = READUINT16(save_p)-357;
|
savedata.emeralds = READUINT16(save_p)-357;
|
||||||
if (savedata.emeralds & (1<<10))
|
|
||||||
savedata.botcolor = 0xFF;
|
|
||||||
savedata.emeralds &= 0xff;
|
|
||||||
|
|
||||||
READSTRINGN(save_p, testname, sizeof(testname));
|
READSTRINGN(save_p, testname, sizeof(testname));
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,13 @@ mobj_t *P_FindNewPosition(UINT32 oldposition);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT8 skincolor;
|
|
||||||
UINT8 skin;
|
UINT8 skin;
|
||||||
UINT8 botskin;
|
UINT8 botskin;
|
||||||
UINT8 botcolor;
|
|
||||||
INT32 score;
|
INT32 score;
|
||||||
INT32 lives;
|
INT32 lives;
|
||||||
INT32 continues;
|
INT32 continues;
|
||||||
UINT16 emeralds;
|
UINT16 emeralds;
|
||||||
|
UINT8 numgameovers;
|
||||||
} savedata_t;
|
} savedata_t;
|
||||||
|
|
||||||
extern savedata_t savedata;
|
extern savedata_t savedata;
|
||||||
|
|
|
@ -3021,19 +3021,19 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
P_RunCachedActions();
|
P_RunCachedActions();
|
||||||
|
|
||||||
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0)
|
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0)
|
||||||
&& (!modifiedgame || savemoddata) && cursaveslot >= 0 && CanSaveLevel(gamemap))
|
&& (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(gamemap))
|
||||||
G_SaveGame((UINT32)cursaveslot);
|
G_SaveGame((UINT32)cursaveslot);
|
||||||
|
|
||||||
lastmaploaded = gamemap; // HAS to be set after saving!!
|
lastmaploaded = gamemap; // HAS to be set after saving!!
|
||||||
|
|
||||||
if (savedata.lives > 0)
|
if (savedata.lives > 0)
|
||||||
{
|
{
|
||||||
|
numgameovers = savedata.numgameovers;
|
||||||
players[consoleplayer].continues = savedata.continues;
|
players[consoleplayer].continues = savedata.continues;
|
||||||
players[consoleplayer].lives = savedata.lives;
|
players[consoleplayer].lives = savedata.lives;
|
||||||
players[consoleplayer].score = savedata.score;
|
players[consoleplayer].score = savedata.score;
|
||||||
botskin = savedata.botskin;
|
if ((botingame = ((botskin = savedata.botskin) != 0)))
|
||||||
botcolor = savedata.botcolor;
|
botcolor = skins[botskin-1].prefcolor;
|
||||||
botingame = (savedata.botskin != 0);
|
|
||||||
emeralds = savedata.emeralds;
|
emeralds = savedata.emeralds;
|
||||||
savedata.lives = 0;
|
savedata.lives = 0;
|
||||||
}
|
}
|
||||||
|
@ -3202,8 +3202,8 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
ST_Start();
|
ST_Start();
|
||||||
|
|
||||||
// Prevent savefile cheating
|
// Prevent savefile cheating
|
||||||
if (cursaveslot >= 0)
|
if (cursaveslot > 0)
|
||||||
cursaveslot = -1;
|
cursaveslot = 0;
|
||||||
|
|
||||||
if (replacedcurrentmap && gamestate == GS_LEVEL && (netgame || multiplayer))
|
if (replacedcurrentmap && gamestate == GS_LEVEL && (netgame || multiplayer))
|
||||||
{
|
{
|
||||||
|
|
12
src/p_user.c
12
src/p_user.c
|
@ -950,6 +950,8 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings)
|
||||||
//
|
//
|
||||||
void P_GivePlayerLives(player_t *player, INT32 numlives)
|
void P_GivePlayerLives(player_t *player, INT32 numlives)
|
||||||
{
|
{
|
||||||
|
if (player->lives == 0x7f) return;
|
||||||
|
|
||||||
player->lives += numlives;
|
player->lives += numlives;
|
||||||
|
|
||||||
if (player->lives > 99)
|
if (player->lives > 99)
|
||||||
|
@ -1153,7 +1155,9 @@ void P_PlayLivesJingle(player_t *player)
|
||||||
if (player && !P_IsLocalPlayer(player))
|
if (player && !P_IsLocalPlayer(player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (gametype == GT_COOP && (netgame || multiplayer) && cv_cooplives.value == 0)
|
if ((player && player->lives == 0x7f)
|
||||||
|
|| (!player && &players[consoleplayer] && players[consoleplayer].lives == 0x7f)
|
||||||
|
|| (gametype == GT_COOP && (netgame || multiplayer) && cv_cooplives.value == 0))
|
||||||
S_StartSound(NULL, sfx_lose);
|
S_StartSound(NULL, sfx_lose);
|
||||||
else if (use1upSound)
|
else if (use1upSound)
|
||||||
S_StartSound(NULL, sfx_oneup);
|
S_StartSound(NULL, sfx_oneup);
|
||||||
|
@ -8160,7 +8164,8 @@ boolean P_GetLives(player_t *player)
|
||||||
INT32 i, maxlivesplayer = -1, livescheck = 1;
|
INT32 i, maxlivesplayer = -1, livescheck = 1;
|
||||||
if (!(netgame || multiplayer)
|
if (!(netgame || multiplayer)
|
||||||
|| (gametype != GT_COOP)
|
|| (gametype != GT_COOP)
|
||||||
|| (cv_cooplives.value == 1))
|
|| (cv_cooplives.value == 1)
|
||||||
|
|| (player->lives == 0x7f))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ((cv_cooplives.value == 2 || cv_cooplives.value == 0) && player->lives > 0)
|
if ((cv_cooplives.value == 2 || cv_cooplives.value == 0) && player->lives > 0)
|
||||||
|
@ -8187,7 +8192,8 @@ boolean P_GetLives(player_t *player)
|
||||||
{
|
{
|
||||||
if (cv_cooplives.value == 2 && (P_IsLocalPlayer(player) || P_IsLocalPlayer(&players[maxlivesplayer])))
|
if (cv_cooplives.value == 2 && (P_IsLocalPlayer(player) || P_IsLocalPlayer(&players[maxlivesplayer])))
|
||||||
S_StartSound(NULL, sfx_jshard); // placeholder
|
S_StartSound(NULL, sfx_jshard); // placeholder
|
||||||
players[maxlivesplayer].lives--;
|
if (players[maxlivesplayer].lives != 0x7f)
|
||||||
|
players[maxlivesplayer].lives--;
|
||||||
player->lives++;
|
player->lives++;
|
||||||
if (player->lives < 1)
|
if (player->lives < 1)
|
||||||
player->lives = 1;
|
player->lives = 1;
|
||||||
|
|
|
@ -684,6 +684,8 @@ static inline void ST_drawRings(void)
|
||||||
static void ST_drawLives(void)
|
static void ST_drawLives(void)
|
||||||
{
|
{
|
||||||
const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0);
|
const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0);
|
||||||
|
INT32 livescount;
|
||||||
|
boolean notgreyedout;
|
||||||
|
|
||||||
if (!stplyr->skincolor)
|
if (!stplyr->skincolor)
|
||||||
return; // Just joined a server, skin isn't loaded yet!
|
return; // Just joined a server, skin isn't loaded yet!
|
||||||
|
@ -723,66 +725,47 @@ static void ST_drawLives(void)
|
||||||
V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, stlivex);
|
V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, stlivex);
|
||||||
|
|
||||||
// lives number
|
// lives number
|
||||||
if ((netgame || multiplayer) && gametype == GT_COOP)
|
if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3)
|
||||||
{
|
{
|
||||||
switch (cv_cooplives.value)
|
INT32 i;
|
||||||
|
livescount = 0;
|
||||||
|
notgreyedout = (stplyr->lives > 0);
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
case 0:
|
if (!playeringame[i])
|
||||||
V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, false);
|
continue;
|
||||||
return;
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
INT32 i, sum = 0;
|
|
||||||
boolean canrespawn = (stplyr->lives > 0);
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (!playeringame[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (players[i].lives < 1)
|
if (players[i].lives < 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (players[i].lives > 1)
|
if (players[i].lives > 1)
|
||||||
canrespawn = true;
|
notgreyedout = true;
|
||||||
|
|
||||||
sum += (players[i].lives);
|
if (players[i].lives == 0x7f)
|
||||||
}
|
{
|
||||||
V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0),
|
livescount = 0x7f;
|
||||||
V_SNAPTOLEFT|V_SNAPTOBOTTOM|(canrespawn ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag,
|
|
||||||
va("%d",sum));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if 0 // render the number of lives you COULD steal
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
INT32 i, sum = 0;
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (!playeringame[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (&players[i] == stplyr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (players[i].lives < 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sum += (players[i].lives - 1);
|
|
||||||
}
|
|
||||||
V_DrawString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0),
|
|
||||||
V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|v_splitflag, va("/%d",sum));
|
|
||||||
}
|
|
||||||
// intentional fallthrough
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
// don't return so the SP one can be drawn below
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
else if (livescount < 99)
|
||||||
|
livescount += (players[i].lives);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
livescount = stplyr->lives;
|
||||||
|
notgreyedout = true;
|
||||||
|
}
|
||||||
|
|
||||||
V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0),
|
if (livescount == 0x7f)
|
||||||
V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,
|
V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, false);
|
||||||
va("%d",stplyr->lives));
|
else
|
||||||
|
{
|
||||||
|
if (livescount > 99)
|
||||||
|
livescount = 99;
|
||||||
|
V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0),
|
||||||
|
V_SNAPTOLEFT|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag,
|
||||||
|
((livescount > 99) ? "!!" : va("%d",livescount)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ST_drawLevelTitle(void)
|
static void ST_drawLevelTitle(void)
|
||||||
|
|
133
src/v_video.c
133
src/v_video.c
|
@ -524,12 +524,21 @@ static inline UINT8 transmappedpdraw(const UINT8 *dest, const UINT8 *source, fix
|
||||||
{
|
{
|
||||||
return *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff));
|
return *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT8 staticstep = 0;
|
||||||
|
static fixed_t staticval = 0;
|
||||||
|
|
||||||
static inline UINT8 staticpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs)
|
static inline UINT8 staticpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs)
|
||||||
{
|
{
|
||||||
UINT8 val = source[ofs>>FRACBITS];
|
UINT8 val = source[ofs>>FRACBITS];
|
||||||
(void)dest;
|
(void)dest;
|
||||||
|
if ((++staticstep) >= 4)
|
||||||
|
{
|
||||||
|
staticstep = 0;
|
||||||
|
staticval = M_RandomFixed();
|
||||||
|
}
|
||||||
if (val < 7) return val;
|
if (val < 7) return val;
|
||||||
return M_RandomKey(7+1)+(val-7);//M_RandomByte();
|
return ((staticval>>staticstep)&7)+(val-7);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws a patch scaled to arbitrary size.
|
// Draws a patch scaled to arbitrary size.
|
||||||
|
@ -660,30 +669,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
|
||||||
y = FixedMul(y,dupy<<FRACBITS);
|
y = FixedMul(y,dupy<<FRACBITS);
|
||||||
x >>= FRACBITS;
|
x >>= FRACBITS;
|
||||||
y >>= FRACBITS;
|
y >>= FRACBITS;
|
||||||
desttop += (y*vid.width) + x;
|
|
||||||
|
|
||||||
// Center it if necessary
|
// Center it if necessary
|
||||||
if (!(scrn & V_SCALEPATCHMASK))
|
if (!(scrn & V_SCALEPATCHMASK))
|
||||||
{
|
{
|
||||||
if (vid.width != BASEVIDWIDTH * dupx)
|
|
||||||
{
|
|
||||||
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
|
|
||||||
// so center this imaginary screen
|
|
||||||
if (scrn & V_SNAPTORIGHT)
|
|
||||||
desttop += (vid.width - (BASEVIDWIDTH * dupx));
|
|
||||||
else if (!(scrn & V_SNAPTOLEFT))
|
|
||||||
desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
|
|
||||||
}
|
|
||||||
if (vid.height != BASEVIDHEIGHT * dupy)
|
|
||||||
{
|
|
||||||
// same thing here
|
|
||||||
if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
|
|
||||||
desttop += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)) * vid.width;
|
|
||||||
else if (scrn & V_SNAPTOBOTTOM)
|
|
||||||
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width;
|
|
||||||
else if (!(scrn & V_SNAPTOTOP))
|
|
||||||
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2;
|
|
||||||
}
|
|
||||||
// if it's meant to cover the whole screen, black out the rest
|
// if it's meant to cover the whole screen, black out the rest
|
||||||
if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT)
|
if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT)
|
||||||
{
|
{
|
||||||
|
@ -691,7 +680,29 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
|
||||||
source = (const UINT8 *)(column) + 3;
|
source = (const UINT8 *)(column) + 3;
|
||||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vid.width != BASEVIDWIDTH * dupx)
|
||||||
|
{
|
||||||
|
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
|
||||||
|
// so center this imaginary screen
|
||||||
|
if (scrn & V_SNAPTORIGHT)
|
||||||
|
x += (vid.width - (BASEVIDWIDTH * dupx));
|
||||||
|
else if (!(scrn & V_SNAPTOLEFT))
|
||||||
|
x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
|
||||||
|
}
|
||||||
|
if (vid.height != BASEVIDHEIGHT * dupy)
|
||||||
|
{
|
||||||
|
// same thing here
|
||||||
|
if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
|
||||||
|
y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy));
|
||||||
|
else if (scrn & V_SNAPTOBOTTOM)
|
||||||
|
y += (vid.height - (BASEVIDHEIGHT * dupy));
|
||||||
|
else if (!(scrn & V_SNAPTOTOP))
|
||||||
|
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
desttop += (y*vid.width) + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pscale != FRACUNIT) // scale width properly
|
if (pscale != FRACUNIT) // scale width properly
|
||||||
|
@ -797,28 +808,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
||||||
y = FixedMul(y,dupy<<FRACBITS);
|
y = FixedMul(y,dupy<<FRACBITS);
|
||||||
x >>= FRACBITS;
|
x >>= FRACBITS;
|
||||||
y >>= FRACBITS;
|
y >>= FRACBITS;
|
||||||
desttop += (y*vid.width) + x;
|
|
||||||
|
|
||||||
// Center it if necessary
|
// Center it if necessary
|
||||||
if (!(scrn & V_SCALEPATCHMASK))
|
if (!(scrn & V_SCALEPATCHMASK))
|
||||||
{
|
{
|
||||||
if (vid.width != BASEVIDWIDTH * dupx)
|
|
||||||
{
|
|
||||||
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
|
|
||||||
// so center this imaginary screen
|
|
||||||
if (scrn & V_SNAPTORIGHT)
|
|
||||||
desttop += (vid.width - (BASEVIDWIDTH * dupx));
|
|
||||||
else if (!(scrn & V_SNAPTOLEFT))
|
|
||||||
desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
|
|
||||||
}
|
|
||||||
if (vid.height != BASEVIDHEIGHT * dupy)
|
|
||||||
{
|
|
||||||
// same thing here
|
|
||||||
if (scrn & V_SNAPTOBOTTOM)
|
|
||||||
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width;
|
|
||||||
else if (!(scrn & V_SNAPTOTOP))
|
|
||||||
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2;
|
|
||||||
}
|
|
||||||
// if it's meant to cover the whole screen, black out the rest
|
// if it's meant to cover the whole screen, black out the rest
|
||||||
if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT)
|
if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT)
|
||||||
{
|
{
|
||||||
|
@ -826,7 +819,29 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
||||||
source = (const UINT8 *)(column) + 3;
|
source = (const UINT8 *)(column) + 3;
|
||||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vid.width != BASEVIDWIDTH * dupx)
|
||||||
|
{
|
||||||
|
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
|
||||||
|
// so center this imaginary screen
|
||||||
|
if (scrn & V_SNAPTORIGHT)
|
||||||
|
x += (vid.width - (BASEVIDWIDTH * dupx));
|
||||||
|
else if (!(scrn & V_SNAPTOLEFT))
|
||||||
|
x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
|
||||||
|
}
|
||||||
|
if (vid.height != BASEVIDHEIGHT * dupy)
|
||||||
|
{
|
||||||
|
// same thing here
|
||||||
|
if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
|
||||||
|
y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy));
|
||||||
|
else if (scrn & V_SNAPTOBOTTOM)
|
||||||
|
y += (vid.height - (BASEVIDHEIGHT * dupy));
|
||||||
|
else if (!(scrn & V_SNAPTOTOP))
|
||||||
|
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
desttop += (y*vid.width) + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++)
|
for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++)
|
||||||
|
@ -1346,7 +1361,7 @@ char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||||
//
|
//
|
||||||
void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
|
void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
{
|
{
|
||||||
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0;
|
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0;
|
||||||
const char *ch = string;
|
const char *ch = string;
|
||||||
INT32 charflags = 0;
|
INT32 charflags = 0;
|
||||||
const UINT8 *colormap = NULL;
|
const UINT8 *colormap = NULL;
|
||||||
|
@ -1362,7 +1377,11 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
scrwidth = vid.width;
|
scrwidth = vid.width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
dupx = dupy = 1;
|
dupx = dupy = 1;
|
||||||
|
scrwidth = vid.width/vid.dupx;
|
||||||
|
left = (scrwidth - BASEVIDWIDTH)/2;
|
||||||
|
}
|
||||||
|
|
||||||
charflags = (option & V_CHARCOLORMASK);
|
charflags = (option & V_CHARCOLORMASK);
|
||||||
|
|
||||||
|
@ -1422,9 +1441,9 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
else
|
else
|
||||||
w = SHORT(hu_font[c]->width) * dupx;
|
w = SHORT(hu_font[c]->width) * dupx;
|
||||||
|
|
||||||
if (cx + w > scrwidth)
|
if (cx+left > scrwidth)
|
||||||
break;
|
break;
|
||||||
if (cx < 0) //left boundary check
|
if (cx+left + w < 0) //left boundary check
|
||||||
{
|
{
|
||||||
cx += w;
|
cx += w;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1455,7 +1474,7 @@ void V_DrawRightAlignedString(INT32 x, INT32 y, INT32 option, const char *string
|
||||||
//
|
//
|
||||||
void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
|
void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
{
|
{
|
||||||
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0;
|
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0;
|
||||||
const char *ch = string;
|
const char *ch = string;
|
||||||
INT32 charflags = 0;
|
INT32 charflags = 0;
|
||||||
const UINT8 *colormap = NULL;
|
const UINT8 *colormap = NULL;
|
||||||
|
@ -1471,7 +1490,11 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
scrwidth = vid.width;
|
scrwidth = vid.width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
dupx = dupy = 1;
|
dupx = dupy = 1;
|
||||||
|
scrwidth = vid.width/vid.dupx;
|
||||||
|
left = (scrwidth - BASEVIDWIDTH)/2;
|
||||||
|
}
|
||||||
|
|
||||||
charflags = (option & V_CHARCOLORMASK);
|
charflags = (option & V_CHARCOLORMASK);
|
||||||
|
|
||||||
|
@ -1529,9 +1552,9 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
w = SHORT(hu_font[c]->width) * dupx / 2;
|
w = SHORT(hu_font[c]->width) * dupx / 2;
|
||||||
if (cx + w > scrwidth)
|
if (cx+left > scrwidth)
|
||||||
break;
|
break;
|
||||||
if (cx < 0) //left boundary check
|
if (cx+left + w < 0) //left boundary check
|
||||||
{
|
{
|
||||||
cx += w;
|
cx += w;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1556,7 +1579,7 @@ void V_DrawRightAlignedSmallString(INT32 x, INT32 y, INT32 option, const char *s
|
||||||
//
|
//
|
||||||
void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
|
void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
{
|
{
|
||||||
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH;
|
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0;
|
||||||
const char *ch = string;
|
const char *ch = string;
|
||||||
INT32 charflags = 0;
|
INT32 charflags = 0;
|
||||||
const UINT8 *colormap = NULL;
|
const UINT8 *colormap = NULL;
|
||||||
|
@ -1572,7 +1595,11 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
scrwidth = vid.width;
|
scrwidth = vid.width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
dupx = dupy = 1;
|
dupx = dupy = 1;
|
||||||
|
scrwidth = vid.width/vid.dupx;
|
||||||
|
left = (scrwidth - BASEVIDWIDTH)/2;
|
||||||
|
}
|
||||||
|
|
||||||
charflags = (option & V_CHARCOLORMASK);
|
charflags = (option & V_CHARCOLORMASK);
|
||||||
|
|
||||||
|
@ -1628,9 +1655,9 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||||
else
|
else
|
||||||
w = (SHORT(tny_font[c]->width) * dupx);
|
w = (SHORT(tny_font[c]->width) * dupx);
|
||||||
|
|
||||||
if (cx + w > scrwidth)
|
if (cx+left > scrwidth)
|
||||||
break;
|
break;
|
||||||
if (cx < 0) //left boundary check
|
if (cx+left + w < 0) //left boundary check
|
||||||
{
|
{
|
||||||
cx += w;
|
cx += w;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1653,7 +1680,7 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st
|
||||||
void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||||
{
|
{
|
||||||
fixed_t cx = x, cy = y;
|
fixed_t cx = x, cy = y;
|
||||||
INT32 w, c, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0;
|
INT32 w, c, dupx, dupy, scrwidth, center = 0, left = 0;
|
||||||
const char *ch = string;
|
const char *ch = string;
|
||||||
INT32 spacewidth = 4, charwidth = 0;
|
INT32 spacewidth = 4, charwidth = 0;
|
||||||
|
|
||||||
|
@ -1667,7 +1694,11 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||||
scrwidth = vid.width;
|
scrwidth = vid.width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
dupx = dupy = 1;
|
dupx = dupy = 1;
|
||||||
|
scrwidth = vid.width/vid.dupx;
|
||||||
|
left = (scrwidth - BASEVIDWIDTH)/2;
|
||||||
|
}
|
||||||
|
|
||||||
switch (option & V_SPACINGMASK)
|
switch (option & V_SPACINGMASK)
|
||||||
{
|
{
|
||||||
|
@ -1720,9 +1751,9 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||||
else
|
else
|
||||||
w = SHORT(hu_font[c]->width) * dupx;
|
w = SHORT(hu_font[c]->width) * dupx;
|
||||||
|
|
||||||
if ((cx>>FRACBITS) + w > scrwidth)
|
if ((cx>>FRACBITS)+left > scrwidth)
|
||||||
break;
|
break;
|
||||||
if (cx < 0) //left boundary check
|
if (cx+left + w < 0) //left boundary check
|
||||||
{
|
{
|
||||||
cx += w<<FRACBITS;
|
cx += w<<FRACBITS;
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue