phase/pause: move to libtrx

This commit is contained in:
Marcin Kurczewski 2025-01-08 11:55:32 +01:00
parent 1ac3c73c7d
commit 65bb6b5505
22 changed files with 101 additions and 34 deletions

View file

@ -429,6 +429,7 @@
"KEYMAP_LEFT": "Left",
"KEYMAP_LEVEL_SKIP_CHEAT": "Level Skip",
"KEYMAP_LOOK": "Look",
"KEYMAP_PAUSE": "Pause",
"KEYMAP_RIGHT": "Right",
"KEYMAP_ROLL": "Roll",
"KEYMAP_RUN": "Run",
@ -497,5 +498,12 @@
"OSD_UI_OFF": "UI disabled",
"OSD_UI_ON": "UI enabled",
"OSD_UNKNOWN_COMMAND": "Unknown command: %s",
"PAUSE_ARE_YOU_SURE": "Are you sure?",
"PAUSE_CONTINUE": "Continue",
"PAUSE_EXIT_TO_TITLE": "Exit to title?",
"PAUSE_NO": "No",
"PAUSE_PAUSED": "Paused",
"PAUSE_QUIT": "Quit",
"PAUSE_YES": "Yes",
},
}

View file

@ -1,6 +1,7 @@
## [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
- added a fade-out effect when exiting the game from the pause screen
- changed demo to be interrupted only by esc or action keys
- changed the turbo cheat to also affect ingame timer (#2167)
- changed the pause screen to wait before yielding control during fade out effect

View file

@ -1,5 +1,6 @@
## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr2-0.8...develop) - ××××-××-××
- added Linux builds and toolchain (#1598)
- added pause dialog (#1638)
- fixed showing inventory ring up/down arrows when uncalled for (#2225)
- fixed Lara activating triggers one frame too early (#2205, regression from 0.7)
- fixed Lara never stepping backwards off a step using her right foot (#1602)

View file

@ -29,6 +29,7 @@ game with new enhancements and features.
- step bug
- free flare from underwater pickup
- drifting into walls during underwater pickups
- added a pause screen
- changed inventory to pause the music rather than muting it
- fixed killing the T-Rex with a grenade launcher crashing the game
- fixed secret rewards not displaying shotgun ammo

View file

@ -1,5 +1,7 @@
#include "game/phase/phase_pause.h"
#include "game/console/common.h"
#include "game/fader.h"
#include "game/game.h"
#include "game/game_string.h"
#include "game/input.h"
@ -10,12 +12,8 @@
#include "game/shell.h"
#include "game/sound.h"
#include "game/text.h"
#include "global/types.h"
#include "global/vars.h"
#include <libtrx/game/fader.h>
#include <libtrx/game/ui/widgets/requester.h>
#include <libtrx/memory.h>
#include "game/ui/widgets/requester.h"
#include "memory.h"
#include <stdbool.h>
#include <stddef.h>
@ -33,6 +31,7 @@ typedef struct {
bool is_ui_ready;
UI_WIDGET *ui;
TEXTSTRING *mode_text;
GAME_FLOW_ACTION action;
FADER back_fader;
} M_PRIV;
@ -40,6 +39,8 @@ static void M_FadeIn(M_PRIV *p);
static void M_FadeOut(M_PRIV *p);
static void M_PauseGame(M_PRIV *p);
static void M_ReturnToGame(M_PRIV *p);
static void M_ExitGame(M_PRIV *p);
static void M_ExitToTitle(M_PRIV *p);
static void M_CreateText(M_PRIV *p);
static void M_RemoveText(M_PRIV *p);
static int32_t M_DisplayRequester(
@ -52,21 +53,30 @@ static void M_Draw(PHASE *phase);
static void M_FadeIn(M_PRIV *const p)
{
M_CreateText(p);
Fader_Init(&p->back_fader, FADER_TRANSPARENT, FADER_SEMI_BLACK, 0.5);
}
static void M_FadeOut(M_PRIV *const p)
{
Fader_Init(&p->back_fader, FADER_ANY, FADER_TRANSPARENT, 0.3);
M_RemoveText(p);
if (p->ui != NULL) {
p->ui->free(p->ui);
p->ui = NULL;
}
if (p->action == GF_NOOP) {
Fader_Init(&p->back_fader, FADER_ANY, FADER_TRANSPARENT, 0.3);
} else {
Fader_Init(&p->back_fader, FADER_ANY, FADER_BLACK, 0.5);
}
p->state = STATE_FADE_OUT;
}
static void M_PauseGame(M_PRIV *const p)
{
p->action = GF_NOOP;
Music_Pause();
Sound_PauseAll();
Overlay_HideGameInfo();
M_CreateText(p);
M_FadeIn(p);
}
@ -74,11 +84,18 @@ static void M_ReturnToGame(M_PRIV *const p)
{
Music_Unpause();
Sound_UnpauseAll();
M_RemoveText(p);
if (p->ui != NULL) {
p->ui->free(p->ui);
p->ui = NULL;
}
M_FadeOut(p);
}
static void M_ExitGame(M_PRIV *const p)
{
p->action = GF_EXIT_GAME;
M_FadeOut(p);
}
static void M_ExitToTitle(M_PRIV *const p)
{
p->action = GF_EXIT_TO_TITLE;
M_FadeOut(p);
}
@ -158,6 +175,10 @@ static PHASE_CONTROL M_Control(PHASE *const phase, int32_t const num_frames)
p->ui->control(p->ui);
}
if (Game_IsExiting()) {
M_ExitGame(p);
}
switch (p->state) {
case STATE_DEFAULT:
if (g_InputDB.pause) {
@ -184,10 +205,8 @@ static PHASE_CONTROL M_Control(PHASE *const phase, int32_t const num_frames)
const int32_t choice = M_DisplayRequester(
p, GS(PAUSE_ARE_YOU_SURE), GS(PAUSE_YES), GS(PAUSE_NO));
if (choice == 0) {
return (PHASE_CONTROL) {
.action = PHASE_ACTION_END,
.gf_cmd = { .action = GF_EXIT_TO_TITLE },
};
M_ExitToTitle(p);
return (PHASE_CONTROL) { .action = PHASE_ACTION_NO_WAIT };
} else if (choice == 1) {
M_ReturnToGame(p);
return (PHASE_CONTROL) { .action = PHASE_ACTION_NO_WAIT };
@ -198,7 +217,7 @@ static PHASE_CONTROL M_Control(PHASE *const phase, int32_t const num_frames)
if (!Fader_IsActive(&p->back_fader)) {
return (PHASE_CONTROL) {
.action = PHASE_ACTION_END,
.gf_cmd = { .action = GF_NOOP },
.gf_cmd = { .action = p->action },
};
}
break;
@ -211,14 +230,18 @@ static PHASE_CONTROL M_Control(PHASE *const phase, int32_t const num_frames)
static void M_Draw(PHASE *const phase)
{
M_PRIV *const p = phase->priv;
Interpolation_Disable();
Game_Draw(false);
Fader_Draw(&p->back_fader);
Interpolation_Enable();
Fader_Draw(&p->back_fader);
Text_Draw();
if (p->ui != NULL) {
p->ui->draw(p->ui);
}
Text_Draw();
Console_Draw();
Output_DrawPolyList();
}
PHASE *Phase_Pause_Create(void)

View file

@ -77,3 +77,11 @@ GS_DEFINE(KEYMAP_ITEM_CHEAT, "Item Cheat")
GS_DEFINE(KEYMAP_LEVEL_SKIP_CHEAT, "Level Skip")
GS_DEFINE(KEYMAP_ENTER_CONSOLE, "Dev Console")
GS_DEFINE(KEYMAP_TURBO_CHEAT, "Turbo Speed")
GS_DEFINE(KEYMAP_PAUSE, "Pause")
GS_DEFINE(PAUSE_PAUSED, "Paused")
GS_DEFINE(PAUSE_EXIT_TO_TITLE, "Exit to title?")
GS_DEFINE(PAUSE_CONTINUE, "Continue")
GS_DEFINE(PAUSE_QUIT, "Quit")
GS_DEFINE(PAUSE_ARE_YOU_SURE, "Are you sure?")
GS_DEFINE(PAUSE_YES, "Yes")
GS_DEFINE(PAUSE_NO, "No")

View file

@ -31,6 +31,7 @@ INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_USE_SMALL_MEDI, SDL_SCANCODE_8)
INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_USE_BIG_MEDI, SDL_SCANCODE_9)
INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_USE_FLARE, SDL_SCANCODE_COMMA)
INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_PAUSE, SDL_SCANCODE_P)
INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SWITCH_RESOLUTION, SDL_SCANCODE_F1)
INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SWITCH_INTERNAL_SCREEN_SIZE, SDL_SCANCODE_F2)
INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_BILINEAR_FILTER, SDL_SCANCODE_F3)

View file

@ -42,6 +42,7 @@ INPUT_ROLE_DEFINE(USE_FLARE, use_flare)
INPUT_ROLE_DEFINE(USE_SMALL_MEDI, use_small_medi)
INPUT_ROLE_DEFINE(USE_BIG_MEDI, use_big_medi)
INPUT_ROLE_DEFINE(PAUSE, pause)
INPUT_ROLE_DEFINE(SWITCH_RESOLUTION, switch_resolution)
INPUT_ROLE_DEFINE(SWITCH_INTERNAL_SCREEN_SIZE, switch_internal_screen_size)
INPUT_ROLE_DEFINE(TOGGLE_BILINEAR_FILTER, toggle_bilinear_filter)

View file

@ -0,0 +1,4 @@
#pragma once
extern void Music_Pause(void);
extern void Music_Unpause(void);

View file

@ -11,6 +11,8 @@ void Output_DrawBlackRectangle(int32_t opacity);
void Output_DrawBackground(void);
void Output_DrawPolyList(void);
extern void Output_SetupBelowWater(bool is_underwater);
extern void Output_SetupAboveWater(bool is_underwater);
extern void Output_RotateLight(int16_t pitch, int16_t yaw);
extern void Output_SetLightAdder(int32_t adder);
extern void Output_SetLightDivider(int32_t divider);

View file

@ -2,5 +2,6 @@
#include "./phase/control.h"
#include "./phase/executor.h"
#include "./phase/phase_pause.h"
#include "./phase/phase_picture.h"
#include "./phase/types.h"

View file

@ -1,6 +1,6 @@
#pragma once
#include <libtrx/game/phase/types.h>
#include "./types.h"
PHASE *Phase_Pause_Create(void);
void Phase_Pause_Destroy(PHASE *phase);

View file

@ -114,6 +114,7 @@ sources = [
'game/objects/names.c',
'game/objects/vars.c',
'game/phase/executor.c',
'game/phase/phase_pause.c',
'game/phase/phase_picture.c',
'game/random.c',
'game/rooms/common.c',

View file

@ -39,7 +39,6 @@ GS_DEFINE(DETAIL_RESOLUTION_FMT, "%dx%d")
GS_DEFINE(SOUND_SET_VOLUMES, "Set Volumes")
GS_DEFINE(CONTROL_RESET_DEFAULTS, "Reset All: Hold %s")
GS_DEFINE(CONTROL_UNBIND, "Unbind: Hold %s")
GS_DEFINE(KEYMAP_PAUSE, "Pause")
GS_DEFINE(KEYMAP_CHANGE_TARGET, "Change Target")
GS_DEFINE(KEYMAP_TOGGLE_UI, "Toggle UI")
GS_DEFINE(KEYMAP_TOGGLE_PHOTO_MODE, "Toggle Photo Mode")
@ -68,13 +67,6 @@ GS_DEFINE(STATS_DEATHS_FMT, "DEATHS %d")
GS_DEFINE(STATS_TIME_TAKEN_FMT, "TIME TAKEN %s")
GS_DEFINE(STATS_FINAL_STATISTICS, "Final Statistics")
GS_DEFINE(STATS_BONUS_STATISTICS, "Bonus Statistics")
GS_DEFINE(PAUSE_PAUSED, "Paused")
GS_DEFINE(PAUSE_EXIT_TO_TITLE, "Exit to title?")
GS_DEFINE(PAUSE_CONTINUE, "Continue")
GS_DEFINE(PAUSE_QUIT, "Quit")
GS_DEFINE(PAUSE_ARE_YOU_SURE, "Are you sure?")
GS_DEFINE(PAUSE_YES, "Yes")
GS_DEFINE(PAUSE_NO, "No")
GS_DEFINE(MISC_EMPTY_SLOT_FMT, "- EMPTY SLOT %d -")
GS_DEFINE(MISC_DEMO_MODE, "Demo Mode")
GS_DEFINE(INV_ITEM_MEDI, "Small Medi Pack")

View file

@ -1,6 +1,5 @@
#pragma once
#include "game/phase/phase_pause.h"
#include "game/phase/phase_photo_mode.h"
#include <libtrx/game/phase.h>

View file

@ -244,7 +244,6 @@ sources = [
'game/phase/phase_demo.c',
'game/phase/phase_game.c',
'game/phase/phase_inventory.c',
'game/phase/phase_pause.c',
'game/phase/phase_photo_mode.c',
'game/phase/phase_stats.c',
'game/requester.c',

View file

@ -50,6 +50,10 @@ static GAME_FLOW_COMMAND M_Control(const bool demo_mode)
Shell_ProcessInput();
Game_ProcessInput();
if (g_InputDB.pause) {
return GF_PauseGame();
}
if (demo_mode) {
if (g_InputDB.menu_confirm || g_InputDB.menu_back) {
return GF_TranslateScriptCommand(g_GameFlow.on_demo_interrupt);

View file

@ -667,6 +667,14 @@ GAME_FLOW_COMMAND GF_StartGame(
return gf_cmd;
}
GAME_FLOW_COMMAND GF_PauseGame(void)
{
PHASE *const subphase = Phase_Pause_Create();
const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(subphase);
Phase_Pause_Destroy(subphase);
return gf_cmd;
}
GAME_FLOW_COMMAND GF_ShowInventory(const INVENTORY_MODE mode)
{
PHASE *const phase = Phase_Inventory_Create(mode);

View file

@ -17,6 +17,7 @@ void GF_ModifyInventory(int32_t level, int32_t type);
GAME_FLOW_COMMAND GF_StartDemo(int32_t level_num);
GAME_FLOW_COMMAND GF_StartGame(
int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type);
GAME_FLOW_COMMAND GF_PauseGame(void);
GAME_FLOW_COMMAND GF_ShowInventory(INVENTORY_MODE mode);
GAME_FLOW_COMMAND GF_ShowInventoryKeys(GAME_OBJECT_ID receptacle_type_id);

View file

@ -81,6 +81,8 @@ static void M_UpdateFromBackend(
s->save |= backend->is_pressed(layout, INPUT_ROLE_SAVE);
s->load |= backend->is_pressed(layout, INPUT_ROLE_LOAD);
s->pause |= backend->is_pressed(layout, INPUT_ROLE_PAUSE);
s->item_cheat |= backend->is_pressed(layout, INPUT_ROLE_ITEM_CHEAT);
s->fly_cheat |= backend->is_pressed(layout, INPUT_ROLE_FLY_CHEAT);
s->level_skip_cheat |= backend->is_pressed(layout, INPUT_ROLE_LEVEL_SKIP_CHEAT);
@ -191,6 +193,7 @@ const char *Input_GetRoleName(const INPUT_ROLE role)
case INPUT_ROLE_LEVEL_SKIP_CHEAT: return GS(KEYMAP_LEVEL_SKIP_CHEAT);
case INPUT_ROLE_TURBO_CHEAT: return GS(KEYMAP_TURBO_CHEAT);
case INPUT_ROLE_ENTER_CONSOLE: return GS(KEYMAP_ENTER_CONSOLE);
case INPUT_ROLE_PAUSE: return GS(KEYMAP_PAUSE);
default: return "";
}
// clang-format on

View file

@ -5,6 +5,7 @@
#include "game/console/common.h"
#include "game/effects.h"
#include "game/game.h"
#include "game/gameflow.h"
#include "game/input.h"
#include "game/items.h"
#include "game/lara/hair.h"
@ -120,13 +121,21 @@ static PHASE_CONTROL M_Control(PHASE *const phase, const int32_t num_frames)
M_FixAudioDrift();
Input_Update();
Shell_ProcessInput();
if (g_InputDB.menu_confirm || g_InputDB.menu_back) {
return (PHASE_CONTROL) {
.action = PHASE_ACTION_END,
.gf_cmd = { .action = GF_NOOP },
};
} else if (g_InputDB.pause) {
const GAME_FLOW_COMMAND gf_cmd = GF_PauseGame();
if (gf_cmd.action != GF_NOOP) {
return (PHASE_CONTROL) {
.action = PHASE_ACTION_END,
.gf_cmd = { .action = GF_NOOP },
};
}
}
Shell_ProcessInput();
g_DynamicLightCount = 0;
@ -157,7 +166,6 @@ static void M_Draw(PHASE *const phase)
Room_DrawAllRooms(g_Camera.pos.room_num);
Output_DrawPolyList();
Console_Draw();
Text_Draw();
Output_DrawPolyList();
Fader_Draw(&p->exit_fader);
}

View file

@ -19,6 +19,7 @@ static const INPUT_ROLE m_LeftRoles[] = {
INPUT_ROLE_STEP_R,
INPUT_ROLE_SLOW,
INPUT_ROLE_ENTER_CONSOLE,
INPUT_ROLE_PAUSE,
(INPUT_ROLE)-1,
// clang-format on
};