mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 12:47:58 +03:00
cmd/demo: add demo_num argument
This commit is contained in:
parent
f8bda9ed08
commit
26d1e0b01c
22 changed files with 95 additions and 33 deletions
|
@ -732,6 +732,7 @@
|
|||
"OSD_GIVE_ITEM_CHEAT": "Lara's backpack just got way heavier!",
|
||||
"OSD_HEAL_ALREADY_FULL_HP": "Lara's already at full health",
|
||||
"OSD_HEAL_SUCCESS": "Healed Lara back to full health",
|
||||
"OSD_INVALID_DEMO": "Invalid demo",
|
||||
"OSD_INVALID_ITEM": "Unknown item: %s",
|
||||
"OSD_INVALID_LEVEL": "Invalid level",
|
||||
"OSD_INVALID_OBJECT": "Invalid object",
|
||||
|
|
|
@ -220,6 +220,7 @@
|
|||
"OSD_GIVE_ITEM_CHEAT": "Lara's backpack just got way heavier!",
|
||||
"OSD_HEAL_ALREADY_FULL_HP": "Lara's already at full health",
|
||||
"OSD_HEAL_SUCCESS": "Healed Lara back to full health",
|
||||
"OSD_INVALID_DEMO": "Invalid demo",
|
||||
"OSD_INVALID_ITEM": "Unknown item: %s",
|
||||
"OSD_INVALID_LEVEL": "Invalid level",
|
||||
"OSD_INVALID_OBJECT": "Invalid object",
|
||||
|
|
|
@ -299,6 +299,7 @@
|
|||
"OSD_GIVE_ITEM_CHEAT": "Lara's backpack just got way heavier!",
|
||||
"OSD_HEAL_ALREADY_FULL_HP": "Lara's already at full health",
|
||||
"OSD_HEAL_SUCCESS": "Healed Lara back to full health",
|
||||
"OSD_INVALID_DEMO": "Invalid demo",
|
||||
"OSD_INVALID_ITEM": "Unknown item: %s",
|
||||
"OSD_INVALID_LEVEL": "Invalid level",
|
||||
"OSD_INVALID_OBJECT": "Invalid object",
|
||||
|
|
|
@ -460,6 +460,7 @@
|
|||
"OSD_GIVE_ITEM_CHEAT": "Lara's backpack just got way heavier!",
|
||||
"OSD_HEAL_ALREADY_FULL_HP": "Lara's already at full health",
|
||||
"OSD_HEAL_SUCCESS": "Healed Lara back to full health",
|
||||
"OSD_INVALID_DEMO": "Invalid demo",
|
||||
"OSD_INVALID_ITEM": "Unknown item: %s",
|
||||
"OSD_INVALID_LEVEL": "Invalid level",
|
||||
"OSD_INVALID_OBJECT": "Invalid object",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr1-4.7.1...develop) - ××××-××-××
|
||||
- added an option for pickup aids, which will show an intermittent twinkle when Lara is nearby pickup items (#2076)
|
||||
- added an optional demo number argument to the `/demo` command
|
||||
- changed demo to be interrupted only by esc or action keys
|
||||
- fixed being unable to load some old custom levels that contain certain (invalid) floor data (#2114, regression from 4.3)
|
||||
- fixed a desync in the Lost Valley demo if responsive swim cancellation was enabled (#2113, regression from 4.6)
|
||||
|
|
|
@ -66,7 +66,8 @@ Currently supported commands:
|
|||
Saves the game to the specified savegame slot.
|
||||
|
||||
- `/demo`
|
||||
Starts the demo.
|
||||
`/demo {num}`
|
||||
Starts the specified demo. If no number is chosen, the demos will cycle.
|
||||
|
||||
- `/title`
|
||||
Exits the game to main screen.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
- added an optional fix for drawing a free flare during the underwater pickup animation (#2123)
|
||||
- added an optional fix for Lara drifting into walls when collecting underwater items (#2096)
|
||||
- added an option to control how music is played while underwater (#1937)
|
||||
- added an optional demo number argument to the `/demo` command
|
||||
- changed demo to be interrupted only by esc or action keys
|
||||
- fixed Lara prioritising throwing a spent flare while mid-air, so to avoid missing ledge grabs (#1989)
|
||||
- fixed Lara at times not being able to jump immediately after going from her walking to running animation (#1587)
|
||||
|
|
|
@ -52,7 +52,8 @@ Currently supported commands:
|
|||
Saves the game to the specified savegame slot.
|
||||
|
||||
- `/demo`
|
||||
Starts the demo.
|
||||
`/demo {num}`
|
||||
Starts the specified demo. If no number is chosen, the demos will cycle.
|
||||
|
||||
- `/title`
|
||||
Exits the game to main screen.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "game/console/cmd/play_demo.h"
|
||||
|
||||
#include "game/game_string.h"
|
||||
#include "game/gameflow/common.h"
|
||||
#include "strings.h"
|
||||
|
||||
|
@ -7,12 +8,26 @@ static COMMAND_RESULT M_Entrypoint(const COMMAND_CONTEXT *ctx);
|
|||
|
||||
static COMMAND_RESULT M_Entrypoint(const COMMAND_CONTEXT *const ctx)
|
||||
{
|
||||
if (!String_IsEmpty(ctx->args)) {
|
||||
int32_t demo_to_load = -1;
|
||||
if (String_ParseInteger(ctx->args, &demo_to_load)) {
|
||||
demo_to_load--;
|
||||
if (demo_to_load >= 0 && demo_to_load < Gameflow_GetDemoCount()) {
|
||||
Gameflow_OverrideCommand((GAMEFLOW_COMMAND) {
|
||||
.action = GF_START_DEMO,
|
||||
.param = demo_to_load,
|
||||
});
|
||||
return CR_SUCCESS;
|
||||
} else {
|
||||
Console_Log(GS(OSD_INVALID_DEMO));
|
||||
return CR_FAILURE;
|
||||
}
|
||||
} else if (String_IsEmpty(ctx->args)) {
|
||||
Gameflow_OverrideCommand(
|
||||
(GAMEFLOW_COMMAND) { .action = GF_START_DEMO, .param = -1 });
|
||||
return CR_SUCCESS;
|
||||
} else {
|
||||
return CR_BAD_INVOCATION;
|
||||
}
|
||||
|
||||
Gameflow_OverrideCommand((GAMEFLOW_COMMAND) { .action = GF_START_DEMO });
|
||||
return CR_SUCCESS;
|
||||
}
|
||||
|
||||
CONSOLE_COMMAND g_Console_Cmd_PlayDemo = {
|
||||
|
|
|
@ -33,6 +33,7 @@ GS_DEFINE(OSD_POS_SET_ITEM, "Teleported to object: %s")
|
|||
GS_DEFINE(OSD_POS_SET_ITEM_FAIL, "Failed to teleport to object: %s")
|
||||
GS_DEFINE(OSD_INVALID_LEVEL, "Invalid level")
|
||||
GS_DEFINE(OSD_PLAY_LEVEL, "Loading %s")
|
||||
GS_DEFINE(OSD_INVALID_DEMO, "Invalid demo")
|
||||
GS_DEFINE(OSD_LOAD_GAME, "Loaded game from save slot %d")
|
||||
GS_DEFINE(OSD_LOAD_GAME_FAIL_UNAVAILABLE_SLOT, "Save slot %d is not available")
|
||||
GS_DEFINE(OSD_LOAD_GAME_FAIL_INVALID_SLOT, "Invalid save slot %d")
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "./types.h"
|
||||
|
||||
extern int32_t Gameflow_GetLevelCount(void);
|
||||
extern int32_t Gameflow_GetDemoCount(void);
|
||||
extern const char *Gameflow_GetLevelFileName(int32_t level_num);
|
||||
extern const char *Gameflow_GetLevelTitle(int32_t level_num);
|
||||
extern int32_t Gameflow_GetGymLevelNumber(void);
|
||||
|
|
|
@ -1374,6 +1374,18 @@ int32_t Gameflow_GetLevelCount(void)
|
|||
return g_GameFlow.level_count;
|
||||
}
|
||||
|
||||
int32_t Gameflow_GetDemoCount(void)
|
||||
{
|
||||
int32_t demo_count = 0;
|
||||
for (int32_t i = g_GameFlow.first_level_num; i <= g_GameFlow.last_level_num;
|
||||
i++) {
|
||||
if (g_GameFlow.levels[i].demo) {
|
||||
demo_count++;
|
||||
}
|
||||
}
|
||||
return demo_count;
|
||||
}
|
||||
|
||||
const char *Gameflow_GetLevelFileName(int32_t level_num)
|
||||
{
|
||||
return g_GameFlow.levels[level_num].level_file;
|
||||
|
|
|
@ -58,7 +58,7 @@ static int32_t m_DemoLevel = -1;
|
|||
static uint32_t *m_DemoPtr = NULL;
|
||||
|
||||
static bool M_ProcessInput(void);
|
||||
static int32_t M_ChooseLevel(void);
|
||||
static int32_t M_ChooseLevel(int32_t demo_num);
|
||||
static void M_PrepareConfig(void);
|
||||
static void M_RestoreConfig(void);
|
||||
static void M_PrepareResumeInfo(void);
|
||||
|
@ -131,10 +131,10 @@ static bool M_ProcessInput(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int32_t M_ChooseLevel(void)
|
||||
static int32_t M_ChooseLevel(const int32_t demo_num)
|
||||
{
|
||||
bool any_demos = false;
|
||||
for (int i = g_GameFlow.first_level_num; i < g_GameFlow.last_level_num;
|
||||
for (int32_t i = g_GameFlow.first_level_num; i <= g_GameFlow.last_level_num;
|
||||
i++) {
|
||||
if (g_GameFlow.levels[i].demo) {
|
||||
any_demos = true;
|
||||
|
@ -144,6 +144,21 @@ static int32_t M_ChooseLevel(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (demo_num >= 0) {
|
||||
int32_t j = 0;
|
||||
for (int32_t i = g_GameFlow.first_level_num;
|
||||
i <= g_GameFlow.last_level_num; i++) {
|
||||
if (g_GameFlow.levels[i].demo) {
|
||||
if (j == demo_num) {
|
||||
return i;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// pick the next demo
|
||||
int16_t level_num = m_DemoLevel;
|
||||
do {
|
||||
level_num++;
|
||||
|
@ -218,7 +233,7 @@ static void M_Start(const PHASE_DEMO_ARGS *const args)
|
|||
return;
|
||||
}
|
||||
|
||||
m_DemoLevel = M_ChooseLevel();
|
||||
m_DemoLevel = M_ChooseLevel(args != NULL ? args->demo_num : -1);
|
||||
if (m_DemoLevel == -1) {
|
||||
m_State = STATE_INVALID;
|
||||
return;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "game/phase/phase.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t demo_num;
|
||||
bool resume_existing;
|
||||
} PHASE_DEMO_ARGS;
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ static PHASE_CONTROL Inv_Close(GAME_OBJECT_ID inv_chosen)
|
|||
if (m_StartDemo) {
|
||||
return (PHASE_CONTROL) {
|
||||
.end = true,
|
||||
.command = { .action = GF_START_DEMO },
|
||||
.command = { .action = GF_START_DEMO, .param = -1 },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "game/option.h"
|
||||
#include "game/output.h"
|
||||
#include "game/phase/phase.h"
|
||||
#include "game/phase/phase_demo.h"
|
||||
#include "game/savegame.h"
|
||||
#include "game/screen.h"
|
||||
#include "game/sound.h"
|
||||
|
@ -172,10 +173,13 @@ void Shell_Main(void)
|
|||
command = GameFlow_InterpretSequence(command.param, GFL_CUTSCENE);
|
||||
break;
|
||||
|
||||
case GF_START_DEMO:
|
||||
Phase_Set(PHASE_DEMO, NULL);
|
||||
case GF_START_DEMO: {
|
||||
PHASE_DEMO_ARGS *const args = Memory_Alloc(sizeof(PHASE_DEMO_ARGS));
|
||||
args->demo_num = command.param;
|
||||
Phase_Set(PHASE_DEMO, args);
|
||||
command = Phase_Run();
|
||||
break;
|
||||
}
|
||||
|
||||
case GF_LEVEL_COMPLETE:
|
||||
command = (GAMEFLOW_COMMAND) { .action = GF_EXIT_TO_TITLE };
|
||||
|
|
|
@ -84,7 +84,7 @@ int16_t TitleSequence(void)
|
|||
}
|
||||
|
||||
if (dir == GFD_START_DEMO) {
|
||||
return GFD_START_DEMO;
|
||||
return GFD_START_DEMO | 0xFF;
|
||||
}
|
||||
|
||||
if (g_Inv_Chosen == O_PHOTO_OPTION) {
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
#include "game/input.h"
|
||||
#include "global/vars.h"
|
||||
|
||||
#include <libtrx/log.h>
|
||||
|
||||
static int32_t m_DemoLevel = 0;
|
||||
static int32_t m_DemoIdx = 0;
|
||||
static INPUT_STATE m_OldDemoInputDB = { 0 };
|
||||
|
||||
static int32_t M_GetNextLevel(void);
|
||||
|
@ -15,20 +13,23 @@ static int32_t M_GetNextLevel(void)
|
|||
if (g_GameFlow.num_demos <= 0) {
|
||||
return -1;
|
||||
}
|
||||
if (m_DemoLevel >= g_GameFlow.num_demos) {
|
||||
m_DemoLevel = 0;
|
||||
}
|
||||
const int32_t level_num = g_GF_ValidDemos[m_DemoLevel];
|
||||
m_DemoLevel++;
|
||||
const int32_t level_num = g_GF_ValidDemos[m_DemoIdx];
|
||||
m_DemoIdx++;
|
||||
m_DemoIdx %= g_GameFlow.num_demos;
|
||||
return level_num;
|
||||
}
|
||||
|
||||
int32_t Demo_ChooseLevel(int32_t level_num)
|
||||
int32_t Demo_ChooseLevel(int32_t demo_num)
|
||||
{
|
||||
if (level_num < 0) {
|
||||
level_num = M_GetNextLevel();
|
||||
if (demo_num < 0) {
|
||||
return M_GetNextLevel();
|
||||
} else if (g_GameFlow.num_demos <= 0) {
|
||||
return -1;
|
||||
} else if (demo_num < 0 || demo_num >= g_GameFlow.num_demos) {
|
||||
return -1;
|
||||
} else {
|
||||
return g_GF_ValidDemos[demo_num];
|
||||
}
|
||||
return level_num;
|
||||
}
|
||||
|
||||
bool Demo_GetInput(void)
|
||||
|
|
|
@ -8,8 +8,6 @@ GS_DEFINE(OSD_FLIPMAP_OFF, "Flipmap set to OFF")
|
|||
GS_DEFINE(OSD_FLIPMAP_FAIL_ALREADY_ON, "Flipmap is already ON")
|
||||
GS_DEFINE(OSD_FLIPMAP_FAIL_ALREADY_OFF, "Flipmap is already OFF")
|
||||
GS_DEFINE(OSD_COMPLETE_LEVEL, "Level complete!")
|
||||
GS_DEFINE(OSD_PLAY_LEVEL, "Loading %s")
|
||||
GS_DEFINE(OSD_INVALID_LEVEL, "Invalid level")
|
||||
GS_DEFINE(OSD_INVALID_SAVE_SLOT, "Invalid save slot %d")
|
||||
GS_DEFINE(OSD_DOOR_OPEN, "Open Sesame!")
|
||||
GS_DEFINE(OSD_DOOR_CLOSE, "Close Sesame!")
|
||||
|
|
|
@ -651,10 +651,9 @@ void GF_ModifyInventory(const int32_t level, const int32_t type)
|
|||
}
|
||||
}
|
||||
|
||||
GAME_FLOW_DIR GF_StartDemo(int32_t level_num)
|
||||
GAME_FLOW_DIR GF_StartDemo(const int32_t level_num)
|
||||
{
|
||||
level_num = Demo_ChooseLevel(level_num);
|
||||
if (level_num == -1) {
|
||||
if (level_num < 0) {
|
||||
return GFD_EXIT_TO_TITLE;
|
||||
}
|
||||
PHASE *const demo_phase = Phase_Demo_Create(level_num);
|
||||
|
|
|
@ -221,6 +221,11 @@ int32_t Gameflow_GetLevelCount(void)
|
|||
return g_GameflowNew.level_count;
|
||||
}
|
||||
|
||||
int32_t Gameflow_GetDemoCount(void)
|
||||
{
|
||||
return g_GameFlow.num_demos;
|
||||
}
|
||||
|
||||
const char *Gameflow_GetLevelFileName(int32_t level_num)
|
||||
{
|
||||
return g_GF_LevelFileNames[level_num];
|
||||
|
@ -253,7 +258,7 @@ void Gameflow_OverrideCommand(const GAMEFLOW_COMMAND command)
|
|||
g_GF_OverrideDir = GFD_START_FMV;
|
||||
break;
|
||||
case GF_START_DEMO:
|
||||
g_GF_OverrideDir = GFD_START_DEMO;
|
||||
g_GF_OverrideDir = GFD_START_DEMO | (command.param & 0xFF);
|
||||
break;
|
||||
case GF_EXIT_TO_TITLE:
|
||||
g_GF_OverrideDir = GFD_EXIT_TO_TITLE;
|
||||
|
|
|
@ -409,7 +409,9 @@ void Shell_Main(void)
|
|||
break;
|
||||
|
||||
case GFD_START_DEMO:
|
||||
gf_option = GF_DoLevelSequence(Demo_ChooseLevel(-1), GFL_DEMO);
|
||||
const int32_t level_num = Demo_ChooseLevel((int8_t)gf_param);
|
||||
gf_option = level_num >= 0 ? GF_DoLevelSequence(level_num, GFL_DEMO)
|
||||
: GFD_EXIT_TO_TITLE;
|
||||
break;
|
||||
|
||||
case GFD_LEVEL_COMPLETE:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue