feat(console): limited console implementation

This commit is contained in:
superp00t 2023-08-16 16:37:38 -04:00
parent 9c3bc2203d
commit 384e52c7d1
31 changed files with 1370 additions and 47 deletions

View File

@ -1,5 +1,6 @@
file(GLOB PRIVATE_SOURCES
"*.cpp"
"command/*/*.cpp"
)
add_library(console STATIC

View File

@ -68,8 +68,7 @@ CVar* CVar::Register(const char* name, const char* help, uint32_t flags, const c
var->m_flags |= 0x80;
}
// TODO
// ConsoleCommandRegister(var->m_key.GetString(), &CvarCommandHandler, category, help);
ConsoleCommandRegister(name, CvarCommandHandler, CATEGORY(category), help);
}
return var;
@ -161,3 +160,49 @@ int32_t CVar::Update() {
return 1;
}
int32_t CvarCommandHandler(const char* command, const char* arguments) {
auto cvar = CVar::Lookup(command);
STORM_ASSERT(cvar);
while (*arguments == ' ') {
arguments++;
}
if (arguments[0] != '\0') {
cvar->Set(arguments, true, true, false, false);
return 1;
}
auto value = cvar->m_stringValue.GetString();
ConsoleWriteA("CVar \"%s\" is \"%s\"", DEFAULT_COLOR, command, value ? value : "");
return 1;
}
int32_t CvarListCommandHandler(const char* command, const char* arguments) {
char text[256];
char text2[256];
for (auto i = CVar::s_registeredCVars.Head(); i != nullptr; i = CVar::s_registeredCVars.Next(i)) {
SStrPrintf(text, sizeof(text), " \"%s\" is \"%s\"", i->m_key.m_str, i->m_stringValue);
if (i->m_defaultValue.GetString()) {
if (SStrCmp(i->m_stringValue.GetString(), i->m_defaultValue.GetString(), STORM_MAX_STR)) {
SStrPrintf(text2, sizeof(text2), " (default \"%s\")", i->m_defaultValue);
SStrPack(text, text2, sizeof(text));
}
}
if (i->m_resetValue.GetString()) {
if (SStrCmp(i->m_stringValue.GetString(), i->m_resetValue.GetString(), STORM_MAX_STR)) {
SStrPrintf(text2, sizeof(text2), " (reset \"%s\")", i->m_resetValue);
SStrPack(text, text2, sizeof(text));
}
}
ConsoleWrite(text, DEFAULT_COLOR);
}
return 1;
}

View File

@ -38,4 +38,8 @@ class CVar : public TSHashObject<CVar, HASHKEY_STRI> {
int32_t Update();
};
int32_t CvarCommandHandler(const char* command, const char* arguments);
int32_t CvarListCommandHandler(const char* command, const char* arguments);
#endif

View File

