Merge branch 'titlemap' into 'master'

Titlemap

See merge request !97
This commit is contained in:
toaster 2017-09-19 07:44:00 -04:00
commit b805380294
14 changed files with 303 additions and 30 deletions

View file

@ -301,7 +301,7 @@ static void D_Display(void)
if (rendermode != render_none)
{
// Fade to black first
if (gamestate != GS_LEVEL // fades to black on its own timing, always
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) // fades to black on its own timing, always
&& wipedefs[wipedefindex] != UINT8_MAX)
{
F_WipeStartScreen();
@ -317,6 +317,12 @@ static void D_Display(void)
// do buffered drawing
switch (gamestate)
{
case GS_TITLESCREEN:
if (!titlemapinaction) {
F_TitleScreenDrawer();
break;
}
// Intentional fall-through
case GS_LEVEL:
if (!gametic)
break;
@ -365,10 +371,6 @@ static void D_Display(void)
HU_Drawer();
break;
case GS_TITLESCREEN:
F_TitleScreenDrawer();
break;
case GS_WAITINGPLAYERS:
// The clientconnect drawer is independent...
case GS_DEDICATEDSERVER:
@ -378,9 +380,10 @@ static void D_Display(void)
// clean up border stuff
// see if the border needs to be initially drawn
if (gamestate == GS_LEVEL)
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
{
// draw the view directly
if (!automapactive && !dedicated && cv_renderview.value)
{
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
@ -438,9 +441,13 @@ static void D_Display(void)
lastdraw = false;
}
ST_Drawer();
HU_Drawer();
if (gamestate == GS_LEVEL)
{
ST_Drawer();
HU_Drawer();
}
else
F_TitleScreenDrawer();
}
// change gamma if needed
@ -680,6 +687,9 @@ void D_AdvanceDemo(void)
void D_StartTitle(void)
{
INT32 i;
S_StopMusic();
if (netgame)
{
if (gametype == GT_COOP)
@ -1345,6 +1355,19 @@ void D_SRB2Main(void)
ultimatemode = true;
}
// rei/miru: bootmap (Idea: starts the game on a predefined map)
if (bootmap && !(M_CheckParm("-warp") && M_IsNextParm()))
{
pstartmap = bootmap;
if (pstartmap < 1 || pstartmap > NUMMAPS)
I_Error("Cannot warp to map %d (out of range)\n", pstartmap);
else
{
autostart = true;
}
}
if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect"))
{
gameaction = ga_nothing;

View file

@ -77,6 +77,8 @@ boolean deh_loaded = false;
static int dbg_line;
static boolean gamedataadded = false;
static boolean titlechanged = false;
static boolean introchanged = false;
ATTRINLINE static FUNCINLINE char myfget_color(MYFILE *f)
{
@ -2667,14 +2669,38 @@ static void readmaincfg(MYFILE *f)
// range check, you morons.
if (introtoplay > 128)
introtoplay = 128;
introchanged = true;
}
else if (fastcmp(word, "LOOPTITLE"))
{
looptitle = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
titlechanged = true;
}
else if (fastcmp(word, "TITLEMAP"))
{
// Support using the actual map name,
// i.e., Level AB, Level FZ, etc.
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z')
value = M_MapNumber(word2[0], word2[1]);
else
value = get_number(word2);
DEH_WriteUndoline(word, va("%d", titlemap), UNDO_NONE);
titlemap = (INT16)value;
titlechanged = true;
}
else if (fastcmp(word, "HIDETITLEPICS"))
{
DEH_WriteUndoline(word, va("%d", hidetitlepics), UNDO_NONE);
hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
titlechanged = true;
}
else if (fastcmp(word, "TITLESCROLLSPEED"))
{
titlescrollspeed = get_number(word2);
titlechanged = true;
}
else if (fastcmp(word, "CREDITSCUTSCENE"))
{
@ -2690,14 +2716,17 @@ static void readmaincfg(MYFILE *f)
else if (fastcmp(word, "NUMDEMOS"))
{
numDemos = (UINT8)get_number(word2);
titlechanged = true;
}
else if (fastcmp(word, "DEMODELAYTIME"))
{
demoDelayTime = get_number(word2);
titlechanged = true;
}
else if (fastcmp(word, "DEMOIDLETIME"))
{
demoIdleTime = get_number(word2);
titlechanged = true;
}
else if (fastcmp(word, "USE1UPSOUND"))
{
@ -2731,14 +2760,32 @@ static void readmaincfg(MYFILE *f)
strlcat(savegamename, "%u.ssg", sizeof(savegamename));
gamedataadded = true;
titlechanged = true;
}
else if (fastcmp(word, "RESETDATA"))
{
P_ResetData(value);
titlechanged = true;
}
else if (fastcmp(word, "CUSTOMVERSION"))
{
strlcpy(customversionstring, word2, sizeof (customversionstring));
//titlechanged = true;
}
else if (fastcmp(word, "BOOTMAP"))
{
// Support using the actual map name,
// i.e., Level AB, Level FZ, etc.
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z')
value = M_MapNumber(word2[0], word2[1]);
else
value = get_number(word2);
DEH_WriteUndoline(word, va("%d", bootmap), UNDO_NONE);
bootmap = (INT16)value;
//titlechanged = true;
}
else
deh_warning("Maincfg: unknown word '%s'", word);
@ -2935,7 +2982,7 @@ static void DEH_LoadDehackedFile(MYFILE *f)
deh_num_warning = 0;
gamedataadded = false;
gamedataadded = titlechanged = introchanged = false;
// it doesn't test the version of SRB2 and version of dehacked file
dbg_line = -1; // start at -1 so the first line is 0.
@ -3236,6 +3283,14 @@ static void DEH_LoadDehackedFile(MYFILE *f)
if (gamedataadded)
G_LoadGameData();
if (gamestate == GS_TITLESCREEN)
{
if (introchanged)
COM_BufAddText("playintro");
else if (titlechanged)
COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed
}
dbg_line = -1;
if (deh_num_warning)
{
@ -8119,6 +8174,12 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"paused")) {
lua_pushboolean(L, paused);
return 1;
} else if (fastcmp(word,"titlemap")) {
lua_pushinteger(L, titlemap);
return 1;
} else if (fastcmp(word,"titlemapinaction")) {
lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF));
return 1;
} else if (fastcmp(word,"gametype")) {
lua_pushinteger(L, gametype);
return 1;

View file

@ -125,6 +125,10 @@ extern INT16 spstage_start;
extern INT16 sstage_start;
extern INT16 sstage_end;
extern INT16 titlemap;
extern boolean hidetitlepics;
extern INT16 bootmap; //bootmap for loading a map on startup
extern boolean looptitle;
extern boolean useNightsSS;

View file

@ -31,11 +31,18 @@
#include "m_random.h"
#include "y_inter.h"
#include "m_cond.h"
#include "p_local.h"
#include "p_setup.h"
#ifdef HAVE_BLUA
#include "lua_hud.h"
#endif
// Stage of animation:
// 0 = text, 1 = art screen
static INT32 finalecount;
INT32 titlescrollspeed = 80;
UINT8 titlemapinaction = TITLEMAP_OFF;
static INT32 timetonext; // Delay between screen changes
static INT32 continuetime; // Short delay when continuing
@ -217,17 +224,19 @@ static void F_SkyScroll(INT32 scrollspeed)
{
INT32 scrolled, x, mx, fakedwidth;
patch_t *pat;
INT16 patwidth;
pat = W_CachePatchName("TITLESKY", PU_CACHE);
animtimer = ((finalecount*scrollspeed)/16) % SHORT(pat->width);
patwidth = SHORT(pat->width);
animtimer = ((finalecount*scrollspeed)/16 + patwidth) % patwidth;
fakedwidth = vid.width / vid.dupx;
if (rendermode == render_soft)
{ // if only hardware rendering could be this elegant and complete
scrolled = (SHORT(pat->width) - animtimer) - 1;
for (x = 0, mx = scrolled; x < fakedwidth; x++, mx = (mx+1)%SHORT(pat->width))
scrolled = (patwidth - animtimer) - 1;
for (x = 0, mx = scrolled; x < fakedwidth; x++, mx = (mx+1)%patwidth)
F_DrawPatchCol(x, pat, mx);
}
#ifdef HWRENDER
@ -235,8 +244,8 @@ static void F_SkyScroll(INT32 scrollspeed)
{ // if only software rendering could be this simple and retarded
scrolled = animtimer;
if (scrolled > 0)
V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat);
for (x = 0; x < fakedwidth; x += SHORT(pat->width))
V_DrawScaledPatch(scrolled - patwidth, 0, 0, pat);
for (x = 0; x < fakedwidth; x += patwidth)
V_DrawScaledPatch(x + scrolled, 0, 0, pat);
}
#endif
@ -278,6 +287,8 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
void F_StartIntro(void)
{
S_StopMusic();
if (introtoplay)
{
if (!cutscenes[introtoplay - 1])
@ -998,7 +1009,7 @@ static const char *credits[] = {
"",
"\1Sprite Artists",
"Odi \"Iceman404\" Atunzu",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Jim \"MotorRoach\" DeMello",
"Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins",
@ -1415,17 +1426,72 @@ void F_GameEndTicker(void)
// ==============
void F_StartTitleScreen(void)
{
S_ChangeMusicInternal("_title", looptitle);
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
finalecount = 0;
else
wipegamestate = GS_TITLESCREEN;
if (titlemap)
{
mapthing_t *startpos;
gamestate_t prevwipegamestate = wipegamestate;
titlemapinaction = TITLEMAP_LOADING;
gamemap = titlemap;
if (!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1);
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
globalweather = mapheaderinfo[gamemap-1]->weather;
G_DoLoadLevel(true);
if (!titlemap)
return;
players[displayplayer].playerstate = PST_DEAD; // Don't spawn the player in dummy (I'm still a filthy cheater)
// Set Default Position
if (playerstarts[0])
startpos = playerstarts[0];
else if (deathmatchstarts[0])
startpos = deathmatchstarts[0];
else
startpos = NULL;
if (startpos)
{
camera.x = startpos->x << FRACBITS;
camera.y = startpos->y << FRACBITS;
camera.subsector = R_PointInSubsector(camera.x, camera.y);
camera.z = camera.subsector->sector->floorheight + ((startpos->options >> ZSHIFT) << FRACBITS);
camera.angle = (startpos->angle % 360)*ANG1;
camera.aiming = 0;
}
else
{
camera.x = camera.y = camera.z = camera.angle = camera.aiming = 0;
camera.subsector = NULL; // toast is filthy too
}
camera.chase = true;
camera.height = 0;
wipegamestate = prevwipegamestate;
}
else
{
titlemapinaction = TITLEMAP_OFF;
gamemap = 1; // g_game.c
CON_ClearHUD();
}
G_SetGamestate(GS_TITLESCREEN);
CON_ClearHUD();
// IWAD dependent stuff.
S_ChangeMusicInternal("_title", looptitle);
animtimer = 0;
demoDelayLeft = demoDelayTime;
@ -1455,12 +1521,21 @@ void F_TitleScreenDrawer(void)
return; // We likely came here from retrying. Don't do a damn thing.
// Draw that sky!
F_SkyScroll(titlescrollspeed);
if (!titlemapinaction)
F_SkyScroll(titlescrollspeed);
// Don't draw outside of the title screewn, or if the patch isn't there.
if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS))
return;
// rei|miru: use title pics?
if (hidetitlepics)
#ifdef HAVE_BLUA
goto luahook;
#else
return;
#endif
V_DrawScaledPatch(30, 14, 0, ttwing);
if (finalecount < 57)
@ -1497,6 +1572,11 @@ void F_TitleScreenDrawer(void)
}
V_DrawScaledPatch(48, 142, 0,ttbanner);
#ifdef HAVE_BLUA
luahook:
LUAh_TitleHUD();
#endif
}
// (no longer) De-Demo'd Title Screen
@ -1509,6 +1589,46 @@ void F_TitleScreenTicker(boolean run)
if (gameaction != ga_nothing || gamestate != GS_TITLESCREEN)
return;
// Execute the titlemap camera settings
if (titlemapinaction)
{
thinker_t *th;
mobj_t *mo2;
mobj_t *cameraref = NULL;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
continue;
mo2 = (mobj_t *)th;
if (!mo2)
continue;
if (mo2->type != MT_ALTVIEWMAN)
continue;
cameraref = mo2;
break;
}
if (cameraref)
{
camera.x = cameraref->x;
camera.y = cameraref->y;
camera.z = cameraref->z;
camera.angle = cameraref->angle;
camera.aiming = cameraref->cusval;
camera.subsector = cameraref->subsector;
}
else
{
// Default behavior: Do a lil' camera spin if a title map is loaded;
camera.angle += titlescrollspeed*ANG1/64;
}
}
// no demos to play? or, are they disabled?
if (!cv_rollingdemos.value || !numDemos)
return;

View file

@ -62,6 +62,15 @@ void F_ContinueDrawer(void);
extern INT32 titlescrollspeed;
typedef enum
{
TITLEMAP_OFF = 0,
TITLEMAP_LOADING,
TITLEMAP_RUNNING
} titlemap_enum;
extern UINT8 titlemapinaction;
//
// WIPE
//

View file

@ -121,6 +121,10 @@ INT16 spstage_start;
INT16 sstage_start;
INT16 sstage_end;
INT16 titlemap = 0;
boolean hidetitlepics = false;
INT16 bootmap; //bootmap for loading a map on startup
boolean looptitle = false;
boolean useNightsSS = false;
@ -1633,6 +1637,21 @@ void G_DoLoadLevel(boolean resetplayer)
if (gamestate == GS_INTERMISSION)
Y_EndIntermission();
// cleanup
if (titlemapinaction == TITLEMAP_LOADING)
{
if (W_CheckNumForName(G_BuildMapName(gamemap)) == LUMPERROR)
{
titlemap = 0; // let's not infinite recursion ok
Command_ExitGame_f();
return;
}
titlemapinaction = TITLEMAP_RUNNING;
}
else
titlemapinaction = TITLEMAP_OFF;
G_SetGamestate(GS_LEVEL);
for (i = 0; i < MAXPLAYERS; i++)
@ -1642,7 +1661,7 @@ void G_DoLoadLevel(boolean resetplayer)
}
// Setup the level.
if (!P_SetupLevel(false))
if (!P_SetupLevel(false)) // this never returns false?
{
// fail so reset game stuff
Command_ExitGame_f();
@ -1991,6 +2010,7 @@ void G_Ticker(boolean run)
break;
case GS_TITLESCREEN:
if (titlemapinaction) P_Ticker(run); // then intentionally fall through
case GS_WAITINGPLAYERS:
F_TitleScreenTicker(run);
break;

View file

@ -42,3 +42,4 @@ boolean LUA_HudEnabled(enum hud option);
void LUAh_GameHUD(player_t *stplyr);
void LUAh_ScoresHUD(void);
void LUAh_TitleHUD(void);

View file

@ -88,11 +88,13 @@ static const char *const patch_opt[] = {
enum hudhook {
hudhook_game = 0,
hudhook_scores
hudhook_scores,
hudhook_title
};
static const char *const hudhook_opt[] = {
"game",
"scores",
"title",
NULL};
// alignment types for v.drawString
@ -808,6 +810,9 @@ int LUA_HudLib(lua_State *L)
lua_newtable(L);
lua_rawseti(L, -2, 3); // HUD[2] = scores rendering functions array
lua_newtable(L);
lua_rawseti(L, -2, 4); // HUD[3] = title rendering functions array
lua_setfield(L, LUA_REGISTRYINDEX, "HUD");
luaL_newmetatable(L, META_HUDINFO);
@ -920,4 +925,29 @@ void LUAh_ScoresHUD(void)
hud_running = false;
}
void LUAh_TitleHUD(void)
{
if (!gL || !(hudAvailable & (1<<hudhook_title)))
return;
hud_running = true;
lua_pop(gL, -1);
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, 4); // HUD[4] = rendering funcs
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
I_Assert(lua_istable(gL, -1));
lua_remove(gL, -3); // pop HUD
lua_pushnil(gL);
while (lua_next(gL, -3) != 0) {
lua_pushvalue(gL, -3); // graphics library (HUD[1])
LUA_Call(gL, 1);
}
lua_pop(gL, -1);
hud_running = false;
}
#endif

View file

@ -34,6 +34,7 @@
#ifdef ESLOPE
#include "p_slopes.h"
#endif
#include "f_finale.h"
// protos.
static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}};
@ -8415,6 +8416,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
#endif
switch (mobj->type)
{
case MT_ALTVIEWMAN:
if (titlemapinaction) mobj->flags &= ~MF_NOTHINK;
break;
case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE:
mobj->fuse = mobj->info->mass;
break;

View file

@ -2667,7 +2667,9 @@ boolean P_SetupLevel(boolean skipprecip)
// As oddly named as this is, this handles music only.
// We should be fine starting it here.
S_Start();
/// ... as long as this isn't a titlemap transition, that is
if (!titlemapinaction)
S_Start();
// Let's fade to black here
// But only if we didn't do the special stage wipe
@ -2681,7 +2683,7 @@ boolean P_SetupLevel(boolean skipprecip)
}
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
if (rendermode != render_none)
if (!titlemapinaction && rendermode != render_none)
{
// Don't include these in the fade!
char tx[64];

View file

@ -165,7 +165,7 @@ fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move)
boolean P_AutoPause(void)
{
// Don't pause even on menu-up or focus-lost in netgames or record attack
if (netgame || modeattacking)
if (netgame || modeattacking || gamestate == GS_TITLESCREEN)
return false;
return (menuactive || window_notinfocus);

View file

@ -914,7 +914,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
chasecam = (cv_chasecam.value != 0);
}
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD)
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN)
chasecam = true; // force chasecam on
else if (player->spectator) // no spectator chasecam
chasecam = false; // force chasecam off

View file

@ -64,10 +64,6 @@ void R_SetupSkyDraw(void)
// the horizon line in a 256x128 sky texture
skytexturemid = (textures[skytexture]->height/2)<<FRACBITS;
// get the right drawer, it was set by screen.c, depending on the
// current video mode bytes per pixel (quick fix)
wallcolfunc = walldrawerfunc;
R_SetSkyScale();
}

View file

@ -173,6 +173,9 @@ void SCR_SetMode(void)
if (SCR_IsAspectCorrect(vid.width, vid.height))
CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT);
#endif*/
wallcolfunc = walldrawerfunc;
// set the apprpriate drawer for the sky (tall or INT16)
setmodeneeded = 0;
}