ui2: port photo mode widget
Some checks are pending
Run code linters / Run code linters (push) Waiting to run

This commit is contained in:
Marcin Kurczewski 2025-04-14 12:19:03 +02:00
parent 740d88f1d3
commit c8dabe4414
No known key found for this signature in database
GPG key ID: CC65E6FD28CAE42A
9 changed files with 122 additions and 244 deletions

View file

@ -12,8 +12,7 @@
#include "game/overlay.h"
#include "game/shell.h"
#include "game/sound.h"
#include "game/ui/common.h"
#include "game/ui/widgets/photo_mode.h"
#include "game/ui2.h"
#include "memory.h"
typedef struct {
@ -40,7 +39,6 @@ static PHASE_CONTROL M_Start(PHASE *const phase)
Music_Pause();
Sound_PauseAll();
p->ui = UI_PhotoMode_Create();
if (!g_Config.ui.enable_photo_mode_ui) {
Console_Log(
GS(OSD_PHOTO_MODE_LAUNCHED),
@ -56,9 +54,6 @@ static void M_End(PHASE *const phase)
M_PRIV *const p = phase->priv;
Camera_ExitPhotoMode();
p->ui->free(p->ui);
p->ui = nullptr;
#if TR_VERSION == 1
g_Config.rendering.enable_fps_counter = p->show_fps_counter;
#endif
@ -92,7 +87,6 @@ static PHASE_CONTROL M_Control(PHASE *const phase, int32_t num_frames)
Output_EndScene();
Sound_Effect(SFX_MENU_LARA_HOME, nullptr, SPM_ALWAYS);
} else {
p->ui->control(p->ui);
Camera_Update();
}
@ -106,7 +100,7 @@ static void M_Draw(PHASE *const phase)
Output_DrawPolyList();
if (!p->taking_screenshot) {
p->ui->draw(p->ui);
UI2_PhotoMode();
}
Output_DrawPolyList();
}

View file

@ -1,221 +0,0 @@
#include "game/ui/widgets/photo_mode.h"
#include "config.h"
#include "game/game_string.h"
#include "game/input.h"
#include "game/text.h"
#include "game/ui/common.h"
#include "game/ui/widgets/label.h"
#include "game/ui/widgets/spacer.h"
#include "game/ui/widgets/stack.h"
#include "game/ui/widgets/window.h"
#include "memory.h"
#include <stdio.h>
#define TITLE_MARGIN 5
#define WINDOW_MARGIN 10
#define DIALOG_PADDING 5
typedef struct {
UI_WIDGET_VTABLE vtable;
UI_WIDGET *window;
UI_WIDGET *title;
UI_WIDGET *outer_stack;
UI_WIDGET *inner_stack;
UI_WIDGET *left_stack;
UI_WIDGET *right_stack;
UI_WIDGET *spacer;
bool shown;
int32_t label_count;
UI_WIDGET **left_labels;
UI_WIDGET **right_labels;
} UI_PHOTO_MODE;
static int32_t M_GetWidth(const UI_PHOTO_MODE *self);
static int32_t M_GetHeight(const UI_PHOTO_MODE *self);
static void M_SetPosition(UI_PHOTO_MODE *self, int32_t x, int32_t y);
static void M_Control(UI_PHOTO_MODE *self);
static void M_Draw(UI_PHOTO_MODE *self);
static void M_Free(UI_PHOTO_MODE *self);
static int32_t M_GetWidth(const UI_PHOTO_MODE *const self)
{
return UI_GetCanvasWidth() - 2 * WINDOW_MARGIN;
}
static int32_t M_GetHeight(const UI_PHOTO_MODE *const self)
{
return UI_GetCanvasHeight() - 2 * WINDOW_MARGIN;
}
static void M_SetPosition(UI_PHOTO_MODE *const self, int32_t x, int32_t y)
{
self->window->set_position(self->window, x, y);
}
static void M_Control(UI_PHOTO_MODE *const self)
{
if (self->window->control != nullptr) {
self->window->control(self->window);
}
self->shown = g_Config.ui.enable_photo_mode_ui;
}
static void M_Draw(UI_PHOTO_MODE *const self)
{
if (self->shown && self->window->draw != nullptr) {
self->window->draw(self->window);
}
}
static void M_Free(UI_PHOTO_MODE *const self)
{
for (int32_t i = 0; i < self->label_count; i++) {
self->left_labels[i]->free(self->left_labels[i]);
self->right_labels[i]->free(self->right_labels[i]);
}
self->spacer->free(self->spacer);
self->title->free(self->title);
self->outer_stack->free(self->outer_stack);
self->inner_stack->free(self->inner_stack);
self->left_stack->free(self->left_stack);
self->right_stack->free(self->right_stack);
self->window->free(self->window);
Memory_Free(self->left_labels);
Memory_Free(self->right_labels);
Memory_Free(self);
}
UI_WIDGET *UI_PhotoMode_Create(void)
{
UI_PHOTO_MODE *const self = Memory_Alloc(sizeof(UI_PHOTO_MODE));
self->vtable = (UI_WIDGET_VTABLE) {
.control = (UI_WIDGET_CONTROL)M_Control,
.draw = (UI_WIDGET_DRAW)M_Draw,
.get_width = (UI_WIDGET_GET_WIDTH)M_GetWidth,
.get_height = (UI_WIDGET_GET_HEIGHT)M_GetHeight,
.set_position = (UI_WIDGET_SET_POSITION)M_SetPosition,
.free = (UI_WIDGET_FREE)M_Free,
};
self->outer_stack = UI_Stack_Create(
UI_STACK_LAYOUT_VERTICAL, UI_STACK_AUTO_SIZE, UI_STACK_AUTO_SIZE);
self->inner_stack = UI_Stack_Create(
UI_STACK_LAYOUT_HORIZONTAL, UI_STACK_AUTO_SIZE, UI_STACK_AUTO_SIZE);
self->left_stack = UI_Stack_Create(
UI_STACK_LAYOUT_VERTICAL, UI_STACK_AUTO_SIZE, UI_STACK_AUTO_SIZE);
self->right_stack = UI_Stack_Create(
UI_STACK_LAYOUT_VERTICAL, UI_STACK_AUTO_SIZE, UI_STACK_AUTO_SIZE);
const char *const title = GS(PHOTO_MODE_TITLE);
self->title = UI_Label_Create(title, UI_LABEL_AUTO_SIZE, TEXT_HEIGHT_FIXED);
UI_Stack_AddChild(self->outer_stack, self->title);
self->spacer = UI_Spacer_Create(TITLE_MARGIN, TITLE_MARGIN);
UI_Stack_AddChild(self->outer_stack, self->spacer);
UI_Stack_AddChild(self->outer_stack, self->inner_stack);
UI_Stack_AddChild(self->inner_stack, self->left_stack);
UI_Stack_AddChild(self->inner_stack, self->right_stack);
char move_role[50];
sprintf(
move_role, "%s%s%s%s%s%s: ",
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_UP),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_DOWN),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_FORWARD),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_BACK),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_LEFT),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_RIGHT));
const char *const rot_role =
"\\{button left} \\{button up} "
"\\{button down} \\{button right} : ";
char z_roll_role[100];
sprintf(z_roll_role, "%s: ", GS(PHOTO_MODE_ROLL_ROLE));
char roll_role[100];
sprintf(roll_role, "%s: ", GS(KEYMAP_ROLL));
char fov_role[100];
sprintf(fov_role, "%s: ", GS(PHOTO_MODE_FOV_ROLE));
char reset_role[100];
sprintf(reset_role, "%s: ", GS(KEYMAP_LOOK));
char help_role[20];
sprintf(
help_role, "%s: ",
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_TOGGLE_UI));
char action_role[100];
sprintf(action_role, "%s: ", GS(KEYMAP_ACTION));
char exit_role[100];
sprintf(
exit_role, "%s/%s: ",
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_TOGGLE_PHOTO_MODE),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_OPTION));
const char *const inputs[] = {
move_role, rot_role, z_roll_role, roll_role, fov_role,
reset_role, help_role, action_role, exit_role, nullptr,
};
const char *const roles[] = {
GS(PHOTO_MODE_MOVE_PROMPT),
GS(PHOTO_MODE_ROTATE_PROMPT),
GS(PHOTO_MODE_ROLL_PROMPT),
GS(PHOTO_MODE_ROTATE90_PROMPT),
GS(PHOTO_MODE_FOV_PROMPT),
GS(PHOTO_MODE_RESET_PROMPT),
GS(MISC_TOGGLE_HELP),
GS(PHOTO_MODE_SNAP_PROMPT),
GS(MISC_EXIT),
nullptr,
};
self->shown = true;
self->label_count = 0;
while (inputs[self->label_count] != nullptr) {
self->label_count++;
}
self->left_labels = Memory_Alloc(sizeof(UI_WIDGET *) * self->label_count);
self->right_labels = Memory_Alloc(sizeof(UI_WIDGET *) * self->label_count);
for (int32_t i = 0; i < self->label_count; i++) {
self->left_labels[i] =
UI_Label_Create(inputs[i], UI_LABEL_AUTO_SIZE, TEXT_HEIGHT_FIXED);
UI_Stack_AddChild(self->left_stack, self->left_labels[i]);
self->right_labels[i] =
UI_Label_Create(roles[i], UI_LABEL_AUTO_SIZE, TEXT_HEIGHT_FIXED);
UI_Stack_AddChild(self->right_stack, self->right_labels[i]);
}
self->window = UI_Window_Create(
self->outer_stack, DIALOG_PADDING, DIALOG_PADDING, DIALOG_PADDING * 2,
DIALOG_PADDING);
M_SetPosition(self, WINDOW_MARGIN, WINDOW_MARGIN);
return (UI_WIDGET *)self;
}

View file

@ -55,11 +55,3 @@ UI_WIDGET *UI_Spacer_Create(const int32_t width, const int32_t height)
self->height = height;
return (UI_WIDGET *)self;
}
void UI_Spacer_SetSize(
UI_WIDGET *const widget, const int32_t width, const int32_t height)
{
UI_SPACER *const self = (UI_SPACER *)widget;
self->width = width;
self->height = height;
}

View file

@ -0,0 +1,111 @@
#include "game/ui2/widgets/photo_mode.h"
#include "config.h"
#include "game/game_string.h"
#include "game/input.h"
#include "game/ui2/widgets/anchor.h"
#include "game/ui2/widgets/frame.h"
#include "game/ui2/widgets/label.h"
#include "game/ui2/widgets/pad.h"
#include "game/ui2/widgets/spacer.h"
#include "game/ui2/widgets/stack.h"
#include <stdio.h>
void UI2_PhotoMode(void)
{
char tmp[50];
UI2_BeginAnchor(0.0f, 0.0f);
UI2_BeginPad(8.0f, 10.0f);
UI2_BeginFrame();
UI2_BeginPad(8.0, 6.0);
UI2_BeginStackEx((UI2_STACK_SETTINGS) {
.orientation = UI2_STACK_VERTICAL,
.spacing = { .v = 8.0f },
});
UI2_Label(GS(PHOTO_MODE_TITLE));
UI2_BeginStack(UI2_STACK_HORIZONTAL);
// Inputs column
UI2_BeginStackEx((UI2_STACK_SETTINGS) {
.orientation = UI2_STACK_VERTICAL,
.spacing = { .v = 0 },
});
sprintf(
tmp, "%s%s%s%s%s%s: ",
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_UP),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_DOWN),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_FORWARD),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_BACK),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_LEFT),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_CAMERA_RIGHT));
UI2_Label(tmp);
UI2_Label(
"\\{button left} \\{button up} "
"\\{button down} \\{button right} : ");
sprintf(tmp, "%s: ", GS(PHOTO_MODE_ROLL_ROLE));
UI2_Label(tmp);
sprintf(tmp, "%s: ", GS(KEYMAP_ROLL));
UI2_Label(tmp);
sprintf(tmp, "%s: ", GS(PHOTO_MODE_FOV_ROLE));
UI2_Label(tmp);
sprintf(tmp, "%s: ", GS(KEYMAP_LOOK));
UI2_Label(tmp);
sprintf(
tmp, "%s: ",
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_TOGGLE_UI));
UI2_Label(tmp);
sprintf(tmp, "%s: ", GS(KEYMAP_ACTION));
UI2_Label(tmp);
sprintf(
tmp, "%s/%s: ",
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_TOGGLE_PHOTO_MODE),
Input_GetKeyName(
INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout,
INPUT_ROLE_OPTION));
UI2_Label(tmp);
UI2_EndStack();
// Behaviors column
UI2_BeginStackEx((UI2_STACK_SETTINGS) {
.orientation = UI2_STACK_VERTICAL,
.spacing = { .v = 0 },
});
UI2_Label(GS(PHOTO_MODE_MOVE_PROMPT));
UI2_Label(GS(PHOTO_MODE_ROTATE_PROMPT));
UI2_Label(GS(PHOTO_MODE_ROLL_PROMPT));
UI2_Label(GS(PHOTO_MODE_ROTATE90_PROMPT));
UI2_Label(GS(PHOTO_MODE_FOV_PROMPT));
UI2_Label(GS(PHOTO_MODE_RESET_PROMPT));
UI2_Label(GS(MISC_TOGGLE_HELP));
UI2_Label(GS(PHOTO_MODE_SNAP_PROMPT));
UI2_Label(GS(MISC_EXIT));
UI2_EndStack();
UI2_EndStack();
UI2_EndStack();
UI2_EndPad();
UI2_EndFrame();
UI2_EndPad();
UI2_EndAnchor();
}

