diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc83940..ed855ca 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(gx) add_subdirectory(math) add_subdirectory(model) add_subdirectory(net) +add_subdirectory(os) add_subdirectory(sound) add_subdirectory(ui) add_subdirectory(util) diff --git a/src/client/ClientHandlers.cpp b/src/client/ClientHandlers.cpp index 4bdc638..c061096 100644 --- a/src/client/ClientHandlers.cpp +++ b/src/client/ClientHandlers.cpp @@ -3,7 +3,7 @@ #include #include -#include "console/Line.hpp" +#include "console/Console.hpp" #include "world/World.hpp" diff --git a/src/client/CmdLine.cpp b/src/client/CmdLine.cpp index 9b86ce2..89b9661 100644 --- a/src/client/CmdLine.cpp +++ b/src/client/CmdLine.cpp @@ -57,7 +57,7 @@ void ProcessCommandLine() { } const char* CmdLineGetString(CMDOPT opt) { - static char buffer[260] = {0}; + static char buffer[260]; SCmdGetString(opt, buffer, 260); diff --git a/src/client/Gui.hpp b/src/client/Gui.hpp deleted file mode 100644 index b230629..0000000 --- a/src/client/Gui.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CLIENT_GUI_HPP -#define CLIENT_GUI_HPP - -#include "client/gui/OsGui.hpp" - -#endif diff --git a/src/client/gui/OsGui.hpp b/src/client/gui/OsGui.hpp deleted file mode 100644 index c7d8da8..0000000 --- a/src/client/gui/OsGui.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef CLIENT_GUI_OS_GUI_HPP -#define CLIENT_GUI_OS_GUI_HPP - -#include - -void* OsGuiGetWindow(int32_t type); - -bool OsGuiIsModifierKeyDown(int32_t key); - -int32_t OsGuiProcessMessage(void* message); - -void OsGuiSetGxWindow(void* window); - -#endif diff --git a/src/client/gui/linux/OsGui.cpp b/src/client/gui/linux/OsGui.cpp deleted file mode 100644 index b2d57a4..0000000 --- a/src/client/gui/linux/OsGui.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "client/gui/OsGui.hpp" - -static void* s_GxDevWindow = nullptr; - -void* OsGuiGetWindow(int32_t type) { - switch (type) { - case 0: - return s_GxDevWindow; - default: - return nullptr; - } -} - -bool OsGuiIsModifierKeyDown(int32_t key) { - // TODO - return false; -} - -int32_t OsGuiProcessMessage(void* message) { - return 0; -} - -void OsGuiSetGxWindow(void* window) { - s_GxDevWindow = window; -} diff --git a/src/client/gui/win/OsGui.cpp b/src/client/gui/win/OsGui.cpp deleted file mode 100644 index 3d4967d..0000000 --- a/src/client/gui/win/OsGui.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "client/gui/OsGui.hpp" -#include - -static void* s_GxDevWindow; - -void* OsGuiGetWindow(int32_t type) { - switch (type) { - case 0: - return s_GxDevWindow; - case 1: - return GetActiveWindow(); - case 2: - return GetForegroundWindow(); - default: - return nullptr; - } -} - -bool OsGuiIsModifierKeyDown(int32_t key) { - // TODO - return false; -} - -int32_t OsGuiProcessMessage(void* message) { - // TODO - return 0; -} - -void OsGuiSetGxWindow(void* window) { - s_GxDevWindow = window; -} diff --git a/src/console/CMakeLists.txt b/src/console/CMakeLists.txt index d10e728..e17ebf9 100644 --- a/src/console/CMakeLists.txt +++ b/src/console/CMakeLists.txt @@ -1,6 +1,7 @@ file(GLOB PRIVATE_SOURCES "*.cpp" "command/*/*.cpp" + "cvar/*.cpp" ) add_library(console STATIC @@ -14,7 +15,6 @@ target_include_directories(console target_link_libraries(console PUBLIC - bc common gx storm diff --git a/src/console/CVar.cpp b/src/console/CVar.cpp index 0cded9e..ffa4dfe 100644 --- a/src/console/CVar.cpp +++ b/src/console/CVar.cpp @@ -1,7 +1,6 @@ #include "console/CVar.hpp" -#include "console/Command.hpp" #include "console/Types.hpp" -#include "console/Line.hpp" +#include "console/Console.hpp" #include "util/SFile.hpp" #include @@ -17,68 +16,85 @@ CVar* CVar::Lookup(const char* name) { : nullptr; } -CVar* CVar::Register(const char* name, const char* help, uint32_t flags, const char* value, bool (*fcn)(CVar*, const char*, const char*, void*), uint32_t category, bool setCommand, void* arg, bool a9) { - CVar* var = CVar::s_registeredCVars.Ptr(name); +CVar* CVar::LookupRegistered(const char* name) { + if (!name) { + return nullptr; + } + auto cv = s_registeredCVars.Ptr(name); + if (!cv) { + return nullptr; + } + if (cv->m_flags & 0x80000000) { + return cv; + } + if (cv->m_flags & 0x80) { + return cv; + } + return nullptr; +} - if (var) { - bool setReset = var->m_resetValue.GetString() == nullptr; - bool setDefault = var->m_defaultValue.GetString() == nullptr; +CVar* CVar::Register(const char* name, const char* help, uint32_t flags, const char* value, HANDLER_FUNC fcn, uint32_t category, bool a7, void* arg, bool a9) { + auto cv = s_registeredCVars.Ptr(name); - var->m_flags |= (var->m_flags & 0xFFFFFFCF); + if (cv) { + bool setReset = cv->m_resetValue.GetString() == nullptr; + bool setDefault = cv->m_defaultValue.GetString() == nullptr; - var->m_callback = fcn; - var->m_arg = arg; + cv->m_flags |= (cv->m_flags & 0xFFFFFFCF); + + cv->m_callback = fcn; + cv->m_arg = arg; bool setValue = false; - if (fcn && !fcn(var, var->GetString(), var->GetString(), arg)) { + if (fcn && !fcn(cv, cv->GetString(), cv->GetString(), arg)) { setValue = true; } - var->Set(value, setValue, setReset, setDefault, false); + cv->Set(value, setValue, setReset, setDefault, false); - if (!setCommand) { - var->m_flags |= 0x80000000; + if (!a7) { + cv->m_flags |= 0x80000000; } - if (a9 && var->m_flags) { - var->m_flags |= 0x80; + if (a9 && cv->m_flags) { + cv->m_flags |= 0x80; } } else { - var = CVar::s_registeredCVars.New(name, 0, 0); + cv = s_registeredCVars.New(name, 0, 0); - var->m_stringValue.Copy(nullptr); - var->m_floatValue = 0.0f; - var->m_intValue = 0; - var->m_modified = 0; - var->m_category = category; - var->m_defaultValue.Copy(nullptr); - var->m_resetValue.Copy(nullptr); - var->m_latchedValue.Copy(nullptr); - var->m_callback = fcn; - var->m_flags = 0; - var->m_arg = arg; - var->m_help.Copy(help); + cv->m_stringValue.Copy(nullptr); + cv->m_floatValue = 0.0f; + cv->m_intValue = 0; + cv->m_modified = 0; + cv->m_category = category; + cv->m_defaultValue.Copy(nullptr); + cv->m_resetValue.Copy(nullptr); + cv->m_latchedValue.Copy(nullptr); + cv->m_callback = fcn; + cv->m_flags = 0; + cv->m_arg = arg; + cv->m_help.Copy(help); - if (setCommand) { - var->Set(value, true, true, false, false); + if (a7) { + cv->Set(value, true, true, false, false); } else { - var->Set(value, true, false, true, false); + cv->Set(value, true, false, true, false); } - var->m_flags = flags | 0x1; + cv->m_flags = flags | 0x1; - if (!setCommand) { - var->m_flags |= 0x8000000; + if (!a7) { + cv->m_flags |= 0x8000000; } - if (a9 && var->m_flags) { - var->m_flags |= 0x80; + if (a9 && cv->m_flags) { + cv->m_flags |= 0x80; } ConsoleCommandRegister(name, CvarCommandHandler, CATEGORY(category), help); } - return var; + return cv; } CVar::CVar() : TSHashObject() { @@ -153,6 +169,14 @@ bool CVar::Set(const char* value, bool setValue, bool setReset, bool setDefault, return true; } +void CVar::SetReadOnly(bool readonly) { + if (readonly) { + this->m_flags |= 0x4; + } else { + this->m_flags &= ~(0x4); + } +} + bool CVar::Reset() { auto value = this->m_resetValue; if (value.GetString() == nullptr) { @@ -193,53 +217,44 @@ static int32_t s_CreatePathDirectories(const char* szPath) { } int32_t CVar::Load(HOSFILE file) { - char fastData[2048] = {0}; - char line[2048] = {0}; + char fastData[CONSOLE_CVAR_MAX_LINE]; + char line[CONSOLE_CVAR_MAX_LINE]; + uint32_t bytesRead; auto size = OsGetFileSize(file); - - char* data = nullptr; - - if (0x1fff < size) { - data = reinterpret_cast(SMemAlloc(size + 1, __FILE__, __LINE__, 0)); - } else { - data = fastData; - } - - auto grown = 0x1fff < size; - - int32_t result = 0; - uint32_t bytesRead = 0; - - if (OsReadFile(file, data, size, &bytesRead) == 0) { - result = 0; - } else { - data[size] = '\0'; - const char* curr = data; - - // Skip over UTF-8 byte order mark - if ((((data != nullptr) && (2 < bytesRead)) && (data[0] == 0xef)) && ((data[1] == 0xbb && (data[2] == 0xbf)))) { - curr = data + 3; + auto data = size >= CONSOLE_CVAR_MAX_LINE ? reinterpret_cast(ALLOC(size + 1)) : fastData; + if (!OsReadFile(file, data, size, &bytesRead)) { + if (fastData != data) { + FREE(data); } - - do { - SStrTokenize(&curr, line, 0x800, "\r\n", 0); - - // Do not execute commands other than "set ..." - if (SStrCmpI(line, "SET ", 4) == 0) { - // Execute without adding to history - ConsoleCommandExecute(line, 0); - } - - result = 1; - } while ((curr != nullptr) && (*curr != '\0')); + return 0; } - if (grown) { - SMemFree(data, __FILE__, __LINE__, 0); + const char* curr = data; + + data[size] = '\0'; + // Skip over UTF-8 byte order mark + if (data && bytesRead >= 3) { + if (data[0] == '\xEF' && data[1] == '\xBB' && data[2] == '\xBF') { + curr += 3; + } } - return result; + do { + SStrTokenize(&curr, line, CONSOLE_CVAR_MAX_LINE, "\r\n", 0); + + // Do not execute commands other than "set ..." + if (SStrCmpI(line, "SET ", 4) == 0) { + // Execute without adding to history + ConsoleCommandExecute(line, 0); + } + } while (curr && *curr); + + if (fastData != data) { + FREE(data); + } + + return 1; } int32_t CVar::Load(const char* filename) { @@ -273,14 +288,10 @@ void CVar::Initialize(const char* filename) { s_CreatePathDirectories(path); - static ConsoleCommandList baseCommands[] = { - { "set", SetCommandHandler, "Set the value of a CVar" }, - { "cvar_reset", CvarResetCommandHandler, "Set the value of a CVar to it's startup value" }, - { "cvar_default", CvarDefaultCommandHandler, "Set the value of a CVar to it's coded default value" }, - { "cvarlist", CvarListCommandHandler, "List cvars" } - }; - - CONSOLE_REGISTER_LIST(DEFAULT, baseCommands); + ConsoleCommandRegister("set", SetCommandHandler, DEFAULT, "Set the value of a CVar"); + ConsoleCommandRegister("cvar_reset", CvarResetCommandHandler, DEFAULT, "Set the value of a CVar to it's startup value"); + ConsoleCommandRegister("cvar_default", CvarDefaultCommandHandler, DEFAULT, "Set the value of a CVar to it's coded default value"); + ConsoleCommandRegister("cvarlist", CvarListCommandHandler, DEFAULT, "List cvars"); CVar::Load(s_filename); } diff --git a/src/console/CVar.hpp b/src/console/CVar.hpp index 41df648..6f87974 100644 --- a/src/console/CVar.hpp +++ b/src/console/CVar.hpp @@ -1,32 +1,26 @@ -#ifndef CONSOLE_C_VAR_HPP -#define CONSOLE_C_VAR_HPP +#ifndef CONSOLE_CVAR_HPP +#define CONSOLE_CVAR_HPP #include #include #include #include -#include "console/Types.hpp" +#define CONSOLE_CVAR_MAX_LINE 2048 + class CVar : public TSHashObject { public: + typedef bool (*HANDLER_FUNC)(CVar*, const char*, const char*, void*); + // Static variables static TSHashTable s_registeredCVars; static bool m_needsSave; // Static functions static CVar* Lookup(const char* name); - static CVar* Register( - const char* name, - const char* help, - uint32_t flags, - const char* value, - bool (*fcn)(CVar*, const char*, const char*, void*) = nullptr, - uint32_t category = CATEGORY::DEFAULT, - bool setCommand = false, - void* arg = nullptr, - bool a9 = false - ); + static CVar* LookupRegistered(const char* name); + static CVar* Register(const char* name, const char* help, uint32_t flags, const char* value, HANDLER_FUNC fcn, uint32_t category, bool a7, void* arg, bool a9); static void Initialize(const char* filename); static int32_t Load(const char* filename); static int32_t Load(HOSFILE fileHandle); @@ -49,7 +43,8 @@ class CVar : public TSHashObject { int32_t GetInt(); const char* GetString(void); void InternalSet(const char*, bool, bool, bool, bool); - bool Set(const char* value, bool setValue, bool setReset, bool setDefault, bool a6); + bool Set(const char*, bool, bool, bool, bool); + void SetReadOnly(bool readonly); bool Reset(); bool Default(); int32_t Update(); diff --git a/src/console/Client.cpp b/src/console/Client.cpp index 6f2c419..d88503d 100644 --- a/src/console/Client.cpp +++ b/src/console/Client.cpp @@ -1,6 +1,7 @@ #include "console/Client.hpp" #include "console/Command.hpp" #include "console/CVar.hpp" +#include "console/Console.hpp" void ConsoleInitializeClientCommand() { ConsoleCommandInitialize(); @@ -15,3 +16,7 @@ void ConsoleInitializeClientCVar(const char* a1) { int32_t ConsoleLoadClientCVar(const char* a1) { return CVar::Load(a1); } + +void ConsoleDestroyClientCommand() { + ConsoleCommandDestroy(); +} diff --git a/src/console/Client.hpp b/src/console/Client.hpp index 082c1d4..6625cae 100644 --- a/src/console/Client.hpp +++ b/src/console/Client.hpp @@ -9,4 +9,6 @@ void ConsoleInitializeClientCVar(const char* a1); int32_t ConsoleLoadClientCVar(const char* a1); +void ConsoleDestroyClientCommand(); + #endif diff --git a/src/console/Command.cpp b/src/console/Command.cpp index 7259618..cb5baba 100644 --- a/src/console/Command.cpp +++ b/src/console/Command.cpp @@ -1,11 +1,26 @@ #include "console/Command.hpp" +#include "console/Console.hpp" #include "console/Line.hpp" - +#include "console/Types.hpp" +#include "console/command/Commands.hpp" +#include #include #include -#include -#include +int32_t s_completionMode = 0; +const char* s_completedCmd = nullptr; +char s_partial[256]; + +char s_repeatBuffer[64]; +uint32_t s_repeatCount = 0; + +TSHashTable g_consoleCommandHash; + +char g_commandHistory[CONSOLE_COMMAND_HISTORY_DEPTH][CONSOLE_COMMAND_BUFFER_SIZE]; +uint32_t g_commandHistoryIndex; + +char g_ExecBuffer[CONSOLE_COMMAND_EXEC_BUFFER_SIZE] = { 0 }; +EXECMODE g_ExecCreateMode = EM_NOTACTIVE; int32_t ValidateFileName(const char* filename) { if (SStrStr(filename, "..") || SStrStr(filename, "\\")) { @@ -25,12 +40,6 @@ int32_t ValidateFileName(const char* filename) { return 1; } -TSHashTable g_consoleCommandHash; -char g_commandHistory[CONSOLE_HISTORY_DEPTH][CONSOLE_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]; @@ -45,7 +54,7 @@ int32_t AddLineToExecFile(const char* currentLine) { SStrPrintf(stringToWrite, sizeof(stringToWrite), "%s\n", currentLine); - if (((sizeof(g_ExecBuffer)-1) - SStrLen(g_ExecBuffer)) != SStrLen(stringToWrite)){ + if (((CONSOLE_COMMAND_EXEC_BUFFER_SIZE - 1) - SStrLen(g_ExecBuffer)) != SStrLen(stringToWrite)) { SStrPack(g_ExecBuffer, stringToWrite, sizeof(g_ExecBuffer)); } @@ -64,37 +73,89 @@ int32_t AddLineToExecFile(const char* currentLine) { return 0; } - // TODO + ConsoleWrite("Begin Typing the commands", ECHO_COLOR); + g_ExecCreateMode = EM_RECORDING; return 1; } +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 i = 0; + while (i < CONSOLE_COMMAND_MAX_LENGTH) { + int32_t chars; + + auto code = SUniSGetUTF8(reinterpret_cast(string), &chars); + if (code == -1 || code == ' ' || chars > CONSOLE_COMMAND_MAX_LENGTH) { + break; + } + + if (chars) { + for (size_t j = 0; j < chars; j++) { + *cmdptr++ = *string++; + } + } + + i += chars; + } + + *cmdptr = '\0'; + + if (command) { + *command = cmd; + } + + auto argptr = arguments; + if (argptr) { + int32_t chars; + + auto code = SUniSGetUTF8(reinterpret_cast(string), &chars); + + // Discard space + while (code != -1 && code == ' ') { + string += chars; + code = SUniSGetUTF8(reinterpret_cast(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); +} void ConsoleCommandDestroy() { g_consoleCommandHash.Clear(); } -char* ConsoleCommandHistory(uint32_t index) { - // Return a pointer to the buffer at the specified index - return g_commandHistory[((g_commandHistoryIndex + (CONSOLE_HISTORY_DEPTH - 1) - index) & (CONSOLE_HISTORY_DEPTH - 1))]; +const char* ConsoleCommandHistory(uint32_t index) { + return g_commandHistory[((g_commandHistoryIndex - index) - 1) & (CONSOLE_COMMAND_HISTORY_DEPTH - 1)]; } void AddToHistory(const char* command) { SStrCopy(g_commandHistory[g_commandHistoryIndex], command, CONSOLE_LINE_LENGTH); - g_commandHistoryIndex = (g_commandHistoryIndex + 1) & (CONSOLE_HISTORY_DEPTH-1); + g_commandHistoryIndex = (g_commandHistoryIndex + 1) & (CONSOLE_COMMAND_HISTORY_DEPTH - 1); } uint32_t ConsoleCommandHistoryDepth() { - return CONSOLE_HISTORY_DEPTH; + return CONSOLE_COMMAND_HISTORY_DEPTH; } int32_t ConsoleCommandRegister(const char* command, COMMANDHANDLER handler, CATEGORY category, const char* helpText) { STORM_ASSERT(command); STORM_ASSERT(handler); - if (SStrLen(command) > (CONSOLE_MAX_CMD_LENGTH - 1) || g_consoleCommandHash.Ptr(command)) { - // The command name exceeds CONSOLE_MAX_CMD_LENGTH, minus the null terminator - // or it has already been registered + if (SStrLen(command) >= CONSOLE_COMMAND_MAX_LENGTH || g_consoleCommandHash.Ptr(command)) { return 0; } @@ -116,106 +177,21 @@ void ConsoleCommandUnregister(const char* command) { } } -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(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(string), &chars); - - // Discard space - while (code != -1 && code == ' ') { - string += chars; - code = SUniSGetUTF8(reinterpret_cast(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); -} - -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; -} - -void ConsoleCommandExecute(char* commandLine, int32_t addToHistory) { +void ConsoleCommandExecute(const 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(SMemAlloc(CONSOLE_CMD_BUFFER_SIZE, __FILE__, __LINE__, 0)); - - auto cmd = ParseCommand(commandLine, &command, arguments, CONSOLE_CMD_BUFFER_SIZE); + auto arguments = reinterpret_cast(ALLOC(CONSOLE_COMMAND_BUFFER_SIZE)); + auto cmd = ParseCommand(commandLine, &command, arguments, CONSOLE_COMMAND_BUFFER_SIZE); if (cmd) { cmd->m_handler(command, arguments); } else { @@ -223,45 +199,25 @@ void ConsoleCommandExecute(char* commandLine, int32_t addToHistory) { } 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.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++; + FREE(arguments); } } void ConsoleInitializeScreenCommand() { - CONSOLE_REGISTER_LIST(CONSOLE, s_consoleSpecificCommands); + ConsoleCommandRegister("fontcolor", ConsoleCommand_FontColor, CONSOLE, "[ColorClassName] [Red 0-255] [Green 0-255] [Blue 0-255]"); + ConsoleCommandRegister("bgcolor", ConsoleCommand_BackGroundColor, CONSOLE, "[alpha 0-255] [Red 0-255] [Green 0-255] [Blue 0-255]"); + ConsoleCommandRegister("highlightcolor", ConsoleCommand_HighLightColor, CONSOLE, "[alpha 0-255] [Red 0-255] [Green 0-255] [Blue 0-255]"); + ConsoleCommandRegister("fontsize", ConsoleCommand_FontSize, CONSOLE, "[15-50] arbitrary font size"); + ConsoleCommandRegister("font", ConsoleCommand_Font, CONSOLE, "[fontname] make sure to use the .ttf file name"); + ConsoleCommandRegister("consolelines", ConsoleCommand_BufferSize, CONSOLE, "[number] number of lines to show in the console"); + ConsoleCommandRegister("clear", ConsoleCommand_ClearConsole, CONSOLE, "Clears the console buffer"); + ConsoleCommandRegister("proportionaltext", ConsoleCommand_Proportional, CONSOLE, "Toggles fixed-width text characters"); + ConsoleCommandRegister("spacing", ConsoleCommand_CharSpacing, CONSOLE, "[float] specifies inter-character spacing, in pixels"); + ConsoleCommandRegister("settings", ConsoleCommand_CurrentSettings, CONSOLE, "Shows current font and console settings"); + ConsoleCommandRegister("default", ConsoleCommand_DefaultSettings, CONSOLE, "Resets all the font and console settings"); + ConsoleCommandRegister("closeconsole", ConsoleCommand_CloseConsole, CONSOLE, "Closes the Console window"); + ConsoleCommandRegister("repeat", ConsoleCommand_RepeatHandler, CONSOLE, "Repeats a command"); + ConsoleCommandRegister("AppendLogToFile", ConsoleCommand_AppendLogToFile, CONSOLE, "[filename = ConsoleLogs/Log.txt] [numLines = all]"); } void ConsoleCommandInitialize() { @@ -269,9 +225,36 @@ void ConsoleCommandInitialize() { } void ConsoleInitializeCommonCommand() { - CONSOLE_REGISTER_LIST(DEFAULT, s_commonCommands); + ConsoleCommandRegister("quit", ConsoleCommand_Quit, DEFAULT, nullptr); + ConsoleCommandRegister("ver", ConsoleCommand_Ver, DEFAULT, nullptr); + ConsoleCommandRegister("setmap", ConsoleCommand_SetMap, DEFAULT, nullptr); } void ConsoleInitializeDebugCommand() { // TODO } + +int32_t ConsoleCommandComplete(const char* partial, const char** previous, int32_t direction) { + auto current = g_consoleCommandHash.Head(); + + if (*previous) { + auto cmd = g_consoleCommandHash.Ptr(*previous); + if (!cmd) { + return 0; + } + // TODO: double check this + current = g_consoleCommandHash.Next(direction ? cmd : cmd->m_linktoslot.Prev()); + } + + auto len = SStrLen(partial); + while (current) { + // console command found + if (SStrCmpI(partial, current->m_key.m_str, len) == 0) { + *previous = current->m_key.m_str; + return 1; + } + current = g_consoleCommandHash.Next(current); + } + + return 0; +} diff --git a/src/console/Command.hpp b/src/console/Command.hpp index d902e82..7e92571 100644 --- a/src/console/Command.hpp +++ b/src/console/Command.hpp @@ -2,67 +2,43 @@ #define CONSOLE_COMMAND_HPP #include "console/Types.hpp" - -#include #include +#include -#define CONSOLE_REGISTER_LIST(category, list) RegisterConsoleCommandList(category, list, sizeof(list) / sizeof(ConsoleCommandList)) +#define CONSOLE_COMMAND_EXEC_BUFFER_SIZE 8192 +#define CONSOLE_COMMAND_BUFFER_SIZE 1024 +#define CONSOLE_COMMAND_MAX_LENGTH 64 +#define CONSOLE_COMMAND_HISTORY_DEPTH 32 -#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 +class CONSOLECOMMAND : public TSHashObject { + public: + COMMANDHANDLER m_handler; + const char* m_helpText; + CATEGORY m_category; +}; + +extern int32_t s_completionMode; +extern const char* s_completedCmd; +extern char s_partial[256]; +extern char s_repeatBuffer[64]; +extern uint32_t s_repeatCount; extern TSHashTable g_consoleCommandHash; -extern char g_commandHistory[CONSOLE_HISTORY_DEPTH][CONSOLE_CMD_BUFFER_SIZE]; -extern uint32_t g_commandHistoryIndex; -extern char g_ExecBuffer[CONSOLE_EXEC_BUFFER_SIZE]; -void ConsoleCommandDestroy(); +void ConsoleCommandInitialize(); -char* ConsoleCommandHistory(uint32_t index); +const char* ConsoleCommandHistory(uint32_t index); uint32_t ConsoleCommandHistoryDepth(); int32_t ConsoleCommandRegister(const char* command, COMMANDHANDLER handler, CATEGORY category, const char* helpText); -void ConsoleCommandInitialize(); - void ConsoleInitializeCommonCommand(); void ConsoleInitializeDebugCommand(); void ConsoleInitializeScreenCommand(); -void RegisterConsoleCommandList(CATEGORY category, ConsoleCommandList list[], size_t count); - -void ConsoleCommandUnregister(const char* command); - -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); +int32_t ConsoleCommandComplete(const char* partial, const char** previous, int32_t direction); #endif diff --git a/src/console/Console.cpp b/src/console/Console.cpp index 8bb1a29..fe1943b 100644 --- a/src/console/Console.cpp +++ b/src/console/Console.cpp @@ -1,13 +1,9 @@ #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() { @@ -22,18 +18,6 @@ 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; } @@ -50,14 +34,6 @@ void ConsoleSetHotKey(KEY hotkey) { s_consoleKey = hotkey; } -void ConsoleSetResizeState(CONSOLERESIZESTATE state) { - s_consoleResizeState = state; -} - -void ConsoleSetHeight(float height) { - s_consoleHeight = height; -} - void ConsolePostClose() { EventPostCloseEx(EventGetCurrentContext()); } diff --git a/src/console/Console.hpp b/src/console/Console.hpp index 4bcae1a..111c557 100644 --- a/src/console/Console.hpp +++ b/src/console/Console.hpp @@ -1,7 +1,6 @@ #ifndef CONSOLE_CONSOLE_HPP #define CONSOLE_CONSOLE_HPP -#include "console/Line.hpp" #include "console/Types.hpp" #include "event/Types.hpp" #include @@ -12,24 +11,28 @@ void ConsoleAccessSetEnabled(int32_t enable); int32_t ConsoleGetActive(); -float ConsoleGetFontHeight(); - -float ConsoleGetLines(); - -float ConsoleGetHeight(); - KEY ConsoleGetHotKey(); -CONSOLERESIZESTATE ConsoleGetResizeState(); - void ConsoleSetActive(int32_t active); void ConsoleSetHotKey(KEY hotkey); -void ConsoleSetHeight(float height); +void ConsoleCommandDestroy(); -void ConsoleSetResizeState(CONSOLERESIZESTATE state); +int32_t ConsoleCommandRegister(const char* command, COMMANDHANDLER handler, CATEGORY category, const char* helpText); + +void ConsoleCommandUnregister(const char* command); + +void ConsoleCommandExecute(const char* commandLine, int32_t addToHistory); void ConsolePostClose(); -#endif // ifndef CONSOLE_CONSOLE_HPP +void ConsoleWrite(const char* str, COLOR_T color); + +void ConsolePrintf(const char* str, ...); + +void ConsoleWriteA(const char* str, COLOR_T color, ...); + +void ConsoleClear(); + +#endif diff --git a/src/console/Detect.cpp b/src/console/Detect.cpp new file mode 100644 index 0000000..15ae97e --- /dev/null +++ b/src/console/Detect.cpp @@ -0,0 +1,467 @@ +#include "console/Detect.hpp" +#include "db/Db.hpp" +#include "db/Startup_Strings.hpp" +#include "gx/CGxFormat.hpp" +#include "gx/Device.hpp" +#include "os/Debug.hpp" +#include "os/Gui.hpp" +#include +#include + +#if defined(WHOA_SYSTEM_MAC) +#include +#include +#endif + +WowClientDB g_videoHardwareDB; + +CGxFormat s_formats[7] = { + { 0, { 640, 480 }, CGxFormat::Fmt_Rgb565, CGxFormat::Fmt_Ds160, 60, 1, true, false, true, true, false }, + { 0, { 800, 600 }, CGxFormat::Fmt_Rgb565, CGxFormat::Fmt_Ds160, 60, 1, true, false, true, true, false }, + { 0, { 640, 480 }, CGxFormat::Fmt_ArgbX888, CGxFormat::Fmt_Ds24X, 60, 1, true, false, true, true, false }, + { 0, { 800, 600 }, CGxFormat::Fmt_ArgbX888, CGxFormat::Fmt_Ds24X, 60, 1, true, false, true, true, false }, + { 0, { 1024, 768 }, CGxFormat::Fmt_ArgbX888, CGxFormat::Fmt_Ds24X, 60, 1, true, false, true, true, false }, + { 0, { 1280, 1024 }, CGxFormat::Fmt_ArgbX888, CGxFormat::Fmt_Ds24X, 60, 1, true, false, true, true, false }, + { 0, { 1600, 1200 }, CGxFormat::Fmt_ArgbX888, CGxFormat::Fmt_Ds24X, 60, 1, true, false, true, true, false } +}; + +CpuHardware s_cpuHwSettings[2] = { + { 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1 } +}; + +SoundHardware s_soundHwSettings[1] = { + { 1, false } +}; + +uint32_t s_detailDoodadDensity[4] = { + 8, + 12, + 16, + 24 +}; + +bool s_animatingDoodads[2][2] = { + { false, false }, + { false, true } +}; + +uint32_t s_waterLOD[2][2] = { + { 0, 0 }, + { 0, 1 } +}; + +float s_particleDensity[4][2] = { + { 0.3f, 0.4f }, + { 0.5f, 0.6f }, + { 0.9f, 1.0f }, + { 1.0f, 1.0f } +}; + +float s_unitDrawDist[4][2] = { + { 35.0f, 50.0f }, + { 50.0f, 75.0f }, + { 75.0f, 300.0f }, + { 300.0f, 300.0f } +}; + +float s_smallCull[4][2] = { + { 0.08f, 0.08f }, + { 0.07f, 0.07f }, + { 0.07f, 0.07f }, + { 0.04f, 0.04f } +}; + +float s_distCull[4][2] = { + { 350.0f, 350.0f }, + { 400.0f, 400.0f }, + { 450.0f, 450.0f }, + { 500.0f, 500.0f }, +}; + +float s_farClip[5][2] = { + { 200.0f, 277.0f }, + { 300.0f, 350.0f }, + { 350.0f, 400.0f }, + { 450.0f, 550.0f }, + { 450.0f, 777.0f } +}; + +void AddResolution(TSGrowableArray& resolutions, const C2iVector& resolution) { + resolutions.Add(1, &resolution); +} + +void ConsoleDetectGetResolutions(TSGrowableArray& resolutions, int32_t widescreen) { + if (widescreen) { + TSGrowableArray modes; + GxAdapterMonitorModes(modes); + + C2iVector prev = { 0, 0 }; + + for (uint32_t i = 0; i < modes.Count(); i++) { + auto& mode = modes[i]; + if ((static_cast(mode.size.x) / static_cast(mode.size.y)) > 1.248f && + mode.size.x >= 640 && + mode.size.y >= 480 && + mode.size.x != prev.x && mode.size.y != prev.y) { + AddResolution(resolutions, mode.size); + prev = mode.size; + } + } + } + + if (!resolutions.Count() || !widescreen) { + // Add generic 4:3 fallback resolutions + AddResolution(resolutions, { 640, 480 }); + AddResolution(resolutions, { 800, 600 }); + AddResolution(resolutions, { 1024, 768 }); + AddResolution(resolutions, { 1152, 864 }); + AddResolution(resolutions, { 1280, 960 }); + AddResolution(resolutions, { 1280, 1024 }); + AddResolution(resolutions, { 1600, 1200 }); + } +} + +void ConsoleDetectSaveHardware(Hardware& hardware, bool& hwChanged) { + uint32_t cpuIdx; + uint32_t memIdx; + uint32_t videoID; + uint32_t soundIdx; + + if (!SRegLoadValue("World of Warcraft\\Client", "HWCpuIdx", 0, &cpuIdx)) { + cpuIdx = hardware.cpuIdx; + } + if (!SRegLoadValue("World of Warcraft\\Client", "HWMemIdx", 0, &memIdx)) { + memIdx = hardware.memIdx; + } + if (!SRegLoadValue("World of Warcraft\\Client", "HWVideoID", 0, &videoID)) { + videoID = hardware.videoID; + } + if (!SRegLoadValue("World of Warcraft\\Client", "HWSoundIdx", 0, &soundIdx)) { + soundIdx = hardware.soundIdx; + } + + bool v2 = (((videoID == 1 || videoID == 168) || (videoID == 169)) || videoID == 170); + if (hardware.cpuIdx == cpuIdx && hardware.memIdx == memIdx && (v2 || hardware.videoID == videoID) && hardware.soundIdx == soundIdx) { + hwChanged = false; + } else { +#if defined(WHOA_SYSTEM_WIN) || defined(WHOA_SYSTEM_LINUX) + auto titleRecord = g_Startup_StringsDB.GetRecord(MSG_TITLE_WOW); + auto title = titleRecord ? titleRecord->m_message : "World of Warcraft"; + auto hwChangedMessageRecord = g_Startup_StringsDB.GetRecord(MSG_HW_CHANGED); + auto message = hwChangedMessageRecord ? hwChangedMessageRecord->m_message : "Hardware changed. Reload default settings?"; + + hwChanged = !OsGuiMessageBox(OsGuiGetWindow(2), 2, message, title); +#endif +#if defined(WHOA_SYSTEM_MAC) + hwChanged = true; +#endif + } + + SRegSaveValue("World of Warcraft\\Client", "HWCpuIdx", 0, hardware.cpuIdx); + SRegSaveValue("World of Warcraft\\Client", "HWMemIdx", 0, hardware.memIdx); + SRegSaveValue("World of Warcraft\\Client", "HWVideoID", 0, hardware.videoID); + SRegSaveValue("World of Warcraft\\Client", "HWSoundIdx", 0, hardware.soundIdx); +} + +[[noreturn]] void PrintStartupError(int32_t messageID, const char* fallbackMessage) { + auto titleRecord = g_Startup_StringsDB.GetRecord(MSG_TITLE_WOW); + auto title = titleRecord ? titleRecord->m_message : "World of Warcraft"; + auto messageRecord = g_Startup_StringsDB.GetRecord(messageID); + auto message = messageRecord ? messageRecord->m_message : fallbackMessage; + + OsGuiMessageBox(OsGuiGetWindow(2), 0, message, title); + + exit(0); +} + +void SetVideoIdx(Hardware& hardware) { + int32_t index = 1; + + while (index < g_videoHardwareDB.m_numRecords) { + auto videoHw = g_videoHardwareDB.GetRecordByIndex(index); + if (hardware.videoDevice.vendorID == videoHw->m_vendorID && + hardware.videoDevice.deviceID == videoHw->m_deviceID) { + hardware.videoID = videoHw->m_ID; + } + index++; + } +} + +#if defined(WHOA_SYSTEM_WIN) || defined(WHOA_SYSTEM_LINUX) + +void ConsoleDetectDetectHardware(Hardware& hardware, bool& hwChanged) { + // anti-feature + + // if (OsIsRemoteSession()) { + // PrintStartupError(12, "Running World of Warcraft through a Remote Desktop connection is not supported. Exiting program."); + // } + + // + + g_videoHardwareDB.Load(__FILE__, __LINE__); + + hardware.cpuIdx = (static_cast(OsGetProcessorTicksPerSecond()) * 0.000001f) > 1500.0f; + hardware.memIdx = 0; + hardware.videoID = 0; + + if (GxAdapterID(hardware.videoDevice.vendorID, + hardware.videoDevice.deviceID, + hardware.videoDevice.driverVersionHi, + hardware.videoDevice.driverVersionLo)) { + SetVideoIdx(hardware); + } + + if (!hardware.videoID) { + hardware.videoDevice.vendorID = 0xFFFF; + if (GxAdapterInfer(hardware.videoDevice.deviceID)) { + SetVideoIdx(hardware); + } + + if (!hardware.videoID) { + PrintStartupError(MSG_GX_NO_DEVICE, "Failed to find a suitable display device. Exiting program."); + } + } + + hardware.cpuHw = &s_cpuHwSettings[hardware.cpuIdx]; + hardware.videoHw = g_videoHardwareDB.GetRecord(hardware.videoID); + hardware.soundHw = &s_soundHwSettings[hardware.soundIdx]; + + ConsoleDetectSaveHardware(hardware, hwChanged); + + char str[1024]; + GxLog("ConsoleDetectDetectHardware():"); + SStrPrintf(str, 1024, "\tcpuIdx: %d", hardware.cpuIdx); + GxLog(str); + SStrPrintf(str, 1024, "\tvideoID: %d", hardware.videoID); + GxLog(str); + SStrPrintf(str, 1024, "\tsoundIdx: %d", hardware.soundIdx); + GxLog(str); + SStrPrintf(str, 1024, "\tmemIdx: %d", hardware.memIdx); + GxLog(str); +} + +#endif + +#if defined(WHOA_SYSTEM_MAC) + +uint32_t FindVRAMSize() { + CGDirectDisplayID activeDisplays[32]; + uint32_t displayCount; + if (CGGetActiveDisplayList(32, activeDisplays, &displayCount)) { + return 0; + } + + CGLRendererInfoObj rend; + GLint nrend; + GLint accelerated; + GLint vram_size; + + auto display_mask = CGDisplayIDToOpenGLDisplayMask(activeDisplays[0]); + if (!CGLQueryRendererInfo(display_mask, &rend, &nrend)) { + CGLDescribeRenderer(rend, 0, kCGLRPRendererCount, &nrend); + for (int32_t i = 0; i < nrend; i++) { + CGLDescribeRenderer(rend, i, kCGLRPAccelerated, &accelerated); + if (accelerated) { + CGLDescribeRenderer(rend, i, kCGLRPVideoMemory, &vram_size); + CGLDestroyRendererInfo(rend); + return static_cast(vram_size); + } + } + } + + CGLDestroyRendererInfo(rend); + return 0; +} + +void ConsoleDetectDetectHardware(Hardware& hardware, bool& hwChanged) { + g_videoHardwareDB.Load(__FILE__, __LINE__); + + if (GxAdapterID(hardware.videoDevice.vendorID, + hardware.videoDevice.deviceID, + hardware.videoDevice.driverVersionHi, + hardware.videoDevice.driverVersionLo)) { + SetVideoIdx(hardware); + } + + if (!hardware.videoIdx) { + hardware.videoDevice.vendorID = 0xFFFF; + if (GxAdapterInfer(hardware.videoDevice.deviceID)) { + SetVideoIdx(hardware); + } + } + + uint32_t hw_cputype = 0; + uint32_t hw_cpusubtype = 0; + uint32_t hw_ncpu = 0; + uint64_t hw_cpufrequency_max = 0; + uint64_t hw_busfrequency_max = 0; + uint64_t hw_l2cachesize = 0; + uint64_t hw_l3cachesize = 0; + + size_t size32 = sizeof(uint32_t); + size_t size64 = sizeof(uint64_t); + + uint32_t hw_cputype; + auto hw_cputype_error = sysctlbyname("hw.cputype", &hw_cputype, &size32, nullptr, 0); + if (hw_cputype_error) { + OsOutputDebugString("[Mac sys detect] ! error %d reading hw.cputype\n", hw_cputype_error); + } + + auto hw_cpusubtype_error = sysctlbyname("hw.cpusubtype", &hw_cpusubtype, &size32, nullptr, 0); + if (hw_cpusubtype_error) { + OsOutputDebugString("[Mac sys detect] ! error %d reading hw.cpusubtype\n", hw_cpusubtype_error); + } + + auto hw_ncpu_error = sysctlbyname("hw.ncpu", &hw_ncpu, &size32, nullptr, 0); + if (hw_ncpu_error) { + OsOutputDebugString("[Mac sys detect] ! error %d reading hw.ncpu\n", hw_ncpu_error); + } + + auto hw_cpufrequency_max_error = sysctlbyname("hw.cpufrequency_max", &hw_cpufrequency_max, &size64, nullptr, 0); + if (hw_cpufrequency_max_error) { + OsOutputDebugString("[Mac sys detect] ! error %d reading hw.cpufrequency_max\n", hw_cpufrequency_max_error); + } + + auto hw_busfrequency_max_error = sysctlbyname("hw.busfrequency_max", hw_busfrequency_max, &size64, nullptr, 0); + if (hw_busfrequency_max_error) { + OsOutputDebugString("[Mac sys detect] ! error %d reading hw.busfrequency_max\n", iVar6); + } + + auto hw_l2cachesize_error = sysctlbyname("hw.l2cachesize", &hw_l2cachesize, &size64, nullptr, 0); + if (hw_l2cachesize_error) { + hw_l2cachesize_error = 0; + OsOutputDebugString("[Mac sys detect] ! error %d reading hw.l2cachesize\n", hw_l2cachesize_error); + } + auto hw_l3cachesize_error = sysctlbyname("hw.l3cachesize", &hw_l3cachesize, &size64, nullptr, 0); + if (hw_l3cachesize_error) { + hw_l3cachesize_error = 0; + OsOutputDebugString("[Mac sys detect] ! error %d reading hw.l3cachesize\n", iVar8); + } + + auto hw_memsize_error = sysctlbyname("hw.memsize", &hw_memsize, &size64, nullptr, 0); + if (hw_memsize_error) { + OsOutputDebugString("[Mac sys detect] ! error %d reading hw.memsize\n", hw_memsize_error); + } + + auto vram_size = FindVRAMSize(); + + bool ddr_ram; + if (hw_busfrequency_max > 110000000 && (hw_busfrequency_max > 140000000 || h2_l3cachesize > 0xFFFFF && hw_l2cachesize > 0x7FFFF)) { + OsOutputDebugString("[Mac sys detect] - DDR RAM\n"); + ddr_ram = true; + } else { + OsOutputDebugString("[Mac sys detect] - non DDR RAM\n"); + ddr_ram = false; + } + + uint32_t cpuIdx; + uint32_t macTier; + + if (hw_cpusubtype_error || hw_cputype_error || hw_ncpu_error || hw_cpufrequency_max_error || hw_busfrequency_max_error || hw_l2cachesize_error || hw_l3cachesize_error || hw_memsize_error) { + OsOutputDebugString("[Mac sys detect] ! error reading specs, down to tier 0\n", v27); + cpuIdx = 0; + macTier = 0; + } else { + macTier = 3; + if (hw_ncpu < 2) { + OsOutputDebugString("[Mac sys detect] - non dual proc, down to tier 2\n"); + macTier = 2; + } + if (hw_busfrequency_max < 500000000) { + OsOutputDebugString("[Mac sys detect] - sub 500MHz FSB, down to tier 2\n"); + macTier = 2; + } + if (hw_memsize < 0x30000000) { + OsOutputDebugString("[Mac sys detect] - under 768MB RAM, down to tier 2\n"); + macTier = 2; + } + if (hw_cpufrequency_max < 1100000000) { + OsOutputDebugString("[Mac sys detect] - under 1.1GHz CPU, down to tier 1\n"); + macTier = 1; + } + if (vram_size < 0x4000000) { + OsOutputDebugString("[Mac sys detect] - < 64MB VRAM, down to tier 1\n"); + macTier = 1; + } + if (hw_cputype == 18 && hw_cpusubtype < 11) { + OsOutputDebugString("[Mac sys detect] - G3 or G4, down to tier 0\n"); + macTier = 0; + } + if (vram_size <= 0x2000000) { + OsOutputDebugString("[Mac sys detect] - <= 32 MB VRAM, down to tier 0\n"); + macTier = 0; + } + if (!ddr_ram) { + OsOutputDebugString("[Mac sys detect] - no DDR RAM, down to tier 0\n"); + macTier = 0; + } + if (hw_l2cachesize <= 0x40000 && hw_l3cachesize <= 0xFFFFF) { + OsOutputDebugString("[Mac sys detect] - L2 <= 256K and L3 <= 1MB, down to tier 0\n"); + macTier = 0; + } + if (hw_memsize < 0x20000000) { + OsOutputDebugString("[Mac sys detect] - < 512MB RAM, down to tier 0\n"); + cpuIdx = 0; + macTier = 0; + } else { + cpuIdx = macTier / 2; + } + } + + hardware.cpuIdx = cpuIdx; + hardware.memIdx = 0; + hardware.soundIdx = 0; + hardware.macTierIdx = macTier; + hardware.macVramMB = vram_size / 0x100000; + + hardware.cpuHw = s_cpuHwSettings[cpuIdx]; + hardware.videoHw = g_videoHardwareDB.GetRecord(hardware.videoID); + hardware.soundHw = s_soundHwSettings[hardware.soundIdx]; + + ConsoleDetectSaveHardware(hardware, hwChanged); + + char str[1024]; + GxLog("ConsoleDetectDetectHardware [Mac] ():"); + SStrPrintf(str, 1024, "\tcpuIdx: %d", hardware.cpuIdx); + GxLog(str); + SStrPrintf(str, 1024, "\tvideoID: %d", hardware.videoIdx); + GxLog(str); + SStrPrintf(str, 1024, "\tsoundIdx: %d", hardware.soundIdx); + GxLog(str); + SStrPrintf(str, 1024, "\tmemIdx: %d", hardware.memIdx); + GxLog(str); + SStrPrintf(str, 1024, "\tmacTierIdx: %d", hardware.macTierIdx); + GxLog(str); + SStrPrintf(str, 1024, "\tmacVramMB: %d", hardware.macVramMB); + GxLog(str); +} + +#endif + +void ConsoleDetectSetDefaultsFormat(DefaultSettings& defaults, const Hardware& hardware) { + defaults.format = &s_formats[hardware.videoHw->m_resolutionIdx]; +} + +void ConsoleDetectSetDefaults(DefaultSettings& defaults, const Hardware& hw) { + defaults.farClip = s_farClip[hw.videoHw->m_farclipIdx][hw.cpuHw->farclipIdx]; + defaults.terrainShadowLOD = hw.videoHw->m_terrainShadowLod; + defaults.detailDoodadDensity = s_detailDoodadDensity[hw.videoHw->m_detailDoodadDensityIdx]; + defaults.detailDoodadAlpha = hw.videoHw->m_detailDoodadAlpha; + defaults.animatingDoodads = s_animatingDoodads[hw.videoHw->m_animatingDoodadIdx][hw.cpuHw->animatingDoodadIdx]; + defaults.trilinear = hw.videoHw->m_trilinear != 0; + defaults.numLights = hw.videoHw->m_numLights; + auto specularity = hw.videoHw->m_specularity != 0; + defaults.unk1A = specularity; + defaults.specularity = specularity; + defaults.waterLOD = s_waterLOD[hw.videoHw->m_waterLodidx][hw.cpuHw->waterLODIdx]; + defaults.particleDensity = s_particleDensity[hw.videoHw->m_particleDensityIdx][hw.cpuHw->particleDensityIdx]; + defaults.unitDrawDist = s_unitDrawDist[hw.videoHw->m_unitDrawDistIdx][hw.cpuHw->unitDrawDistIdx]; + defaults.smallCull = s_smallCull[hw.videoHw->m_smallCullDistIdx][hw.cpuHw->smallCullDistIdx]; + defaults.distCull = s_distCull[hw.videoHw->m_smallCullDistIdx][hw.cpuHw->smallCullDistIdx]; + defaults.format = s_formats + hw.videoHw->m_resolutionIdx; + defaults.baseMipLevel = hw.videoHw->m_baseMipLevel; + defaults.unk19 = true; + defaults.numChannels = 0; + defaults.fivePointOne = false; +} diff --git a/src/console/Detect.hpp b/src/console/Detect.hpp new file mode 100644 index 0000000..266f094 --- /dev/null +++ b/src/console/Detect.hpp @@ -0,0 +1,74 @@ +#ifndef CONSOLE_DETECT_HPP +#define CONSOLE_DETECT_HPP + +#include +#include + +#include "gx/CGxFormat.hpp" + +#include "db/rec/VideoHardwareRec.hpp" + +struct CpuHardware { + uint32_t farclipIdx; + uint32_t animatingDoodadIdx; + uint32_t waterLODIdx; + uint32_t particleDensityIdx; + uint32_t smallCullDistIdx; + uint32_t unitDrawDistIdx; +}; + +struct SoundHardware { + uint32_t numChannels; + bool fivePointOne; +}; + +struct Hardware { + struct Device { + uint16_t vendorID; + uint16_t deviceID; + uint32_t driverVersionHi; + uint32_t driverVersionLo; + }; + + Device videoDevice; + Device soundDevice; + uint32_t cpuIdx; + uint32_t videoID; + uint32_t soundIdx; + uint32_t memIdx; + VideoHardwareRec* videoHw; + CpuHardware* cpuHw; + SoundHardware* soundHw; +}; + +struct DefaultSettings { + float farClip; + uint32_t terrainShadowLOD; + uint32_t detailDoodadDensity; + uint32_t detailDoodadAlpha; + bool animatingDoodads; + bool trilinear; + uint32_t numLights; + bool specularity; + bool unk19; + bool unk1A; + uint32_t waterLOD; + float particleDensity; + float unitDrawDist; + float smallCull; + float distCull; + CGxFormat* format; + uint32_t baseMipLevel; + uint32_t numChannels; + bool fivePointOne; +}; + +void ConsoleDetectGetResolutions(TSGrowableArray& list, int32_t widescreen); + +void ConsoleDetectDetectHardware(Hardware& hardware, bool& hwChanged); + +void ConsoleDetectSetDefaultsFormat(DefaultSettings& defaults, const Hardware& hardware); + +void ConsoleDetectSetDefaults(DefaultSettings& defaults, const Hardware& hw); + +#endif diff --git a/src/console/Device.cpp b/src/console/Device.cpp index c8b9fcb..4fff099 100644 --- a/src/console/Device.cpp +++ b/src/console/Device.cpp @@ -1,459 +1,345 @@ #include "console/Device.hpp" #include "client/CmdLine.hpp" -#include "client/Gui.hpp" -#include "console/Console.hpp" +#include "os/Gui.hpp" #include "console/CVar.hpp" -#include "console/Command.hpp" -#include "event/Input.hpp" -#include "gx/Gx.hpp" +#include "console/Console.hpp" +#include "console/Detect.hpp" +#include "console/Gx.hpp" +#include "console/cvar/Gx.hpp" +#include "os/Input.hpp" +#include "gx/CGxFormat.hpp" #include "gx/Device.hpp" -#include +#include "gx/Types.hpp" +#include "console/command/Commands.hpp" +#include "db/Startup_Strings.hpp" +#include +#include #include - +#include CVar* s_cvHwDetect; -CVar* s_cvGxFixedFunction; -CVar* s_cvGxWindowResizeLock; -CVar* s_cvGxVideoOptionsVersion; -CVar* s_cvGxMaxFPSBk; -CVar* s_cvGxMaxFPS; -CVar* s_cvGxOverride; -CVar* s_cvGxStereoEnabled; -CVar* s_cvGxFixLag; -CVar* s_cvGxMultisampleQuality; -CVar* s_cvGxMultisample; -CVar* s_cvGxCursor; -CVar* s_cvGxAspect; -CVar* s_cvGxVSync; -CVar* s_cvGxTripleBuffer; -CVar* s_cvGxRefresh; -CVar* s_cvGxDepthBits; -CVar* s_cvGxColorBits; -CVar* s_cvGxMaximize; -CVar* s_cvGxResolution; -CVar* s_cvGxWidescreen; -CVar* s_cvGxWindow; -CVar* s_cvGxApi; DefaultSettings s_defaults; -bool s_hwDetect; +Hardware s_hardware; +bool s_hardwareDetected; bool s_hwChanged; +bool s_hwDetect; +TSGrowableArray s_gxMonitorModes; +CGxDevice* s_device; +char s_windowTitle[256]; CGxFormat s_requestedFormat; +CGxFormat s_fallbackFormat = { 0, { 640, 480 }, CGxFormat::Fmt_Rgb565, CGxFormat::Fmt_Ds160, 60, true, true, false, true, true, false }; +CGxFormat s_lastGoodFormat; +CGxFormat s_desktopFormat = { 0, { 800, 600 }, CGxFormat::Fmt_Rgb565, CGxFormat::Fmt_Ds24X, 60, true, true, false, true, true, false }; -const char* g_gxApiNames[GxApis_Last] = { - "OpenGL", // GxApi_OpenGl - "D3D9", // GxApi_D3d9 - "D3D9Ex", // GxApi_D3d9Ex - "D3D10", // GxApi_D3d10 - "D3D11", // GxApi_D3d11 - "GLL", // GxApi_GLL - "GLSDL" // GxApi_GLSDL +uint32_t s_FormatTobpp[4] = { + 16, + 32, + 32, + 32 }; -EGxApi g_gxApiSupported[] = { -#if defined(WHOA_SYSTEM_WIN) - GxApi_D3d9, -#endif - -#if defined(WHOA_SYSTEM_MAC) - GxApi_GLL, -#endif - -#if defined(WHOA_BUILD_GLSDL) - GxApi_GLSDL, -#endif -}; - -size_t g_numGxApiSupported = sizeof(g_gxApiSupported) / sizeof(EGxApi); - - -bool CVGxWindowResizeLockCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; +void OnGxStereoChanged() { + // ??? } -bool GxVideoOptionsVersionCallback(CVar*, const char*, const char*, void*) { - return true; -} +void ValidateFormatMonitor(CGxFormat& fmt) { + static C2iVector standardSizes[] = { + { 1600, 1200 }, + { 1280, 1024 }, + { 1280, 960 }, + { 1152, 864 }, + { 1024, 768 }, + { 800, 600 }, + { 640, 480 } + }; -bool CVGxMaxFPSBkCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} + auto fmtbpp = s_FormatTobpp[fmt.colorFormat]; -bool CVGxMaxFPSCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} + int32_t lowRate = 9999; -bool CVGxOverrideCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} + int32_t i = 0; + while (i < s_gxMonitorModes.Count()) { + auto& size = s_gxMonitorModes[i].size; -bool CVGxStereoEnabledCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxFixLagCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxMultisampleQualityCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxMultisampleCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxCursorCallback(CVar*, const char*, const char* value, void*) { - s_requestedFormat.hwCursor = SStrToInt(value) != 0; - ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); - return true; -} - -bool CVGxAspectCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxVSyncCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxTripleBufferCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxRefreshCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxDepthBitsCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxColorBitsCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxMaximizeCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxResolutionCallback(CVar*, const char*, const char*, void*) { - // static C2iVector legalSizes[] = { - // {} - // } - - // TODO - return true; -} - -bool CVGxWindowCallback(CVar*, const char*, const char*, void*) { - // TODO - return true; -} - -bool CVGxApiCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { - for (size_t api = 0; api < g_numGxApiSupported; api++) { - auto apiString = g_gxApiNames[g_gxApiSupported[api]]; - if (SStrCmpI(newValue, apiString, STORM_MAX_STR) == 0) { - // New gxApi is supported, pass - ConsoleWrite("GxApi set pending gxRestart", DEFAULT_COLOR); - return true; + if (fmt.size.x == size.x && fmt.size.y == size.y && fmtbpp == s_gxMonitorModes[i].bpp) { + uint32_t refreshRate = s_gxMonitorModes[i].refreshRate; + if (refreshRate < lowRate) { + lowRate = refreshRate; + } + if (fmt.refreshRate == refreshRate) { + return; + } } + + i++; } - // Supported gxApi not supplied, show available apis - constexpr size_t msgsize = 1024; - char msg[msgsize] = {0}; - SStrPack(msg, "unsupported api, must be one of ", msgsize); - - for (size_t api = 0; api < g_numGxApiSupported; api++) { - if (api > 0) { - SStrPack(msg, ", ", msgsize); - } - auto apiString = g_gxApiNames[g_gxApiSupported[api]]; - SStrPack(msg, "'", msgsize); - SStrPack(msg, apiString, msgsize); - SStrPack(msg, "'", msgsize); + auto rate = lowRate; + if (lowRate == 9999) { + GxLog("ValidateFormatMonitor(): unable to find monitor refresh"); + rate = 60; } - ConsoleWrite(msg, DEFAULT_COLOR); - return false; + GxLog("ValidateFormatMonitor(): invalid refresh rate %d, set to %d", fmt.refreshRate, rate); + fmt.refreshRate = rate; } -int32_t CCGxRestart(const char*, const char*) { - // TODO - return 1; -} +void ConsoleDeviceStereoInitialize() { + s_cvGxStereoConvergence = CVar::Register( + "gxStereoConvergence", + "Set stereoscopic rendering convergence depth", + 0x1, + "1", + CVGxStereoConvergenceCallback, + GRAPHICS, + false, + nullptr, + false + ); + s_cvGxStereoSeparation = CVar::Register( + "gxStereoSeparation", + "Set stereoscopic rendering separation percentage", + 0x1, + "25", + CVGxStereoSeparationCallback, + GRAPHICS, + false, + nullptr, + false + ); -EGxApi GxApiDefault() { -#if defined(WHOA_SYSTEM_WIN) - return GxApi_D3d9; -#endif - -#if defined(WHOA_SYSTEM_MAC) - return GxApi_GLL; -#endif - -#if defined(WHOA_SYSTEM_LINUX) - return GxApi_GLSDL; -#endif -} - -void RegisterGxCVars() { - const auto& format = s_defaults.format; - - // TODO: bool isChinese = s_currentLocaleIndex == 4 (zhCN) - bool isChinese = false; - - const uint32_t graphics = CATEGORY::GRAPHICS; - - s_cvGxWidescreen = CVar::Register("widescreen", "Allow widescreen support", 0x0, "1", nullptr, graphics); - s_cvGxWindow = CVar::Register("gxWindow", "toggle fullscreen/window", 0x1 | 0x2, isChinese ? "1" : "0", &CVGxWindowCallback, graphics); - s_cvGxMaximize = CVar::Register("gxMaximize", "maximize game window", 0x1 | 0x2, isChinese ? "1" : "0", &CVGxMaximizeCallback, graphics); - - char value[260] = {}; - SStrPrintf(value, sizeof(value), "%s", CGxFormat::formatToColorBitsString[format.colorFormat]); - s_cvGxColorBits = CVar::Register("gxColorBits", "color bits", 0x1 | 0x2, value, &CVGxColorBitsCallback, graphics); - - SStrPrintf(value, sizeof(value), "%s", CGxFormat::formatToColorBitsString[format.depthFormat]); - s_cvGxDepthBits = CVar::Register("gxDepthBits", "depth bits", 0x1 | 0x2, value, &CVGxDepthBitsCallback, graphics); - - SStrPrintf(value, 260, "%dx%d", format.size.x, format.size.y); - s_cvGxResolution = CVar::Register("gxResolution", "resolution", 0x1 | 0x2, value, &CVGxResolutionCallback, graphics); - - s_cvGxRefresh = CVar::Register("gxRefresh", "refresh rate", 0x1 | 0x2, "75", &CVGxRefreshCallback, graphics); - s_cvGxTripleBuffer = CVar::Register("gxTripleBuffer", "triple buffer", 0x1 | 0x2, "0", &CVGxTripleBufferCallback, graphics); - s_cvGxApi = CVar::Register("gxApi", "graphics api", 0x1 | 0x2, g_gxApiNames[GxApiDefault()], &CVGxApiCallback, graphics); - - s_cvGxVSync = CVar::Register("gxVSync", "vsync on or off", 0x1 | 0x2, "1", &CVGxVSyncCallback, graphics); - s_cvGxAspect = CVar::Register("gxAspect", "constrain window aspect", 0x1 | 0x2, "1", &CVGxAspectCallback, graphics); - - s_cvGxCursor = CVar::Register("gxCursor", "toggle hardware cursor", 0x1 | 0x2, "1", &CVGxCursorCallback, graphics); - - // TODO: v10 = *(_DWORD*)(dword_CABB60 + 84); - int v10 = 0; - SStrPrintf(value, sizeof(value), "%d", v10); - s_cvGxMultisample = CVar::Register("gxMultisample", "multisample", 0x1 | 0x2, value, &CVGxMultisampleCallback, graphics); - s_cvGxMultisampleQuality = CVar::Register("gxMultisampleQuality", "multisample quality", 0x1 | 0x2, "0.0", &CVGxMultisampleQualityCallback, graphics); - - // TODO: v10 = *(_DWORD*)(dword_CABB60 + 80); - SStrPrintf(value, sizeof(value), "%d", v10); - s_cvGxFixLag = CVar::Register("gxFixLag", "prevent cursor lag", 0x1 | 0x2, value, &CVGxFixLagCallback, graphics); - s_cvGxStereoEnabled = CVar::Register("gxStereoEnabled", "Enable stereoscopic rendering", 0x1, "0", &CVGxStereoEnabledCallback, graphics); - s_cvGxOverride = CVar::Register("gxOverride", "gx overrides", 0x1, "", &CVGxOverrideCallback, graphics); - s_cvGxMaxFPS = CVar::Register("maxFPS", "Set FPS limit", 0x1, "200", &CVGxMaxFPSCallback, graphics); - s_cvGxMaxFPSBk = CVar::Register("maxFPSBk", "Set background FPS limit", 0x1, "30", &CVGxMaxFPSBkCallback, graphics); - s_cvGxVideoOptionsVersion = CVar::Register("videoOptionsVersion", "Video options version", 0x1 | 0x2, "0", &GxVideoOptionsVersionCallback, graphics); - s_cvGxWindowResizeLock = CVar::Register("windowResizeLock", "prevent resizing in windowed mode", 1, "0", &CVGxWindowResizeLockCallback, graphics); - s_cvGxFixedFunction = CVar::Register("fixedFunction", "Force fixed function rendering", 0x1 | 0x2, "0", 0, graphics); -} - -void UpdateGxCVars() { - s_cvGxColorBits->Update(); - s_cvGxDepthBits->Update(); - s_cvGxWindow->Update(); - s_cvGxResolution->Update(); - s_cvGxRefresh->Update(); - s_cvGxTripleBuffer->Update(); - s_cvGxApi->Update(); - s_cvGxVSync->Update(); - s_cvGxAspect->Update(); - s_cvGxMaximize->Update(); - s_cvGxCursor->Update(); - s_cvGxMultisample->Update(); - s_cvGxMultisampleQuality->Update(); - s_cvGxFixLag->Update(); -} - -void SetGxCVars(const CGxFormat& format) { - char value[1024] = {}; - - s_cvGxColorBits->Set(CGxFormat::formatToColorBitsString[format.colorFormat], true, false, false, true); - s_cvGxDepthBits->Set(CGxFormat::formatToColorBitsString[format.depthFormat], true, false, false, true); - - SStrPrintf(value, sizeof(value), "%d", format.window); - s_cvGxWindow->Set(value, true, false, false, true); - - SStrPrintf(value, sizeof(value), "%dx%d", format.size.x, format.size.y); - s_cvGxResolution->Set(value, true, false, false, true); - - SStrPrintf(value, sizeof(value), "%d", format.refreshRate); - s_cvGxRefresh->Set(value, true, false, false, true); - - // TODO: (format + 28) > 1 - s_cvGxTripleBuffer->Set("0", true, false, false, true); - - SStrPrintf(value, sizeof(value), "%d", format.vsync); - s_cvGxVSync->Set(value, true, false, false, true); - - // TODO: format.aspectRatio - SStrPrintf(value, sizeof(value), "%d", 0); - s_cvGxAspect->Set(value, true, false, false, true); - - SStrPrintf(value, sizeof(value), "%d", format.maximize); - s_cvGxMaximize->Set(value, true, false, false, true); - - SStrPrintf(value, sizeof(value), "%d", format.hwCursor); - s_cvGxCursor->Set(value, true, false, false, true); - - SStrPrintf(value, sizeof(value), "%d", format.sampleCount); - s_cvGxMultisample->Set(value, true, false, false, true); - - // TODO: format.multisampleQuality - SStrPrintf(value, sizeof(value), "%f", 0.0f); - s_cvGxMultisampleQuality->Set(value, true, false, false, true); - - SStrPrintf(value, sizeof(value), "%d", format.fixLag); - s_cvGxFixLag->Set(value, true, false, false, true); - - UpdateGxCVars(); + // g_theGxDevicePtr->AddStereoChangedCallback(nullsub_3); + GxAddStereoChangedCallback(OnGxStereoChanged); } void ConsoleDeviceInitialize(const char* title) { GxLogOpen(); - s_cvHwDetect = CVar::Register("hwDetect", "do hardware detection", 0x1, "1", nullptr, CATEGORY::GRAPHICS); + s_cvHwDetect = CVar::Register( + "hwDetect", + "do hardware detection", + 0x1, + "1", + nullptr, + GRAPHICS, + false, + nullptr, + false + ); - // TODO: sub_76BA30(&unk_CABB38, &byte_CABCBD); << ConsoleDetect - // TODO: byte_CABCBC = 1; + ConsoleDetectDetectHardware(s_hardware, s_hwChanged); + s_hardwareDetected = true; - if (CmdLineGetBool(WOWCMD_HW_DETECT) || s_cvHwDetect->GetInt() != 0) { + if (CmdLineGetBool(CMD_HW_DETECT) == 1 || s_cvHwDetect->GetInt() != 0) { s_hwDetect = true; s_cvHwDetect->Set("0", true, false, false, true); } else { s_hwDetect = false; } + ConsoleAccessSetEnabled(CmdLineGetBool(CMD_CONSOLE) == 1); - ConsoleAccessSetEnabled(CmdLineGetBool(WOWCMD_CONSOLE)); - - // TODO: sub_76B520(&unk_CABAF0, &unk_CABB38); - - // CHANGE: Remove this when the rest will be ready - s_defaults.format.size.x = 1024; - s_defaults.format.size.y = 768; - s_defaults.format.colorFormat = CGxFormat::Fmt_Argb8888; - s_defaults.format.depthFormat = CGxFormat::Fmt_Ds248; + ConsoleDetectSetDefaultsFormat(s_defaults, s_hardware); RegisterGxCVars(); - ConsoleCommandRegister("gxRestart", &CCGxRestart, CATEGORY::GRAPHICS, nullptr); - // TODO: GxAdapterMonitorModes((int)&unk_CABCC8); - // TODO: ValidateFormatMonitor(&unk_CABDA8); + ConsoleCommandRegister("gxRestart", CCGxRestart, GRAPHICS, nullptr); - // TODO: if ( GxAdapterDesktopMode(&v28) ) - if (true) { - s_requestedFormat.size.x = 1024; - s_requestedFormat.size.y = 768; - s_requestedFormat.colorFormat = CGxFormat::Fmt_Argb8888; - s_requestedFormat.depthFormat = CGxFormat::Fmt_Ds248; + GxAdapterMonitorModes(s_gxMonitorModes); + ValidateFormatMonitor(s_fallbackFormat); + + CGxMonitorMode mode; + mode.size = { 0, 0 }; + if (GxAdapterDesktopMode(mode)) { + s_desktopFormat.size = mode.size; + s_desktopFormat.colorFormat = mode.bpp > 16 ? CGxFormat::Fmt_ArgbX888 : CGxFormat::Fmt_Rgb565; + s_desktopFormat.refreshRate = mode.refreshRate; } - GxLog("ConsoleDeviceInitialize(): hwDetect = %d, hwChanged = %d", s_hwDetect, s_hwChanged); - if (CmdLineGetBool(WOWCMD_RES_800x600)) { - s_requestedFormat.size.x = 800; - s_requestedFormat.size.y = 600; - } else if (CmdLineGetBool(WOWCMD_RES_1024x768)) { - s_requestedFormat.size.x = 1024; - s_requestedFormat.size.y = 768; - } else if (CmdLineGetBool(WOWCMD_RES_1280x960)) { - s_requestedFormat.size.x = 1280; - s_requestedFormat.size.y = 960; - } else if (CmdLineGetBool(WOWCMD_RES_1280x1024)) { - s_requestedFormat.size.x = 1280; - s_requestedFormat.size.y = 1024; - } else if (CmdLineGetBool(WOWCMD_RES_1600x1200)) { - s_requestedFormat.size.x = 1600; - s_requestedFormat.size.y = 1200; + if (CmdLineGetBool(CMD_RES_800x600)) { + s_requestedFormat.size = { 800, 600 }; + } else if (CmdLineGetBool(CMD_RES_1024x768)) { + s_requestedFormat.size = { 1024, 768 }; + } else if (CmdLineGetBool(CMD_RES_1280x960)) { + s_requestedFormat.size = { 1280, 960 }; + } else if (CmdLineGetBool(CMD_RES_1280x1024)) { + s_requestedFormat.size = { 1280, 1024 }; + } else if (CmdLineGetBool(CMD_RES_1600x1200)) { + s_requestedFormat.size = { 1600, 1200 }; } - if (s_cvGxFixedFunction->GetInt() != 0) { - // TODO: (dword_CABD20 = 0) s_requestedFormat.unknown_field = 0; - s_requestedFormat.pos.y = 0; // <--- CHECK THIS - s_requestedFormat.pos.x = 0; + // TODO: fixed function rendering!!! + if (s_cvFixedFunction->GetInt()) { + // TODO: IMPORTANT: figure out what these are called + s_requestedFormat.unk48 = 0; + s_requestedFormat.unk38 = 0; } if (s_hwDetect || s_hwChanged) { - // TODO Sub76B3F0(&UnkCABAF0, &UnkCABB38); - s_cvGxFixedFunction->Set("0", true, false, false, true); - // TODO memcpy(&s_requestedFormat, &s_defaults.format, sizeof(s_requestedFormat)); - + ConsoleDetectSetDefaults(s_defaults, s_hardware); + s_cvFixedFunction->Set("0", true, false, false, true); + memcpy(&s_requestedFormat, s_defaults.format, sizeof(CGxFormat)); s_requestedFormat.window = s_cvGxWindow->GetInt() != 0; s_requestedFormat.maximize = s_cvGxMaximize->GetInt() != 0; - - // TODO temporary override - s_requestedFormat.maximize = 0; - SetGxCVars(s_requestedFormat); } - EGxApi api = GxApiDefault(); - - auto gxApiName = s_cvGxApi->GetString(); - - auto gxOverride = CmdLineGetString(WOWCMD_GX_OVERRIDE); - if (*gxOverride != '\0') { - gxApiName = gxOverride; - } else if (CmdLineGetBool(CMD_OPENGL)) { - gxApiName = g_gxApiNames[GxApi_OpenGl]; - } else if (CmdLineGetBool(CMD_D3D)) { - gxApiName = g_gxApiNames[GxApi_D3d9]; - } else if (CmdLineGetBool(CMD_D3D9EX)) { - gxApiName = g_gxApiNames[GxApi_D3d9Ex]; - } - - // Sanitize chosen gxApi against list of supported gxApis - for (size_t i = 0; i < g_numGxApiSupported; i++) { - EGxApi supportedApi = g_gxApiSupported[i]; - if (SStrCmpI(gxApiName, g_gxApiNames[supportedApi], STORM_MAX_STR) == 0) { - api = supportedApi; - break; + auto gxApi = GxDefaultApi(); + auto cvGxApi = CVar::Lookup("gxApi"); + if (cvGxApi) { + auto requestedGxApi = cvGxApi->GetString(); + for (auto api = GxApi_OpenGl; api < GxApis_Last; api = static_cast(static_cast(api) + 1)) { + if (GxApiSupported(api) && !SStrCmpI(requestedGxApi, g_gxApiNames[api], STORM_MAX_STR)) { + gxApi = api; + break; + } } } + if (CmdLineGetBool(CMD_OPENGL) && GxApiSupported(GxApi_OpenGl)) { + gxApi = GxApi_OpenGl; + } + if (CmdLineGetBool(CMD_D3D) && GxApiSupported(GxApi_D3d9)) { + gxApi = GxApi_D3d9; + } + if (CmdLineGetBool(CMD_D3D9EX) && GxApiSupported(GxApi_D3d9Ex)) { + gxApi = GxApi_D3d9Ex; + } s_requestedFormat.fixLag = s_cvGxFixLag->GetInt() != 0; - s_requestedFormat.hwTnL = !CmdLineGetBool(CMD_SW_TNL); - - bool windowed = s_cvGxWindow->GetInt() != 0; + s_requestedFormat.hwTnL = CmdLineGetBool(CMD_SW_TNL) == 0; + bool window = s_cvGxWindow->GetInt() != 0; if (CmdLineGetBool(CMD_FULL_SCREEN)) { - windowed = false; - } else if (CmdLineGetBool(WOWCMD_WINDOWED)) { - windowed = true; + window = false; + } else if (CmdLineGetBool(CMD_WINDOWED)) { + window = true; + } + s_requestedFormat.window = window; + s_desktopFormat.window = window; + + bool bVar1 = false; + CGxFormat apiFormat = s_requestedFormat; + ValidateFormatMonitor(apiFormat); + s_device = GxDevCreate(gxApi, OsWindowProc, apiFormat); + while (!s_device) { + if (apiFormat.sampleCount < 2) { + auto colorFormat = apiFormat.colorFormat; + if (colorFormat <= CGxFormat::Fmt_Rgb565) { + if (bVar1) { + GxLog("ConsoleDeviceInitialize(): no output device available!"); + auto titleRecord = g_Startup_StringsDB.GetRecord(MSG_TITLE_WOW); + auto title = titleRecord ? titleRecord->m_message : "World of Warcraft"; + const char* message; + if (gxApi == GxApi_D3d9 || gxApi == GxApi_D3d9Ex) { + auto messageRecord = g_Startup_StringsDB.GetRecord(MSG_GX_INIT_FAILED_D3D); + message = messageRecord ? messageRecord->m_message : "World of Warcraft was unable to start up 3D acceleration. Please make sure DirectX 9.0c is installed and your video drivers are up-to-date."; + } else { + auto messageRecord = g_Startup_StringsDB.GetRecord(MSG_GX_INIT_FAILED); + message = messageRecord ? messageRecord->m_message : "World of Warcraft was unable to start up 3D acceleration."; + } + OsGuiMessageBox(nullptr, 0, message, title); + GxLogClose(); + exit(0); + } + + apiFormat = s_desktopFormat; + bVar1 = true; + } else if (apiFormat.depthFormat <= CGxFormat::Fmt_Ds160) { + apiFormat.colorFormat = static_cast(static_cast(apiFormat.colorFormat - 1)); + apiFormat.depthFormat = colorFormat != CGxFormat::Fmt_ArgbX888 ? CGxFormat::Fmt_Ds320 : CGxFormat::Fmt_Ds160; + } else { + apiFormat.depthFormat = static_cast(static_cast(apiFormat.depthFormat - 1)); + } + } else { + apiFormat.sampleCount = std::max(apiFormat.sampleCount - 2, static_cast(1)); + } + + ValidateFormatMonitor(apiFormat); + s_device = GxDevCreate(gxApi, OsWindowProc, apiFormat); + } + memcpy(&s_requestedFormat, &apiFormat, sizeof(CGxFormat)); + memcpy(&s_lastGoodFormat, &apiFormat, sizeof(CGxFormat)); + + SetGxCVars(apiFormat); + + if (GxCaps().m_numTmus < 2) { + GxDevDestroy(s_device); + GxLog("ConsoleDeviceInitialize(): output device does not have dual TMUs!"); + auto titleRecord = g_Startup_StringsDB.GetRecord(MSG_TITLE_WOW); + auto title = titleRecord ? titleRecord->m_message : "World of Warcraft"; + auto messageRecord = g_Startup_StringsDB.GetRecord(MSG_HW_UNSUPPORTED); + auto message = messageRecord ? messageRecord->m_message : "Your 3D accelerator card is not supported by World of Warcraft. Please install a 3D acceler ator card with dual-TMU support."; + OsGuiMessageBox(nullptr, 0, message, title); + GxLogClose(); + exit(0); } - s_requestedFormat.window = windowed; - // TODO: byte_CABD47 = windowed; + if (!GxCaps().m_numStreams) { + GxDevDestroy(s_device); + GxLog("ConsoleDeviceInitialize(): output device has 0 streams"); + auto titleRecord = g_Startup_StringsDB.GetRecord(MSG_TITLE_WOW); + auto title = titleRecord ? titleRecord->m_message : "World of Warcraft"; + auto messageRecord = g_Startup_StringsDB.GetRecord(MSG_HW_UNSUPPORTED); + auto message = messageRecord ? messageRecord->m_message : "Your 3D accelerator card is not supported by World of Warcraft. Please install a 3D acceler ator card with dual-TMU support."; + OsGuiMessageBox(nullptr, 0, message, title); + GxLogClose(); + exit(0); + } - GxLog("GxApi_%s selected\n", g_gxApiNames[api]); - - // Set internally (CVar value reflects the current gxApi at launch), - // this will not Set() as CVar gxApi is latched - s_cvGxApi->InternalSet(g_gxApiNames[api], true, false, false, true); - - CGxFormat format; - memcpy(&format, &s_requestedFormat, sizeof(s_requestedFormat)); - - CGxDevice* device = GxDevCreate(api, OsWindowProc, format); - - // TODO + switch (GxDevApi()) { + case GxApi_OpenGl: + case GxApi_GLL: + case GxApi_GLSDL: + ConsoleGxOverride(s_hardware.videoHw->m_oglOverrides); + break; + case GxApi_D3d9: + case GxApi_D3d9Ex: + ConsoleGxOverride(s_hardware.videoHw->m_d3DOverrides); + break; + default: + break; + } + ConsoleGxOverride(CmdLineGetString(CMD_GX_OVERRIDE)); + for (auto override = GxOverride_PixelShader; override < GxOverrides_Last; override = static_cast(static_cast(override) + 1)) { + if (s_consoleGxOverrideSet[override]) { + GxDevOverride(override, s_consoleGxOverrideVal[override]); + } + } + OsGuiSetGxWindow(GxDevWindow()); + if (!title) { + title = ""; + } + SStrCopy(s_windowTitle, title, sizeof(s_windowTitle)); auto gxWindow = GxDevWindow(); - OsGuiSetGxWindow(gxWindow); + if (gxWindow) { + OsGuiSetWindowTitle(gxWindow, s_windowTitle); + } + if (s_hwDetect || s_hwChanged) { + // TODO: IMPORTANT: find out what the real name is + s_defaults.unk19 = GxCaps().m_shaderTargets[GxSh_Pixel] != 0; + } + + char videoOptionsVersion[32]; + SStrPrintf(videoOptionsVersion, sizeof(videoOptionsVersion), "%d", 3); + + s_cvVideoOptionsVersion->Set(videoOptionsVersion, true, false, false, true); + + ConsoleDeviceStereoInitialize(); // TODO + // OsSetSleepInBackground(1); + // OsSetBackgroundSleepMs(250); +} + +bool ConsoleDeviceExists() { + return s_device != nullptr; +} + +void ConsoleDeviceDestroy() { + GxRemoveStereoChangedCallback(OnGxStereoChanged); + s_cvVideoOptionsVersion->Update(); + GxDevDestroy(s_device); + s_device = nullptr; + GxLogClose(); } diff --git a/src/console/Device.hpp b/src/console/Device.hpp index a958f38..2004f86 100644 --- a/src/console/Device.hpp +++ b/src/console/Device.hpp @@ -3,10 +3,18 @@ #include "gx/CGxFormat.hpp" -struct DefaultSettings { - CGxFormat format; -}; +#include "console/Detect.hpp" + +extern DefaultSettings s_defaults; +extern Hardware s_hardware; +extern bool s_hwChanged; +extern bool s_hwDetect; +extern CGxFormat s_requestedFormat; void ConsoleDeviceInitialize(const char* title); +bool ConsoleDeviceExists(); + +void ConsoleDeviceDestroy(); + #endif diff --git a/src/console/Gx.cpp b/src/console/Gx.cpp new file mode 100644 index 0000000..f5ef3db --- /dev/null +++ b/src/console/Gx.cpp @@ -0,0 +1,72 @@ +#include "console/Gx.hpp" +#include +#include + +const char* g_gxApiNames[GxApis_Last] = { + "OpenGL", // GxApi_OpenGl + "D3D9", // GxApi_D3d9 + "D3D9Ex", // GxApi_D3d9Ex + "D3D10", // GxApi_D3d10 + "D3D11", // GxApi_D3d11 + "GLL", // GxApi_GLL + "GLSDL" // GxApi_GLSDL +}; + +int32_t s_consoleGxOverrideSet[GxOverrides_Last]; +uint32_t s_consoleGxOverrideVal[GxOverrides_Last]; + +void ConsoleGxOverride(const char* str) { + char value[256]; + char override[256]; + + while (*str) { + SStrTokenize(&str, override, 256, " ,", 0); + SStrTokenize(&str, value, 256, " ;", 0); + + if (override[0] && value[0]) { + auto gxOverride = static_cast(std::atol(override)); + auto gxValue = std::atol(value); + + if (gxOverride < GxOverrides_Last) { + if (gxOverride == 0) { + switch (gxValue) { + case 0: + case 1: + case 2: + gxValue = 1; + break; + case 3: + gxValue = 2; + break; + case 4: + gxValue = 3; + break; + case 5: + gxValue = 7; + break; + case 6: + gxValue = 8; + break; + case 7: + gxValue = 9; + break; + case 8: + gxValue = 10; + break; + case 10: + gxValue = 12; + break; + case 11: + gxValue = 13; + break; + default: + break; + } + } + + s_consoleGxOverrideSet[gxOverride] = 1; + s_consoleGxOverrideVal[gxOverride] = gxValue; + } + } + } +} diff --git a/src/console/Gx.hpp b/src/console/Gx.hpp new file mode 100644 index 0000000..a0fb7ac --- /dev/null +++ b/src/console/Gx.hpp @@ -0,0 +1,14 @@ +#ifndef CONSOLE_GX_HPP +#define CONSOLE_GX_HPP + +#include +#include "gx/Types.hpp" + +extern const char* g_gxApiNames[GxApis_Last]; + +extern int32_t s_consoleGxOverrideSet[GxOverrides_Last]; +extern uint32_t s_consoleGxOverrideVal[GxOverrides_Last]; + +void ConsoleGxOverride(const char* str); + +#endif diff --git a/src/console/Handlers.cpp b/src/console/Handlers.cpp index 6bf03d5..6095243 100644 --- a/src/console/Handlers.cpp +++ b/src/console/Handlers.cpp @@ -1,12 +1,17 @@ +#include +#include #include "console/Handlers.hpp" #include "console/Line.hpp" #include "console/Console.hpp" #include "console/Command.hpp" #include "console/Screen.hpp" +#include "console/Text.hpp" +#include "console/Highlight.hpp" #include "event/Event.hpp" -#include +#include "event/Types.hpp" -static int32_t s_historyIndex = 0; +#define SHIFT_MODIFIER(data) ((data->metaKeyState & (1 << KEY_LSHIFT) | (1 << KEY_RSHIFT)) != 0) +#define CTRL_MODIFIER(data) ((data->metaKeyState & (1 << KEY_LCONTROL) | (1 << KEY_RCONTROL)) != 0) namespace { @@ -21,19 +26,22 @@ int32_t OnChar(const EVENT_DATA_CHAR* data, void* param) { character[0] = char(data->ch); character[1] = 0; + // TODO: add custom behavior to support non-ASCII commands? + // SUniSPutUTF8(data->ch, character); + PasteInInputLine(character); ResetHighlight(); return 0; } - // SUniSPutUTF8(data->ch, character); - - return 1; } int32_t OnIdle(const EVENT_DATA_IDLE* data, void* param) { - // TODO repeat buffer logic + if (s_repeatCount && (*s_repeatBuffer)) { + ConsoleCommandExecute(s_repeatBuffer, 0); + s_repeatCount--; + } ConsoleScreenAnimate(data->elapsedSec); @@ -58,71 +66,108 @@ int32_t OnKeyDown(const EVENT_DATA_KEY* data, void* param) { return 1; } - auto anyControl = (1 << KEY_LCONTROL) | (1 << KEY_RCONTROL); - - auto line = GetInputLine(); + auto lineptr = GetInputLine(); switch (data->key) { case KEY_ESCAPE: - if (line->inputpos < line->inputstart || line->inputpos == line->inputstart) { + if (lineptr->inputstart < lineptr->inputpos) { ConsoleSetActive(0); } else { - line->inputpos = line->inputstart; - line->chars = line->inputstart; - line->buffer[line->inputstart] = '\0'; - SetInputString(line->buffer); + lineptr->inputpos = lineptr->inputstart; + lineptr->chars = lineptr->inputstart; + lineptr->buffer[lineptr->inputstart] = '\0'; + SetInputString(lineptr->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(); + if (CTRL_MODIFIER(data)) { + CopyHighlightToClipboard(); } break; case KEY_V: - if (data->metaKeyState & anyControl) { - PasteClipboardToHighlight(); + if (CTRL_MODIFIER(data)) { + PasteClipboardInInputLine(); } break; + case KEY_ENTER: + if (lineptr->inputstart < lineptr->inputpos) { + lineptr->inputpos = 0; + GenerateNodeString(lineptr); + ConsoleCommandExecute(lineptr->buffer + lineptr->inputstart, 1); + s_historyIndex = -1; + } + break; + case KEY_BACKSPACE: + lineptr->Backspace(); + break; + case KEY_TAB: + if (s_completionMode == 0) { + s_completedCmd = nullptr; + s_completionMode = 1; + SStrCopy(s_partial, lineptr->buffer + lineptr->inputstart, STORM_MAX_STR); + } + if (ConsoleCommandComplete(s_partial, &s_completedCmd, SHIFT_MODIFIER(data))) { + MakeCommandCurrent(lineptr, s_completedCmd); + } + SetInputString(lineptr->buffer); + break; case KEY_LEFT: - if (line->inputstart <= line->inputpos && line->inputpos != line->inputstart) { - line->inputpos--; + if (lineptr->inputstart < lineptr->inputpos) { + lineptr->inputpos--; } break; + case KEY_UP: + lineptr->Up(); + break; case KEY_RIGHT: - if (line->inputpos < line->chars) { - line->inputpos++; + if (lineptr->inputpos < lineptr->chars) { + lineptr->inputpos++; } break; - - case KEY_BACKSPACE: - BackspaceLine(line); + case KEY_DOWN: + lineptr->Down(); + break; + case KEY_DELETE: + lineptr->Delete(); + break; + case KEY_HOME: + if (CTRL_MODIFIER(data)) { + s_currlineptr = s_linelist.Tail(); + } else { + if (lineptr->inputpos > lineptr->inputstart) { + lineptr->inputpos = lineptr->inputstart; + } + } + break; + case KEY_END: + if (CTRL_MODIFIER(data)) { + s_currlineptr = s_linelist.Head(); + } else { + if (lineptr->inputpos < lineptr->chars) { + lineptr->inputpos = lineptr->chars; + } + } + break; + case KEY_PAGEUP: + MoveLinePtr(1, SHIFT_MODIFIER(data)); + break; + case KEY_PAGEDOWN: + MoveLinePtr(0, SHIFT_MODIFIER(data)); + break; + default: 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; + if (data->key != KEY_TAB + && data->key != KEY_LSHIFT + && data->key != KEY_RSHIFT + && data->key != KEY_LALT + && data->key != KEY_RALT + && !(CTRL_MODIFIER(data))) { + s_completionMode = 0; ResetHighlight(); } - // TODO return 0; } @@ -132,34 +177,52 @@ int32_t OnKeyDownRepeat(const EVENT_DATA_KEY* data, void* param) { return 0; } - auto anyControl = (1 << KEY_LCONTROL) | (1 << KEY_RCONTROL); + if (EventIsKeyDown(ConsoleGetHotKey()) || !ConsoleGetActive()) { + return 1; + } - auto line = GetInputLine(); + auto lineptr = GetInputLine(); switch (data->key) { - case KEY_PAGEUP: - MoveLinePtr(1, data->metaKeyState); - break; - case KEY_PAGEDOWN: - MoveLinePtr(0, data->metaKeyState); + case KEY_BACKSPACE: + lineptr->Backspace(); break; case KEY_LEFT: - if (line->inputstart <= line->inputpos && line->inputpos != line->inputstart) { - line->inputpos--; + if (lineptr->inputstart < lineptr->inputpos) { + lineptr->inputpos--; } break; + case KEY_UP: + lineptr->Up(); + break; case KEY_RIGHT: - if (line->inputpos < line->chars) { - line->inputpos++; + if (lineptr->inputstart < lineptr->inputpos) { + lineptr->inputpos++; } break; - case KEY_BACKSPACE: - BackspaceLine(line); + case KEY_DOWN: + lineptr->Down(); + break; + case KEY_DELETE: + lineptr->Delete(); + break; + case KEY_PAGEUP: + MoveLinePtr(1, SHIFT_MODIFIER(data)); + break; + case KEY_PAGEDOWN: + MoveLinePtr(0, SHIFT_MODIFIER(data)); + break; + default: 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; + if (data->key != KEY_TAB + && data->key != KEY_LSHIFT + && data->key != KEY_RSHIFT + && data->key != KEY_LALT + && data->key != KEY_RALT + && !(CTRL_MODIFIER(data))) { + s_completionMode = 0; ResetHighlight(); } @@ -167,51 +230,50 @@ int32_t OnKeyDownRepeat(const EVENT_DATA_KEY* data, void* param) { } int32_t OnKeyUp(const EVENT_DATA_KEY* data, void* param) { - // TODO - return 1; + if (data->key == ConsoleGetHotKey()) { + if (ConsoleAccessGetEnabled()) { + return 0; + } + } + + return !ConsoleGetActive(); } int32_t OnMouseDown(const EVENT_DATA_MOUSE* data, void* param) { - auto consoleHeight = ConsoleGetHeight(); - auto fontHeight = ConsoleGetFontHeight(); - - if (EventIsKeyDown(ConsoleGetHotKey()) || !ConsoleGetActive() || (1.0f - consoleHeight) > data->y) { + if (EventIsKeyDown(ConsoleGetHotKey()) || !ConsoleGetActive() || (1.0f - s_consoleHeight) > data->y) { return 1; } float clickPos = 1.0f - data->y; - if (clickPos < (std::min(consoleHeight, 1.0f) - (fontHeight * 0.75f)) || clickPos > consoleHeight) { + if (clickPos < (std::min(s_consoleHeight, 1.0f) - (s_fontHeight * 0.75f)) || clickPos > s_consoleHeight) { ResetHighlight(); - auto line = GetLineAtMousePosition(data->y); + auto lineptr = GetLineAtMousePosition(data->y); - if (line) { - SetHighlightCopyText(line->buffer); - SetHighlightState(HS_HIGHLIGHTING); + if (lineptr) { + SStrCopy(s_copyText, lineptr->buffer, CONSOLE_HIGHLIGHT_CLIPBOARD_SIZE); + s_highlightState = HS_HIGHLIGHTING; - float v7 = 1.0f - (consoleHeight - (fontHeight * 0.75f) - (fontHeight) - ((consoleHeight - clickPos) / fontHeight - 1.0) * fontHeight); + float v7 = 1.0f - (s_consoleHeight - (s_fontHeight * 0.75f) - (s_fontHeight) - ((s_consoleHeight - clickPos) / s_fontHeight - 1.0) * s_fontHeight); - auto hRect = GetHighlightRect(); + s_hRect.bottom = v7; + s_hRect.top = v7 - s_fontHeight; - hRect.bottom = v7; - hRect.top = v7 - fontHeight; - - SetHighlightStart(v7); - SetHighlightEnd(v7); + s_highlightHStart = v7; + s_highlightHEnd = v7; UpdateHighlight(); return 0; } - ResetHighlightCopyText(); + s_copyText[0] = '\0'; return 0; } ResetHighlight(); - - ConsoleSetResizeState(CS_STRETCH); + s_consoleResizeState = CS_STRETCH; return 1; } @@ -221,16 +283,16 @@ int32_t OnMouseMove(const EVENT_DATA_MOUSE* data, void* param) { return 1; } - if (ConsoleGetResizeState() == CS_STRETCH) { - auto newHeight = std::max(1.0f - data->y, ConsoleGetFontHeight()); - ConsoleSetHeight(newHeight); - } else if ((1.0f - ConsoleGetHeight()) > data->y) { + if (s_consoleResizeState == CS_STRETCH) { + auto newHeight = std::max(1.0f - data->y, s_fontHeight); + s_consoleHeight = newHeight; + } else if ((1.0f - s_consoleHeight) > data->y) { return 1; } - SetHighlightEnd(data->x); + s_highlightHEnd = data->x; - if (GetHighlightState() == HS_HIGHLIGHTING) { + if (s_highlightState == HS_HIGHLIGHTING) { UpdateHighlight(); } @@ -242,8 +304,8 @@ int32_t OnMouseUp(const EVENT_DATA_MOUSE* data, void* param) { return 1; } - SetHighlightState(HS_ENDHIGHLIGHT); - ConsoleSetResizeState(CS_NONE); + s_highlightState = HS_ENDHIGHLIGHT; + s_consoleResizeState = CS_NONE; return 1; } diff --git a/src/console/Highlight.cpp b/src/console/Highlight.cpp new file mode 100644 index 0000000..fb6c2cb --- /dev/null +++ b/src/console/Highlight.cpp @@ -0,0 +1,59 @@ +#include "console/Highlight.hpp" +#include "console/Text.hpp" +#include "os/Clipboard.hpp" + +HIGHLIGHTSTATE s_highlightState = HS_NONE; +RECTF s_hRect = { 0.0f, 0.0f, 0.0f, 0.0f }; +float s_highlightHStart = 0.0f; +float s_highlightHEnd = 0.0f; +uint32_t s_highlightLeftCharIndex = 0; +uint32_t s_highlightRightCharIndex = 0; +int32_t s_highlightInput = 0; +char s_copyText[CONSOLE_HIGHLIGHT_CLIPBOARD_SIZE] = { 0 }; + +void ResetHighlight() { + s_highlightState = HS_NONE; + s_hRect = { 0.0f, 0.0f, 0.0f, 0.0f }; +} + +void UpdateHighlight() { + auto font = TextBlockGetFontPtr(s_textFont); + STORM_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, s_fontHeight, 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, s_fontHeight, right, len, &s_hRect.right, 0.0f, 1.0f, s_charSpacing, s_baseTextFlags); +} + +void CopyHighlightToClipboard() { + char buffer[CONSOLE_HIGHLIGHT_CLIPBOARD_SIZE]; + + if (s_copyText[0] != '\0') { + auto highlightWidth = s_highlightRightCharIndex - s_highlightLeftCharIndex; + if (highlightWidth >= (CONSOLE_HIGHLIGHT_CLIPBOARD_SIZE-1)) { + highlightWidth = CONSOLE_HIGHLIGHT_CLIPBOARD_SIZE-1; + } + + SStrCopy(buffer, &s_copyText[s_highlightLeftCharIndex], highlightWidth); + buffer[highlightWidth] = '\0'; + + OsClipboardPutString(buffer); + } + + ResetHighlight(); +} diff --git a/src/console/Highlight.hpp b/src/console/Highlight.hpp new file mode 100644 index 0000000..984c2ee --- /dev/null +++ b/src/console/Highlight.hpp @@ -0,0 +1,31 @@ +#ifndef CONSOLE_HIGHLIGHT_HPP +#define CONSOLE_HIGHLIGHT_HPP + +#include +#include + +#define CONSOLE_HIGHLIGHT_CLIPBOARD_SIZE 128 + +enum HIGHLIGHTSTATE { + HS_NONE = 0, + HS_HIGHLIGHTING = 1, + HS_ENDHIGHLIGHT = 2, + NUM_HIGHLIGHTSTATES +}; + +extern HIGHLIGHTSTATE s_highlightState; +extern RECTF s_hRect; +extern float s_highlightHStart; +extern float s_highlightHEnd; +extern uint32_t s_highlightLeftCharIndex; +extern uint32_t s_highlightRightCharIndex; +extern int32_t s_highlightInput; +extern char s_copyText[CONSOLE_HIGHLIGHT_CLIPBOARD_SIZE]; + +void ResetHighlight(); + +void UpdateHighlight(); + +void CopyHighlightToClipboard(); + +#endif diff --git a/src/console/Line.cpp b/src/console/Line.cpp index 3a2bdc0..aea27c3 100644 --- a/src/console/Line.cpp +++ b/src/console/Line.cpp @@ -1,24 +1,203 @@ -#include "console/Line.hpp" -#include "console/Types.hpp" #include "console/Console.hpp" +#include "console/Highlight.hpp" +#include "console/Line.hpp" +#include "console/Command.hpp" +#include "console/Text.hpp" #include "console/Screen.hpp" #include "gx/Device.hpp" - -#include -#include - -#include +#include "os/Clipboard.hpp" +#include +#include #include +#include -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; +int32_t s_historyIndex = 0; +// in this list +// head = the input line +// tail = the oldest line +STORM_LIST(CONSOLELINE) s_linelist; +CONSOLELINE* s_currlineptr; +uint32_t s_NumLines = 0; +SCritSect s_critsect; + +void CONSOLELINE::Up() { + if ((ConsoleCommandHistoryDepth() - 1) == s_historyIndex) { + return; + } + + auto previous = ConsoleCommandHistory(s_historyIndex + 1); + + if (previous) { + MakeCommandCurrent(this, previous); + s_historyIndex++; + SetInputString(this->buffer); + } +} + +void CONSOLELINE::Down() { + if (s_historyIndex == -1) { + return; + } + + const char* next; + + if (s_historyIndex == 0) { + next = ""; + } else { + if (!(next = ConsoleCommandHistory(s_historyIndex - 1))) { + return; + } + } + + MakeCommandCurrent(this, next); + s_historyIndex--; + SetInputString(this->buffer); +} + +void CONSOLELINE::Delete() { + if (this->inputpos > this->chars) { + return; + } + + auto pos = this->inputpos; + memmove(this->buffer + pos, this->buffer + pos + 1, this->chars - pos); + this->chars--; + SetInputString(this->buffer); +} + +void CONSOLELINE::Backspace() { + auto pos = this->inputpos; + + if (this->inputstart >= pos) { + return; + } + + if (pos < this->chars) { + memmove(this->buffer + pos - 1, this->buffer + pos, (this->chars - pos) + 1); + } else { + this->buffer[pos - 1] = '\0'; + } + + this->inputpos--; + this->chars--; + SetInputString(this->buffer); +} + +CONSOLELINE::~CONSOLELINE() { + if (this->buffer) { + FREE(this->buffer); + } + + if (this->fontPointer) { + GxuFontDestroyString(this->fontPointer); + } +} + +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 + }; + + GxuFontCreateString( + font, + node->buffer, + s_fontHeight, + pos, + 1.0f, + s_fontHeight, + 0.0f, + node->fontPointer, + GxVJ_Middle, GxHJ_Left, + s_baseTextFlags, + s_colorArray[node->colorType], + s_charSpacing, + 1.0f); + + STORM_ASSERT(node->fontPointer); + } +} + +void SetInputString(const char* buffer) { + if (s_inputString) { + GxuFontDestroyString(s_inputString); + } + s_inputString = nullptr; + + if (buffer && buffer[0] != '\0') { + C3Vector pos = { 0.0f, 0.0f, 1.0f }; + + auto font = TextBlockGetFontPtr(s_textFont); + + GxuFontCreateString( + font, + buffer, + s_fontHeight, + pos, + 1.0f, + s_fontHeight, + 0.0f, + s_inputString, + GxVJ_Middle, GxHJ_Left, + s_baseTextFlags, + s_colorArray[INPUT_COLOR], + s_charSpacing, + 1.0f); + } +} + +void ReserveInputSpace(CONSOLELINE* line, uint32_t chars) { + size_t newsize = line->chars + chars; + if (newsize >= line->charsalloc) { + while (line->charsalloc <= newsize) { + line->charsalloc += CONSOLE_LINE_EXTRA_BYTES; + } + + auto buffer = reinterpret_cast(ALLOC(line->charsalloc)); + SStrCopy(buffer, line->buffer, line->charsalloc); + FREE(line->buffer); + line->buffer = buffer; + } +} + +void MoveLinePtr(int32_t direction, int32_t modifier) { + auto lineptr = s_currlineptr; + + if (modifier == 1) { + for (int32_t i = 0; i < 10 && lineptr != nullptr; i++) { + lineptr = direction == 1 ? lineptr->m_link.Next() : lineptr->m_link.Prev(); + } + } else { + lineptr = direction == 1 ? lineptr->m_link.Next() : lineptr->m_link.Prev(); + } + + if (lineptr) { + s_currlineptr = lineptr; + } +} + +void MakeCommandCurrent(CONSOLELINE* lineptr, const 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; +} void EnforceMaxLines() { if (s_NumLines <= CONSOLE_LINES_MAX) { @@ -27,17 +206,11 @@ void EnforceMaxLines() { // Pop oldest line off the list auto lineptr = s_linelist.Tail(); - - if (lineptr == nullptr) { - lineptr = s_currlineptr; + if (lineptr == s_currlineptr) { + s_currlineptr = lineptr->Prev(); } - if (lineptr == nullptr) { - return; - } - - // Clean up oldest line. - s_linelist.UnlinkNode(lineptr); + // Clean up oldest line s_linelist.DeleteNode(lineptr); s_NumLines--; @@ -47,37 +220,36 @@ 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(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; + // Create a fresh input line, with "> " prefixed before the caret + if (head && head->inputpos != 0) { + return head; } - return head; + auto line = NEW(CONSOLELINE); + line->buffer = reinterpret_cast(ALLOC(CONSOLE_LINE_EXTRA_BYTES)); + line->charsalloc = CONSOLE_LINE_EXTRA_BYTES; + + s_linelist.LinkToHead(line); + s_NumLines++; + + SStrCopy(line->buffer, "> ", line->charsalloc); + SetInputString(line->buffer); + auto chars = SStrLen(line->buffer); + line->inputstart = chars; + line->inputpos = chars; + line->chars = chars; + line->colorType = INPUT_COLOR; + + s_currlineptr = line; + + EnforceMaxLines(); + + return line; } CONSOLELINE* GetLineAtMousePosition(float y) { // Loop through linelist to find line at mouse position - int32_t linePos = static_cast((ConsoleGetHeight() - (1.0 - y)) / ConsoleGetFontHeight()); + auto linePos = static_cast((s_consoleHeight - (1.0 - y)) / s_fontHeight); if (linePos == 1) { return s_linelist.Head(); @@ -87,7 +259,7 @@ CONSOLELINE* GetLineAtMousePosition(float y) { linePos--; } - CONSOLELINE* line = s_currlineptr; + auto line = s_currlineptr; while (linePos > 1) { linePos--; @@ -106,32 +278,73 @@ CONSOLELINE* GetLineAtMousePosition(float y) { 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; +void PasteInInputLine(const 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(ALLOC(line->charsalloc)); + SStrCopy(input, &line->buffer[line->inputpos], STORM_MAX_STR); + + auto buffer = reinterpret_cast(ALLOC(line->charsalloc)); + 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) { + FREE(input); + } + + if (buffer) { + FREE(buffer); + } + } + } else { + for (int32_t i = 0; i < len; i++) { + line->buffer[line->inputpos++] = characters[i]; } - auto buffer = reinterpret_cast(SMemAlloc(line->charsalloc, __FILE__, __LINE__, 0)); - SStrCopy(buffer, line->buffer, line->charsalloc); - SMemFree(line->buffer, __FILE__, __LINE__, 0x0); - line->buffer = buffer; + line->buffer[line->inputpos] = '\0'; + line->chars = line->inputpos; } + + SetInputString(line->buffer); } void ConsoleWrite(const char* str, COLOR_T color) { - if (g_theGxDevicePtr == nullptr || str[0] == '\0') { + if (!str || !*str || !GxDevExists() || !s_textFont) { return; } s_critsect.Enter(); - auto l = reinterpret_cast(SMemAlloc(sizeof(CONSOLELINE), __FILE__, __LINE__, 0)); - auto lineptr = new(l) CONSOLELINE(); - + auto lineptr = NEW(CONSOLELINE); auto head = s_linelist.Head(); - if (head == nullptr || head->inputpos == 0) { // Attach console line to head s_linelist.LinkToHead(lineptr); @@ -143,21 +356,31 @@ void ConsoleWrite(const char* str, COLOR_T color) { size_t len = SStrLen(str) + 1; lineptr->chars = len; lineptr->charsalloc = len; - lineptr->buffer = reinterpret_cast(SMemAlloc(len, __FILE__, __LINE__, 0)); + lineptr->buffer = reinterpret_cast(ALLOC(len)); lineptr->colorType = color; - SStrCopy(lineptr->buffer, str, STORM_MAX_STR); GenerateNodeString(lineptr); s_NumLines++; - EnforceMaxLines(); - // s_critsect.Leave(); } +void ConsolePrintf(const char* str, ...) { + char buffer[1024] = {0}; + + if (str != nullptr && str[0] != '\0') { + va_list list; + va_start(list, str); + vsnprintf(buffer, sizeof(buffer), str, list); + va_end(list); + + ConsoleWrite(buffer, DEFAULT_COLOR); + } +} + void ConsoleWriteA(const char* str, COLOR_T color, ...) { char buffer[1024] = {0}; @@ -171,78 +394,16 @@ void ConsoleWriteA(const char* str, COLOR_T 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 PasteClipboardInInputLine() { + auto str = OsClipboardGetString(); + if (str) { + PasteInInputLine(str); + FREE(str); + ResetHighlight(); } } void ConsoleClear() { s_NumLines = 0; - - auto ptr = s_linelist.Head(); - - while (ptr) { - s_linelist.UnlinkNode(ptr); - s_linelist.DeleteNode(ptr); - ptr = s_linelist.Head(); - } + s_linelist.Clear(); } diff --git a/src/console/Line.hpp b/src/console/Line.hpp index f0419a3..927cb02 100644 --- a/src/console/Line.hpp +++ b/src/console/Line.hpp @@ -4,27 +4,59 @@ #include "console/Types.hpp" #include +#include #define CONSOLE_LINES_MAX 256 #define CONSOLE_LINE_LENGTH 1024 -#define CONSOLE_LINE_PREALLOC 16 +#define CONSOLE_LINE_EXTRA_BYTES 16 -void ConsoleWrite(const char* str, COLOR_T color); -void ConsoleWriteA(const char* str, COLOR_T color, ...); +class CONSOLELINE : public TSLinkedNode { + public: + char* buffer = nullptr; + uint32_t chars = 0; + uint32_t charsalloc = 0; + uint32_t inputpos = 0; + uint32_t inputstart = 0; + COLOR_T colorType = DEFAULT_COLOR; + CGxString* fontPointer = nullptr; -void PasteInInputLine(char* characters); + void Up(); + void Down(); + void Delete(); + void Backspace(); + ~CONSOLELINE(); +}; + +extern int32_t s_historyIndex; +extern STORM_LIST(CONSOLELINE) s_linelist; +extern CONSOLELINE* s_currlineptr; +extern uint32_t s_NumLines; +extern SCritSect s_critsect; + +void GenerateNodeString(CONSOLELINE* node); + +void SetInputString(const char* buffer); + +void ReserveInputSpace(CONSOLELINE* lineptr, uint32_t len); void MoveLinePtr(int32_t direction, int32_t modifier); -void BackspaceLine(CONSOLELINE* line); - -void ReserveInputSpace(CONSOLELINE* line, size_t len); +void MakeCommandCurrent(CONSOLELINE* lineptr, const char* command); CONSOLELINE* GetInputLine(); -CONSOLELINE* GetCurrentLine(); CONSOLELINE* GetLineAtMousePosition(float y); -void ConsoleClear(); +void PasteInInputLine(const char* characters); + +void PasteClipboardInInputLine(); + +// void BackspaceLine(CONSOLELINE* line); + +// CONSOLELINE* GetCurrentLine(); + +// CONSOLELINE* GetLineAtMousePosition(float y); + +// void ConsoleClear(); #endif diff --git a/src/console/Screen.cpp b/src/console/Screen.cpp index e1452f6..fe454eb 100644 --- a/src/console/Screen.cpp +++ b/src/console/Screen.cpp @@ -2,7 +2,9 @@ #include "console/Console.hpp" #include "console/Command.hpp" #include "console/Handlers.hpp" +#include "console/Highlight.hpp" #include "console/Line.hpp" +#include "console/Text.hpp" #include "console/Types.hpp" #include "gx/Buffer.hpp" #include "gx/Coordinate.hpp" @@ -17,30 +19,15 @@ #include #include -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_charSpacing = 0.0f; -static CGxString* s_inputString = nullptr; - -static char s_fontName[STORM_MAX_PATH]; 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 }; +float s_consoleLines = 10.0f; +float s_consoleHeight = s_consoleLines * s_fontHeight; +CONSOLERESIZESTATE s_consoleResizeState = CS_NONE; -static CImVector s_colorArray[] = { +CImVector s_colorArray[NUM_COLORTYPES] = { { 0xFF, 0xFF, 0xFF, 0xFF }, // DEFAULT_COLOR { 0xFF, 0xFF, 0xFF, 0xFF }, // INPUT_COLOR { 0x80, 0x80, 0x80, 0xFF }, // ECHO_COLOR @@ -116,7 +103,7 @@ void DrawCaret(C3Vector& caretpos) { float minY = caretpos.y; float maxX = caretpos.x + (s_caretpixwidth * 2); - float maxY = caretpos.y + ConsoleGetFontHeight(); + float maxY = caretpos.y + s_fontHeight; C3Vector position[] = { { minX, minY, 0.0f }, @@ -153,107 +140,6 @@ 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(SMemAlloc(line->charsalloc, __FILE__, __LINE__, 0x0)); - SStrCopy(input, &line->buffer[line->inputpos], STORM_MAX_STR); - - auto buffer = reinterpret_cast(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); - BC_ASSERT(node->fontPointer); - } -} - void PaintText(void* param, const RECTF* rect, const RECTF* visible, float elapsedSec) { if (s_rect.bottom >= 1.0f) { return; @@ -273,7 +159,7 @@ void PaintText(void* param, const RECTF* rect, const RECTF* visible, float elaps C3Vector pos = { s_rect.left, - (ConsoleGetFontHeight() * 0.75f) + s_rect.bottom, + (s_fontHeight * 0.75f) + s_rect.bottom, 1.0f }; @@ -289,14 +175,14 @@ void PaintText(void* param, const RECTF* rect, const RECTF* visible, float elaps if (line->inputpos) { caretpos = pos; - GxuFontGetTextExtent(font, line->buffer, line->inputpos, ConsoleGetFontHeight(), &caretpos.x, 0.0f, 1.0f, s_charSpacing, s_baseTextFlags); + GxuFontGetTextExtent(font, line->buffer, line->inputpos, s_fontHeight, &caretpos.x, 0.0f, 1.0f, s_charSpacing, s_baseTextFlags); DrawCaret(caretpos); } - pos.y += ConsoleGetFontHeight(); + pos.y += s_fontHeight; - for (auto lineptr = GetCurrentLine(); (lineptr && pos.y < 1.0); lineptr = lineptr->Next()) { + for (auto lineptr = s_currlineptr; (lineptr && pos.y < 1.0); lineptr = lineptr->Next()) { if (lineptr != line) { if (lineptr->fontPointer == nullptr) { GenerateNodeString(lineptr); @@ -304,101 +190,15 @@ void PaintText(void* param, const RECTF* rect, const RECTF* visible, float elaps GxuFontSetStringPosition(lineptr->fontPointer, pos); GxuFontAddToBatch(s_batch, lineptr->fontPointer); - pos.y += ConsoleGetFontHeight(); + pos.y += s_fontHeight; } } GxuFontRenderBatch(s_batch); } -void UpdateHighlight() { - auto font = TextBlockGetFontPtr(s_textFont); - BC_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 - ConsoleGetHeight(), 1.0f) : 1.0f; + auto finalPos = ConsoleGetActive() ? std::min(1.0f - s_consoleHeight, 1.0f) : 1.0f; finalPos = std::max(finalPos, 0.0f); if (s_rect.bottom == finalPos) { @@ -407,7 +207,7 @@ void ConsoleScreenAnimate(float elapsedSec) { auto currentPos = finalPos; - if (ConsoleGetResizeState() == CS_NONE) { + if (s_consoleResizeState == CS_NONE) { auto direction = s_rect.bottom <= finalPos ? 1.0f : -1.0f; currentPos = s_rect.bottom + direction * elapsedSec * 5.0f; @@ -430,7 +230,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(ConsoleGetFontHeight())); + s_textFont = TextBlockGenerateFont(s_fontName, 0, NDCToDDCHeight(s_fontHeight)); ScrnLayerCreate(&s_rect, 6.0f, 0x1 | 0x2, nullptr, PaintBackground, &s_layerBackground); ScrnLayerCreate(&s_rect, 7.0f, 0x1 | 0x2, nullptr, PaintText, &s_layerText); diff --git a/src/console/Screen.hpp b/src/console/Screen.hpp index fce64dc..d4366b8 100644 --- a/src/console/Screen.hpp +++ b/src/console/Screen.hpp @@ -1,46 +1,15 @@ #ifndef CONSOLE_SCREEN_HPP #define CONSOLE_SCREEN_HPP -#define HIGHLIGHT_COPY_SIZE 128 +#include "console/Types.hpp" -#include "console/Line.hpp" -#include - -enum HIGHLIGHTSTATE { - HS_NONE = 0, - HS_HIGHLIGHTING = 1, - HS_ENDHIGHLIGHT = 2, - NUM_HIGHLIGHTSTATES -}; +extern float s_consoleLines; +extern float s_consoleHeight; +extern CONSOLERESIZESTATE s_consoleResizeState; +extern CImVector s_colorArray[NUM_COLORTYPES]; 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 diff --git a/src/console/Text.cpp b/src/console/Text.cpp new file mode 100644 index 0000000..148686f --- /dev/null +++ b/src/console/Text.cpp @@ -0,0 +1,12 @@ +#include "console/Text.hpp" + +CGxStringBatch* s_batch; +uint32_t s_baseTextFlags = 0x8; +int32_t s_caret = 0; +float s_caretpixwidth; +float s_caretpixheight; +float s_charSpacing = 0.0f; +CGxString* s_inputString = nullptr; +char s_fontName[STORM_MAX_PATH]; +float s_fontHeight = 0.02f; +HTEXTFONT s_textFont; diff --git a/src/console/Text.hpp b/src/console/Text.hpp new file mode 100644 index 0000000..d1f9dc5 --- /dev/null +++ b/src/console/Text.hpp @@ -0,0 +1,18 @@ +#ifndef CONSOLE_TEXT_HPP +#define CONSOLE_TEXT_HPP + +#include "gx/Font.hpp" +#include "storm/String.hpp" + +extern CGxStringBatch* s_batch; +extern uint32_t s_baseTextFlags; +extern int32_t s_caret; +extern float s_caretpixwidth; +extern float s_caretpixheight; +extern float s_charSpacing; +extern CGxString* s_inputString; +extern char s_fontName[STORM_MAX_PATH]; +extern float s_fontHeight; +extern HTEXTFONT s_textFont; + +#endif diff --git a/src/console/Types.hpp b/src/console/Types.hpp index 9a2297c..17b8b3b 100644 --- a/src/console/Types.hpp +++ b/src/console/Types.hpp @@ -2,7 +2,6 @@ #define CONSOLE_TYPES_HPP #include "gx/Font.hpp" - #include #include @@ -50,32 +49,4 @@ enum CONSOLERESIZESTATE { typedef int32_t (*COMMANDHANDLER)(const char*, const char*); -class CONSOLECOMMAND : public TSHashObject { - public: - COMMANDHANDLER m_handler; - const char* m_helpText; - CATEGORY m_category; -}; - -class CONSOLELINE : public TSLinkedNode { - public: - char* buffer; - uint32_t chars; - uint32_t charsalloc; - uint32_t inputpos; - uint32_t inputstart; - COLOR_T colorType; - CGxString* fontPointer; - - ~CONSOLELINE(); -}; - -class ConsoleCommandList { - public: - const char* m_command; - COMMANDHANDLER m_handler; - const char* m_helpText; -}; - - #endif diff --git a/src/console/command/Commands.hpp b/src/console/command/Commands.hpp new file mode 100644 index 0000000..93a427f --- /dev/null +++ b/src/console/command/Commands.hpp @@ -0,0 +1,32 @@ +#ifndef CONSOLE_COMMAND_COMMANDS_HPP +#define CONSOLE_COMMAND_COMMANDS_HPP + +#include + +#include "console/Types.hpp" + +#define DECLARE_COMMAND(x) int32_t ConsoleCommand_##x(const char* command, const char* arguments) + +int32_t CCGxRestart(const char* command, const char* argument); + +DECLARE_COMMAND(Quit); +DECLARE_COMMAND(Ver); +DECLARE_COMMAND(SetMap); + +DECLARE_COMMAND(Help); +DECLARE_COMMAND(FontColor); +DECLARE_COMMAND(BackGroundColor); +DECLARE_COMMAND(HighLightColor); +DECLARE_COMMAND(FontSize); +DECLARE_COMMAND(Font); +DECLARE_COMMAND(BufferSize); +DECLARE_COMMAND(ClearConsole); +DECLARE_COMMAND(Proportional); +DECLARE_COMMAND(CharSpacing); +DECLARE_COMMAND(CurrentSettings); +DECLARE_COMMAND(DefaultSettings); +DECLARE_COMMAND(CloseConsole); +DECLARE_COMMAND(RepeatHandler); +DECLARE_COMMAND(AppendLogToFile); + +#endif diff --git a/src/console/command/console/AppendLogToFile.cpp b/src/console/command/console/AppendLogToFile.cpp index ef60729..395542e 100644 --- a/src/console/command/console/AppendLogToFile.cpp +++ b/src/console/command/console/AppendLogToFile.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_AppendLogToFile(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(AppendLogToFile) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/BackGroundColor.cpp b/src/console/command/console/BackGroundColor.cpp index 41dbeb1..79498e3 100644 --- a/src/console/command/console/BackGroundColor.cpp +++ b/src/console/command/console/BackGroundColor.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_BackGroundColor(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(BackGroundColor) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/BufferSize.cpp b/src/console/command/console/BufferSize.cpp index 2602e03..e779e1e 100644 --- a/src/console/command/console/BufferSize.cpp +++ b/src/console/command/console/BufferSize.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_BufferSize(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(BufferSize) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/CharSpacing.cpp b/src/console/command/console/CharSpacing.cpp index 05d6da9..fd97165 100644 --- a/src/console/command/console/CharSpacing.cpp +++ b/src/console/command/console/CharSpacing.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_CharSpacing(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(CharSpacing) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/ClearConsole.cpp b/src/console/command/console/ClearConsole.cpp index a625345..18e090a 100644 --- a/src/console/command/console/ClearConsole.cpp +++ b/src/console/command/console/ClearConsole.cpp @@ -1,7 +1,7 @@ -#include "console/Command.hpp" #include "console/Console.hpp" +#include "console/command/Commands.hpp" -int32_t ConsoleCommand_ClearConsole(const char* command, const char* arguments) { +DECLARE_COMMAND(ClearConsole) { ConsoleClear(); return 1; } diff --git a/src/console/command/console/CloseConsole.cpp b/src/console/command/console/CloseConsole.cpp index 6456635..7e5e6ae 100644 --- a/src/console/command/console/CloseConsole.cpp +++ b/src/console/command/console/CloseConsole.cpp @@ -1,7 +1,7 @@ -#include "console/Command.hpp" #include "console/Console.hpp" +#include "console/command/Commands.hpp" -int32_t ConsoleCommand_CloseConsole(const char* command, const char* arguments) { +DECLARE_COMMAND(CloseConsole) { ConsoleSetActive(false); return 1; } diff --git a/src/console/command/console/CurrentSettings.cpp b/src/console/command/console/CurrentSettings.cpp index 60ef851..e881389 100644 --- a/src/console/command/console/CurrentSettings.cpp +++ b/src/console/command/console/CurrentSettings.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_CurrentSettings(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(CurrentSettings) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/DefaultSettings.cpp b/src/console/command/console/DefaultSettings.cpp index d9bb63c..42fd75a 100644 --- a/src/console/command/console/DefaultSettings.cpp +++ b/src/console/command/console/DefaultSettings.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_DefaultSettings(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(DefaultSettings) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/Font.cpp b/src/console/command/console/Font.cpp index cd0391f..1e04bc0 100644 --- a/src/console/command/console/Font.cpp +++ b/src/console/command/console/Font.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_Font(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(Font) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/FontColor.cpp b/src/console/command/console/FontColor.cpp index 2c8777e..99b9cad 100644 --- a/src/console/command/console/FontColor.cpp +++ b/src/console/command/console/FontColor.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_FontColor(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(FontColor) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/FontSize.cpp b/src/console/command/console/FontSize.cpp index 596edfb..76eea24 100644 --- a/src/console/command/console/FontSize.cpp +++ b/src/console/command/console/FontSize.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_FontSize(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(FontSize) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/Help.cpp b/src/console/command/console/Help.cpp index 1d0180d..8d165e7 100644 --- a/src/console/command/console/Help.cpp +++ b/src/console/command/console/Help.cpp @@ -1,5 +1,6 @@ +#include "console/Console.hpp" #include "console/Command.hpp" -#include "console/Line.hpp" +#include "console/command/Commands.hpp" struct CategoryTranslation { CATEGORY categoryValue; @@ -7,18 +8,18 @@ struct CategoryTranslation { }; CategoryTranslation s_translation[] = { - { DEBUG, "debug" }, + { DEBUG, "debug" }, { GRAPHICS, "graphics" }, - { CONSOLE, "console" }, - { COMBAT, "combat" }, - { GAME, "game" }, - { DEFAULT, "default" }, - { NET, "net" }, - { SOUND, "sound" }, - { GM, "gm" } + { CONSOLE, "console" }, + { COMBAT, "combat" }, + { GAME, "game" }, + { DEFAULT, "default" }, + { NET, "net" }, + { SOUND, "sound" }, + { GM, "gm" } }; -int32_t ConsoleCommand_Help(const char* command, const char* arguments) { +DECLARE_COMMAND(Help) { char buffer[128]; bool showCategories = *arguments == '\0'; @@ -42,70 +43,72 @@ int32_t ConsoleCommand_Help(const char* command, const char* arguments) { 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); + return 1; + } - ConsoleWrite(buffer, WARNING_COLOR); + for (size_t i = 0; i < numTranslation; i++) { + auto& translation = s_translation[i]; - buffer[0] = '\0'; + 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); - uint32_t counter = 0; + ConsoleWrite(buffer, WARNING_COLOR); - 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)); + buffer[0] = '\0'; - if (++counter == 8) { - ConsoleWrite(buffer, DEFAULT_COLOR); - buffer[0] = '\0'; - counter = 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; } } - - const char* wr = nullptr; - - if (buffer[0]) { - auto comma = reinterpret_cast(SStrChrR(buffer, ',')); - if (comma) { - *comma = 0x00; - } - - wr = buffer; - } else { - wr = "NONE"; - } - - ConsoleWrite(wr, DEFAULT_COLOR); - break; } + + const char* wr = nullptr; + + if (buffer[0]) { + auto comma = reinterpret_cast(SStrChrR(buffer, ',')); + if (comma) { + *comma = '\0'; + } + + 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); } + 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; } diff --git a/src/console/command/console/HighLightColor.cpp b/src/console/command/console/HighLightColor.cpp index 1749c24..0569b5e 100644 --- a/src/console/command/console/HighLightColor.cpp +++ b/src/console/command/console/HighLightColor.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_HighLightColor(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(HighLightColor) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/Proportional.cpp b/src/console/command/console/Proportional.cpp index bb4d6cc..7263e10 100644 --- a/src/console/command/console/Proportional.cpp +++ b/src/console/command/console/Proportional.cpp @@ -1,6 +1,6 @@ -#include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_Proportional(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(Proportional) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/RepeatHandler.cpp b/src/console/command/console/RepeatHandler.cpp index 5ea1125..a75fc7a 100644 --- a/src/console/command/console/RepeatHandler.cpp +++ b/src/console/command/console/RepeatHandler.cpp @@ -1,7 +1,6 @@ -#include "console/Command.hpp" -#include "console/Console.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_RepeatHandler(const char* command, const char* arguments) { - // TODO - return 1; +DECLARE_COMMAND(RepeatHandler) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/command/console/Ver.cpp b/src/console/command/console/Ver.cpp index c165c8f..8f6b964 100644 --- a/src/console/command/console/Ver.cpp +++ b/src/console/command/console/Ver.cpp @@ -1,7 +1,7 @@ -#include "console/Command.hpp" -#include "console/Line.hpp" +#include "console/Console.hpp" +#include "console/command/Commands.hpp" -int32_t ConsoleCommand_Ver(const char* command, const char* arguments) { +DECLARE_COMMAND(Ver) { ConsoleWrite("Whoa ", DEFAULT_COLOR); return 1; } diff --git a/src/console/command/default/GxRestart.cpp b/src/console/command/default/GxRestart.cpp new file mode 100644 index 0000000..197639d --- /dev/null +++ b/src/console/command/default/GxRestart.cpp @@ -0,0 +1,16 @@ +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" + +int32_t CCGxRestart(const char* command, const char* argument) { + // sub_512900(); + // ValidateFormatMonitor(s_requestedFormat); + + // if (!GxDevSetFormat(s_requestedFormat)) { + // ConsoleWrite("unable to set requested display mode", DEFAULT_COLOR); + // memcpy(&s_requestedFormat, &s_lastGoodFormat, sizeof(CGxFormat)); + + // if (!GxDevSetFormat()) + // } + + WHOA_UNIMPLEMENTED(1); +} diff --git a/src/console/command/default/Quit.cpp b/src/console/command/default/Quit.cpp index ea1a9da..6f662c5 100644 --- a/src/console/command/default/Quit.cpp +++ b/src/console/command/default/Quit.cpp @@ -1,7 +1,7 @@ -#include "console/Command.hpp" #include "console/Console.hpp" +#include "console/command/Commands.hpp" -int32_t ConsoleCommand_Quit(const char* command, const char* arguments) { +DECLARE_COMMAND(Quit) { ConsolePostClose(); return 1; } diff --git a/src/console/command/default/SetMap.cpp b/src/console/command/default/SetMap.cpp index f4e8459..ee73695 100644 --- a/src/console/command/default/SetMap.cpp +++ b/src/console/command/default/SetMap.cpp @@ -1,5 +1,7 @@ #include "console/Command.hpp" +#include "console/command/Commands.hpp" +#include "util/Unimplemented.hpp" -int32_t ConsoleCommand_SetMap(const char* command, const char* arguments) { - return 1; +DECLARE_COMMAND(SetMap) { + WHOA_UNIMPLEMENTED(1); } diff --git a/src/console/cvar/Gx.cpp b/src/console/cvar/Gx.cpp new file mode 100644 index 0000000..48f784e --- /dev/null +++ b/src/console/cvar/Gx.cpp @@ -0,0 +1,641 @@ +#include "console/cvar/Gx.hpp" +#include "console/Gx.hpp" +#include "console/Console.hpp" +#include "console/Detect.hpp" +#include "console/Device.hpp" +#include "console/Types.hpp" +#include "gx/CGxFormat.hpp" +#include "gx/CGxMonitorMode.hpp" +#include "gx/Device.hpp" +#include "gx/Types.hpp" +#include "gx/Gx.hpp" +#include "os/Input.hpp" +#include "storm/String.hpp" +#include +#include + +CVar* s_cvGxStereoEnabled; +CVar* s_cvGxRefresh; +CVar* s_cvGxMaximize; +CVar* s_cvGxMultisample; +CVar* s_cvGxCursor; +CVar* s_cvGxStereoSeparation; +CVar* s_cvGxMultisampleQuality; +CVar* s_cvGxResolution; +CVar* s_cvGxOverride; +CVar* s_cvGxFixLag; +CVar* s_cvMaxFPS; +CVar* s_cvGxVSync; +CVar* s_cvVideoOptionsVersion; +CVar* s_cvGxStereoConvergence; +CVar* s_cvMaxFPSBk; +CVar* s_cvGxTripleBuffer; +CVar* s_cvGxDepthBits; +CVar* s_cvGxColorBits; +CVar* s_cvGxApi; +CVar* s_cvGxAspect; +CVar* s_cvFixedFunction; +CVar* s_cvWidescreen; +CVar* s_cvGxWindow; +CVar* s_cvWindowResizeLock; + +static const char* formatToInt[CGxFormat::Formats_Last] = { + "16", + "24", + "24", + "30", + "16", + "24", + "24", + "32" +}; + +bool CVGxColorBitsCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + auto colorBits = SStrToInt(newValue); + switch (colorBits) { + case 16: + s_requestedFormat.colorFormat = CGxFormat::Fmt_Rgb565; + break; + case 24: + s_requestedFormat.colorFormat = CGxFormat::Fmt_ArgbX888; + break; + case 30: + s_requestedFormat.colorFormat = CGxFormat::Fmt_Argb2101010; + break; + default: + ConsoleWrite("Color bits must be 16, 24, or 30", DEFAULT_COLOR); + return false; + } + + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxDepthBitsCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + auto depthBits = SStrToInt(newValue); + switch (depthBits) { + case 16: + s_requestedFormat.depthFormat = CGxFormat::Fmt_Ds160; + break; + case 24: + s_requestedFormat.depthFormat = CGxFormat::Fmt_Ds24X; + break; + case 32: + s_requestedFormat.depthFormat = CGxFormat::Fmt_Ds320; + break; + default: + ConsoleWrite("Depth bits must be 16, 24, or 32", DEFAULT_COLOR); + return false; + } + + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxTripleBufferCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + auto tripleBuffer = SStrToInt(newValue); + if (tripleBuffer > 1) { + ConsoleWrite("TripleBuffer must be 0 or 1", DEFAULT_COLOR); + return false; + } + + // TODO + // s_requestedFormat.unk1C = (tripleBuffer != 0) + 1; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return 1; +} + +bool CVGxApiCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + for (EGxApi api = GxApi_OpenGl; api < GxApis_Last; api = static_cast(static_cast(api) + 1)) { + if (GxApiSupported(api)) { + if (!SStrCmpI(newValue, g_gxApiNames[api], STORM_MAX_STR)) { + ConsoleWrite("GxApi set pending gxRestart", DEFAULT_COLOR); + return true; + } + } + } + + // User supplied an unknown gxApi string + // display list of available gxApis + char message[1024]; + SStrCopy(message, "unsupported api, must be one of ", sizeof(message)); + + uint32_t i = 0; + for (EGxApi api = GxApi_OpenGl; api < GxApis_Last; api = static_cast(static_cast(api) + 1)) { + if (GxApiSupported(api)) { + if (i) { + SStrPack(message, ", ", sizeof(message)); + } + + SStrPack(message, "'", sizeof(message)); + SStrPack(message, g_gxApiNames[api], sizeof(message)); + SStrPack(message, "'", sizeof(message)); + i++; + } + } + + ConsoleWrite(message, DEFAULT_COLOR); + return false; +} + +bool CVGxVSyncCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + s_requestedFormat.vsync = SStrToInt(newValue); + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxWindowCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + s_requestedFormat.window = SStrToInt(newValue) != 0; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxAspectCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + s_requestedFormat.aspect = SStrToInt(newValue) != 0; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxMaximizeCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + s_requestedFormat.maximize = SStrToInt(newValue) != 0; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxCursorCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + s_requestedFormat.hwCursor = SStrToInt(newValue) != 0; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxMultisampleCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + auto sampleCount = SStrToInt(newValue); + s_requestedFormat.sampleCount = std::max(1, std::min(sampleCount, 16)); + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxMultisampleQualityCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + auto sampleQuality = SStrToFloat(newValue); + s_requestedFormat.sampleQuality = std::max(0.0f, std::min(sampleQuality, 1.0f)); + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxFixLagCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + s_requestedFormat.fixLag = SStrToInt(newValue) != 0; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxOverrideCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + ConsoleGxOverride(newValue); + return true; +} + +bool CVGxMaxFPSCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + auto maxFPS = SStrToInt(newValue); + GxSetMaxFPS(std::max(8, maxFPS)); + return true; +} + +bool CVGxMaxFPSBkCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + auto maxFPSBk = SStrToInt(newValue); + GxSetMaxFPSBk(std::max(8, maxFPSBk)); + return true; +} + +bool CVGxWindowResizeLockCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + OsInputSetWindowResizeLock(SStrToInt(newValue)); + return true; +} + +bool CVGxStereoEnabledCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + s_requestedFormat.stereoEnabled = SStrToInt(newValue) == 1; + return true; +} + +bool CVGxStereoConvergenceCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + GxStereoSetConvergence(SStrToFloat(newValue)); + return true; +} + +bool CVGxStereoSeparationCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + GxStereoSetSeparation(SStrToFloat(newValue)); + return true; +} + +bool CVGxResolutionCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + C2iVector size = { -1, -1 }; + uint8_t x; + sscanf(newValue, "%d%c%d", &size.x, &x, &size.y); + + if (s_requestedFormat.window) { + s_requestedFormat.size = size; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; + } + + TSGrowableArray resolutions; + ConsoleDetectGetResolutions(resolutions, s_cvWidescreen->GetInt()); + + uint32_t i; + for (i = 0; i < resolutions.Count(); i++) { + if (size.x == resolutions[i].x && size.y == resolutions[i].y) { + break; + } + } + + char str[256]; + char rez[16]; + if (i == resolutions.Count()) { + SStrCopy(str, "invalid resolution, must be one of ", sizeof(str)); + for (uint32_t i = 0; i < resolutions.Count(); i++) { + if (i) { + SStrPack(str, ", ", sizeof(str)); + } + + // flush line + if (SStrLen(str) > 100) { + ConsoleWrite(str, DEFAULT_COLOR); + *str = '\0'; + } + + SStrPrintf(rez, sizeof(rez), "%dx%d", resolutions[i].x, resolutions[i].y); + SStrPack(str, rez, sizeof(str)); + } + + ConsoleWrite(str, DEFAULT_COLOR); + return 0; + } + + s_requestedFormat.size = size; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxRefreshCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + auto refreshRate = SStrToUnsigned(newValue); + + TSGrowableArray modes; + GxAdapterMonitorModes(modes); + + uint32_t i; + for (i = 0; i < modes.Count(); i++) { + if (modes[i].refreshRate == refreshRate) { + break; + } + } + + if (i == modes.Count()) { + ConsoleWrite("Unsupported refresh rate", DEFAULT_COLOR); + return false; + } + + s_requestedFormat.refreshRate = refreshRate; + ConsoleWrite("set pending gxRestart", DEFAULT_COLOR); + return true; +} + +bool CVGxVideoOptionsVersionCallback(CVar* h, const char* oldValue, const char* newValue, void* arg) { + return true; +} + +void RegisterGxCVars() { + auto format = s_defaults.format; + + // TODO CURRENT_LANGUAGE check + auto v1 = true; + + s_cvWidescreen = CVar::Register( + "widescreen", + "Allow widescreen support", + 0, + "1", + nullptr, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxWindow = CVar::Register( + "gxWindow", + "toggle fullscreen/window", + 0x1 | 0x2, + v1 ? "1" : "0", + CVGxWindowCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxMaximize = CVar::Register( + "gxMaximize", + "maximize game window", + 0x1 | 0x2, + v1 ? "1" : "0", + CVGxMaximizeCallback, + GRAPHICS, + false, + nullptr, + false + ); + + char colorBits[260]; + SStrPrintf(colorBits, 260, "%s", formatToInt[format->colorFormat]); + s_cvGxColorBits = CVar::Register( + "gxColor", + "color bits", + 0x1 | 0x2, + colorBits, + CVGxColorBitsCallback, + GRAPHICS, + false, + nullptr, + false + ); + + char depthBits[260]; + SStrPrintf(depthBits, 260, "%s", formatToInt[format->depthFormat]); + s_cvGxDepthBits = CVar::Register( + "gxDepthBits", + "depth bits", + 0x1 | 0x2, + colorBits, + CVGxDepthBitsCallback, + GRAPHICS, + false, + nullptr, + false); + + char resolution[260]; + SStrPrintf(resolution, 260, "%dx%d", format->size.x, format->size.y); + s_cvGxResolution = CVar::Register( + "gxResolution", + "resolution", + 0x1 | 0x2, + resolution, + CVGxResolutionCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxRefresh = CVar::Register( + "gxRefresh", + "refresh rate", + 0x1 | 0x2, + "75", + CVGxRefreshCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxTripleBuffer = CVar::Register( + "gxTripleBuffer", + "triple buffer", + 0x1 | 0x2, + "0", + CVGxTripleBufferCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxApi = CVar::Register( + "gxApi", + "graphics api", + 0x1 | 0x2, + g_gxApiNames[GxDefaultApi()], + CVGxApiCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxVSync = CVar::Register( + "gxVSync", + "vsync on or off", + 0x1 | 0x2, + "1", + CVGxVSyncCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxAspect = CVar::Register( + "gxAspect", + "constrain window aspect", + 0x1 | 0x2, + "1", + CVGxAspectCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxCursor = CVar::Register( + "gxCursor", + "toggle hardware cursor", + 0x1 | 0x2, + "1", + CVGxCursorCallback, + GRAPHICS, + false, + nullptr, + false + ); + + char multisample[260]; + SStrPrintf(multisample, 260, "%d", s_hardware.videoHw->m_multisample); + s_cvGxMultisample = CVar::Register( + "gxMultisample", + "multisample", + 0x1 | 0x2, + multisample, + CVGxMultisampleCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxMultisampleQuality = CVar::Register( + "gxMultisampleQuality", + "multisample quality", + 0x1 | 0x2, + "0.0", + CVGxMultisampleQualityCallback, + GRAPHICS, + false, + nullptr, + false + ); + + char fixLag[260]; + SStrPrintf(fixLag, 260, "%d", s_hardware.videoHw->m_fixLag); + s_cvGxFixLag = CVar::Register( + "gxFixLag", + "prevent cursor lag", + 0x1 | 0x2, + fixLag, + CVGxFixLagCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxStereoEnabled = CVar::Register( + "gxStereoEnabled", + "Enable stereoscopic rendering", + 0x1, + "0", + CVGxStereoEnabledCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvGxOverride = CVar::Register( + "gxOverride", + "gx overrides", + 0x1, + "", + CVGxOverrideCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvMaxFPS = CVar::Register( + "maxFPS", + "Set FPS limit", + 0x1, + "200", + CVGxMaxFPSCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvMaxFPSBk = CVar::Register( + "maxFPSBk", + "Set background FPS limit", + 0x1, + "30", + CVGxMaxFPSBkCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvVideoOptionsVersion = CVar::Register( + "videoOptionsVersion", + "Video options version", + 0x1 | 0x2, + "0", + CVGxVideoOptionsVersionCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvWindowResizeLock = CVar::Register( + "windowResizeLock", + "prevent resizing in windowed mode", + 0x1, + "0", + CVGxWindowResizeLockCallback, + GRAPHICS, + false, + nullptr, + false + ); + + s_cvFixedFunction = CVar::Register( + "fixedFunction", + "Force fixed function rendering", + 0x1 | 0x2, + "0", + nullptr, + GRAPHICS, + false, + nullptr, + false + ); +} + +void UpdateGxCVars() { + s_cvGxColorBits->Update(); + s_cvGxDepthBits->Update(); + s_cvGxWindow->Update(); + s_cvGxResolution->Update(); + s_cvGxRefresh->Update(); + s_cvGxTripleBuffer->Update(); + s_cvGxApi->Update(); + s_cvGxVSync->Update(); + s_cvGxAspect->Update(); + s_cvGxMaximize->Update(); + s_cvGxCursor->Update(); + s_cvGxMultisample->Update(); + s_cvGxMultisampleQuality->Update(); + s_cvGxFixLag->Update(); +} + +void SetGxCVars(const CGxFormat& format) { + char value[1024]; + + s_cvGxColorBits->Set(formatToInt[format.colorFormat], true, false, false, true); + + s_cvGxDepthBits->Set(formatToInt[format.depthFormat], true, false, false, true); + + SStrPrintf(value, 1024, "%d", format.window); + s_cvGxWindow->Set(value, true, false, false, true); + + SStrPrintf(value, 1024, "%dx%d", format.size.x, format.size.y); + s_cvGxResolution->Set(value, true, false, false, true); + + SStrPrintf(value, 1024, "%d", format.refreshRate); + s_cvGxRefresh->Set(value, true, false, false, true); + + s_cvGxTripleBuffer->Set(format.backbuffers > 1 ? "1" : "0", true, false, false, true); + + SStrPrintf(value, 1024, "%d", format.vsync); + s_cvGxVSync->Set(value, true, false, false, true); + + SStrPrintf(value, 1024, "%d", format.aspect); + s_cvGxAspect->Set(value, true, false, false, true); + + SStrPrintf(value, 1024, "%d", format.maximize); + s_cvGxMaximize->Set(value, true, false, false, true); + + SStrPrintf(value, 1024, "%d", format.hwCursor); + s_cvGxCursor->Set(value, true, false, false, true); + + SStrPrintf(value, 1024, "%d", format.sampleCount); + s_cvGxMultisample->Set(value, true, false, false, true); + + SStrPrintf(value, 1024, "%f", format.sampleQuality); + s_cvGxMultisampleQuality->Set(value, true, false, false, true); + + SStrPrintf(value, 1024, "%d", format.fixLag); + s_cvGxFixLag->Set(value, true, false, false, true); + + UpdateGxCVars(); +} diff --git a/src/console/cvar/Gx.hpp b/src/console/cvar/Gx.hpp new file mode 100644 index 0000000..e0a00ef --- /dev/null +++ b/src/console/cvar/Gx.hpp @@ -0,0 +1,43 @@ +#ifndef CONSOLE_C_VAR_GX_HPP +#define CONSOLE_C_VAR_GX_HPP + +#include "gx/CGxFormat.hpp" +#include "console/CVar.hpp" + +extern CVar* s_cvGxStereoEnabled; +extern CVar* s_cvGxRefresh; +extern CVar* s_cvGxMaximize; +extern CVar* s_cvGxMultisample; +extern CVar* s_cvGxCursor; +extern CVar* s_cvGxStereoSeparation; +extern CVar* s_cvGxMultisampleQuality; +extern CVar* s_cvGxResolution; +extern CVar* s_cvHwDetect; +extern CVar* s_cvGxOverride; +extern CVar* s_cvGxFixLag; +extern CVar* s_cvMaxFPS; +extern CVar* s_cvGxVSync; +extern CVar* s_cvVideoOptionsVersion; +extern CVar* s_cvGxStereoConvergence; +extern CVar* s_cvMaxFPSBk; +extern CVar* s_cvGxTripleBuffer; +extern CVar* s_cvGxDepthBits; +extern CVar* s_cvGxColorBits; +extern CVar* s_cvGxApi; +extern CVar* s_cvGxAspect; +extern CVar* s_cvFixedFunction; +extern CVar* s_cvWidescreen; +extern CVar* s_cvGxWindow; +extern CVar* s_cvWindowResizeLock; + +void RegisterGxCVars(); + +void UpdateGxCVars(); + +void SetGxCVars(const CGxFormat& format); + +bool CVGxStereoConvergenceCallback(CVar* h, const char* oldValue, const char* newValue, void* arg); + +bool CVGxStereoSeparationCallback(CVar* h, const char* oldValue, const char* newValue, void* arg); + +#endif diff --git a/src/event/CMakeLists.txt b/src/event/CMakeLists.txt index db6b7e4..fe2e410 100644 --- a/src/event/CMakeLists.txt +++ b/src/event/CMakeLists.txt @@ -1,32 +1,11 @@ file(GLOB PRIVATE_SOURCES "*.cpp") -if (WHOA_SYSTEM_WIN) - file(GLOB WIN_SOURCES - "win/*.cpp" - ) - list(APPEND PRIVATE_SOURCES ${WIN_SOURCES}) -endif () - -if (WHOA_SYSTEM_MAC) +if(WHOA_SYSTEM_MAC) file(GLOB MAC_SOURCES - "mac/*.cpp" "mac/*.mm" ) list(APPEND PRIVATE_SOURCES ${MAC_SOURCES}) -endif () - -if (WHOA_SYSTEM_LINUX) - file(GLOB LINUX_SOURCES - "linux/*.cpp" - ) - list(APPEND PRIVATE_SOURCES ${LINUX_SOURCES}) -endif () - -# SDL has its own input event processing -if (WHOA_BUILD_GLSDL) - file(GLOB SDL_SOURCES "sdl/*.cpp") - list(APPEND PRIVATE_SOURCES ${SDL_SOURCES}) -endif () +endif() add_library(event STATIC ${PRIVATE_SOURCES} @@ -41,15 +20,10 @@ target_link_libraries(event PRIVATE client gx + os PUBLIC bc common storm tempest ) - -if (WHOA_BUILD_GLSDL) - target_link_libraries(event - PRIVATE - SDL2::SDL2-static) -endif () diff --git a/src/event/Input.cpp b/src/event/Input.cpp index fd06895..7ace7f3 100644 --- a/src/event/Input.cpp +++ b/src/event/Input.cpp @@ -3,6 +3,7 @@ #include "event/EvtContext.hpp" #include "event/Queue.hpp" #include "gx/Window.hpp" +#include "os/Input.hpp" #include #include #include @@ -19,7 +20,6 @@ namespace Input { CRect s_boundingRect; - OSEVENT s_queue[32]; MOUSEBUTTON s_buttonConversion[16] = { MOUSE_BUTTON_NONE, @@ -46,22 +46,8 @@ uint32_t Input::s_buttonState; C2iVector Input::s_currentMouse; uint32_t Input::s_mouseHoldButton; MOUSEMODE Input::s_mouseMode; -int32_t Input::s_numlockState; -uint32_t Input::s_osButtonState; -OS_MOUSE_MODE Input::s_osMouseMode; int32_t Input::s_simulatedRightButtonClick; uint32_t Input::s_metaKeyState; -int32_t Input::s_queueHead; -int32_t Input::s_queueTail; -int32_t Input::s_windowFocused; - -#if defined(WHOA_SYSTEM_WIN) - int32_t Input::s_savedMouseSpeed; -#endif - -#if defined(WHOA_SYSTEM_MAC) - double Input::s_savedMouseSpeed; -#endif void PostChar(EvtContext* context, int32_t ch, int32_t repeat) { EVENT_DATA_CHAR data; @@ -632,95 +618,3 @@ const char* KeyCodeToString(KEY key) { return "UNKNOWN"; } -void OsInputInitialize() { - #if defined(WHOA_SYSTEM_WIN) - Input::s_numlockState = GetAsyncKeyState(144); - int32_t mouseSpeed = 10; - SystemParametersInfoA(SPI_GETMOUSESPEED, 0, &mouseSpeed, 0); - Input::s_savedMouseSpeed = mouseSpeed; - #endif - - #if defined(WHOA_SYSTEM_MAC) - // Legacy Carbon input handling - // if (!byte_143EFE0) { - // Carbon_OsInputRegisterHICommandHandler(0x71756974, sub_A4F230); - // } - - MacClient::SetMouseCoalescingEnabled(true); - Input::s_savedMouseSpeed = MacClient::GetMouseSpeed(); - #endif -} - -bool OsInputIsUsingCocoaEventLoop() { - // TODO - - return true; -} - -void OsInputPostEvent(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3) { - // TODO -} - -int32_t OsQueueGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) { - if (Input::s_queueTail == Input::s_queueHead) { - return 0; - } - - OSEVENT event = Input::s_queue[Input::s_queueTail]; - - *id = event.id; - *param0 = event.param[0]; - *param1 = event.param[1]; - *param2 = event.param[2]; - *param3 = event.param[3]; - - if (Input::s_queueTail == OS_QUEUE_SIZE - 1) { - Input:: s_queueTail = 0; - } else { - ++Input::s_queueTail; - } - - return 1; -} - -void OsQueuePut(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3) { - int32_t nextTail = 0; - int32_t nextHead = 0; - - if (Input::s_queueHead != OS_QUEUE_SIZE - 1) { - nextHead = Input::s_queueHead + 1; - } - - if (nextHead == Input::s_queueTail) { - if (nextHead != OS_QUEUE_SIZE - 1) { - nextTail = nextHead + 1; - } - - Input::s_queueTail = nextTail; - } - - OSEVENT* event = &Input::s_queue[Input::s_queueHead]; - - event->id = id; - event->param[0] = param0; - event->param[1] = param1; - event->param[2] = param2; - event->param[3] = param3; - - Input::s_queueHead = nextHead; -} - -void OsQueueSetParam(int32_t index, int32_t param) { - int32_t pos = Input::s_queueTail; - - while (pos != Input::s_queueHead) { - OSEVENT* event = &Input::s_queue[pos]; - event->param[index] = param; - - if (pos == OS_QUEUE_SIZE - 1) { - pos = 0; - } else { - ++pos; - } - } -} diff --git a/src/event/Input.hpp b/src/event/Input.hpp index e913099..9267b7a 100644 --- a/src/event/Input.hpp +++ b/src/event/Input.hpp @@ -4,8 +4,6 @@ #include "event/Types.hpp" #include -#define OS_QUEUE_SIZE 32 - class C2iVector; class CRect; class EvtContext; @@ -16,22 +14,8 @@ namespace Input { extern C2iVector s_currentMouse; extern uint32_t s_mouseHoldButton; extern MOUSEMODE s_mouseMode; - extern uint32_t s_osButtonState; - extern OS_MOUSE_MODE s_osMouseMode; - extern int32_t s_numlockState; extern int32_t s_simulatedRightButtonClick; extern uint32_t s_metaKeyState; - extern int32_t s_queueHead; - extern int32_t s_queueTail; - extern int32_t s_windowFocused; - - #if defined(WHOA_SYSTEM_WIN) - extern int32_t s_savedMouseSpeed; - #endif - - #if defined(WHOA_SYSTEM_MAC) - extern double s_savedMouseSpeed; - #endif } void CheckMouseModeState(); @@ -54,24 +38,4 @@ void IEvtInputSetMouseMode(EvtContext* context, MOUSEMODE mode, uint32_t holdBut const char* KeyCodeToString(KEY key); -int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3); - -void OsInputInitialize(); - -bool OsInputIsUsingCocoaEventLoop(); - -void OsInputPostEvent(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3); - -void OsInputSetMouseMode(OS_MOUSE_MODE mode); - -void OsInputGetMousePosition(int32_t* x, int32_t* y); - -int32_t OsQueueGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3); - -void OsQueuePut(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3); - -void OsQueueSetParam(int32_t index, int32_t param); - -int32_t OsWindowProc(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam); - #endif diff --git a/src/event/Types.hpp b/src/event/Types.hpp index a195799..e2f2262 100644 --- a/src/event/Types.hpp +++ b/src/event/Types.hpp @@ -186,40 +186,6 @@ enum MOUSEMODE { MOUSE_MODES = 0x2 }; -enum OSINPUT { - OS_INPUT_CAPTURE_CHANGED = 0, - OS_INPUT_CHAR = 1, - OS_INPUT_STRING = 2, - OS_INPUT_IME = 3, - OS_INPUT_SIZE = 4, - OS_INPUT_CLOSE = 5, - OS_INPUT_FOCUS = 6, - OS_INPUT_KEY_DOWN = 7, - OS_INPUT_KEY_UP = 8, - OS_INPUT_MOUSE_DOWN = 9, - OS_INPUT_MOUSE_MOVE = 10, - OS_INPUT_MOUSE_WHEEL = 11, - OS_INPUT_MOUSE_MOVE_RELATIVE = 12, - OS_INPUT_MOUSE_UP = 13, - OS_INPUT_14 = 14, - OS_INPUT_15 = 15, - OS_INPUT_16 = 16, - OS_INPUT_17 = 17, - OS_INPUT_18 = 18, - OS_INPUT_SHUTDOWN = 19 -}; - -enum OS_MOUSE_MODE { - OS_MOUSE_MODE_NORMAL = 0, - OS_MOUSE_MODE_RELATIVE = 1, - OS_MOUSE_MODES = 2, -}; - -struct OSEVENT { - OSINPUT id; - int32_t param[4]; -}; - struct EVENT_DATA_CHAR { int32_t ch; uint32_t metaKeyState; diff --git a/src/event/mac/Event.h b/src/event/mac/Event.h deleted file mode 100644 index 0205cb5..0000000 --- a/src/event/mac/Event.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef EVENT_MAC_EVENT_H -#define EVENT_MAC_EVENT_H - -void RunCocoaEventLoop(); - -#endif diff --git a/src/event/mac/Event.hpp b/src/event/mac/Event.hpp new file mode 100644 index 0000000..d6051a9 --- /dev/null +++ b/src/event/mac/Event.hpp @@ -0,0 +1,6 @@ +#ifndef EVENT_MAC_EVENT_HPP +#define EVENT_MAC_EVENT_HPP + +void RunCocoaEventLoop(); + +#endif diff --git a/src/event/mac/Event.mm b/src/event/mac/Event.mm index fa0455f..237e9c9 100644 --- a/src/event/mac/Event.mm +++ b/src/event/mac/Event.mm @@ -1,4 +1,4 @@ -#include "event/mac/Event.h" +#include "event/mac/Event.hpp" #include "event/Event.hpp" #include diff --git a/src/event/sdl/Input.hpp b/src/event/sdl/Input.hpp deleted file mode 100644 index 4843acb..0000000 --- a/src/event/sdl/Input.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef EVENT_SDL_INPUT_HPP -#define EVENT_SDL_INPUT_HPP - -#include "event/Input.hpp" - -bool SDLInputActive(); - -int32_t SDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3); - -void SDLInputGetMousePosition(int32_t* x, int32_t *y); - -#endif diff --git a/src/gx/CGxCaps.hpp b/src/gx/CGxCaps.hpp index 0797ca8..469b691 100644 --- a/src/gx/CGxCaps.hpp +++ b/src/gx/CGxCaps.hpp @@ -22,7 +22,7 @@ class CGxCaps { int32_t m_texFilterAnisotropic = 0; uint32_t m_maxTexAnisotropy = 0; int32_t m_depthBias = 0; - int32_t m_hardwareCursor = 0; + int32_t m_hwCursor = 0; int32_t int130 = 1; int32_t int134 = 0; int32_t int138 = 0; diff --git a/src/gx/CGxDevice.cpp b/src/gx/CGxDevice.cpp index 71ae9c6..ba87b97 100644 --- a/src/gx/CGxDevice.cpp +++ b/src/gx/CGxDevice.cpp @@ -8,27 +8,36 @@ #include "gx/Transform.hpp" #include "gx/Draw.hpp" #include "util/SFile.hpp" -#include "event/Input.hpp" +#include "os/Input.hpp" +#include +#include +#include #include #include #include #include #include -#include -#include #if defined(WHOA_SYSTEM_WIN) - #include "gx/d3d/CGxDeviceD3d.hpp" + +#include "gx/d3d/CGxDeviceD3d.hpp" + #endif #if defined(WHOA_BUILD_GLSDL) - #include "gx/glsdl/CGxDeviceGLSDL.hpp" + +#include +#include "gx/glsdl/CGxDeviceGLSDL.hpp" + #endif #if defined(WHOA_SYSTEM_MAC) #include "gx/gll/CGxDeviceGLL.hpp" #endif +HSLOG CGxDevice::m_log; +uint32_t CGxDevice::m_logBytes; + uint32_t CGxDevice::s_alphaRef[] = { 0, // GxBlend_Opaque 224, // GxBlend_AlphaKey @@ -106,23 +115,331 @@ uint32_t CGxDevice::s_texFormatBytesPerBlock[] = { CGxShader* CGxDevice::s_uiVertexShader = nullptr; CGxShader* CGxDevice::s_uiPixelShader = nullptr; -void CGxDevice::LogOpen() { +#if defined(WHOA_SYSTEM_WIN) + +uint16_t HToI(const char* h, uint32_t count) { + uint32_t i = 0; + while (count) { + auto cur = *h; + --count; + i *= 16; + ++h; + if (isxdigit(cur)) { + if (isdigit(cur)) { + i += cur - '0'; + } else { + i += toupper(cur) - '7'; + } + } + } + return i; +} + +int32_t CGxDevice::AdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow) { + int32_t result = 0; + vendorID = 0xFFFF; + deviceID = 0xFFFF; + + driverVersionHi = 0; + driverVersionLow = 0; + + DISPLAY_DEVICE dd; + memset(&dd, 0, sizeof(dd)); + dd.cb = sizeof(DISPLAY_DEVICE); + + DWORD device = 0; + + while (EnumDisplayDevices(0, device, &dd, 0)) { + if (dd.StateFlags & 4) { + break; + } + + device++; + } + + uint16_t vI; + uint16_t dI; + if (strlen(dd.DeviceID) > 20 && (vI = HToI(&dd.DeviceID[8], 4)) && (dI = HToI(&dd.DeviceID[17], 4))) { + vendorID = vI; + deviceID = dI; + result = true; + } else { + HINSTANCE d3dLib = nullptr; + LPDIRECT3D9 d3d = nullptr; + + if (CGxDeviceD3d::ILoadD3dLib(d3dLib, d3d)) { + D3DADAPTER_IDENTIFIER9 d3dadapterid; + if (d3d->GetAdapterIdentifier(0, 0, &d3dadapterid) >= D3D_OK) { + vendorID = d3dadapterid.VendorId; + deviceID = d3dadapterid.DeviceId; + driverVersionLow = d3dadapterid.DriverVersion.LowPart; + driverVersionHi = d3dadapterid.DriverVersion.HighPart; + result = true; + } + CGxDeviceD3d::IUnloadD3dLib(d3dLib, d3d); + } + } + + // NOTE: this doesn't appear to be a typo on our part + Log("CGxDevice::DeviceAdapterID(): RET: %d, VID: %x, DID: %x, DVER: %x.%x", result, vendorID, deviceID, driverVersionHi, driverVersionLow); + return result; +} + +int32_t CGxDevice::AdapterInfer(uint16_t& deviceID) { + HINSTANCE d3dLib; + LPDIRECT3D9 d3d; + D3DCAPS9 d3dcaps; + + int32_t result = 0; + + if (!CGxDeviceD3d::ILoadD3dLib(d3dLib, d3d)) { + return result; + } + + if (d3d->GetDeviceCaps(0, D3DDEVTYPE_HAL, &d3dcaps) == D3D_OK) { + if ((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0 && d3dcaps.MaxSimultaneousTextures > 2 && d3dcaps.PixelShaderVersion >= 0x200) { + deviceID = 3; + result = 1; + } else if ((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) { + if (d3dcaps.MaxSimultaneousTextures > 2 && d3dcaps.PixelShaderVersion >= 0x101) { + deviceID = 2; + result = 1; + } else if (d3dcaps.MaxSimultaneousTextures >= 2) { + deviceID = 1; + result = 1; + } + } else { + deviceID = 0; + result = 1; + } + } + + CGxDeviceD3d::IUnloadD3dLib(d3dLib, d3d); + Log("CGxDevice::DeviceAdapterInfer(): RET: %d, DID: %x", result, deviceID); + return result; +} + +// TODO: replace this invented name +int32_t FindDisplayDevice(PDISPLAY_DEVICE device, uint32_t flag) { + DWORD i = 0; + device->cb = sizeof(DISPLAY_DEVICE); + while (EnumDisplayDevices(nullptr, i, device, 0)) { + if ((device->StateFlags & flag) == flag) { + return 1; + } + } + + return 0; +} + +int32_t CGxDevice::AdapterMonitorModes(TSGrowableArray& modes) { + modes.SetCount(0); + + DISPLAY_DEVICE device; + if (!FindDisplayDevice(&device, DISPLAY_DEVICE_PRIMARY_DEVICE)) { + return 0; + } + + DEVMODE dm; + dm.dmSize = sizeof(DEVMODE); + + DWORD i = 0; + while (EnumDisplaySettings(device.DeviceName, i, &dm)) { + if ((dm.dmPelsWidth >= 640 && dm.dmPelsHeight >= 480) + && dm.dmBitsPerPel >= 16) { + auto mode = modes.New(); + + mode->size.x = dm.dmPelsWidth; + mode->size.y = dm.dmPelsHeight; + mode->bpp = dm.dmBitsPerPel; + mode->refreshRate = dm.dmDisplayFrequency; + } + + i++; + } + + qsort(modes.Ptr(), modes.Count(), sizeof(CGxMonitorMode), CGxMonitorModeSort); + + return modes.Count() != 0; +} + +int32_t CGxDevice::AdapterDesktopMode(CGxMonitorMode& mode) { + DISPLAY_DEVICE device; + if (!FindDisplayDevice(&device, DISPLAY_DEVICE_ACTIVE|DISPLAY_DEVICE_PRIMARY_DEVICE)) { + return 0; + } + + DEVMODE dm; + dm.dmSize = sizeof(DEVMODE); + if (!EnumDisplaySettings(device.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) { + return 0; + } + + mode.size.x = dm.dmPelsWidth; + mode.size.y = dm.dmPelsHeight; + mode.refreshRate = dm.dmDisplayFrequency; + mode.bpp = dm.dmBitsPerPel; + return 1; +} + +#elif (WHOA_SYSTEM_MAC) + +int32_t CGxDevice::AdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow) { + // TODO: proper implementation + vendorID = 0xFFFF; + deviceID = 3; + driverVersionHi = 0; + driverVersionLow = 0; + return 1; +} + +int32_t CGxDevice::AdapterInfer(uint16_t& deviceID) { // TODO + deviceID = 3; + return 1; +} + +int32_t CGxDevice::AdapterMonitorModes(TSGrowableArray& modes) { + // TODO: Mac support + return 0; +} + +int32_t CGxDevice::AdapterDesktopMode(CGxMonitorMode& mode) { + // TODO: Mac support + return 0; +} + +#elif (WHOA_BUILD_GLSDL) + +int32_t CGxDevice::AdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow) { + // TODO + vendorID = 0xFFFF; + deviceID = 3; + driverVersionHi = 0; + driverVersionLow = 0; + return 1; +} + +int32_t CGxDevice::AdapterInfer(uint16_t& deviceID) { + // TODO + deviceID = 3; + return 1; +} + +int32_t CGxDevice::AdapterMonitorModes(TSGrowableArray& modes) { + auto primaryDisplay = SDL_GetPrimaryDisplay(); + if (!primaryDisplay) { + return false; + } + + int32_t displayModeCount; + auto displayModes = SDL_GetFullscreenDisplayModes(primaryDisplay, &displayModeCount); + if (displayModes == nullptr) { + return false; + } + + modes.SetCount(displayModeCount); + for (auto i = 0; i < displayModeCount; i++) { + auto displayMode = displayModes[i]; + CGxMonitorMode& mode = modes[i]; + mode.size.x = displayMode->w; + mode.size.y = displayMode->h; + mode.bpp = SDL_BITSPERPIXEL(displayMode->format); + mode.refreshRate = static_cast(displayMode->refresh_rate_numerator / displayMode->refresh_rate_denominator); + } + + SDL_free(displayModes); + + qsort(modes.Ptr(), modes.Count(), sizeof(CGxMonitorMode), CGxMonitorModeSort); + + return true; +} + +int32_t CGxDevice::AdapterDesktopMode(CGxMonitorMode& mode) { + auto primaryDisplay = SDL_GetPrimaryDisplay(); + if (!primaryDisplay) { + return 0; + } + + auto displayMode = SDL_GetDesktopDisplayMode(primaryDisplay); + if (!displayMode) { + return 0; + } + + mode.size.x = displayMode->w; + mode.size.y = displayMode->h; + mode.bpp = SDL_BITSPERPIXEL(displayMode->format); + mode.refreshRate = static_cast(displayMode->refresh_rate_numerator / displayMode->refresh_rate_denominator); + + return 1; +} + +#endif + +void CGxDevice::LogOpen() { + if (!m_log) { + OsCreateDirectory("Logs", 0); + SLogCreate("Logs\\gx.log", 0, &m_log); + m_logBytes = 0; + } } void CGxDevice::LogClose() { - // TODO + if (m_log) { + SLogClose(m_log); + m_log = nullptr; + } +} + +void CGxDevice::VLog(const char* format, va_list args) { + char buffer[2048]; + if (m_log) { + vsnprintf(buffer, sizeof(buffer), format, args); + if (m_logBytes < 0x200000) { + SLogWrite(m_log, "%s", buffer); + m_logBytes += strlen(buffer); + } + } } void CGxDevice::Log(const char* format, ...) { - // TODO + va_list args; + va_start(args, format); + if (m_log) { + VLog(format, args); + } } void CGxDevice::Log(const CGxFormat& format) { - // TODO + static const char* s_formatToString[] = { + "Rgb565", + "ArgbX888", + "Argb2101010", + "Ds160", + "Ds24X", + "Ds248", + "Ds320" + }; + + if (format.window) { + Log("\tFormat: %d x %d Window, %s, multisample %d", + format.size.x, + format.size.y, + s_formatToString[format.depthFormat], + format.sampleCount); + } else { + Log("\tFormat %d x %d @ %d Fullscreen, %s, %s, multisample %d", + format.size.x, + format.size.y, + format.refreshRate, + s_formatToString[format.colorFormat], + s_formatToString[format.depthFormat], + format.sampleCount); + } } #if defined(WHOA_SYSTEM_WIN) + CGxDevice* CGxDevice::NewD3d() { return NEW(CGxDeviceD3d); } @@ -131,12 +448,15 @@ CGxDevice* CGxDevice::NewD3d9Ex() { // TODO return nullptr; } + #endif #if defined(WHOA_SYSTEM_MAC) + CGxDevice* CGxDevice::NewGLL() { return NEW(CGxDeviceGLL); } + #endif CGxDevice* CGxDevice::NewOpenGl() { @@ -144,9 +464,11 @@ CGxDevice* CGxDevice::NewOpenGl() { } #if defined(WHOA_BUILD_GLSDL) + CGxDevice* CGxDevice::NewGLSDL() { return NEW(CGxDeviceGLSDL); } + #endif uint32_t CGxDevice::PrimCalcCount(EGxPrim primType, uint32_t count) { @@ -168,93 +490,6 @@ void CGxDevice::ICursorUpdate(EGxTexCommand command, uint32_t width, uint32_t he } } - -#if defined(WHOA_SYSTEM_WIN) - -// TODO: replace this invented name -int32_t FindDisplayDevice(PDISPLAY_DEVICE device, uint32_t flag) { - DWORD i = 0; - device->cb = sizeof(DISPLAY_DEVICE); - while (EnumDisplayDevices(nullptr, i, device, 0)) { - if ((device->StateFlags & flag) == flag) { - return 1; - } - } - - return 0; -} - -bool CGxDevice::AdapterMonitorModes(TSGrowableArray& modes) { - modes.SetCount(0); - - DISPLAY_DEVICE device; - if (!FindDisplayDevice(&device, DISPLAY_DEVICE_PRIMARY_DEVICE)) { - return false; - } - - DEVMODE dm; - dm.dmSize = sizeof(DEVMODE); - - DWORD i = 0; - while (EnumDisplaySettings(&device, i, &dm)) { - if ((dm.dmPelsWidth >= 640 && dm.dmPelsHeight >= 480) - && dm.dmBitsPerPel >= 16) { - auto mode = modes.New(); - - mode->size.x = dm.dmPelsWidth; - mode->size.y = dm.dmPelsHeight; - mode->bpp = dm.dmBitsPerPel; - mode->refreshRate = dm.dmDisplayFrequency; - } - - i++; - } - - qsort(modes.Ptr(), modes.Count(), sizeof(CGxMonitorMode), CGxMonitorModeSort); - - return modes.Count() != 0; -} - -#elif (WHOA_SYSTEM_MAC) - -bool CGxDevice::AdapterMonitorModes(TSGrowableArray& modes) { - // TODO: Mac support - return false; -} - -#elif (WHOA_BUILD_GLSDL) - -bool CGxDevice::AdapterMonitorModes(TSGrowableArray& modes) { - auto primaryDisplay = SDL_GetPrimaryDisplay(); - if (!primaryDisplay) { - return false; - } - - int32_t displayModeCount; - auto displayModes = SDL_GetFullscreenDisplayModes(primaryDisplay, &displayModeCount); - if (displayModes == nullptr) { - return false; - } - - modes.SetCount(displayModeCount); - for (auto i = 0; i < displayModeCount; i++) { - auto displayMode = displayModes[i]; - CGxMonitorMode& mode = modes[i]; - mode.size.x = displayMode->w; - mode.size.y = displayMode->h; - mode.bpp = displayMode->format.BitsPerPixel; - mode.refreshRate = static_cast(displayMode->format.refresh_rate); - } - - SDL_free(displayModes); - - qsort(modes.Ptr(), modes.Count(), sizeof(CGxMonitorMode), CGxMonitorModeSort); - - return true; -} - -#endif - CGxDevice::CGxDevice() { // TODO // - implement rest of constructor @@ -321,6 +556,10 @@ const CGxCaps& CGxDevice::Caps() const { return this->m_caps; } +EGxApi CGxDevice::DeviceApi() { + return this->m_api; +} + int32_t CGxDevice::DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat& format) { this->m_windowProc = windowProc; @@ -1366,7 +1605,7 @@ void CGxDevice::XformSetViewport(float minX, float maxX, float minY, float maxY, return; } - this->intF6C = 1; + this->m_needsReset = 1; this->m_viewport.x.l = minX; this->m_viewport.x.h = maxX; diff --git a/src/gx/CGxDevice.hpp b/src/gx/CGxDevice.hpp index d3e2699..05235b7 100644 --- a/src/gx/CGxDevice.hpp +++ b/src/gx/CGxDevice.hpp @@ -11,7 +11,9 @@ #include "gx/Shader.hpp" #include "cursor/Cursor.hpp" #include +#include #include +#include #include #include @@ -39,6 +41,14 @@ struct ShaderConstants { class CGxDevice { public: + // Types + typedef void (*DEVICE_RESTORED_CALLBACK)(); + typedef void (*TEXTURE_RECREATION_CALLBACK)(); + typedef void (*STEREO_CHANGED_CALLBACK)(); + + static HSLOG m_log; + static uint32_t m_logBytes; + // Static variables static uint32_t s_alphaRef[]; static C3Vector s_pointScaleIdentity; @@ -52,13 +62,19 @@ class CGxDevice { static CGxShader* s_uiPixelShader; // Static functions - static bool AdapterMonitorModes(TSGrowableArray& modes); + static int32_t AdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow); + static int32_t AdapterInfer(uint16_t& deviceID); + static int32_t AdapterDesktopMode(CGxMonitorMode& mode); + static int32_t AdapterMonitorModes(TSGrowableArray& modes); static void ICursorUpdate(EGxTexCommand, uint32_t, uint32_t, uint32_t, uint32_t, void*, uint32_t&, const void*&); static void LogOpen(); + static void VLog(const char* format, va_list args); static void Log(const char* format, ...); static void Log(const CGxFormat& format); static void LogClose(); static uint32_t PrimCalcCount(EGxPrim primType, uint32_t count); + + // graphics api factory #if defined(WHOA_SYSTEM_WIN) static CGxDevice* NewD3d(); static CGxDevice* NewD3d9Ex(); @@ -111,7 +127,7 @@ class CGxDevice { TSFixedArray m_hwRenderStates; uint32_t m_baseMipLevel = 0; // TODO placeholder int32_t m_cursorVisible = 0; - int32_t m_hardwareCursor = 0; + int32_t m_hwCursor = 0; uint32_t m_cursorHotspotX = 0; uint32_t m_cursorHotspotY = 0; uint32_t m_cursor[CURSOR_IMAGE_SIZE] = { 0 }; @@ -156,6 +172,7 @@ class CGxDevice { const CGxCaps& Caps() const; CGxBuf* BufCreate(CGxPool* pool, uint32_t itemSize, uint32_t itemCount, uint32_t index); CGxBuf* BufStream(EGxPoolTarget target, uint32_t itemSize, uint32_t itemCount); + EGxApi DeviceApi(); void DeviceCreatePools(); void DeviceCreateStreamBufs(); const CRect& DeviceCurWindow(); diff --git a/src/gx/CGxFormat.cpp b/src/gx/CGxFormat.cpp index 140daa9..82d71fa 100644 --- a/src/gx/CGxFormat.cpp +++ b/src/gx/CGxFormat.cpp @@ -1,7 +1,5 @@ #include "gx/CGxFormat.hpp" -const char* CGxFormat::formatToColorBitsString[Formats_Last] = { "16", "24", "24", "30", "16", "24", "24", "32" }; - CGxFormat::CGxFormat() { this->size.x = 0; this->size.y = 0; @@ -12,12 +10,12 @@ CGxFormat::CGxFormat() { this->stereoEnabled = false; this->sampleCount = 1; this->aspect = 1; - this->unk1 = -1; - this->unk2 = -1; - this->unk3 = -1; - this->unk4 = -1; - this->unk5 = -1; - this->unk6 = -1; + this->unk38 = 0xFFFFFFFF; + this->unk3C = 0xFFFFFFFF; + this->unk40 = 0xFFFFFFFF; + this->unk44 = 0xFFFFFFFF; + this->unk48 = 0xFFFFFFFF; + this->unk4C = 0xFFFFFFFF; } CGxFormat::CGxFormat(bool p_window, const C2iVector& p_size, Format p_colorFormat, Format p_depthFormat, uint32_t p_refreshRate, uint32_t p_vsync, bool p_hwTnl, bool p_fixLag, bool p_hwCursor, bool p_aspect, bool p_maximize) { @@ -41,10 +39,10 @@ CGxFormat::CGxFormat(bool p_window, const C2iVector& p_size, Format p_colorForma this->maximize = p_maximize; this->backbuffers = 1; this->sampleCount = 1; - this->unk1 = -1; - this->unk2 = -1; - this->unk3 = -1; - this->unk4 = -1; - this->unk5 = -1; - this->unk6 = -1; + this->unk38 = 0xFFFFFFFF; + this->unk3C = 0xFFFFFFFF; + this->unk40 = 0xFFFFFFFF; + this->unk44 = 0xFFFFFFFF; + this->unk48 = 0xFFFFFFFF; + this->unk4C = 0xFFFFFFFF; } diff --git a/src/gx/CGxFormat.hpp b/src/gx/CGxFormat.hpp index 7f2960e..c2fc870 100644 --- a/src/gx/CGxFormat.hpp +++ b/src/gx/CGxFormat.hpp @@ -22,8 +22,6 @@ class CGxFormat { CGxFormat(); CGxFormat(bool p_window, const C2iVector& p_size, Format p_colorFormat, Format p_depthFormat, uint32_t p_refreshRate, uint32_t p_vsync, bool p_hwTnl, bool p_fixLag, bool p_hwCursor, bool p_aspect, bool p_maximize); - static const char* formatToColorBitsString[Formats_Last]; - // Member variables uint32_t apiSpecificModeID; bool hwTnL; @@ -41,12 +39,12 @@ class CGxFormat { uint32_t refreshRate; uint32_t vsync; bool stereoEnabled; - uint32_t unk1; - uint32_t unk2; - uint32_t unk3; - uint32_t unk4; - uint32_t unk5; - uint32_t unk6; + uint32_t unk38; + uint32_t unk3C; + uint32_t unk40; + uint32_t unk44; + uint32_t unk48; + uint32_t unk4C; C2iVector pos; }; diff --git a/src/gx/CGxMonitorMode.hpp b/src/gx/CGxMonitorMode.hpp index a1447cb..a07c0ce 100644 --- a/src/gx/CGxMonitorMode.hpp +++ b/src/gx/CGxMonitorMode.hpp @@ -11,6 +11,6 @@ class CGxMonitorMode { uint32_t refreshRate; }; -int32_t CGxMonitorModeSort(const void* i, const void* j); +int32_t CGxMonitorModeSort(const void* a, const void* b); #endif diff --git a/src/gx/CMakeLists.txt b/src/gx/CMakeLists.txt index 97bc974..99ee7a2 100644 --- a/src/gx/CMakeLists.txt +++ b/src/gx/CMakeLists.txt @@ -61,11 +61,11 @@ if (WHOA_SYSTEM_WIN) endif () endif () -# Link SDL2 and GLEW for GLSDL +# Link SDL3 and GLEW for GLSDL if (WHOA_BUILD_GLSDL) target_link_libraries(gx PRIVATE - SDL2::SDL2-static + SDL3::SDL3-static libglew_static ) endif () diff --git a/src/gx/Device.cpp b/src/gx/Device.cpp index 5bb4c21..4d2e311 100644 --- a/src/gx/Device.cpp +++ b/src/gx/Device.cpp @@ -59,8 +59,7 @@ CGxDevice* GxDevCreate(EGxApi api, int32_t (*windowProc)(void* window, uint32_t } if (!device) { - SErrPrepareAppFatal(__FILE__, __LINE__); - SErrDisplayAppFatal("GxDevCreate: failed to create graphics device %d", api); + SErrPrepareAppFatal(__FILE__, __LINE__); SErrDisplayAppFatal("GxDevCreate: failed to create graphics device %d", api); } // STORM_ASSERT(device != nullptr); @@ -78,15 +77,19 @@ CGxDevice* GxDevCreate(EGxApi api, int32_t (*windowProc)(void* window, uint32_t } } - -int32_t GxDevExists() { - return g_theGxDevicePtr != nullptr; +void GxDevDestroy(CGxDevice* device) { + // TODO + // device->DeviceDestroy(); } EGxApi GxDevApi() { return g_theGxDevicePtr->m_api; } +bool GxDevExists() { + return g_theGxDevicePtr != nullptr; +} + void* GxDevWindow() { return g_theGxDevicePtr->DeviceWindow(); } @@ -95,7 +98,12 @@ int32_t GxMasterEnable(EGxMasterEnables state) { return g_theGxDevicePtr->MasterEnable(state); } -EGxApi GxApiDefault() { +void GxDevOverride(EGxOverride override, uint32_t value) { + // TODO + // g_theGxDevicePtr->DeviceOverride(override, value); +} + +EGxApi GxDefaultApi() { #if defined(WHOA_SYSTEM_WIN) return GxApi_D3d9; #endif @@ -110,13 +118,69 @@ EGxApi GxApiDefault() { } bool GxApiSupported(EGxApi api) { - return (g_supportedApis & static_cast(api)) != 0; + return (g_supportedApis & (1 << static_cast(api))) != 0; } -bool GxAdapterMonitorModes(TSGrowableArray& modes) { +int32_t GxAdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLo) { + return g_theGxDevicePtr->AdapterID(vendorID, deviceID, driverVersionHi, driverVersionLo); +} + +int32_t GxAdapterInfer(uint16_t& deviceID) { + return g_theGxDevicePtr->AdapterInfer(deviceID); +} + +int32_t GxAdapterMonitorModes(TSGrowableArray& modes) { return CGxDevice::AdapterMonitorModes(modes); } +int32_t GxAdapterDesktopMode(CGxMonitorMode& mode) { + return CGxDevice::AdapterDesktopMode(mode); +} + void GxLogOpen() { CGxDevice::LogOpen(); } + +void GxLog(const char* format, ...) { + va_list args; + va_start(args, format); + CGxDevice::VLog(format, args); +} + +void GxLogClose() { + CGxDevice::LogClose(); +} + +void GxAddStereoChangedCallback(CGxDevice::STEREO_CHANGED_CALLBACK callback) { + // TODO + // g_theGxDevicePtr->AddStereoChangedCallback(callback); +} + +int32_t GxRemoveStereoChangedCallback(CGxDevice::STEREO_CHANGED_CALLBACK callback) { + // TODO + // return g_theGxDevicePtr->RemoveStereoChangedCallback(callback); + return 1; +} + +void GxStereoSetConvergence(float value) { + // TODO + // return g_theGxDevicePtr->StereoSetConvergence(value); +} + +void GxStereoSetSeparation(float value) { + // TODO + // return g_theGxDevicePtr->StereoSetSeparation(value); +} + +const CGxCaps& GxCaps() { + return g_theGxDevicePtr->Caps(); +} + +bool GxCapsWindowHasFocus(int32_t a1) { + // TODO + return true; +} + +void GxCapsWindowSize(CRect& rect) { + g_theGxDevicePtr->CapsWindowSize(rect); +} diff --git a/src/gx/Device.hpp b/src/gx/Device.hpp index 7ead52b..ddfce25 100644 --- a/src/gx/Device.hpp +++ b/src/gx/Device.hpp @@ -9,12 +9,51 @@ class CGxFormat; extern CGxDevice* g_theGxDevicePtr; + +bool GxApiSupported(EGxApi api); + +EGxApi GxDefaultApi(); + CGxDevice* GxDevCreate(EGxApi api, int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat& format); +void GxDevDestroy(CGxDevice* device); + EGxApi GxDevApi(void); +bool GxDevExists(); + void* GxDevWindow(); int32_t GxMasterEnable(EGxMasterEnables state); +void GxDevOverride(EGxOverride override, uint32_t value); + +int32_t GxAdapterDesktopMode(CGxMonitorMode& mode); + +int32_t GxAdapterMonitorModes(TSGrowableArray& modes); + +int32_t GxAdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow); + +int32_t GxAdapterInfer(uint16_t& deviceID); + +void GxLogOpen(); + +void GxLog(const char* format, ...); + +void GxLogClose(); + +void GxAddStereoChangedCallback(CGxDevice::STEREO_CHANGED_CALLBACK callback); + +int32_t GxRemoveStereoChangedCallback(CGxDevice::STEREO_CHANGED_CALLBACK callback); + +void GxStereoSetConvergence(float value); + +void GxStereoSetSeparation(float value); + +const CGxCaps& GxCaps(); + +bool GxCapsWindowHasFocus(int32_t); + +void GxCapsWindowSize(CRect&); + #endif diff --git a/src/gx/Gx.cpp b/src/gx/Gx.cpp index 566e582..e3160bb 100644 --- a/src/gx/Gx.cpp +++ b/src/gx/Gx.cpp @@ -37,44 +37,6 @@ const char** g_gxShaderProfileNames[GxShTargets_Last] = { static uint32_t s_maxFPS; static uint32_t s_maxFPSBk; -const CGxCaps& GxCaps() { - return g_theGxDevicePtr->Caps(); -} - -bool GxCapsWindowHasFocus(int32_t a1) { - // TODO - return true; -} - -void GxCapsWindowSize(CRect& rect) { - g_theGxDevicePtr->CapsWindowSize(rect); -} - -void GxFormatColor(CImVector& color) { - if (GxCaps().m_colorFormat == GxCF_rgba) { - CImVector formattedColor = { - color.r, - color.g, - color.b, - color.a - }; - - color = formattedColor; - } -} - -void GxLogOpen() { - CGxDevice::LogOpen(); -} - -void GxLogClose() { - CGxDevice::LogClose(); -} - -void GxLog(const char* format, ...) { - // TODO -} - void GxSetMaxFPS(uint32_t maxFPS) { s_maxFPS = maxFPS; } @@ -90,3 +52,16 @@ uint32_t GxGetMaxFPS() { uint32_t GxGetMaxFPSBk() { return s_maxFPSBk; } + +void GxFormatColor(CImVector& color) { + if (GxCaps().m_colorFormat == GxCF_rgba) { + CImVector formattedColor = { + color.r, + color.g, + color.b, + color.a + }; + + color = formattedColor; + } +} diff --git a/src/gx/Gx.hpp b/src/gx/Gx.hpp index 3efb3bb..0384d98 100644 --- a/src/gx/Gx.hpp +++ b/src/gx/Gx.hpp @@ -10,20 +10,8 @@ class CRect; extern const char** g_gxShaderProfileNames[GxShTargets_Last]; -const CGxCaps& GxCaps(); - -bool GxCapsWindowHasFocus(int32_t); - -void GxCapsWindowSize(CRect&); - void GxFormatColor(CImVector&); -void GxLogOpen(); - -void GxLogClose(); - -void GxLog(const char* format, ...); - void GxSetMaxFPS(uint32_t maxFPS); void GxSetMaxFPSBk(uint32_t maxFPSBk); diff --git a/src/gx/d3d/CGxDeviceD3d.cpp b/src/gx/d3d/CGxDeviceD3d.cpp index db39e06..e9b355b 100644 --- a/src/gx/d3d/CGxDeviceD3d.cpp +++ b/src/gx/d3d/CGxDeviceD3d.cpp @@ -530,7 +530,7 @@ void CGxDeviceD3d::DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2) { // TODO - this->intF6C = 1; + this->m_needsReset = 1; return; } else { @@ -538,7 +538,7 @@ void CGxDeviceD3d::DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2) { } } - this->intF6C = 1; + this->m_needsReset = 1; } break; @@ -1746,7 +1746,7 @@ void CGxDeviceD3d::IStateSync() { // TODO - if (this->intF6C) { + if (this->m_needsReset) { this->IXformSetViewport(); } } @@ -2124,7 +2124,7 @@ void CGxDeviceD3d::IXformSetViewport() { this->m_d3dDevice->SetViewport(&d3dViewport); - this->intF6C = 0; + this->m_needsReset = 0; } void CGxDeviceD3d::IXformSetWorld() { @@ -2159,7 +2159,7 @@ void CGxDeviceD3d::SceneClear(uint32_t mask, CImVector color) { flags |= 0x2; } - if (this->intF6C) { + if (this->m_needsReset) { this->IXformSetViewport(); } @@ -2200,12 +2200,8 @@ void CGxDeviceD3d::ShaderCreate(CGxShader* shaders[], EGxShTarget target, const } int32_t CGxDeviceD3d::StereoEnabled() { - return this->m_d3dStereoEnabled == 1; -} - -void CGxDeviceD3d::CursorUnlock() { - CGxDevice::CursorUnlock(x, y); - this->m_hwCursorNeedsUpdate = 1; + // return this->m_d3dStereoEnabled == 1; + return 0; } void CGxDeviceD3d::XformSetProjection(const C44Matrix& matrix) { diff --git a/src/gx/glsdl/CGxDeviceGLSDL.cpp b/src/gx/glsdl/CGxDeviceGLSDL.cpp index 2c622a0..ddc49f1 100644 --- a/src/gx/glsdl/CGxDeviceGLSDL.cpp +++ b/src/gx/glsdl/CGxDeviceGLSDL.cpp @@ -1,5 +1,5 @@ #include "gx/glsdl/CGxDeviceGLSDL.hpp" -#include "event/Input.hpp" +#include "os/Input.hpp" #include "gx/Blit.hpp" #include "gx/CGxBatch.hpp" #include "gx/Shader.hpp" @@ -681,9 +681,13 @@ void CGxDeviceGLSDL::ISetCaps(const CGxFormat& format) { this->m_caps.m_texMaxSize[GxTex_Rectangle] = 4096; this->m_caps.m_texMaxSize[GxTex_NonPow2] = 4096; - this->m_caps.m_hardwareCursor = 0; + this->m_caps.m_hwCursor = 0; // TODO + + // TODO: proper implementation + this->m_caps.m_numTmus = 2; + this->m_caps.m_numStreams = 1; } void CGxDeviceGLSDL::IShaderBindPixel(CGxShader* sh) { diff --git a/src/gx/glsdl/GLSDLContext.cpp b/src/gx/glsdl/GLSDLContext.cpp index 0f1216b..8b94426 100644 --- a/src/gx/glsdl/GLSDLContext.cpp +++ b/src/gx/glsdl/GLSDLContext.cpp @@ -27,7 +27,7 @@ void GLSDLContext::Create(GLSDLWindow* window) { void GLSDLContext::Destroy() { BC_ASSERT(this->m_sdlGLContext != nullptr); - SDL_GL_DeleteContext(this->m_sdlGLContext); + SDL_GL_DestroyContext(this->m_sdlGLContext); this->m_sdlGLContext = nullptr; } @@ -37,7 +37,7 @@ bool GLSDLContext::IsCurrentContext() { void GLSDLContext::MakeCurrent(GLSDLWindow* window) { auto status = SDL_GL_MakeCurrent(window->m_sdlWindow, this->m_sdlGLContext); - BC_ASSERT(status == 0); + BC_ASSERT(status); } int32_t GLSDLContext::GetSampleCount() { diff --git a/src/gx/glsdl/GLSDLContext.hpp b/src/gx/glsdl/GLSDLContext.hpp index 10727f6..8fd074a 100644 --- a/src/gx/glsdl/GLSDLContext.hpp +++ b/src/gx/glsdl/GLSDLContext.hpp @@ -1,6 +1,6 @@ #ifndef GX_GL_SDL_GL_SDL_CONTEXT_HPP -#include +#include #include "gx/glsdl/GLSDLWindow.hpp" #include "gx/glsdl/GLTypes.hpp" diff --git a/src/gx/glsdl/GLSDLWindow.cpp b/src/gx/glsdl/GLSDLWindow.cpp index 51c918a..e7cc762 100644 --- a/src/gx/glsdl/GLSDLWindow.cpp +++ b/src/gx/glsdl/GLSDLWindow.cpp @@ -68,15 +68,13 @@ void GLSDLWindow::Create(const char* title, const GLSDLWindowRect& rect, GLTextu this->m_sdlWindow = SDL_CreateWindow( title, - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, static_cast(rect.size.width), static_cast(rect.size.height), SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE ); BC_ASSERT(this->m_sdlWindow != nullptr); - SDL_StartTextInput(); + SDL_StartTextInput(this->m_sdlWindow); } void GLSDLWindow::Swap() { diff --git a/src/gx/glsdl/GLSDLWindow.hpp b/src/gx/glsdl/GLSDLWindow.hpp index 70cd765..40d84bb 100644 --- a/src/gx/glsdl/GLSDLWindow.hpp +++ b/src/gx/glsdl/GLSDLWindow.hpp @@ -2,7 +2,7 @@ #define GX_GL_SDL_GL_SDL_WINDOW_HPP #include -#include +#include #include "gx/glsdl/GLTypes.hpp" diff --git a/src/gx/texture/CBLPFile.cpp b/src/gx/texture/CBLPFile.cpp index 00e1b32..53ccbaa 100644 --- a/src/gx/texture/CBLPFile.cpp +++ b/src/gx/texture/CBLPFile.cpp @@ -141,11 +141,13 @@ void CBLPFile::DecompPalARGB8888(uint8_t* data, void* tempbuffer, uint32_t color auto pixels = data; auto bytes = reinterpret_cast(tempbuffer); - for (auto i = colorSize; i; i--) { + auto i = colorSize; + while (i != 0) { *reinterpret_cast(pixels) = this->m_header.extended.palette[*bytes]; pixels[3] = 0xFF; pixels += 4; bytes++; + i--; } auto alphaBits = this->AlphaBits(); diff --git a/src/gx/texture/CBLPFile.hpp b/src/gx/texture/CBLPFile.hpp index 1301094..ef77584 100644 --- a/src/gx/texture/CBLPFile.hpp +++ b/src/gx/texture/CBLPFile.hpp @@ -27,7 +27,10 @@ struct BlpPalPixel { uint8_t pad; }; +static_assert(sizeof(BlpPalPixel) == 4); + class CBLPFile { +#pragma pack(push, 1) struct BLPHeader { uint32_t magic = 0x32504C42; uint32_t formatVersion = 1; @@ -49,6 +52,7 @@ class CBLPFile { } jpeg; } extended; }; +#pragma pack(pop) public: // Static variables diff --git a/src/gx/texture/CGxTex.cpp b/src/gx/texture/CGxTex.cpp index 740ed80..168c1a2 100644 --- a/src/gx/texture/CGxTex.cpp +++ b/src/gx/texture/CGxTex.cpp @@ -1,5 +1,5 @@ #include "gx/texture/CGxTex.hpp" -#include "gx/Gx.hpp" +#include "gx/Device.hpp" #include CGxTexFlags::CGxTexFlags(EGxTexFilter filter, uint32_t wrapU, uint32_t wrapV, uint32_t force, uint32_t generateMipMaps, uint32_t renderTarget, uint32_t maxAnisotropy) { diff --git a/src/model/CM2Cache.cpp b/src/model/CM2Cache.cpp index 4cc1fc0..cb2f63c 100644 --- a/src/model/CM2Cache.cpp +++ b/src/model/CM2Cache.cpp @@ -1,5 +1,5 @@ #include "model/CM2Cache.hpp" -#include "gx/Gx.hpp" +#include "gx/Device.hpp" #include "model/CM2Shared.hpp" #include "model/Model2.hpp" #include "util/Filesystem.hpp" diff --git a/src/os/CMakeLists.txt b/src/os/CMakeLists.txt new file mode 100644 index 0000000..f71fba4 --- /dev/null +++ b/src/os/CMakeLists.txt @@ -0,0 +1,58 @@ +file(GLOB PRIVATE_SOURCES + "*.cpp" + "internal/*.cpp" +) + +if(WHOA_SYSTEM_WIN) + file(GLOB WIN_SOURCES + "win/*.cpp") + + list(APPEND PRIVATE_SOURCES ${WIN_SOURCES}) +endif() + +if(WHOA_SYSTEM_MAC) + file(GLOB MAC_SOURCES + "mac/*.mm") + + set_source_files_properties(${MAC_SOURCES} + PROPERTIES COMPILE_FLAGS "-x objective-c++" + ) + + list(APPEND PRIVATE_SOURCES ${MAC_SOURCES}) +endif() + +if(WHOA_SYSTEM_LINUX) + file(GLOB LINUX_SOURCES + "linux/*.cpp") + + list(APPEND PRIVATE_SOURCES ${LINUX_SOURCES}) +endif() + +if(WHOA_BUILD_GLSDL) + file(GLOB SDL_SOURCES + "sdl/*.cpp") + + list(APPEND PRIVATE_SOURCES ${SDL_SOURCES}) +endif() + +add_library(os STATIC + ${PRIVATE_SOURCES} +) + +target_include_directories(os + PRIVATE + ${CMAKE_SOURCE_DIR}/src +) + +target_link_libraries(os + PUBLIC + storm + common +) + +if(WHOA_BUILD_GLSDL) + target_link_libraries(os + PRIVATE + SDL3::SDL3-static + ) +endif() diff --git a/src/os/Clipboard.hpp b/src/os/Clipboard.hpp new file mode 100644 index 0000000..089d6ab --- /dev/null +++ b/src/os/Clipboard.hpp @@ -0,0 +1,10 @@ +#ifndef OS_CLIPBOARD_HPP +#define OS_CLIPBOARD_HPP + +#include + +char* OsClipboardGetString(); + +int32_t OsClipboardPutString(const char*); + +#endif diff --git a/src/os/Compat.hpp b/src/os/Compat.hpp index a5aeb05..7c30868 100644 --- a/src/os/Compat.hpp +++ b/src/os/Compat.hpp @@ -2,7 +2,7 @@ #define OS_COMPAT_HPP #if defined(WHOA_SYSTEM_MAC) - #include "os/compat/Mac.hpp" +#include "os/mac/Compat.hpp" #endif #endif diff --git a/src/os/Debug.hpp b/src/os/Debug.hpp new file mode 100644 index 0000000..290f5c4 --- /dev/null +++ b/src/os/Debug.hpp @@ -0,0 +1,6 @@ +#ifndef OS_DEBUG_HPP +#define OS_DEBUG_HPP + +void OsOutputDebugString(const char* format, ...); + +#endif diff --git a/src/os/Gui.hpp b/src/os/Gui.hpp new file mode 100644 index 0000000..7f9c3f2 --- /dev/null +++ b/src/os/Gui.hpp @@ -0,0 +1,18 @@ +#ifndef OS_GUI_HPP +#define OS_GUI_HPP + +#include + +void* OsGuiGetWindow(int32_t type); + +bool OsGuiIsModifierKeyDown(int32_t key); + +int32_t OsGuiProcessMessage(void* message); + +void OsGuiSetGxWindow(void* window); + +int32_t OsGuiMessageBox(void* parentWindow, int32_t style, const char* message, const char* title); + +void OsGuiSetWindowTitle(void* window, const char* title); + +#endif diff --git a/src/os/Input.hpp b/src/os/Input.hpp new file mode 100644 index 0000000..1f4b935 --- /dev/null +++ b/src/os/Input.hpp @@ -0,0 +1,23 @@ +#ifndef OS_INPUT_HPP +#define OS_INPUT_HPP + +#include "os/Types.hpp" +#include + +int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3); + +void OsInputSetWindowResizeLock(int32_t resizeLock); + +void OsInputInitialize(); + +bool OsInputIsUsingCocoaEventLoop(); + +void OsInputPostEvent(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3); + +void OsInputSetMouseMode(OS_MOUSE_MODE mode); + +void OsInputGetMousePosition(int32_t* x, int32_t* y); + +int32_t OsWindowProc(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam); + +#endif diff --git a/src/os/Queue.cpp b/src/os/Queue.cpp new file mode 100644 index 0000000..0bbf9c0 --- /dev/null +++ b/src/os/Queue.cpp @@ -0,0 +1,66 @@ +#include "os/Queue.hpp" +#include "os/internal/Queue.hpp" + +int32_t OsQueueGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) { + if (s_queueTail == s_queueHead) { + return 0; + } + + OSEVENT event = s_queue[s_queueTail]; + + *id = event.id; + *param0 = event.param[0]; + *param1 = event.param[1]; + *param2 = event.param[2]; + *param3 = event.param[3]; + + if (s_queueTail == (OS_QUEUE_SIZE - 1)) { + s_queueTail = 0; + } else { + ++s_queueTail; + } + + return 1; +} + +void OsQueuePut(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3) { + int32_t nextTail = 0; + int32_t nextHead = 0; + + if (s_queueHead != OS_QUEUE_SIZE - 1) { + nextHead = s_queueHead + 1; + } + + if (nextHead == s_queueTail) { + if (nextHead != OS_QUEUE_SIZE - 1) { + nextTail = nextHead + 1; + } + + s_queueTail = nextTail; + } + + auto event = &s_queue[s_queueHead]; + + event->id = id; + event->param[0] = param0; + event->param[1] = param1; + event->param[2] = param2; + event->param[3] = param3; + + s_queueHead = nextHead; +} + +void OsQueueSetParam(int32_t index, int32_t param) { + int32_t pos = s_queueTail; + + while (pos != s_queueHead) { + auto event = &s_queue[pos]; + event->param[index] = param; + + if (pos == OS_QUEUE_SIZE - 1) { + pos = 0; + } else { + ++pos; + } + } +} diff --git a/src/os/Queue.hpp b/src/os/Queue.hpp new file mode 100644 index 0000000..229f087 --- /dev/null +++ b/src/os/Queue.hpp @@ -0,0 +1,12 @@ +#ifndef OS_QUEUE_HPP +#define OS_QUEUE_HPP + +#include "os/Types.hpp" + +int32_t OsQueueGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3); + +void OsQueuePut(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3); + +void OsQueueSetParam(int32_t index, int32_t param); + +#endif diff --git a/src/os/Types.hpp b/src/os/Types.hpp new file mode 100644 index 0000000..978e81d --- /dev/null +++ b/src/os/Types.hpp @@ -0,0 +1,40 @@ +#ifndef OS_TYPES_HPP +#define OS_TYPES_HPP + +#include + +enum OSINPUT { + OS_INPUT_CAPTURE_CHANGED = 0, + OS_INPUT_CHAR = 1, + OS_INPUT_STRING = 2, + OS_INPUT_IME = 3, + OS_INPUT_SIZE = 4, + OS_INPUT_CLOSE = 5, + OS_INPUT_FOCUS = 6, + OS_INPUT_KEY_DOWN = 7, + OS_INPUT_KEY_UP = 8, + OS_INPUT_MOUSE_DOWN = 9, + OS_INPUT_MOUSE_MOVE = 10, + OS_INPUT_MOUSE_WHEEL = 11, + OS_INPUT_MOUSE_MOVE_RELATIVE = 12, + OS_INPUT_MOUSE_UP = 13, + OS_INPUT_14 = 14, + OS_INPUT_15 = 15, + OS_INPUT_16 = 16, + OS_INPUT_17 = 17, + OS_INPUT_18 = 18, + OS_INPUT_SHUTDOWN = 19 +}; + +enum OS_MOUSE_MODE { + OS_MOUSE_MODE_NORMAL = 0, + OS_MOUSE_MODE_RELATIVE = 1, + OS_MOUSE_MODES = 2, +}; + +struct OSEVENT { + OSINPUT id; + int32_t param[4]; +}; + +#endif diff --git a/src/os/internal/Input.cpp b/src/os/internal/Input.cpp new file mode 100644 index 0000000..f6ec56b --- /dev/null +++ b/src/os/internal/Input.cpp @@ -0,0 +1,23 @@ +#include "os/internal/Input.hpp" + +int32_t s_numlockState; + +uint32_t s_osButtonState; + +OS_MOUSE_MODE s_osMouseMode; + +int32_t s_windowFocused; + +int32_t s_WindowResizeLock; + +#if defined(WHOA_SYSTEM_WIN) + +int32_t s_savedMouseSpeed; + +#endif + +#if defined(WHOA_SYSTEM_MAC) + +double s_savedMouseSpeed; + +#endif diff --git a/src/os/internal/Input.hpp b/src/os/internal/Input.hpp new file mode 100644 index 0000000..f8e1bc4 --- /dev/null +++ b/src/os/internal/Input.hpp @@ -0,0 +1,28 @@ +#ifndef OS_INTERNAL_INPUT_HPP +#define OS_INTERNAL_INPUT_HPP + +#include "os/Types.hpp" + +extern int32_t s_numlockState; + +extern uint32_t s_osButtonState; + +extern OS_MOUSE_MODE s_osMouseMode; + +extern int32_t s_windowFocused; + +extern int32_t s_WindowResizeLock; + +#if defined(WHOA_SYSTEM_WIN) + +extern int32_t s_savedMouseSpeed; + +#endif + +#if defined(WHOA_SYSTEM_MAC) + +extern double s_savedMouseSpeed; + +#endif + +#endif diff --git a/src/os/internal/Queue.cpp b/src/os/internal/Queue.cpp new file mode 100644 index 0000000..7a791a5 --- /dev/null +++ b/src/os/internal/Queue.cpp @@ -0,0 +1,6 @@ +#include "os/internal/Queue.hpp" + +OSEVENT s_queue[32]; + +int32_t s_queueHead; +int32_t s_queueTail; diff --git a/src/os/internal/Queue.hpp b/src/os/internal/Queue.hpp new file mode 100644 index 0000000..d452fc1 --- /dev/null +++ b/src/os/internal/Queue.hpp @@ -0,0 +1,13 @@ +#ifndef OS_INTERNAL_QUEUE_HPP +#define OS_INTERNAL_QUEUE_HPP + +#define OS_QUEUE_SIZE 32 + +#include "os/Types.hpp" + +extern OSEVENT s_queue[OS_QUEUE_SIZE]; + +extern int32_t s_queueHead; +extern int32_t s_queueTail; + +#endif diff --git a/src/os/linux/Clipboard.cpp b/src/os/linux/Clipboard.cpp new file mode 100644 index 0000000..e600310 --- /dev/null +++ b/src/os/linux/Clipboard.cpp @@ -0,0 +1,25 @@ +#include "os/Clipboard.hpp" + +#if defined(WHOA_BUILD_GLSDL) + +#include "os/sdl/Clipboard.hpp" + +char* OsClipboardGetString() { + return OsSDLClipboardGetString(); +} + +int32_t OsClipboardPutString(const char* str) { + return OsSDLClipboardPutString(str); +} + +#else + +char* OsClipboardGetString() { + return nullptr; +} + +int32_t OsClipboardPutString(const char* str) { + return 0; +} + +#endif diff --git a/src/os/linux/Debug.cpp b/src/os/linux/Debug.cpp new file mode 100644 index 0000000..adb3500 --- /dev/null +++ b/src/os/linux/Debug.cpp @@ -0,0 +1,11 @@ +#include "os/Debug.hpp" +#include +#include + +void OsOutputDebugString(const char* format, ...) { + // TODO + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + return; +} diff --git a/src/os/linux/Gui.cpp b/src/os/linux/Gui.cpp new file mode 100644 index 0000000..43a3b9d --- /dev/null +++ b/src/os/linux/Gui.cpp @@ -0,0 +1,51 @@ +#include "os/Gui.hpp" +#if defined(WHOA_BUILD_GLSDL) +#include "os/sdl/Gui.hpp" +#endif + +static void* s_GxDevWindow = nullptr; + +void* OsGuiGetWindow(int32_t type) { + switch (type) { + case 0: + case 1: + case 2: + return s_GxDevWindow; + default: + return nullptr; + } +} + +bool OsGuiIsModifierKeyDown(int32_t key) { + // TODO + return false; +} + +int32_t OsGuiProcessMessage(void* message) { + return 0; +} + +void OsGuiSetGxWindow(void* window) { + s_GxDevWindow = window; +} + +#if defined(WHOA_BUILD_GLSDL) + +int32_t OsGuiMessageBox(void* parentWindow, int32_t style, const char* message, const char* title) { + return OsSDLGuiMessageBox(parentWindow, style, message, title); +} + +void OsGuiSetWindowTitle(void* window, const char* title) { + return OsSDLGuiSetWindowTitle(window, title); +} + +#else + +int32_t OsGuiMessageBox(void* parentWindow, int32_t style, const char* message, const char* title) { + return 1; +} + +void OsGuiSetWindowTitle(void* window, const char* title) { +} + +#endif diff --git a/src/event/linux/Input.cpp b/src/os/linux/Input.cpp similarity index 51% rename from src/event/linux/Input.cpp rename to src/os/linux/Input.cpp index bd381f0..fef9999 100644 --- a/src/event/linux/Input.cpp +++ b/src/os/linux/Input.cpp @@ -1,18 +1,21 @@ #include -#include "event/Input.hpp" +#include "os/Input.hpp" +#include "os/Queue.hpp" + +#include "os/internal/Queue.hpp" #if defined(WHOA_BUILD_GLSDL) -#include "event/sdl/Input.hpp" +#include "os/sdl/Input.hpp" #endif int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) { #if defined(WHOA_BUILD_GLSDL) - if (SDLInputActive()) { - return SDLInputGet(id, param0, param1, param2, param3); + if (OsSDLInputActive()) { + return OsSDLInputGet(id, param0, param1, param2, param3); } #endif - if (Input::s_queueTail == Input::s_queueHead) { + if (s_queueTail == s_queueHead) { return 0; } @@ -21,18 +24,31 @@ int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param return OsQueueGet(id, param0, param1, param2, param3); } +void OsInputSetWindowResizeLock(int32_t resizeLock) { +#if defined(WHOA_BUILD_GLSDL) + OsSDLInputSetWindowResizeLock(resizeLock); +#endif +} + +void OsInputInitialize() { +} + +bool OsInputIsUsingCocoaEventLoop() { + return false; +} + +void OsInputPostEvent(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3) { + // TODO +} + void OsInputSetMouseMode(OS_MOUSE_MODE mode) { // TODO } -int32_t OsWindowProc(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam) { - return 0; -} - void OsInputGetMousePosition(int32_t* x, int32_t* y) { #if defined(WHOA_BUILD_GLSDL) - if (SDLInputActive()) { - SDLInputGetMousePosition(x, y); + if (OsSDLInputActive()) { + OsSDLInputGetMousePosition(x, y); return; } #endif @@ -44,3 +60,7 @@ void OsInputGetMousePosition(int32_t* x, int32_t* y) { *y = 0; } } + +int32_t OsWindowProc(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam) { + return 0; +} diff --git a/src/os/mac/Clipboard.mm b/src/os/mac/Clipboard.mm new file mode 100644 index 0000000..54cedb5 --- /dev/null +++ b/src/os/mac/Clipboard.mm @@ -0,0 +1,11 @@ +#include "os/Clipboard.hpp" + +char* OsClipboardGetString() { + // TODO + return nullptr; +} + +int32_t OsClipboardPutString(const char* str) { + // TODO + return 0; +} diff --git a/src/os/compat/Mac.hpp b/src/os/mac/Compat.hpp similarity index 78% rename from src/os/compat/Mac.hpp rename to src/os/mac/Compat.hpp index 22d89e6..6a754cc 100644 --- a/src/os/compat/Mac.hpp +++ b/src/os/mac/Compat.hpp @@ -1,5 +1,5 @@ -#ifndef OS_COMPAT_MAC_HPP -#define OS_COMPAT_MAC_HPP +#ifndef OS_MAC_COMPAT_HPP +#define OS_MAC_COMPAT_HPP #ifdef __OBJC__ #include diff --git a/src/os/mac/Debug.mm b/src/os/mac/Debug.mm new file mode 100644 index 0000000..adb3500 --- /dev/null +++ b/src/os/mac/Debug.mm @@ -0,0 +1,11 @@ +#include "os/Debug.hpp" +#include +#include + +void OsOutputDebugString(const char* format, ...) { + // TODO + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + return; +} diff --git a/src/client/gui/mac/OsGui.cpp b/src/os/mac/Gui.mm similarity index 52% rename from src/client/gui/mac/OsGui.cpp rename to src/os/mac/Gui.mm index 151cefa..5bcdf91 100644 --- a/src/client/gui/mac/OsGui.cpp +++ b/src/os/mac/Gui.mm @@ -1,4 +1,4 @@ -#include "client/gui/OsGui.hpp" +#include "os/Gui.hpp" void* OsGuiGetWindow(int32_t type) { return nullptr; @@ -16,3 +16,12 @@ int32_t OsGuiProcessMessage(void* message) { void OsGuiSetGxWindow(void* window) { // TODO } + +int32_t OsGuiMessageBox(void* parentWindow, int32_t style, const char* message, const char* title) { + // TODO + return 1; +} + +void OsGuiSetWindowTitle(void* window, const char* title) { + // TODO +} diff --git a/src/event/mac/Input.cpp b/src/os/mac/Input.mm similarity index 67% rename from src/event/mac/Input.cpp rename to src/os/mac/Input.mm index 3263d76..c893f06 100644 --- a/src/event/mac/Input.cpp +++ b/src/os/mac/Input.mm @@ -1,7 +1,9 @@ -#include "event/Input.hpp" +#include "os/Input.hpp" #include #include +double Input::s_savedMouseSpeed; + static C2iVector s_mousePos; int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) { @@ -33,6 +35,26 @@ int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param return queue_result; } +void OsInputSetWindowResizeLock(int32_t resizeLock) { + s_WindowResizeLock = resizeLock; +} + +void OsInputInitialize() { + // Legacy Carbon input handling + // if (!byte_143EFE0) { + // Carbon_OsInputRegisterHICommandHandler(0x71756974, sub_A4F230); + // } + + MacClient::SetMouseCoalescingEnabled(true); + Input::s_savedMouseSpeed = MacClient::GetMouseSpeed(); +} + +bool OsInputIsUsingCocoaEventLoop() { + // TODO + + return true; +} + void OsInputSetMouseMode(OS_MOUSE_MODE mode) { // TODO } diff --git a/src/os/sdl/Clipboard.cpp b/src/os/sdl/Clipboard.cpp new file mode 100644 index 0000000..f2f6e72 --- /dev/null +++ b/src/os/sdl/Clipboard.cpp @@ -0,0 +1,15 @@ +#include "os/sdl/Clipboard.hpp" +#include + +#include + +char* OsSDLClipboardGetString() { + auto sdlText = SDL_GetClipboardText(); + auto text = SStrDupA(sdlText, __FILE__, __LINE__); + SDL_free(sdlText); + return text; +} + +int32_t OsSDLClipboardPutString(const char* str) { + return SDL_SetClipboardText(str); +} diff --git a/src/os/sdl/Clipboard.hpp b/src/os/sdl/Clipboard.hpp new file mode 100644 index 0000000..c77b035 --- /dev/null +++ b/src/os/sdl/Clipboard.hpp @@ -0,0 +1,10 @@ +#ifndef OS_SDL_CLIPBOARD_HPP +#define OS_SDL_CLIPBOARD_HPP + +#include + +char* OsSDLClipboardGetString(); + +int32_t OsSDLClipboardPutString(const char* str); + +#endif diff --git a/src/os/sdl/Gui.cpp b/src/os/sdl/Gui.cpp new file mode 100644 index 0000000..e40720f --- /dev/null +++ b/src/os/sdl/Gui.cpp @@ -0,0 +1,62 @@ +#include "os/sdl/Gui.hpp" +#include + +static SDL_MessageBoxButtonData s_ok_button = { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "OK" }; + +static SDL_MessageBoxButtonData s_ok_cancel_buttons[2] = { + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "OK" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "Cancel" } +}; + +static SDL_MessageBoxButtonData s_yes_no_buttons[2] = { + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Yes" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "No" } +}; + +static SDL_MessageBoxButtonData s_yes_no_cancel_buttons[3] = { + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Yes" }, + { 0, 1, "No" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "Cancel" } +}; + +int32_t OsSDLGuiMessageBox(void* parentWindow, int32_t style, const char* message, const char* title) { + SDL_MessageBoxData box; + box.flags = 0; + box.window = static_cast(parentWindow); + box.title = title; + box.message = message; + box.colorScheme = nullptr; + + switch (style) { + case 0: + // type = MB_OK; + box.numbuttons = 1; + box.buttons = &s_ok_button; + break; + case 1: + // type = MB_OKCANCEL; + box.numbuttons = 2; + box.buttons = s_ok_cancel_buttons; + break; + case 2: + // type = MB_YESNO; + box.numbuttons = 2; + box.buttons = s_yes_no_buttons; + break; + case 3: + // type = MB_YESNOCANCEL; + box.numbuttons = 3; + box.buttons = s_yes_no_cancel_buttons; + break; + } + + int buttonid; + SDL_ShowMessageBox(&box, &buttonid); + return static_cast(buttonid); +} + +void OsSDLGuiSetWindowTitle(void* window, const char* title) { + if (window) { + SDL_SetWindowTitle(static_cast(window), title); + } +} diff --git a/src/os/sdl/Gui.hpp b/src/os/sdl/Gui.hpp new file mode 100644 index 0000000..2d1698d --- /dev/null +++ b/src/os/sdl/Gui.hpp @@ -0,0 +1,10 @@ +#ifndef OS_SDL_GUI_HPP +#define OS_SDL_GUI_HPP + +#include + +int32_t OsSDLGuiMessageBox(void* parentWindow, int32_t style, const char* message, const char* title); + +void OsSDLGuiSetWindowTitle(void* window, const char* title); + +#endif diff --git a/src/event/sdl/Input.cpp b/src/os/sdl/Input.cpp similarity index 87% rename from src/event/sdl/Input.cpp rename to src/os/sdl/Input.cpp index 2409c09..063b1f4 100644 --- a/src/event/sdl/Input.cpp +++ b/src/os/sdl/Input.cpp @@ -1,12 +1,17 @@ #include -#include "event/sdl/Input.hpp" -#include "client/Gui.hpp" +#include "event/Types.hpp" +#include "os/internal/Input.hpp" +#include "os/internal/Queue.hpp" +#include "os/sdl/Input.hpp" +#include "os/Input.hpp" +#include "os/Queue.hpp" +#include "os/Gui.hpp" #include "gx/Device.hpp" #include "gx/Window.hpp" #include -#include +#include static const std::unordered_map s_keyConversion = { { SDL_SCANCODE_LSHIFT, KEY_LSHIFT }, @@ -138,15 +143,23 @@ static MOUSEBUTTON s_buttonConversion[16] = { MOUSE_BUTTON_XBUTTON12 }; -bool SDLInputActive() { +bool OsSDLInputActive() { return OsGuiGetWindow(0) != nullptr && GxDevApi() == GxApi_GLSDL; } -void SDLInputGetMousePosition(int32_t* x, int32_t *y) { - int mouseX; - int mouseY; +void OsSDLInputSetWindowResizeLock(int32_t resizeLock) { + s_WindowResizeLock = resizeLock; + auto window = static_cast(OsGuiGetWindow(0)); + if (window) { + SDL_SetWindowResizable(window, !resizeLock); + } +} - if (Input::s_osMouseMode == OS_MOUSE_MODE_RELATIVE) { +void OsSDLInputGetMousePosition(int32_t* x, int32_t *y) { + float mouseX; + float mouseY; + + if (s_osMouseMode == OS_MOUSE_MODE_RELATIVE) { SDL_GetMouseState(&mouseX, &mouseY); } else { SDL_GetGlobalMouseState(&mouseX, &mouseY); @@ -174,10 +187,10 @@ bool ConvertScancode(SDL_Scancode scancode, KEY& key) { return false; } -int32_t SDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) { +int32_t OsSDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) { *id = static_cast(-1); - if (Input::s_queueTail != Input::s_queueHead) { + if (s_queueTail != s_queueHead) { OsQueueGet(id, param0, param1, param2, param3); return 1; } @@ -190,21 +203,21 @@ int32_t SDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* para while (SDL_PollEvent(&event)) { switch (event.type) { - case SDL_KEYDOWN: - case SDL_KEYUP: { + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: { KEY key; - if (ConvertScancode(event.key.keysym.scancode, key)) { - *id = event.type == SDL_KEYUP ? OS_INPUT_KEY_UP : OS_INPUT_KEY_DOWN; + if (ConvertScancode(event.key.scancode, key)) { + *id = event.type == SDL_EVENT_KEY_UP ? OS_INPUT_KEY_UP : OS_INPUT_KEY_DOWN; *param0 = key; return 1; } break; } - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: { + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: { // Is this an up or down mouse click? - *id = event.type == SDL_MOUSEBUTTONUP ? OS_INPUT_MOUSE_UP : OS_INPUT_MOUSE_DOWN; + *id = event.type == SDL_EVENT_MOUSE_BUTTON_UP ? OS_INPUT_MOUSE_UP : OS_INPUT_MOUSE_DOWN; // XY click coordinates auto x = static_cast(event.button.x); @@ -225,7 +238,7 @@ int32_t SDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* para return 1; } - case SDL_MOUSEMOTION: { + case SDL_EVENT_MOUSE_MOTION: { auto x = static_cast(event.motion.x); auto y = static_cast(event.motion.y); @@ -236,7 +249,7 @@ int32_t SDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* para *param3 = 0; return 1; } - case SDL_TEXTINPUT: { + case SDL_EVENT_TEXT_INPUT: { // text input string holding one or more UTF-8 characters auto text = reinterpret_cast(event.text.text); @@ -261,7 +274,7 @@ int32_t SDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* para } // deque first character if any - if (Input::s_queueTail != Input::s_queueHead) { + if (s_queueTail != s_queueHead) { OsQueueGet(id, param0, param1, param2, param3); return 1; } @@ -270,7 +283,7 @@ int32_t SDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* para break; } - case SDL_WINDOWEVENT_RESIZED: { + case SDL_EVENT_WINDOW_RESIZED: { auto width = static_cast(event.window.data1); auto height = static_cast(event.window.data2); @@ -291,7 +304,7 @@ int32_t SDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* para break; } - case SDL_QUIT: { + case SDL_EVENT_QUIT: { *id = OS_INPUT_CLOSE; return 1; } diff --git a/src/os/sdl/Input.hpp b/src/os/sdl/Input.hpp new file mode 100644 index 0000000..ba2cf1b --- /dev/null +++ b/src/os/sdl/Input.hpp @@ -0,0 +1,14 @@ +#ifndef OS_SDL_INPUT_HPP +#define OS_SDL_INPUT_HPP + +#include "os/Input.hpp" + +bool OsSDLInputActive(); + +void OsSDLInputSetWindowResizeLock(int32_t resizeLock); + +int32_t OsSDLInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3); + +void OsSDLInputGetMousePosition(int32_t* x, int32_t *y); + +#endif diff --git a/src/os/win/Clipboard.cpp b/src/os/win/Clipboard.cpp new file mode 100644 index 0000000..1693a5d --- /dev/null +++ b/src/os/win/Clipboard.cpp @@ -0,0 +1,73 @@ +#include "os/Clipboard.hpp" +#include "gx/Device.hpp" +#include "gx/Types.hpp" +#include +#include + +char* IOsClipboardGetString(HWND window) { + if (!OpenClipboard(window)) { + return nullptr; + } + auto handle = GetClipboardData(CF_UNICODETEXT); + auto widestr = reinterpret_cast(GlobalLock(handle)); + if (!widestr) { + return nullptr; + } + + // Get length of UTF-8 text + auto length = WideCharToMultiByte(CP_UTF8, 0, widestr, -1, nullptr, 0, nullptr, nullptr); + auto str = reinterpret_cast(SMemAlloc(length, __FILE__, __LINE__, 0x0)); + // Convert UTF-16 into UTF-8 + WideCharToMultiByte(CP_UTF8, 0, widestr, -1, str, length, nullptr, nullptr); + str[length - 1] = '\0'; + + GlobalUnlock(handle); + CloseClipboard(); + + return str; +} + +int32_t IOsClipboardPutString(const char* str, HWND window) { + // Allocate twice as large UTF-16 string + auto length = SStrLen(str) + 1; + auto memory = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE | GMEM_ZEROINIT, length * 2); + if (!memory) { + return 0; + } + // Get access to global memory + auto widestr = reinterpret_cast(GlobalLock(memory)); + if (!widestr) { + GlobalFree(memory); + return 0; + } + // Convert UTF-8 string into UTF-16 string + MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, str, length - 1, widestr, length * 2); + // Finish writing to memory + GlobalUnlock(memory); + + // Copy UTF-16 text into clipboard + if (!OpenClipboard(nullptr)) { + GlobalFree(memory); + return 0; + } + if (!EmptyClipboard()) { + CloseClipboard(); + GlobalFree(memory); + return 0; + } + SetClipboardData(CF_UNICODETEXT, memory); + CloseClipboard(); + + return 1; +} + +int32_t OsClipboardPutString(const char* str) { + return IOsClipboardPutString(str, GxDevApi() == GxApi_GLSDL ? static_cast(nullptr) : static_cast(GxDevWindow())); +} + +char* OsClipboardGetString() { + return IOsClipboardGetString( + GxDevApi() == GxApi_GLSDL ? + static_cast(nullptr) : + static_cast(GxDevWindow())); +} diff --git a/src/os/win/Debug.cpp b/src/os/win/Debug.cpp new file mode 100644 index 0000000..680200b --- /dev/null +++ b/src/os/win/Debug.cpp @@ -0,0 +1,15 @@ +#include "os/Debug.hpp" +#include +#include +#include + +void OsOutputDebugString(const char* format, ...) { + char buffer[256]; + + va_list args; + va_start(args, format); + + vsnprintf(buffer, sizeof(buffer), format, args); + OutputDebugString(buffer); + return; +} diff --git a/src/os/win/Gui.cpp b/src/os/win/Gui.cpp new file mode 100644 index 0000000..85f157f --- /dev/null +++ b/src/os/win/Gui.cpp @@ -0,0 +1,82 @@ +#include "os/Gui.hpp" +#include +#include +#include +#include + +static void* s_GxDevWindow; + +void* OsGuiGetWindow(int32_t type) { + switch (type) { + case 0: + return s_GxDevWindow; + case 1: + return GetActiveWindow(); + case 2: + return GetForegroundWindow(); + default: + return nullptr; + } +} + +bool OsGuiIsModifierKeyDown(int32_t key) { + // TODO + return false; +} + +int32_t OsGuiProcessMessage(void* message) { + // TODO + return 0; +} + +void OsGuiSetGxWindow(void* window) { + s_GxDevWindow = window; +} + +int32_t OsGuiMessageBox(void* parentWindow, int32_t style, const char* message, const char* title) { + auto messagelength = SUniConvertUTF8to16Len(reinterpret_cast(message), STORM_MAX_STR, nullptr); + auto messagebuffer = reinterpret_cast(alloca(2 * messagelength)); + SUniConvertUTF8to16(messagebuffer, messagelength, reinterpret_cast(message), STORM_MAX_STR, nullptr, nullptr); + + title = title ? title : ""; + auto titlelength = SUniConvertUTF8to16Len(reinterpret_cast(title), STORM_MAX_STR, nullptr); + auto titlebuffer = reinterpret_cast(alloca(2 * titlelength)); + SUniConvertUTF8to16(titlebuffer, titlelength, reinterpret_cast(title), STORM_MAX_STR, nullptr, nullptr); + + UINT type = 0; + switch (style) { + case 0: + type = 0; + break; + case 1: + type = MB_OKCANCEL; + break; + case 2: + type = MB_YESNO; + break; + case 3: + type = MB_YESNOCANCEL; + break; + } + + auto result = MessageBoxW( + static_cast(parentWindow), + reinterpret_cast(messagebuffer), + reinterpret_cast(titlebuffer), + type); + if (result == IDOK || result == IDYES) { + return 0; + } + + if (result == IDNO) { + return 1; + } + return 2; +} + +void OsGuiSetWindowTitle(void* window, const char* title) { + auto widetitlelength = SUniConvertUTF8to16Len(reinterpret_cast(title), STORM_MAX_STR, nullptr); + auto widetitle = reinterpret_cast(alloca(2 * widetitlelength)); + SUniConvertUTF8to16(widetitle, widetitlelength, reinterpret_cast(title), STORM_MAX_STR, nullptr, nullptr); + SetWindowTextW(static_cast(window), reinterpret_cast(widetitle)); +} diff --git a/src/event/win/Input.cpp b/src/os/win/Input.cpp similarity index 94% rename from src/event/win/Input.cpp rename to src/os/win/Input.cpp index 5866f53..2869146 100644 --- a/src/event/win/Input.cpp +++ b/src/os/win/Input.cpp @@ -1,11 +1,15 @@ -#include "event/Input.hpp" -#include "client/Gui.hpp" +#include "os/Input.hpp" +#include "os/Queue.hpp" +#include "os/Gui.hpp" +#include "os/internal/Input.hpp" +#include "os/internal/Queue.hpp" +#include "event/Types.hpp" #include #include #include #if defined(WHOA_BUILD_GLSDL) -#include "event/sdl/Input.hpp" +#include "os/sdl/Input.hpp" #endif static const uint32_t s_latin5lookup[256] = { @@ -143,7 +147,6 @@ static const uint32_t s_thailookup[256] = { 0x20, 0x20, 0x20, 0x20 }; - static RECT s_defaultWindowRect; static int32_t s_savedResize; @@ -414,7 +417,7 @@ int32_t ConvertKeyCode(uint32_t vkey, KEY* key) { bool ProcessMouseEvent(MOUSEBUTTON button, uint32_t message, HWND hwnd, OSINPUT id) { POINT mousePos; - if (Input::s_osMouseMode == OS_MOUSE_MODE_RELATIVE) { + if (s_osMouseMode == OS_MOUSE_MODE_RELATIVE) { // TODO } else { GetCursorPos(&mousePos); @@ -435,11 +438,11 @@ int32_t HandleMouseDown(uint32_t message, uintptr_t wparam, bool* xbutton, HWND return 0; } - if (Input::s_osButtonState == 0) { + if (s_osButtonState == 0) { SetCapture(hwnd); } - Input::s_osButtonState |= button; + s_osButtonState |= button; auto xb = ProcessMouseEvent(button, message, hwnd, OS_INPUT_MOUSE_DOWN); @@ -456,9 +459,9 @@ int32_t HandleMouseUp(uint32_t message, uintptr_t wparam, bool* xbutton, HWND hw return 0; } - Input::s_osButtonState &= ~button; + s_osButtonState &= ~button; - if (Input::s_osButtonState == 0) { + if (s_osButtonState == 0) { // TODO ReleaseCapture(); // TODO @@ -473,11 +476,27 @@ int32_t HandleMouseUp(uint32_t message, uintptr_t wparam, bool* xbutton, HWND hw return 1; } +void OsInputSetWindowResizeLock(int32_t resizeLock) { +#if defined(WHOA_BUILD_GLSDL) + if (OsSDLInputActive()) { + OsSDLInputSetWindowResizeLock(resizeLock); + } +#endif + s_WindowResizeLock = resizeLock; +} + +void OsInputInitialize() { + s_numlockState = GetAsyncKeyState(144); + int32_t mouseSpeed = 10; + SystemParametersInfoA(SPI_GETMOUSESPEED, 0, &mouseSpeed, 0); + s_savedMouseSpeed = mouseSpeed; +} + int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) { #if defined(WHOA_BUILD_GLSDL) - if (SDLInputActive()) { + if (OsSDLInputActive()) { // SDL handles input events for us - return SDLInputGet(id, param0, param1, param2, param3); + return OsSDLInputGet(id, param0, param1, param2, param3); } #endif @@ -516,7 +535,7 @@ int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param } } - if (Input::s_queueTail != Input::s_queueHead) { + if (s_queueTail != s_queueHead) { OsQueueGet(id, param0, param1, param2, param3); return 1; } @@ -527,7 +546,7 @@ int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param MSG msg; auto peekResult = PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE); - if (Input::s_queueTail != Input::s_queueHead) { + if (s_queueTail != s_queueHead) { break; } @@ -544,14 +563,14 @@ int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param break; } - if (Input::s_queueTail != Input::s_queueHead) { + if (s_queueTail != s_queueHead) { break; } TranslateMessage(&msg); DispatchMessage(&msg); - if (Input::s_queueTail != Input::s_queueHead) { + if (s_queueTail != s_queueHead) { break; } } @@ -565,22 +584,22 @@ void OsInputSetMouseMode(OS_MOUSE_MODE mode) { STORM_VALIDATE(mode < OS_MOUSE_MODES); STORM_VALIDATE_END_VOID; - if (Input::s_osMouseMode == mode) { + if (s_osMouseMode == mode) { return; } if (mode == OS_MOUSE_MODE_NORMAL) { - Input::s_osMouseMode = mode; + s_osMouseMode = mode; RestoreMouse(); } else if (mode == OS_MOUSE_MODE_RELATIVE) { - Input::s_osMouseMode = mode; + s_osMouseMode = mode; CenterMouse(); } } void OsInputGetMousePosition(int32_t* x, int32_t* y) { #if defined(WHOA_BUILD_GLSDL) - if (SDLInputActive()) { + if (OsSDLInputActive()) { SDLInputGetMousePosition(x, y); return; } @@ -593,7 +612,7 @@ void OsInputGetMousePosition(int32_t* x, int32_t* y) { GetCursorPos(&pt); ScreenToClient(window, &pt); - if (Input::s_osMouseMode != OS_MOUSE_MODE_RELATIVE) { + if (s_osMouseMode != OS_MOUSE_MODE_RELATIVE) { SaveMouse(window, pt); } @@ -629,13 +648,13 @@ int32_t OsWindowProc(void* window, uint32_t message, uintptr_t wparam, intptr_t case WM_ACTIVATE: { auto isMinimized = IsIconic(hwnd); auto isActive = wparam != WA_INACTIVE; - Input::s_windowFocused = isActive && !isMinimized; + s_windowFocused = isActive && !isMinimized; // TODO capture // TODO mouse speed - OsQueuePut(OS_INPUT_FOCUS, Input::s_windowFocused != 0, 0, 0, 0); + OsQueuePut(OS_INPUT_FOCUS, s_windowFocused != 0, 0, 0, 0); break; } @@ -744,7 +763,7 @@ int32_t OsWindowProc(void* window, uint32_t message, uintptr_t wparam, intptr_t case WM_MOUSEMOVE: { // TODO - if (Input::s_osMouseMode == OS_MOUSE_MODE_RELATIVE) { + if (s_osMouseMode == OS_MOUSE_MODE_RELATIVE) { // TODO } else { POINT mousePos; diff --git a/src/ui/CSimpleEditBox.cpp b/src/ui/CSimpleEditBox.cpp index e9b287c..eaee9fc 100644 --- a/src/ui/CSimpleEditBox.cpp +++ b/src/ui/CSimpleEditBox.cpp @@ -1,5 +1,5 @@ #include "ui/CSimpleEditBox.hpp" -#include "gx/Gx.hpp" +#include "gx/Device.hpp" #include "gx/Coordinate.hpp" #include "ui/CSimpleEditBoxScript.hpp" #include "ui/CSimpleFontedFrameFont.hpp" diff --git a/src/ui/FrameScript.cpp b/src/ui/FrameScript.cpp index efef8f8..47903d2 100644 --- a/src/ui/FrameScript.cpp +++ b/src/ui/FrameScript.cpp @@ -8,6 +8,7 @@ #include "util/SFile.hpp" #include #include +#include #include #include #include @@ -98,11 +99,6 @@ const char* FrameScript_EventObject::GetName() { return this->m_key.m_str; } -int64_t OsGetAsyncClocksPerSecond() { - // TODO - - return 1000.0; -} int32_t FrameScript_CompileFunction(const char* name, const char* wrapper, const char* body, CStatus* status) { lua_State* L = FrameScript::s_context; diff --git a/src/world/CWorld.cpp b/src/world/CWorld.cpp index 7da5185..4ee7904 100644 --- a/src/world/CWorld.cpp +++ b/src/world/CWorld.cpp @@ -1,5 +1,5 @@ #include "world/CWorld.hpp" -#include "gx/Gx.hpp" +#include "gx/Device.hpp" #include "gx/Shader.hpp" #include "model/Model2.hpp"