@ -1,7 +1,10 @@
#include "console/Client.hpp"
#include "console/Command.hpp"
void ConsoleInitializeClientCommand() {
// TODO
ConsoleCommandInitialize();
ConsoleInitializeCommonCommand();
ConsoleInitializeDebugCommand();
}
void ConsoleInitializeClientCVar(const char* a1) {

View File

@ -1,5 +1,11 @@
#include "console/Command.hpp"
#include "console/Line.hpp"
#include <storm/Error.hpp>
#include <storm/Unicode.hpp>
#include <cctype>
#include <algorithm>
int32_t ValidateFileName(const char* filename) {
if (SStrStr(filename, "..") || SStrStr(filename, "\\")) {
@ -22,6 +28,47 @@ int32_t ValidateFileName(const char* filename) {
TSHashTable<CONSOLECOMMAND, HASHKEY_STRI> g_consoleCommandHash;
char g_commandHistory[HISTORY_DEPTH][CMD_BUFFER_SIZE];
uint32_t g_commandHistoryIndex;
char g_ExecBuffer[CONSOLE_EXEC_BUFFER_SIZE] = {0};
EXECMODE g_ExecCreateMode = EM_NOTACTIVE;
int32_t AddLineToExecFile(const char* currentLine) {
char stringToWrite[STORM_MAX_PATH];
if (g_ExecCreateMode != EM_PROMPTOVERWRITE) {
if (!SStrCmpI(currentLine, "end", STORM_MAX_STR)) {
if (g_ExecCreateMode != EM_APPEND) {
g_ExecCreateMode = EM_WRITEFILE;
}
return 1;
}
SStrPrintf(stringToWrite, sizeof(stringToWrite), "%s\n", currentLine);
if (((sizeof(g_ExecBuffer)-1) - SStrLen(g_ExecBuffer)) != SStrLen(stringToWrite)){
SStrPack(g_ExecBuffer, stringToWrite, sizeof(g_ExecBuffer));
}
return 0;
}
if (currentLine[0] == 'n') {
ConsoleWrite("Canceled File Creation", ECHO_COLOR);
g_ExecCreateMode = EM_NOTACTIVE;
return 0;
}
if (currentLine[0] != 'y') {
ConsoleWrite("You must type 'y' to confirm overwrite. Process aborted!", ERROR_COLOR);
g_ExecCreateMode = EM_NOTACTIVE;
return 0;
}
// TODO
return 1;
}
void ConsoleCommandDestroy() {
g_consoleCommandHash.Clear();
@ -32,6 +79,11 @@ char* ConsoleCommandHistory(uint32_t index) {
return g_commandHistory[((g_commandHistoryIndex + (HISTORY_DEPTH - 1) - index) & (HISTORY_DEPTH - 1))];
}
void AddToHistory(const char* command) {
SStrCopy(g_commandHistory[g_commandHistoryIndex], command, CONSOLE_LINE_LENGTH);
g_commandHistoryIndex = (g_commandHistoryIndex + 1) & (HISTORY_DEPTH-1);
}
uint32_t ConsoleCommandHistoryDepth() {
return HISTORY_DEPTH;
}
@ -40,7 +92,7 @@ void ConsoleCommandInitialize() {
ConsoleCommandRegister("help", ConsoleCommand_Help, CONSOLE, "Provides help information about a command.");
}
int32_t ConsoleCommandRegister(const char* command, int32_t (*handler)(const char*, const char*), CATEGORY category, const char* helpText) {
int32_t ConsoleCommandRegister(const char* command, COMMANDHANDLER handler, CATEGORY category, const char* helpText) {
STORM_ASSERT(command);
STORM_ASSERT(handler);
@ -52,10 +104,9 @@ int32_t ConsoleCommandRegister(const char* command, int32_t (*handler)(const cha
// Register the new command
auto commandPtr = g_consoleCommandHash.New(command, 0, 0);
commandPtr->command = command;
commandPtr->handler = handler;
commandPtr->helpText = helpText;
commandPtr->category = category;
commandPtr->m_handler = handler;
commandPtr->m_helpText = helpText;
commandPtr->m_category = category;
return 1;
}
@ -69,18 +120,162 @@ void ConsoleCommandUnregister(const char* command) {
}
}
int32_t ConsoleCommand_Help(const char* command, const char* arguments) {
// TODO
return 0;
CONSOLECOMMAND* ParseCommand(const char* commandLine, const char** command, char* arguments, size_t argsize) {
STORM_ASSERT(commandLine);
auto string = commandLine;
static char cmd[32] = { 0 };
auto cmdptr = &cmd[0];
int32_t end = CONSOLE_MAX_CMD_LENGTH;
int32_t i = 0;
while (i < end) {
int32_t chars;
auto code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
if (code == -1 || code == ' ' || chars > CONSOLE_MAX_CMD_LENGTH) {
break;
}
if (chars) {
for (size_t c = 0; c < chars; c++) {
*cmdptr = *string;
cmdptr += chars;
string += chars;
}
}
i += chars;
}
*cmdptr = '\0';
if (command) {
*command = cmd;
}
auto argptr = arguments;
if (arguments) {
int32_t chars;
auto code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
// Discard space
while(code != -1 && code == ' ') {
string += chars;
code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
}
SStrCopy(argptr, string, argsize);
auto len = SStrLen(argptr);
while (len > 0 && (argptr[len-1] == ' ')) {
len--;
argptr[len] = '\0';
}
}
return g_consoleCommandHash.Ptr(cmd);
}
int32_t ConsoleCommand_Quit(const char* command, const char* arguments) {
// TODO
// ConsolePostClose()
return 0;
void MakeCommandCurrent(CONSOLELINE* lineptr, char* command) {
auto len = lineptr->inputstart;
lineptr->inputpos = len;
lineptr->chars = len;
lineptr->buffer[len] = '\0';
len = SStrLen(command);
ReserveInputSpace(lineptr, len);
SStrCopy(lineptr->buffer + lineptr->inputpos, command, STORM_MAX_STR);
len = lineptr->inputpos + len;
lineptr->inputpos = len;
lineptr->chars = len;
}
int32_t ConsoleCommand_Ver(const char* command, const char* arguments) {
// TODO
return 0;
void ConsoleCommandExecute(char* commandLine, int32_t addToHistory) {
auto em = g_ExecCreateMode;
if (em == EM_RECORDING || em == EM_PROMPTOVERWRITE || em == EM_APPEND) {
AddLineToExecFile(commandLine);
return;
}
auto history = ConsoleCommandHistory(0);
if (addToHistory && (history == nullptr || SStrCmp(commandLine, history, STORM_MAX_STR))) {
AddToHistory(commandLine);
}
const char* command = nullptr;
auto arguments = reinterpret_cast<char*>(SMemAlloc(CMD_BUFFER_SIZE, __FILE__, __LINE__, 0));
auto cmd = ParseCommand(commandLine, &command, arguments, CMD_BUFFER_SIZE);
if (cmd) {
cmd->m_handler(command, arguments);
} else {
ConsoleWrite("Unknown command", DEFAULT_COLOR);
}
if (arguments) {
SMemFree(arguments, __FILE__, __LINE__, 0);
}
}
static ConsoleCommandList s_consoleSpecificCommands[] = {
{ "fontcolor", ConsoleCommand_FontColor, "[ColorClassName] [Red 0-255] [Green 0-255] [Blue 0-255]" },
{ "bgcolor", ConsoleCommand_BackGroundColor, "[alpha 0-255] [Red 0-255] [Green 0-255] [Blue 0-255]" },
{ "highlightcolor", ConsoleCommand_HighLightColor, "[alpha 0-255] [Red 0-255] [Green 0-255] [Blue 0-255]" },
{ "fontsize", ConsoleCommand_FontSize, "[15-50] arbitrary font size" },
{ "font", ConsoleCommand_Font, "[fontname] make sure to use the .ttf file name" },
{ "consolelines", ConsoleCommand_BufferSize, "[number] number of lines to show in the console" },
{ "clear", ConsoleCommand_ClearConsole, "Clears the console buffer" },
{ "proportionaltext", ConsoleCommand_Proportional, "Toggles fixed-width text characters" },
{ "spacing", ConsoleCommand_CharSpacing, "[float] specifies inter-character spacing, in pixels" },
{ "settings", ConsoleCommand_CurrentSettings, "Shows current font and console settings" },
{ "default", ConsoleCommand_DefaultSettings, "Resets all the font and console settings" },
{ "closeconsole", ConsoleCommand_CloseConsole, "Closes the Console window" },
{ "repeat", ConsoleCommand_RepeatHandler, "Repeats a command" },
{ "AppendLogToFile", ConsoleCommand_AppendLogToFile, "[filename = ConsoleLogs/Log<Timestamp>.txt] [numLines = all]" }
};
static ConsoleCommandList s_commonCommands[] = {
{ "quit", ConsoleCommand_Quit, nullptr },
{ "ver", ConsoleCommand_Ver, nullptr },
{ "setmap", ConsoleCommand_SetMap, nullptr }
};
void RegisterConsoleCommandList(CATEGORY category, ConsoleCommandList list[], size_t count) {
size_t i = 0;
while (i < count) {
auto& cmd = list[i];
ConsoleCommandRegister(cmd.m_command, cmd.m_handler, category, cmd.m_helpText);
i++;
}
}
void ConsoleInitializeScreenCommand() {
CONSOLE_REGISTER_LIST(CONSOLE, s_consoleSpecificCommands);
}
void ConsoleCommandInitialize() {
ConsoleCommandRegister("help", ConsoleCommand_Help, CONSOLE, "Provides help information about a command.");
}
void ConsoleInitializeCommonCommand() {
CONSOLE_REGISTER_LIST(DEFAULT, s_commonCommands);
}
void ConsoleInitializeDebugCommand() {
// TODO
}

View File

@ -4,11 +4,13 @@
#include <storm/Hash.hpp>
#include <cstdint>
#define EXEC_BUFFER_SIZE 8192
#define CMD_BUFFER_SIZE 1024
#define MAX_CMD_LENGTH 64
#define HISTORY_DEPTH 32
#define NOHELP nullptr
#define CONSOLE_REGISTER_LIST(category, list) RegisterConsoleCommandList(category, list, std::size(list))
#define CONSOLE_EXEC_BUFFER_SIZE 8192
#define CONSOLE_CMD_BUFFER_SIZE 1024
#define CONSOLE_MAX_CMD_LENGTH 64
#define CONSOLE_HISTORY_DEPTH 32
#define CONSOLE_NOHELP nullptr
enum CATEGORY {
DEBUG,
@ -24,17 +26,26 @@ enum CATEGORY {
LAST
};
struct CONSOLECOMMAND : TSHashObject<CONSOLECOMMAND, HASHKEY_STRI> {
const char* command;
int32_t (*handler)(const char*, const char*);
const char* helpText;
CATEGORY category;
typedef int32_t (*COMMANDHANDLER)(const char*, const char*);
class CONSOLECOMMAND : public TSHashObject<CONSOLECOMMAND, HASHKEY_STRI> {
public:
COMMANDHANDLER m_handler;
const char* m_helpText;
CATEGORY m_category;
};
class ConsoleCommandList {
public:
const char* m_command;
COMMANDHANDLER m_handler;
const char* m_helpText;
};
extern TSHashTable<CONSOLECOMMAND, HASHKEY_STRI> g_consoleCommandHash;
extern char g_commandHistory[HISTORY_DEPTH][CMD_BUFFER_SIZE];
extern char g_commandHistory[CONSOLE_HISTORY_DEPTH][CONSOLE_CMD_BUFFER_SIZE];
extern uint32_t g_commandHistoryIndex;
extern char g_ExecBuffer[EXEC_BUFFER_SIZE];
extern char g_ExecBuffer[CONSOLE_EXEC_BUFFER_SIZE];
void ConsoleCommandDestroy();
@ -42,16 +53,44 @@ char* ConsoleCommandHistory(uint32_t index);
uint32_t ConsoleCommandHistoryDepth();
int32_t ConsoleCommandRegister(const char* command, COMMANDHANDLER handler, CATEGORY category, const char* helpText);
void ConsoleCommandInitialize();
int32_t ConsoleCommandRegister(const char* command, int32_t (*handler)(const char*, const char*), CATEGORY category, const char* helpText);
void ConsoleInitializeCommonCommand();
void ConsoleInitializeDebugCommand();
void ConsoleInitializeScreenCommand();
void RegisterConsoleCommandList(CATEGORY category, ConsoleCommandList list[], size_t count);
void ConsoleCommandUnregister(const char* command);
int32_t ConsoleCommand_Help(const char* command, const char* arguments);
void ConsoleCommandExecute(char* commandLine, int32_t addToHistory);
void MakeCommandCurrent(CONSOLELINE* lineptr, char* command);
// Commands
int32_t ConsoleCommand_Quit(const char* command, const char* arguments);
int32_t ConsoleCommand_Ver(const char* command, const char* arguments);
int32_t ConsoleCommand_SetMap(const char* command, const char* arguments);
int32_t ConsoleCommand_Help(const char* command, const char* arguments);
int32_t ConsoleCommand_FontColor(const char* command, const char* arguments);
int32_t ConsoleCommand_BackGroundColor(const char* command, const char* arguments);
int32_t ConsoleCommand_HighLightColor(const char* command, const char* arguments);
int32_t ConsoleCommand_FontSize(const char* command, const char* arguments);
int32_t ConsoleCommand_Font(const char* command, const char* arguments);
int32_t ConsoleCommand_BufferSize(const char* command, const char* arguments);
int32_t ConsoleCommand_ClearConsole(const char* command, const char* arguments);
int32_t ConsoleCommand_Proportional(const char* command, const char* arguments);
int32_t ConsoleCommand_CharSpacing(const char* command, const char* arguments);
int32_t ConsoleCommand_CurrentSettings(const char* command, const char* arguments);
int32_t ConsoleCommand_DefaultSettings(const char* command, const char* arguments);
int32_t ConsoleCommand_CloseConsole(const char* command, const char* arguments);
int32_t ConsoleCommand_RepeatHandler(const char* command, const char* arguments);
int32_t ConsoleCommand_AppendLogToFile(const char* command, const char* arguments);
#endif

View File

@ -1,8 +1,13 @@
#include "console/Console.hpp"
#include "event/Context.hpp"
#include "event/Event.hpp"
static int32_t s_active;
static int32_t s_consoleAccessEnabled;
static KEY s_consoleKey = KEY_TILDE;
static float s_consoleLines = 10.0f;
static float s_fontHeight = 0.02f;
static float s_consoleHeight = s_consoleLines * s_fontHeight;
static CONSOLERESIZESTATE s_consoleResizeState = CS_NONE;
int32_t ConsoleAccessGetEnabled() {
@ -17,6 +22,18 @@ int32_t ConsoleGetActive() {
return s_active;
}
float ConsoleGetFontHeight() {
return s_fontHeight;
}
float ConsoleGetHeight() {
return s_consoleHeight;
}
float ConsoleGetLines() {
return s_consoleLines;
}
KEY ConsoleGetHotKey() {
return s_consoleKey;
}
@ -36,3 +53,11 @@ void ConsoleSetHotKey(KEY hotkey) {
void ConsoleSetResizeState(CONSOLERESIZESTATE state) {
s_consoleResizeState = state;
}
void ConsoleSetHeight(float height) {
s_consoleHeight = height;
}
void ConsolePostClose() {
EventPostCloseEx(EventGetCurrentContext());
}

View File

@ -11,6 +11,12 @@ void ConsoleAccessSetEnabled(int32_t enable);
int32_t ConsoleGetActive();
float ConsoleGetFontHeight();
float ConsoleGetLines();
float ConsoleGetHeight();
KEY ConsoleGetHotKey();
CONSOLERESIZESTATE ConsoleGetResizeState();
@ -19,6 +25,10 @@ void ConsoleSetActive(int32_t active);
void ConsoleSetHotKey(KEY hotkey);
void ConsoleSetHeight(float height);
void ConsoleSetResizeState(CONSOLERESIZESTATE state);
void ConsolePostClose();
#endif // ifndef CONSOLE_CONSOLE_HPP

View File

@ -1,13 +1,34 @@
#include "console/Handlers.hpp"
#include "console/Line.hpp"
#include "console/Console.hpp"
#include "console/Command.hpp"
#include "console/Screen.hpp"
#include "event/Event.hpp"
#include <cstdint>
static int32_t s_historyIndex = 0;
namespace {
int32_t OnChar(const EVENT_DATA_CHAR* data, void* param) {
// TODO
char character[2];
if (ConsoleAccessGetEnabled() && EventIsKeyDown(ConsoleGetHotKey())) {
return 0;
}
if (ConsoleGetActive()) {
character[0] = char(data->ch);
character[1] = 0;
PasteInInputLine(character);
ResetHighlight();
return 0;
}
// SUniSPutUTF8(data->ch, character);
return 1;
}
@ -27,7 +48,7 @@ int32_t OnKeyDown(const EVENT_DATA_KEY* data, void* param) {
// Reset the highlight when toggled off
if (!ConsoleGetActive()) {
// TODO ResetHighlight();
ResetHighlight();
}
return 0;
@ -37,6 +58,70 @@ int32_t OnKeyDown(const EVENT_DATA_KEY* data, void* param) {
return 1;
}
auto anyControl = (1 << KEY_LCONTROL) | (1 << KEY_RCONTROL);
auto line = GetInputLine();
switch (data->key) {
case KEY_ESCAPE:
if (line->inputpos < line->inputstart || line->inputpos == line->inputstart) {
ConsoleSetActive(0);
} else {
line->inputpos = line->inputstart;
line->chars = line->inputstart;
line->buffer[line->inputstart] = '\0';
SetInputString(line->buffer);
}
break;
case KEY_PAGEUP:
MoveLinePtr(1, data->metaKeyState);
break;
case KEY_PAGEDOWN:
MoveLinePtr(0, data->metaKeyState);
break;
case KEY_ENTER:
if (line->inputstart <= line->inputpos && line->inputpos != line->inputstart) {
line->inputpos = 0;
GenerateNodeString(line);
ConsoleCommandExecute(line->buffer + line->inputstart, 1);
s_historyIndex = -1;
}
break;
case KEY_HOME:
break;
case KEY_END:
break;
case KEY_C:
if (data->metaKeyState & anyControl) {
CutHighlightToClipboard();
}
break;
case KEY_V:
if (data->metaKeyState & anyControl) {
PasteClipboardToHighlight();
}
break;
case KEY_LEFT:
if (line->inputstart <= line->inputpos && line->inputpos != line->inputstart) {
line->inputpos--;
}
break;
case KEY_RIGHT:
if (line->inputpos < line->chars) {
line->inputpos++;
}
break;
case KEY_BACKSPACE:
BackspaceLine(line);
break;
}
if (data->key != KEY_TAB && data->key != KEY_LSHIFT && data->key != KEY_RSHIFT && data->key != KEY_LALT && data->key != KEY_RALT && !(data->metaKeyState & anyControl)) {
// s_completionMode = 0;
ResetHighlight();
}
// TODO
return 0;
}
@ -52,17 +137,79 @@ int32_t OnKeyUp(const EVENT_DATA_KEY* data, void* param) {
}
int32_t OnMouseDown(const EVENT_DATA_MOUSE* data, void* param) {
// TODO
auto consoleHeight = ConsoleGetHeight();
auto fontHeight = ConsoleGetFontHeight();
if (EventIsKeyDown(ConsoleGetHotKey()) || !ConsoleGetActive() || (1.0f - consoleHeight) > data->y) {
return 1;
}
float clickPos = 1.0f - data->y;
if (clickPos < (std::min(consoleHeight, 1.0f) - (fontHeight * 0.75f)) || clickPos > consoleHeight) {
ResetHighlight();
auto line = GetLineAtMousePosition(data->y);
if (line) {
SetHighlightCopyText(line->buffer);
SetHighlightState(HS_HIGHLIGHTING);
float v7 = 1.0f - (consoleHeight - (fontHeight * 0.75f) - (fontHeight) - ((consoleHeight - clickPos) / fontHeight - 1.0) * fontHeight);
auto hRect = GetHighlightRect();
hRect.bottom = v7;
hRect.top = v7 - fontHeight;
SetHighlightStart(v7);
SetHighlightEnd(v7);
UpdateHighlight();
return 0;
}
ResetHighlightCopyText();
return 0;
}
ResetHighlight();
ConsoleSetResizeState(CS_STRETCH);
return 1;
}
int32_t OnMouseMove(const EVENT_DATA_MOUSE* data, void* param) {
// TODO
if (EventIsKeyDown(ConsoleGetHotKey()) || !ConsoleGetActive()) {
return 1;
}
if (ConsoleGetResizeState() == CS_STRETCH) {
auto newHeight = std::max(1.0f - data->y, ConsoleGetFontHeight());
ConsoleSetHeight(newHeight);
} else if ((1.0f - ConsoleGetHeight()) > data->y) {
return 1;
}
SetHighlightEnd(data->x);
if (GetHighlightState() == HS_HIGHLIGHTING) {
UpdateHighlight();
}
return 1;
}
int32_t OnMouseUp(const EVENT_DATA_MOUSE* data, void* param) {
// TODO
if (EventIsKeyDown(ConsoleGetHotKey()) || !ConsoleGetActive()) {
return 1;
}
SetHighlightState(HS_ENDHIGHLIGHT);
ConsoleSetResizeState(CS_NONE);
return 1;
}

245
src/console/Line.cpp Normal file
View File

@ -0,0 +1,245 @@
#include "console/Line.hpp"
#include "console/Types.hpp"
#include "console/Console.hpp"
#include "console/Screen.hpp"
#include "gx/Device.hpp"
#include <storm/List.hpp>
#include <storm/thread/SCritSect.hpp>
static SCritSect s_critsect;
// In this list:
// The head = the input line.
// The tail = the oldest line printed.
static STORM_LIST(CONSOLELINE) s_linelist;
// Pointer to the current line. Determines what region of the console history gets rendered.
static CONSOLELINE* s_currlineptr = nullptr;
static uint32_t s_NumLines = 0;
void EnforceMaxLines() {
if (s_NumLines <= CONSOLE_LINES_MAX) {
return;
}
// Pop oldest line off the list
auto lineptr = s_linelist.Tail();
if (lineptr == nullptr) {
lineptr = s_currlineptr;
}
if (lineptr == nullptr) {
return;
}
// Clean up oldest line.
s_linelist.UnlinkNode(lineptr);
s_linelist.DeleteNode(lineptr);
s_NumLines--;
}
CONSOLELINE* GetInputLine() {
auto head = s_linelist.Head();
// If the list is empty, or the list's head is an entered input-line,
// Create a fresh input line, with "> " prefixed before the caret.
if (!head || head->inputpos == 0) {
auto l = SMemAlloc(sizeof(CONSOLELINE), __FILE__, __LINE__, 0);
auto line = new(l) CONSOLELINE();
line->buffer = reinterpret_cast<char*>(SMemAlloc(CONSOLE_LINE_PREALLOC, __FILE__, __LINE__, 0));
line->charsalloc = CONSOLE_LINE_PREALLOC;
s_linelist.LinkToHead(line);
SStrCopy(line->buffer, "> ", line->charsalloc);
SetInputString(line->buffer);
auto chars = SStrLen(line->buffer);
s_NumLines++;
line->inputstart = chars;
line->inputpos = chars;
line->chars = chars;
line->colorType = INPUT_COLOR;
s_currlineptr = line;
EnforceMaxLines();
return line;
}
return head;
}
CONSOLELINE* GetLineAtMousePosition(float y) {
// Loop through linelist to find line at mouse position
int32_t linePos = static_cast<int32_t>((ConsoleGetHeight() - (1.0 - y)) / ConsoleGetFontHeight());
if (linePos == 1) {
return s_linelist.Head();
}
if (s_currlineptr != s_linelist.Head()) {
linePos--;
}
CONSOLELINE* line = s_currlineptr;
while (linePos > 1) {
linePos--;
if (!line) {
line = s_linelist.Head();
}
if (line == nullptr) {
return nullptr;
}
line = line->Next();
}
return line;
}
void ReserveInputSpace(CONSOLELINE* line, size_t len) {
size_t newsize = line->chars + len;
if (newsize >= line->charsalloc) {
while (line->charsalloc <= newsize) {
line->charsalloc += CONSOLE_LINE_PREALLOC;
}
auto buffer = reinterpret_cast<char*>(SMemAlloc(line->charsalloc, __FILE__, __LINE__, 0));
SStrCopy(buffer, line->buffer, line->charsalloc);
SMemFree(line->buffer, __FILE__, __LINE__, 0x0);
line->buffer = buffer;
}
}
void ConsoleWrite(const char* str, COLOR_T color) {
if (g_theGxDevicePtr == nullptr || str[0] == '\0') {
return;
}
s_critsect.Enter();
auto l = reinterpret_cast<char*>(SMemAlloc(sizeof(CONSOLELINE), __FILE__, __LINE__, 0));
auto lineptr = new(l) CONSOLELINE();
auto head = s_linelist.Head();
if (head == nullptr || head->inputpos == 0) {
// Attach console line to head
s_linelist.LinkToHead(lineptr);
} else {
// Attach console line between head and head-1
s_linelist.LinkNode(lineptr, 1, head->Prev());
}
size_t len = SStrLen(str) + 1;
lineptr->chars = len;
lineptr->charsalloc = len;
lineptr->buffer = reinterpret_cast<char*>(SMemAlloc(len, __FILE__, __LINE__, 0));
lineptr->colorType = color;
SStrCopy(lineptr->buffer, str, STORM_MAX_STR);
GenerateNodeString(lineptr);
s_NumLines++;
EnforceMaxLines();
//
s_critsect.Leave();
}
void ConsoleWriteA(const char* str, COLOR_T color, ...) {
char buffer[1024] = {0};
if (str != nullptr && str[0] != '\0') {
va_list list;
va_start(list, color);
vsnprintf(buffer, sizeof(buffer), str, list);
va_end(list);
ConsoleWrite(buffer, color);
}
}
void MoveLinePtr(int32_t direction, int32_t modifier) {
CONSOLELINE* lineptr = s_currlineptr;
auto anyControl = (1 << KEY_LCONTROL) | (1 << KEY_RCONTROL);
if (modifier & anyControl) {
for (int32_t i = 0; i < 10 && lineptr != nullptr; i++) {
CONSOLELINE* next;
if (direction == 1) {
next = lineptr->m_link.Next();
} else {
next = lineptr->m_link.Prev();
}
if (next != nullptr) {
lineptr = next;
}
}
} else {
// if (s_currlineptr == s_linelist.Head()) {
// s_currlineptr = s_currlineptr->Prev();
// }
if (direction == 1) {
lineptr = lineptr->m_link.Next();
} else {
lineptr = lineptr->m_link.Prev();
}
}
if (lineptr) {
s_currlineptr = lineptr;
}
}
void BackspaceLine(CONSOLELINE* line) {
if (line->inputstart <= line->inputpos && line->inputpos != line->inputstart) {
if (line->inputpos < line->chars) {
memmove(line->buffer + line->inputpos + -1, line->buffer + line->inputpos, (line->chars - line->inputpos) + 1);
} else {
line->buffer[line->inputpos - 1] = '\0';
}
line->chars--;
line->inputpos--;
SetInputString(line->buffer);
}
}
CONSOLELINE* GetCurrentLine() {
return s_currlineptr;
}
CONSOLELINE::~CONSOLELINE() {
if (this->buffer) {
SMemFree(this->buffer, __FILE__, __LINE__, 0);
}
if (this->fontPointer) {
GxuFontDestroyString(this->fontPointer);
}
}
void ConsoleClear() {
s_NumLines = 0;
auto ptr = s_linelist.Head();
while (ptr) {
s_linelist.UnlinkNode(ptr);
s_linelist.DeleteNode(ptr);
ptr = s_linelist.Head();
}
}

44
src/console/Line.hpp Normal file
View File

@ -0,0 +1,44 @@
#ifndef CONSOLE_LINE_HPP
#define CONSOLE_LINE_HPP
#include "console/Types.hpp"
#include "gx/Font.hpp"
#include <storm/List.hpp>
#define CONSOLE_LINES_MAX 256
#define CONSOLE_LINE_LENGTH 1024
#define CONSOLE_LINE_PREALLOC 16
class CONSOLELINE : public TSLinkedNode<CONSOLELINE> {
public:
char* buffer;
uint32_t chars;
uint32_t charsalloc;
uint32_t inputpos;
uint32_t inputstart;
COLOR_T colorType;
CGxString* fontPointer;
~CONSOLELINE();
};
void ConsoleWrite(const char* str, COLOR_T color);
void ConsoleWriteA(const char* str, COLOR_T color, ...);
void PasteInInputLine(char* characters);
void MoveLinePtr(int32_t direction, int32_t modifier);
void BackspaceLine(CONSOLELINE* line);
void ReserveInputSpace(CONSOLELINE* line, size_t len);
CONSOLELINE* GetInputLine();
CONSOLELINE* GetCurrentLine();
CONSOLELINE* GetLineAtMousePosition(float y);
void ConsoleClear();
#endif

View File

@ -1,6 +1,8 @@
#include "console/Screen.hpp"
#include "console/Console.hpp"
#include "console/Command.hpp"
#include "console/Handlers.hpp"
#include "console/Line.hpp"
#include "console/Types.hpp"
#include "gx/Buffer.hpp"
#include "gx/Coordinate.hpp"
@ -10,23 +12,34 @@
#include "gx/Gx.hpp"
#include "gx/RenderState.hpp"
#include "gx/Screen.hpp"
#include <bc/Debug.hpp>
#include <storm/String.hpp>
#include <tempest/Rect.hpp>
#include <algorithm>
static CGxStringBatch* s_batch;
static uint32_t s_baseTextFlags = 0x8;
static int32_t s_caret = 0;
static float s_caretpixwidth;
static float s_caretpixheight;
static float s_consoleLines = 10.0f;
static float s_fontHeight = 0.02f;
static float s_consoleHeight = s_consoleLines * s_fontHeight;
static float s_charSpacing = 0.0f;
static CGxString* s_inputString = nullptr;
static char s_fontName[STORM_MAX_PATH];
static int32_t s_highlightState;
static HLAYER s_layerBackground;
static HLAYER s_layerText;
static RECTF s_rect = { 0.0f, 1.0f, 1.0f, 1.0f };
static HTEXTFONT s_textFont;
static HIGHLIGHTSTATE s_highlightState = HS_NONE;
static RECTF s_hRect = { 0.0f, 0.0f, 0.0f, 0.0f };
static float s_highlightHStart = 0.0f;
static float s_highlightHEnd = 0.0f;
static uint32_t s_highlightLeftCharIndex = 0;
static uint32_t s_highlightRightCharIndex = 0;
static int32_t s_highlightInput = 0;
static char s_copyText[HIGHLIGHT_COPY_SIZE] = { 0 };
static CImVector s_colorArray[] = {
{ 0xFF, 0xFF, 0xFF, 0xFF }, // DEFAULT_COLOR
{ 0xFF, 0xFF, 0xFF, 0xFF }, // INPUT_COLOR
@ -70,7 +83,64 @@ void DrawBackground() {
}
void DrawHighLight() {
// TODO
uint16_t indices[] = {
0, 1, 2, 3
};
C3Vector position[] = {
{ s_hRect.left, s_hRect.bottom, 0.0f },
{ s_hRect.right, s_hRect.bottom, 0.0f },
{ s_hRect.left, s_hRect.top, 0.0f },
{ s_hRect.right, s_hRect.top, 0.0f }
};
GxRsPush();
GxRsSet(GxRs_Lighting, 0);
GxRsSet(GxRs_BlendingMode, GxBlend_Alpha);
GxRsSet(GxRs_AlphaRef, CGxDevice::s_alphaRef[GxBlend_Alpha]);
GxPrimLockVertexPtrs(4, position, sizeof(C3Vector), nullptr, 0, &s_colorArray[HIGHLIGHT_COLOR], 0, nullptr, 0, nullptr, 0, nullptr, 0);
GxDrawLockedElements(GxPrim_TriangleStrip, 4, indices);
GxPrimUnlockVertexPtrs();
GxRsPop();
}
void DrawCaret(C3Vector& caretpos) {
uint16_t indices[] = {
0, 1, 2, 3
};
float minX = caretpos.x;
float minY = caretpos.y;
float maxX = caretpos.x + (s_caretpixwidth * 2);
float maxY = caretpos.y + ConsoleGetFontHeight();
C3Vector position[] = {
{ minX, minY, 0.0f },
{ maxX, minY, 0.0f },
{ minX, maxY, 0.0f },
{ maxX, maxY, 0.0f }
};
GxRsPush();
GxRsSet(GxRs_Lighting, 0);
GxRsSet(GxRs_Fog, 0);
GxRsSet(GxRs_DepthTest, 0);
GxRsSet(GxRs_DepthWrite, 0);
GxRsSet(GxRs_Culling, 0);
GxRsSet(GxRs_PolygonOffset, 0.0f);
GxRsSet(GxRs_BlendingMode, GxBlend_Alpha);
GxRsSet(GxRs_AlphaRef, CGxDevice::s_alphaRef[GxBlend_Alpha]);
GxPrimLockVertexPtrs(4, position, sizeof(C3Vector), nullptr, 0, &s_colorArray[INPUT_COLOR], 0, nullptr, 0, nullptr, 0, nullptr, 0);
GxDrawLockedElements(GxPrim_TriangleStrip, 4, indices);
GxPrimUnlockVertexPtrs();
GxRsPop();
}
void PaintBackground(void* param, const RECTF* rect, const RECTF* visible, float elapsedSec) {
@ -83,12 +153,252 @@ void PaintBackground(void* param, const RECTF* rect, const RECTF* visible, float
}
}
void SetInputString(char* buffer) {
// s_highlightState = HS_NONE;
// s_hRect = { 0.0f, 0.0f, 0.0f, 0.0f };
// s_highlightLeftCharIndex = 0;
// s_highlightRightCharIndex = 0;
// s_highlightInput = 0;
if (s_inputString) {
GxuFontDestroyString(s_inputString);
}
s_inputString = nullptr;
auto fontHeight = ConsoleGetFontHeight();
if (buffer && buffer[0] != '\0') {
C3Vector pos = { 0.0f, 0.0f, 1.0f };
auto font = TextBlockGetFontPtr(s_textFont);
GxuFontCreateString(font, buffer, fontHeight, pos, 1.0f, fontHeight, 0.0f, s_inputString, GxVJ_Middle, GxHJ_Left, s_baseTextFlags, s_colorArray[INPUT_COLOR], s_charSpacing, 1.0f);
}
}
void PasteInInputLine(char* characters) {
auto len = SStrLen(characters);
if (!len) {
return;
}
auto line = GetInputLine();
ReserveInputSpace(line, len);
if (line->inputpos < line->chars) {
if (len <= 1) {
memmove(&line->buffer[line->inputpos + 1], &line->buffer[line->inputpos], line->chars - (line->inputpos + 1));
line->buffer[line->inputpos] = *characters;
line->inputpos++;
line->chars++;
} else {
auto input = reinterpret_cast<char*>(SMemAlloc(line->charsalloc, __FILE__, __LINE__, 0x0));
SStrCopy(input, &line->buffer[line->inputpos], STORM_MAX_STR);
auto buffer = reinterpret_cast<char*>(SMemAlloc(line->charsalloc, __FILE__, __LINE__, 0x0));
SStrCopy(buffer, line->buffer, STORM_MAX_STR);
buffer[line->inputpos] = '\0';
SStrPack(buffer, characters, line->charsalloc);
auto len = SStrLen(buffer);
line->inputpos = len;
SStrPack(buffer, input, line->charsalloc);
SStrCopy(line->buffer, buffer, STORM_MAX_STR);
line->chars = SStrLen(line->buffer);
if (input) {
SMemFree(input, __FILE__, __LINE__, 0);
}
if (buffer) {
SMemFree(input, __FILE__, __LINE__, 0);
}
}
} else {
for (int32_t i = 0; i < len; i++) {
line->buffer[line->inputpos++] = characters[i];
}
line->buffer[line->inputpos] = '\0';
line->chars = line->inputpos;
}
SetInputString(line->buffer);
}
void GenerateNodeString(CONSOLELINE* node) {
auto font = TextBlockGetFontPtr(s_textFont);
if (font && node && node->buffer && node->buffer[0] != '\0') {
if (node->fontPointer) {
GxuFontDestroyString(node->fontPointer);
}
C3Vector pos = {
0.0f, 0.0f, 1.0f
};
auto fontHeight = ConsoleGetFontHeight();
GxuFontCreateString(font, node->buffer, fontHeight, pos, 1.0f, fontHeight, 0.0f, node->fontPointer, GxVJ_Middle, GxHJ_Left, s_baseTextFlags, s_colorArray[node->colorType], s_charSpacing, 1.0f);
BLIZZARD_ASSERT(node->fontPointer);
}
}
void PaintText(void* param, const RECTF* rect, const RECTF* visible, float elapsedSec) {
// TODO
if (s_rect.bottom >= 1.0f) {
return;
}
static float carettime = 0.0f;
static C3Vector caretpos = { 0.0f, 0.0f, 0.0f };
//
carettime += elapsedSec;
if ((!s_caret && carettime > 0.2) || (carettime > 0.3)) {
s_caret = !s_caret;
carettime = 0;
}
auto line = GetInputLine();
C3Vector pos = {
s_rect.left,
(ConsoleGetFontHeight() * 0.75f) + s_rect.bottom,
1.0f
};
GxuFontClearBatch(s_batch);
if (s_inputString) {
GxuFontSetStringPosition(s_inputString, pos);
GxuFontAddToBatch(s_batch, s_inputString);
}
auto font = TextBlockGetFontPtr(s_textFont);
if (line->inputpos) {
caretpos = pos;
GxuFontGetTextExtent(font, line->buffer, line->inputpos, ConsoleGetFontHeight(), &caretpos.x, 0.0f, 1.0f, s_charSpacing, s_baseTextFlags);
DrawCaret(caretpos);
}
pos.y += ConsoleGetFontHeight();
for (auto lineptr = GetCurrentLine(); (lineptr && pos.y < 1.0); lineptr = lineptr->Next()) {
if (lineptr != line) {
if (lineptr->fontPointer == nullptr) {
GenerateNodeString(lineptr);
}
GxuFontSetStringPosition(lineptr->fontPointer, pos);
GxuFontAddToBatch(s_batch, lineptr->fontPointer);
pos.y += ConsoleGetFontHeight();
}
}
GxuFontRenderBatch(s_batch);
}
void UpdateHighlight() {
auto font = TextBlockGetFontPtr(s_textFont);
BLIZZARD_ASSERT(font);
auto len = SStrLen(s_copyText);
float left = std::min(s_highlightHStart, s_highlightHEnd);
float right = std::max(s_highlightHStart, s_highlightHEnd);
auto chars = GxuFontGetMaxCharsWithinWidth(font, s_copyText, ConsoleGetFontHeight(), left, len, &s_hRect.left, 0.0f, 1.0f, s_charSpacing, s_baseTextFlags);
s_highlightLeftCharIndex = chars;
if (chars) {
s_highlightRightCharIndex = chars - 1;
}
if (s_hRect.left < 0.015f) {
s_hRect.left = 0.0f;
}
s_highlightRightCharIndex = GxuFontGetMaxCharsWithinWidth(font, s_copyText, ConsoleGetFontHeight(), right, len, &s_hRect.right, 0.0f, 1.0f, s_charSpacing, s_baseTextFlags);
}
void ResetHighlight() {
s_highlightState = HS_NONE;
s_hRect = { 0.0f, 0.0f, 0.0f, 0.0f };
}
HIGHLIGHTSTATE GetHighlightState() {
return s_highlightState;
}
void SetHighlightState(HIGHLIGHTSTATE hs) {
s_highlightState = hs;
}
char* GetHighlightCopyText() {
return s_copyText;
}
void SetHighlightCopyText(char* text) {
SStrCopy(s_copyText, text, HIGHLIGHT_COPY_SIZE);
}
void ResetHighlightCopyText() {
s_copyText[0] = '\0';
}
RECTF& GetHighlightRect() {
return s_hRect;
}
void SetHighlightStart(float start) {
s_highlightHStart = start;
}
void SetHighlightEnd(float end) {
s_highlightHEnd = end;
}
void CutHighlightToClipboard() {
char buffer[HIGHLIGHT_COPY_SIZE];
if (s_copyText[0] != '\0') {
uint32_t size = s_highlightRightCharIndex - s_highlightLeftCharIndex;
uint32_t capsize = HIGHLIGHT_COPY_SIZE-1;
size = std::min(size, capsize);
SStrCopy(buffer, &s_copyText[s_highlightLeftCharIndex], size);
buffer[size] = '\0';
// OsClipboardPutString(buffer);
}
ResetHighlight();
}
void PasteClipboardToHighlight() {
// auto buffer = OsClipboardGetString();
// PasteInInputLine(buffer);
// SMemFree(buffer, __FILE__, __LINE__, 0);
// ResetHighlight();
}
void ConsoleScreenAnimate(float elapsedSec) {
auto finalPos = ConsoleGetActive() ? std::min(1.0f - s_consoleHeight, 1.0f) : 1.0f;
auto finalPos = ConsoleGetActive() ? std::min(1.0f - ConsoleGetHeight(), 1.0f) : 1.0f;
finalPos = std::max(finalPos, 0.0f);
if (s_rect.bottom == finalPos) {
@ -120,7 +430,7 @@ void ConsoleScreenInitialize(const char* title) {
s_caretpixheight = height == 0.0f ? 1.0f : 1.0f / height;
SStrCopy(s_fontName, "Fonts\\ARIALN.ttf", sizeof(s_fontName));
s_textFont = TextBlockGenerateFont(s_fontName, 0, NDCToDDCHeight(s_fontHeight));
s_textFont = TextBlockGenerateFont(s_fontName, 0, NDCToDDCHeight(ConsoleGetFontHeight()));
ScrnLayerCreate(&s_rect, 6.0f, 0x1 | 0x2, nullptr, PaintBackground, &s_layerBackground);
ScrnLayerCreate(&s_rect, 7.0f, 0x1 | 0x2, nullptr, PaintText, &s_layerText);
@ -128,10 +438,11 @@ void ConsoleScreenInitialize(const char* title) {
RegisterHandlers();
// TODO register commands
ConsoleInitializeScreenCommand();
// TODO EventSetConfirmCloseCallback(EventCloseCallback, 0);
// TODO ConsoleCommandExecute("ver", 1);
ConsoleCommandExecute("ver", 1);
s_batch = GxuFontCreateBatch(false, false);
}

View File

@ -1,8 +1,46 @@
#ifndef CONSOLE_SCREEN_HPP
#define CONSOLE_SCREEN_HPP
#define HIGHLIGHT_COPY_SIZE 128
#include "console/Line.hpp"
#include <storm/region/Types.hpp>
enum HIGHLIGHTSTATE {
HS_NONE = 0,
HS_HIGHLIGHTING = 1,
HS_ENDHIGHLIGHT = 2,
NUM_HIGHLIGHTSTATES
};
void ConsoleScreenAnimate(float elapsedSec);
void ConsoleScreenInitialize(const char* title);
void SetInputString(char* buffer);
void ResetHighlight();
void UpdateHighlight();
HIGHLIGHTSTATE GetHighlightState();
void SetHighlightState(HIGHLIGHTSTATE hs);
void SetHighlightCopyText(char* text);
char* GetHighlightCopyText();
void ResetHighlightCopyText();
void SetHighlightStart(float start);
void SetHighlightEnd(float end);
RECTF& GetHighlightRect();
void CutHighlightToClipboard();
void PasteClipboardToHighlight();
void GenerateNodeString(CONSOLELINE* node);
#endif

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_AppendLogToFile(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_BackGroundColor(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_BufferSize(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_CharSpacing(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_ClearConsole(const char* command, const char* arguments) {
ConsoleClear();
return 1;
}

View File

@ -0,0 +1,7 @@
#include "console/Command.hpp"
#include "console/Console.hpp"
int32_t ConsoleCommand_CloseConsole(const char* command, const char* arguments) {
ConsoleSetActive(false);
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_CurrentSettings(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_DefaultSettings(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_Font(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_FontColor(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_FontSize(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,111 @@
#include "console/Command.hpp"
#include "console/Line.hpp"
struct CategoryTranslation {
CATEGORY categoryValue;
char categoryString[20];
};
CategoryTranslation s_translation[] = {
{ DEBUG, "debug" },
{ GRAPHICS, "graphics" },
{ CONSOLE, "console" },
{ COMBAT, "combat" },
{ GAME, "game" },
{ DEFAULT, "default" },
{ NET, "net" },
{ SOUND, "sound" },
{ GM, "gm" }
};
int32_t ConsoleCommand_Help(const char* command, const char* arguments) {
char buffer[128];
bool showCategories = *arguments == '\0';
auto numTranslation = std::size(s_translation);
if (showCategories) {
memset(buffer, 0, sizeof(buffer));
ConsoleWrite("Console help categories: ", DEFAULT_COLOR);
uint32_t offset = 0;
for (size_t i = 0; i < numTranslation; i++) {
auto& translation = s_translation[i];
SStrPack(buffer, translation.categoryString, sizeof(buffer));
if (i + 1 != numTranslation) {
SStrPack(buffer, ", ", sizeof(buffer));
}
}
ConsoleWrite(buffer, WARNING_COLOR);
ConsoleWrite("For more information type 'help [command] or [category]'", WARNING_COLOR);
} else {
for (size_t i = 0; i < numTranslation; i++) {
auto& translation = s_translation[i];
if (SStrCmpI(translation.categoryString, arguments, STORM_MAX_STR) == 0) {
if (translation.categoryValue != NONE) {
memset(buffer, 0, sizeof(buffer));
SStrPrintf(buffer, sizeof(buffer), "Commands registered for the category %s:", arguments);
ConsoleWrite(buffer, WARNING_COLOR);
buffer[0] = '\0';
uint32_t counter = 0;
for (auto cmd = g_consoleCommandHash.Head(); cmd; cmd = g_consoleCommandHash.Next(cmd)) {
if (cmd->m_category == translation.categoryValue) {
SStrPack(buffer, cmd->m_key.m_str, sizeof(buffer));
SStrPack(buffer, ", ", sizeof(buffer));
if (++counter == 8) {
ConsoleWrite(buffer, DEFAULT_COLOR);
buffer[0] = '\0';
counter = 0;
}
}
}
char* wr;
if (buffer[0]) {
auto comma = reinterpret_cast<char*>(SStrChrR(buffer, ','));
if (comma) {
*comma = 0x00;
}
wr = buffer;
} else {
wr = "NONE";
}
ConsoleWrite(wr, DEFAULT_COLOR);
break;
}
}
}
auto cmd = g_consoleCommandHash.Ptr(arguments);
if (cmd == nullptr) {
return 1;
}
SStrPrintf(buffer, 0xa5, "Help for command %s:", arguments);
ConsoleWrite(buffer, WARNING_COLOR);
auto help = cmd->m_helpText;
if (help == nullptr) {
help = "No help yet";
}
SStrPrintf(buffer, 0xa5, " %s %s", arguments, help);
ConsoleWrite(buffer, DEFAULT_COLOR);
}
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_HighLightColor(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,6 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_Proportional(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,7 @@
#include "console/Command.hpp"
#include "console/Console.hpp"
int32_t ConsoleCommand_RepeatHandler(const char* command, const char* arguments) {
// TODO
return 1;
}

View File

@ -0,0 +1,7 @@
#include "console/Command.hpp"
#include "console/Line.hpp"
int32_t ConsoleCommand_Ver(const char* command, const char* arguments) {
ConsoleWrite("Whoa <https://github.com/whoahq/whoa>", DEFAULT_COLOR);
return 1;
}

View File

@ -0,0 +1,7 @@
#include "console/Command.hpp"
#include "console/Console.hpp"
int32_t ConsoleCommand_Quit(const char* command, const char* arguments) {
ConsolePostClose();
return 1;
}

View File

@ -0,0 +1,5 @@
#include "console/Command.hpp"
int32_t ConsoleCommand_SetMap(const char* command, const char* arguments) {
return 1;
}