View file

@ -1,5 +0,0 @@
#pragma once
#include "./base.h"
UI_WIDGET *UI_PhotoMode_Create(void);

View file

@ -3,4 +3,3 @@
#include "./base.h"
UI_WIDGET *UI_Spacer_Create(int32_t width, int32_t height);
void UI_Spacer_SetSize(UI_WIDGET *widget, int32_t width, int32_t height);

View file

@ -9,5 +9,6 @@
#include "./ui2/widgets/frame.h"
#include "./ui2/widgets/label.h"
#include "./ui2/widgets/pad.h"
#include "./ui2/widgets/photo_mode.h"
#include "./ui2/widgets/spacer.h"
#include "./ui2/widgets/stack.h"

View file

@ -0,0 +1,7 @@
#pragma once
#include "../common.h"
// A photo mode tutorial dialog.
void UI2_PhotoMode(void);

View file

@ -199,7 +199,6 @@ sources = [
'game/ui/events.c',
'game/ui/widgets/frame.c',
'game/ui/widgets/label.c',
'game/ui/widgets/photo_mode.c',
'game/ui/widgets/requester.c',
'game/ui/widgets/spacer.c',
'game/ui/widgets/stack.c',
@ -214,6 +213,7 @@ sources = [
'game/ui2/widgets/frame.c',
'game/ui2/widgets/label.c',
'game/ui2/widgets/pad.c',
'game/ui2/widgets/photo_mode.c',
'game/ui2/widgets/prompt.c',
'game/ui2/widgets/spacer.c',
'game/ui2/widgets/stack.c',