mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 12:47:58 +03:00
parent
53101ab9a5
commit
8bab311d79
15 changed files with 198 additions and 12 deletions
|
@ -4,6 +4,7 @@
|
|||
- added `/nextlevel` alias to `/endlevel` console command
|
||||
- added `/quit` alias to `/exit` console command
|
||||
- added an option to toggle the in-game UI, such as healthbars and ammo text (#1656)
|
||||
- added the ability to cycle through console prompt history (#1571)
|
||||
- changed the easter egg console command to pack more punch
|
||||
- changed `/set` console command to do fuzzy matching (LostArtefacts/libtrx#38)
|
||||
- fixed console caret position off by a couple of pixels (regression from 3.0)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
- added `/sfx` command
|
||||
- added `/nextlevel` alias to `/endlevel` console command
|
||||
- added `/quit` alias to `/exit` console command
|
||||
- added the ability to cycle through console prompt history (#1571)
|
||||
- changed `/set` console command to do fuzzy matching (LostArtefacts/libtrx#38)
|
||||
- fixed crash in the `/set` console command (regression from 0.3)
|
||||
- fixed using console in cutscenes immediately exiting the game (regression from 0.3)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "config/file.h"
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "game/console/history.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "game/console/common.h"
|
||||
|
||||
#include "./internal.h"
|
||||
#include "game/console/extern.h"
|
||||
#include "game/game_string.h"
|
||||
#include "game/ui/widgets/console.h"
|
||||
|
@ -18,6 +19,7 @@ static UI_WIDGET *m_Console;
|
|||
void Console_Init(void)
|
||||
{
|
||||
m_Console = UI_Console_Create();
|
||||
Console_History_Init();
|
||||
}
|
||||
|
||||
void Console_Shutdown(void)
|
||||
|
@ -27,6 +29,8 @@ void Console_Shutdown(void)
|
|||
m_Console = NULL;
|
||||
}
|
||||
|
||||
Console_History_Shutdown();
|
||||
|
||||
m_IsOpened = false;
|
||||
}
|
||||
|
||||
|
|
91
src/libtrx/game/console/history.c
Normal file
91
src/libtrx/game/console/history.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include "game/console/history.h"
|
||||
|
||||
#include "config/file.h"
|
||||
#include "memory.h"
|
||||
#include "utils.h"
|
||||
#include "vector.h"
|
||||
|
||||
#define MAX_HISTORY_ENTRIES 30
|
||||
|
||||
VECTOR *m_History = NULL;
|
||||
static const char *m_Path = "cfg/" PROJECT_NAME "_console_history.json5";
|
||||
|
||||
void M_LoadFromJSON(JSON_OBJECT *const root_obj)
|
||||
{
|
||||
JSON_ARRAY *const arr = JSON_ObjectGetArray(root_obj, "entries");
|
||||
if (arr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Console_History_Clear();
|
||||
for (size_t i = 0; i < arr->length; i++) {
|
||||
const char *const line = JSON_ArrayGetString(arr, i, NULL);
|
||||
if (line != NULL) {
|
||||
Console_History_Append(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void M_DumpToJSON(JSON_OBJECT *const root_obj)
|
||||
{
|
||||
JSON_ARRAY *const arr = JSON_ArrayNew();
|
||||
|
||||
bool has_elements = false;
|
||||
for (int32_t i = 0; i < Console_History_GetLength(); i++) {
|
||||
JSON_ArrayAppendString(arr, Console_History_Get(i));
|
||||
has_elements = true;
|
||||
}
|
||||
|
||||
if (has_elements) {
|
||||
JSON_ObjectAppendArray(root_obj, "entries", arr);
|
||||
} else {
|
||||
JSON_ArrayFree(arr);
|
||||
}
|
||||
}
|
||||
|
||||
void Console_History_Init(void)
|
||||
{
|
||||
m_History = Vector_Create(sizeof(char *));
|
||||
ConfigFile_Read(m_Path, &M_LoadFromJSON);
|
||||
}
|
||||
|
||||
void Console_History_Shutdown(void)
|
||||
{
|
||||
if (m_History != NULL) {
|
||||
ConfigFile_Write(m_Path, &M_DumpToJSON);
|
||||
for (int32_t i = m_History->count - 1; i >= 0; i--) {
|
||||
char *const prompt = *(char **)Vector_Get(m_History, i);
|
||||
Memory_Free(prompt);
|
||||
}
|
||||
Vector_Free(m_History);
|
||||
m_History = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Console_History_GetLength(void)
|
||||
{
|
||||
return m_History->count;
|
||||
}
|
||||
|
||||
void Console_History_Clear(void)
|
||||
{
|
||||
Vector_Clear(m_History);
|
||||
}
|
||||
|
||||
void Console_History_Append(const char *const prompt)
|
||||
{
|
||||
if (m_History->count == MAX_HISTORY_ENTRIES) {
|
||||
Vector_RemoveAt(m_History, 0);
|
||||
}
|
||||
char *prompt_copy = Memory_DupStr(prompt);
|
||||
Vector_Add(m_History, &prompt_copy);
|
||||
}
|
||||
|
||||
const char *Console_History_Get(const int32_t idx)
|
||||
{
|
||||
if (idx < 0 || idx >= m_History->count) {
|
||||
return NULL;
|
||||
}
|
||||
const char *const prompt = *(char **)Vector_Get(m_History, idx);
|
||||
return prompt;
|
||||
}
|
4
src/libtrx/game/console/internal.h
Normal file
4
src/libtrx/game/console/internal.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
void Console_History_Init(void);
|
||||
void Console_History_Shutdown(void);
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "game/clock.h"
|
||||
#include "game/console/common.h"
|
||||
#include "game/console/history.h"
|
||||
#include "game/text.h"
|
||||
#include "game/ui/common.h"
|
||||
#include "game/ui/events.h"
|
||||
|
@ -16,8 +17,9 @@
|
|||
#include <string.h>
|
||||
|
||||
#define WINDOW_MARGIN 5
|
||||
#define LOG_MARGIN 10
|
||||
#define MAX_LOG_LINES 20
|
||||
#define MAX_LISTENERS 4
|
||||
#define LOG_MARGIN 10
|
||||
#define LOG_SCALE 0.8
|
||||
#define DELAY_PER_CHAR 0.2
|
||||
|
||||
|
@ -28,17 +30,17 @@ typedef struct {
|
|||
UI_WIDGET *spacer;
|
||||
char *log_lines;
|
||||
int32_t logs_on_screen;
|
||||
int32_t history_idx;
|
||||
|
||||
int32_t listener1;
|
||||
int32_t listener2;
|
||||
int32_t listener3;
|
||||
|
||||
int32_t listeners[MAX_LISTENERS];
|
||||
struct {
|
||||
double expire_at;
|
||||
UI_WIDGET *label;
|
||||
} logs[MAX_LOG_LINES];
|
||||
} UI_CONSOLE;
|
||||
|
||||
static void M_MoveHistoryUp(UI_CONSOLE *self);
|
||||
static void M_MoveHistoryDown(UI_CONSOLE *self);
|
||||
static void M_HandlePromptCancel(const EVENT *event, void *data);
|
||||
static void M_HandlePromptConfirm(const EVENT *event, void *data);
|
||||
static void M_HandleCanvasResize(const EVENT *event, void *data);
|
||||
|
@ -51,6 +53,30 @@ static void M_Control(UI_CONSOLE *self);
|
|||
static void M_Draw(UI_CONSOLE *self);
|
||||
static void M_Free(UI_CONSOLE *self);
|
||||
|
||||
static void M_MoveHistoryUp(UI_CONSOLE *const self)
|
||||
{
|
||||
self->history_idx--;
|
||||
CLAMP(self->history_idx, 0, Console_History_GetLength());
|
||||
const char *const new_prompt = Console_History_Get(self->history_idx);
|
||||
if (new_prompt == NULL) {
|
||||
UI_Prompt_ChangeText(self->prompt, "");
|
||||
} else {
|
||||
UI_Prompt_ChangeText(self->prompt, new_prompt);
|
||||
}
|
||||
}
|
||||
|
||||
static void M_MoveHistoryDown(UI_CONSOLE *const self)
|
||||
{
|
||||
self->history_idx++;
|
||||
CLAMP(self->history_idx, 0, Console_History_GetLength());
|
||||
const char *const new_prompt = Console_History_Get(self->history_idx);
|
||||
if (new_prompt == NULL) {
|
||||
UI_Prompt_ChangeText(self->prompt, "");
|
||||
} else {
|
||||
UI_Prompt_ChangeText(self->prompt, new_prompt);
|
||||
}
|
||||
}
|
||||
|
||||
static void M_HandlePromptCancel(const EVENT *const event, void *const data)
|
||||
{
|
||||
Console_Close();
|
||||
|
@ -58,9 +84,13 @@ static void M_HandlePromptCancel(const EVENT *const event, void *const data)
|
|||
|
||||
static void M_HandlePromptConfirm(const EVENT *const event, void *const data)
|
||||
{
|
||||
UI_CONSOLE *const self = (UI_CONSOLE *)data;
|
||||
const char *text = event->data;
|
||||
Console_History_Append(text);
|
||||
Console_Eval(text);
|
||||
Console_Close();
|
||||
|
||||
self->history_idx = Console_History_GetLength();
|
||||
}
|
||||
|
||||
static void M_HandleCanvasResize(const EVENT *event, void *data)
|
||||
|
@ -69,6 +99,24 @@ static void M_HandleCanvasResize(const EVENT *event, void *data)
|
|||
UI_Stack_SetSize(self->container, M_GetWidth(self), M_GetHeight(self));
|
||||
}
|
||||
|
||||
static void M_HandleKeyDown(const EVENT *const event, void *const user_data)
|
||||
{
|
||||
if (!Console_IsOpened()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UI_CONSOLE *const self = user_data;
|
||||
const UI_INPUT key = (UI_INPUT)(uintptr_t)event->data;
|
||||
|
||||
// clang-format off
|
||||
switch (key) {
|
||||
case UI_KEY_UP: M_MoveHistoryUp(self); break;
|
||||
case UI_KEY_DOWN: M_MoveHistoryDown(self); break;
|
||||
default: break;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
static void M_UpdateLogCount(UI_CONSOLE *const self)
|
||||
{
|
||||
self->logs_on_screen = 0;
|
||||
|
@ -114,9 +162,9 @@ static void M_Free(UI_CONSOLE *const self)
|
|||
self->spacer->free(self->spacer);
|
||||
self->prompt->free(self->prompt);
|
||||
self->container->free(self->container);
|
||||
UI_Events_Unsubscribe(self->listener1);
|
||||
UI_Events_Unsubscribe(self->listener2);
|
||||
UI_Events_Unsubscribe(self->listener3);
|
||||
for (int32_t i = 0; i < MAX_LISTENERS; i++) {
|
||||
UI_Events_Unsubscribe(self->listeners[i]);
|
||||
}
|
||||
Memory_Free(self);
|
||||
}
|
||||
|
||||
|
@ -151,12 +199,15 @@ UI_WIDGET *UI_Console_Create(void)
|
|||
|
||||
M_SetPosition(self, WINDOW_MARGIN, WINDOW_MARGIN);
|
||||
|
||||
self->listener1 = UI_Events_Subscribe(
|
||||
"confirm", self->prompt, M_HandlePromptConfirm, NULL);
|
||||
self->listener2 =
|
||||
int32_t i = 0;
|
||||
self->listeners[i++] = UI_Events_Subscribe(
|
||||
"confirm", self->prompt, M_HandlePromptConfirm, self);
|
||||
self->listeners[i++] =
|
||||
UI_Events_Subscribe("cancel", self->prompt, M_HandlePromptCancel, NULL);
|
||||
self->listener3 =
|
||||
self->listeners[i++] =
|
||||
UI_Events_Subscribe("canvas_resize", NULL, M_HandleCanvasResize, self);
|
||||
self->listeners[i++] =
|
||||
UI_Events_Subscribe("key_down", NULL, M_HandleKeyDown, self);
|
||||
|
||||
return (UI_WIDGET *)self;
|
||||
}
|
||||
|
@ -165,6 +216,7 @@ void UI_Console_HandleOpen(UI_WIDGET *const widget)
|
|||
{
|
||||
UI_CONSOLE *const self = (UI_CONSOLE *)widget;
|
||||
UI_Prompt_SetFocus(self->prompt, true);
|
||||
self->history_idx = Console_History_GetLength();
|
||||
}
|
||||
|
||||
void UI_Console_HandleClose(UI_WIDGET *const widget)
|
||||
|
|
|
@ -213,6 +213,7 @@ static void M_HandleKeyDown(const EVENT *const event, void *const user_data)
|
|||
case UI_KEY_BACK: M_DeleteCharBack(self); break;
|
||||
case UI_KEY_RETURN: M_Confirm(self); break;
|
||||
case UI_KEY_ESCAPE: M_Cancel(self); break;
|
||||
default: break;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
@ -305,3 +306,12 @@ void UI_Prompt_Clear(UI_WIDGET *const widget)
|
|||
UI_PROMPT *const self = (UI_PROMPT *)widget;
|
||||
M_Clear(self);
|
||||
}
|
||||
|
||||
void UI_Prompt_ChangeText(UI_WIDGET *widget, const char *new_text)
|
||||
{
|
||||
UI_PROMPT *const self = (UI_PROMPT *)widget;
|
||||
Memory_FreePointer(&self->current_text);
|
||||
self->current_text = Memory_DupStr(new_text);
|
||||
self->caret_pos = strlen(new_text);
|
||||
M_UpdateCaretLabel(self);
|
||||
}
|
||||
|
|
8
src/libtrx/include/libtrx/game/console/history.h
Normal file
8
src/libtrx/include/libtrx/game/console/history.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t Console_History_GetLength(void);
|
||||
void Console_History_Clear(void);
|
||||
void Console_History_Append(const char *prompt);
|
||||
const char *Console_History_Get(int32_t idx);
|
|
@ -3,6 +3,8 @@
|
|||
#include "./events.h"
|
||||
|
||||
typedef enum {
|
||||
UI_KEY_UP,
|
||||
UI_KEY_DOWN,
|
||||
UI_KEY_LEFT,
|
||||
UI_KEY_RIGHT,
|
||||
UI_KEY_HOME,
|
||||
|
|
|
@ -7,6 +7,7 @@ void UI_Prompt_SetSize(UI_WIDGET *widget, int32_t width, int32_t height);
|
|||
|
||||
void UI_Prompt_SetFocus(UI_WIDGET *widget, bool is_focused);
|
||||
void UI_Prompt_Clear(UI_WIDGET *widget);
|
||||
void UI_Prompt_ChangeText(UI_WIDGET *widget, const char *new_text);
|
||||
|
||||
extern const char *UI_Prompt_GetPromptChar(void);
|
||||
extern int32_t UI_Prompt_GetCaretFlashRate(void);
|
||||
|
|
|
@ -36,3 +36,9 @@
|
|||
|
||||
#define MKTAG(a, b, c, d) \
|
||||
((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24))
|
||||
|
||||
#if TR_VERSION == 1
|
||||
#define PROJECT_NAME "TR1X"
|
||||
#elif TR_VERSION == 2
|
||||
#define PROJECT_NAME "TR2X"
|
||||
#endif
|
||||
|
|
|
@ -88,6 +88,7 @@ sources = [
|
|||
'game/console/cmd/sfx.c',
|
||||
'game/console/cmd/teleport.c',
|
||||
'game/console/common.c',
|
||||
'game/console/history.c',
|
||||
'game/game_string.c',
|
||||
'game/items.c',
|
||||
'game/objects/names.c',
|
||||
|
|
|
@ -18,6 +18,8 @@ UI_INPUT UI_TranslateInput(uint32_t system_keycode)
|
|||
{
|
||||
// clang-format off
|
||||
switch (system_keycode) {
|
||||
case SDLK_UP: return UI_KEY_UP;
|
||||
case SDLK_DOWN: return UI_KEY_DOWN;
|
||||
case SDLK_LEFT: return UI_KEY_LEFT;
|
||||
case SDLK_RIGHT: return UI_KEY_RIGHT;
|
||||
case SDLK_HOME: return UI_KEY_HOME;
|
||||
|
|
|
@ -16,6 +16,8 @@ UI_INPUT UI_TranslateInput(uint32_t system_keycode)
|
|||
{
|
||||
// clang-format off
|
||||
switch (system_keycode) {
|
||||
case VK_UP: return UI_KEY_UP;
|
||||
case VK_DOWN: return UI_KEY_DOWN;
|
||||
case VK_LEFT: return UI_KEY_LEFT;
|
||||
case VK_RIGHT: return UI_KEY_RIGHT;
|
||||
case VK_HOME: return UI_KEY_HOME;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue