feat(console): hardware detection et cetera

This commit is contained in:
superp00t 2025-04-12 04:35:49 -04:00
parent 97bbe2ea66
commit 31f215ea14
118 changed files with 4059 additions and 1931 deletions

View File

@ -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)

View File

@ -3,7 +3,7 @@
#include <storm/Error.hpp>
#include <common/DataStore.hpp>
#include "console/Line.hpp"
#include "console/Console.hpp"
#include "world/World.hpp"

View File

@ -57,7 +57,7 @@ void ProcessCommandLine() {
}
const char* CmdLineGetString(CMDOPT opt) {
static char buffer[260] = {0};
static char buffer[260];
SCmdGetString(opt, buffer, 260);

View File

@ -1,6 +0,0 @@
#ifndef CLIENT_GUI_HPP
#define CLIENT_GUI_HPP
#include "client/gui/OsGui.hpp"
#endif

View File

@ -1,14 +0,0 @@
#ifndef CLIENT_GUI_OS_GUI_HPP
#define CLIENT_GUI_OS_GUI_HPP
#include <cstdint>
void* OsGuiGetWindow(int32_t type);
bool OsGuiIsModifierKeyDown(int32_t key);
int32_t OsGuiProcessMessage(void* message);
void OsGuiSetGxWindow(void* window);
#endif

View File

@ -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;
}

View File

@ -1,31 +0,0 @@
#include "client/gui/OsGui.hpp"
#include <windows.h>
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;
}

View File

@ -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

View File

@ -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 <bc/os/File.hpp>
@ -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<CVar, HASHKEY_STRI>() {
@ -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<char*>(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<char*>(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);
}

View File

@ -1,32 +1,26 @@
#ifndef CONSOLE_C_VAR_HPP
#define CONSOLE_C_VAR_HPP
#ifndef CONSOLE_CVAR_HPP
#define CONSOLE_CVAR_HPP
#include <cstdint>
#include <common/String.hpp>
#include <storm/Hash.hpp>
#include <bc/os/File.hpp>
#include "console/Types.hpp"
#define CONSOLE_CVAR_MAX_LINE 2048
class CVar : public TSHashObject<CVar, HASHKEY_STRI> {
public:
typedef bool (*HANDLER_FUNC)(CVar*, const char*, const char*, void*);
// Static variables
static TSHashTable<CVar, HASHKEY_STRI> 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<CVar, HASHKEY_STRI> {
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();

View File

@ -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();
}

View File

@ -9,4 +9,6 @@ void ConsoleInitializeClientCVar(const char* a1);
int32_t ConsoleLoadClientCVar(const char* a1);
void ConsoleDestroyClientCommand();
#endif

View File

@ -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 <cctype>
#include <storm/Error.hpp>
#include <storm/Unicode.hpp>
#include <cctype>
#include <algorithm>
int32_t s_completionMode = 0;
const char* s_completedCmd = nullptr;
char s_partial[256];
char s_repeatBuffer[64];
uint32_t s_repeatCount = 0;
TSHashTable<CONSOLECOMMAND, HASHKEY_STRI> 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<CONSOLECOMMAND, HASHKEY_STRI> 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<const uint8_t*>(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<const uint8_t*>(string), &chars);
// Discard space
while (code != -1 && code == ' ') {
string += chars;
code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
}
SStrCopy(argptr, string, argsize);
auto len = SStrLen(argptr);
while (len > 0 && (argptr[len - 1] == ' ')) {
len--;
argptr[len] = '\0';
}
}
return g_consoleCommandHash.Ptr(cmd);
}
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<const uint8_t*>(string), &chars);
if (code == -1 || code == ' ' || chars > CONSOLE_MAX_CMD_LENGTH) {
break;
}
if (chars) {
for (size_t c = 0; c < chars; c++) {
*cmdptr = *string;
cmdptr += chars;
string += chars;
}
}
i += chars;
}
*cmdptr = '\0';
if (command) {
*command = cmd;
}
auto argptr = arguments;
if (arguments) {
int32_t chars;
auto code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
// Discard space
while (code != -1 && code == ' ') {
string += chars;
code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
}
SStrCopy(argptr, string, argsize);
auto len = SStrLen(argptr);
while (len > 0 && (argptr[len-1] == ' ')) {
len--;
argptr[len] = '\0';
}
}
return g_consoleCommandHash.Ptr(cmd);
}
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<char*>(SMemAlloc(CONSOLE_CMD_BUFFER_SIZE, __FILE__, __LINE__, 0));
auto cmd = ParseCommand(commandLine, &command, arguments, CONSOLE_CMD_BUFFER_SIZE);
auto arguments = reinterpret_cast<char*>(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<Timestamp>.txt] [numLines = all]" }
};
static ConsoleCommandList s_commonCommands[] = {
{ "quit", ConsoleCommand_Quit, nullptr },
{ "ver", ConsoleCommand_Ver, nullptr },
{ "setmap", ConsoleCommand_SetMap, nullptr }
};
void RegisterConsoleCommandList(CATEGORY category, ConsoleCommandList list[], size_t count) {
size_t i = 0;
while (i < count) {
auto& cmd = list[i];
ConsoleCommandRegister(cmd.m_command, cmd.m_handler, category, cmd.m_helpText);
i++;
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<Timestamp>.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;
}

View File

@ -2,67 +2,43 @@
#define CONSOLE_COMMAND_HPP
#include "console/Types.hpp"
#include <storm/Hash.hpp>
#include <cstdint>
#include <storm/Hash.hpp>
#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<CONSOLECOMMAND, HASHKEY_STRI> {
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<CONSOLECOMMAND, HASHKEY_STRI> 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

View File

@ -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());
}

View File

@ -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 <cstdint>
@ -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

467
src/console/Detect.cpp Normal file
View File

@ -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 <common/Processor.hpp>
#include <storm/Registry.hpp>
#if defined(WHOA_SYSTEM_MAC)
#include <OpenGL/gl.h>
#include <sys/sysctl.h>
#endif
WowClientDB<VideoHardwareRec> 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<C2iVector>& resolutions, const C2iVector& resolution) {
resolutions.Add(1, &resolution);
}
void ConsoleDetectGetResolutions(TSGrowableArray<C2iVector>& resolutions, int32_t widescreen) {
if (widescreen) {
TSGrowableArray<CGxMonitorMode> modes;
GxAdapterMonitorModes(modes);
C2iVector prev = { 0, 0 };
for (uint32_t i = 0; i < modes.Count(); i++) {
auto& mode = modes[i];
if ((static_cast<float>(mode.size.x) / static_cast<float>(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<float>(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<uint32_t>(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;
}

74
src/console/Detect.hpp Normal file
View File

@ -0,0 +1,74 @@
#ifndef CONSOLE_DETECT_HPP
#define CONSOLE_DETECT_HPP
#include <storm/Array.hpp>
#include <tempest/Vector.hpp>
#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<C2iVector>& 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

View File

@ -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 <cstring>
#include "gx/Types.hpp"
#include "console/command/Commands.hpp"
#include "db/Startup_Strings.hpp"
#include <storm/String.hpp>
#include <tempest/Vector.hpp>
#include <cstdio>
#include <cstring>
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<CGxMonitorMode> 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<EGxApi>(static_cast<int32_t>(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<CGxFormat::Format>(static_cast<int32_t>(apiFormat.colorFormat - 1));
apiFormat.depthFormat = colorFormat != CGxFormat::Fmt_ArgbX888 ? CGxFormat::Fmt_Ds320 : CGxFormat::Fmt_Ds160;
} else {
apiFormat.depthFormat = static_cast<CGxFormat::Format>(static_cast<int32_t>(apiFormat.depthFormat - 1));
}
} else {
apiFormat.sampleCount = std::max(apiFormat.sampleCount - 2, static_cast<uint32_t>(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<EGxOverride>(static_cast<int32_t>(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();
}

View File

@ -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

72
src/console/Gx.cpp Normal file
View File

@ -0,0 +1,72 @@
#include "console/Gx.hpp"
#include <storm/String.hpp>
#include <cstdlib>
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<EGxOverride>(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;
}
}
}
}

14
src/console/Gx.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef CONSOLE_GX_HPP
#define CONSOLE_GX_HPP
#include <cstdint>
#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

View File

@ -1,12 +1,17 @@
#include <cstdint>
#include <storm/String.hpp>
#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 <cstdint>
#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;
}

59
src/console/Highlight.cpp Normal file
View File

@ -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();
}

31
src/console/Highlight.hpp Normal file
View File

@ -0,0 +1,31 @@
#ifndef CONSOLE_HIGHLIGHT_HPP
#define CONSOLE_HIGHLIGHT_HPP
#include <cstdint>
#include <storm/Region.hpp>
#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

View File

@ -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 <storm/List.hpp>
#include <storm/thread/SCritSect.hpp>
#include <cstdio>
#include "os/Clipboard.hpp"
#include <bc/Memory.hpp>
#include <storm/Thread.hpp>
#include <cstdarg>
#include <cstdio>
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<char*>(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<char*>(SMemAlloc(CONSOLE_LINE_PREALLOC, __FILE__, __LINE__, 0));
line->charsalloc = CONSOLE_LINE_PREALLOC;
s_linelist.LinkToHead(line);
SStrCopy(line->buffer, "> ", line->charsalloc);
SetInputString(line->buffer);
auto chars = SStrLen(line->buffer);
s_NumLines++;
line->inputstart = chars;
line->inputpos = chars;
line->chars = chars;
line->colorType = INPUT_COLOR;
s_currlineptr = line;
EnforceMaxLines();
return line;
// 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<char*>(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<int32_t>((ConsoleGetHeight() - (1.0 - y)) / ConsoleGetFontHeight());
auto linePos = static_cast<int32_t>((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<char*>(ALLOC(line->charsalloc));
SStrCopy(input, &line->buffer[line->inputpos], STORM_MAX_STR);
auto buffer = reinterpret_cast<char*>(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<char*>(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<char*>(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<char*>(SMemAlloc(len, __FILE__, __LINE__, 0));
lineptr->buffer = reinterpret_cast<char*>(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();
}

View File

@ -4,27 +4,59 @@
#include "console/Types.hpp"
#include <storm/List.hpp>
#include <storm/Thread.hpp>
#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<CONSOLELINE> {
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

View File

@ -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 <tempest/Rect.hpp>
#include <algorithm>
static CGxStringBatch* s_batch;
static uint32_t s_baseTextFlags = 0x8;
static int32_t s_caret = 0;
static float s_caretpixwidth;
static float s_caretpixheight;
static float s_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<char*>(SMemAlloc(line->charsalloc, __FILE__, __LINE__, 0x0));
SStrCopy(input, &line->buffer[line->inputpos], STORM_MAX_STR);
auto buffer = reinterpret_cast<char*>(SMemAlloc(line->charsalloc, __FILE__, __LINE__, 0x0));
SStrCopy(buffer, line->buffer, STORM_MAX_STR);
buffer[line->inputpos] = '\0';
SStrPack(buffer, characters, line->charsalloc);
auto len = SStrLen(buffer);
line->inputpos = len;
SStrPack(buffer, input, line->charsalloc);
SStrCopy(line->buffer, buffer, STORM_MAX_STR);
line->chars = SStrLen(line->buffer);
if (input) {
SMemFree(input, __FILE__, __LINE__, 0);
}
if (buffer) {
SMemFree(input, __FILE__, __LINE__, 0);
}
}
} else {
for (int32_t i = 0; i < len; i++) {
line->buffer[line->inputpos++] = characters[i];
}
line->buffer[line->inputpos] = '\0';
line->chars = line->inputpos;
}
SetInputString(line->buffer);
}
void GenerateNodeString(CONSOLELINE* node) {
auto font = TextBlockGetFontPtr(s_textFont);
if (font && node && node->buffer && node->buffer[0] != '\0') {
if (node->fontPointer) {
GxuFontDestroyString(node->fontPointer);
}
C3Vector pos = {
0.0f, 0.0f, 1.0f
};
auto fontHeight = ConsoleGetFontHeight();
GxuFontCreateString(font, node->buffer, fontHeight, pos, 1.0f, fontHeight, 0.0f, node->fontPointer, GxVJ_Middle, GxHJ_Left, s_baseTextFlags, s_colorArray[node->colorType], s_charSpacing, 1.0f);
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);

View File

@ -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 <storm/region/Types.hpp>
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

12
src/console/Text.cpp Normal file
View File

@ -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;

18
src/console/Text.hpp Normal file
View File

@ -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

View File

@ -2,7 +2,6 @@
#define CONSOLE_TYPES_HPP
#include "gx/Font.hpp"
#include <storm/Hash.hpp>
#include <storm/List.hpp>
@ -50,32 +49,4 @@ enum CONSOLERESIZESTATE {
typedef int32_t (*COMMANDHANDLER)(const char*, const char*);
class CONSOLECOMMAND : public TSHashObject<CONSOLECOMMAND, HASHKEY_STRI> {
public:
COMMANDHANDLER m_handler;
const char* m_helpText;
CATEGORY m_category;
};
class CONSOLELINE : public TSLinkedNode<CONSOLELINE> {
public:
char* buffer;
uint32_t chars;
uint32_t charsalloc;
uint32_t inputpos;
uint32_t inputstart;
COLOR_T colorType;
CGxString* fontPointer;
~CONSOLELINE();
};
class ConsoleCommandList {
public:
const char* m_command;
COMMANDHANDLER m_handler;
const char* m_helpText;
};
#endif

View File

@ -0,0 +1,32 @@
#ifndef CONSOLE_COMMAND_COMMANDS_HPP
#define CONSOLE_COMMAND_COMMANDS_HPP
#include <cstdint>
#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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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<char*>(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<char*>(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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 <https://github.com/whoahq/whoa>", DEFAULT_COLOR);
return 1;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

641
src/console/cvar/Gx.cpp Normal file
View File

@ -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 <storm/Array.hpp>
#include <cstdio>
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<EGxApi>(static_cast<int32_t>(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<EGxApi>(static_cast<int32_t>(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<C2iVector> 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<CGxMonitorMode> 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();
}

43
src/console/cvar/Gx.hpp Normal file
View File

@ -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

View File

@ -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 ()

View File

@ -3,6 +3,7 @@
#include "event/EvtContext.hpp"
#include "event/Queue.hpp"
#include "gx/Window.hpp"
#include "os/Input.hpp"
#include <common/Time.hpp>
#include <storm/String.hpp>
#include <storm/Unicode.hpp>
@ -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;
}
}
}

View File

@ -4,8 +4,6 @@
#include "event/Types.hpp"
#include <cstdint>
#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

View File

@ -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;

View File

@ -1,6 +0,0 @@
#ifndef EVENT_MAC_EVENT_H
#define EVENT_MAC_EVENT_H
void RunCocoaEventLoop();
#endif

6
src/event/mac/Event.hpp Normal file
View File

@ -0,0 +1,6 @@
#ifndef EVENT_MAC_EVENT_HPP
#define EVENT_MAC_EVENT_HPP
void RunCocoaEventLoop();
#endif

View File

@ -1,4 +1,4 @@
#include "event/mac/Event.h"
#include "event/mac/Event.hpp"
#include "event/Event.hpp"
#include <AppKit/AppKit.h>

View File

@ -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

View File

@ -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;

View File

@ -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 <storm/Error.hpp>
#include <bc/Memory.hpp>
#include <bc/os/File.hpp>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <limits>
#include <storm/Error.hpp>
#include <bc/Memory.hpp>
#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 <SDL3/SDL.h>
#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<CGxMonitorMode>& 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<CGxMonitorMode>& 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<CGxMonitorMode>& 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<uint32_t>(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<uint32_t>(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<CGxMonitorMode>& 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<CGxMonitorMode>& modes) {
// TODO: Mac support
return false;
}
#elif (WHOA_BUILD_GLSDL)
bool CGxDevice::AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& 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<uint32_t>(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;

View File

@ -11,7 +11,9 @@
#include "gx/Shader.hpp"
#include "cursor/Cursor.hpp"
#include <cstdint>
#include <cstdarg>
#include <storm/Hash.hpp>
#include <storm/Log.hpp>
#include <tempest/Box.hpp>
#include <tempest/Rect.hpp>
@ -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<CGxMonitorMode>& 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<CGxMonitorMode>& 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<CGxStateBom> 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();

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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

View File

@ -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 ()

View File

@ -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<uint32_t>(api)) != 0;
return (g_supportedApis & (1 << static_cast<uint32_t>(api))) != 0;
}
bool GxAdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& 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<CGxMonitorMode>& 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);
}

View File

@ -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<CGxMonitorMode>& 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

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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) {

View File

@ -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() {

View File

@ -1,6 +1,6 @@
#ifndef GX_GL_SDL_GL_SDL_CONTEXT_HPP
#include <SDL2/SDL.h>
#include <SDL3/SDL.h>
#include "gx/glsdl/GLSDLWindow.hpp"
#include "gx/glsdl/GLTypes.hpp"

View File

@ -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<int>(rect.size.width), static_cast<int>(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() {

View File

@ -2,7 +2,7 @@
#define GX_GL_SDL_GL_SDL_WINDOW_HPP
#include <cstdint>
#include <SDL2/SDL.h>
#include <SDL3/SDL.h>
#include "gx/glsdl/GLTypes.hpp"

View File

@ -141,11 +141,13 @@ void CBLPFile::DecompPalARGB8888(uint8_t* data, void* tempbuffer, uint32_t color
auto pixels = data;
auto bytes = reinterpret_cast<uint8_t*>(tempbuffer);
for (auto i = colorSize; i; i--) {
auto i = colorSize;
while (i != 0) {
*reinterpret_cast<BlpPalPixel*>(pixels) = this->m_header.extended.palette[*bytes];
pixels[3] = 0xFF;
pixels += 4;
bytes++;
i--;
}
auto alphaBits = this->AlphaBits();

View File

@ -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

View File

@ -1,5 +1,5 @@
#include "gx/texture/CGxTex.hpp"
#include "gx/Gx.hpp"
#include "gx/Device.hpp"
#include <algorithm>
CGxTexFlags::CGxTexFlags(EGxTexFilter filter, uint32_t wrapU, uint32_t wrapV, uint32_t force, uint32_t generateMipMaps, uint32_t renderTarget, uint32_t maxAnisotropy) {

View File

@ -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"

58
src/os/CMakeLists.txt Normal file
View File

@ -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()

10
src/os/Clipboard.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef OS_CLIPBOARD_HPP
#define OS_CLIPBOARD_HPP
#include <cstdint>
char* OsClipboardGetString();
int32_t OsClipboardPutString(const char*);
#endif

View File

@ -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

6
src/os/Debug.hpp Normal file
View File

@ -0,0 +1,6 @@
#ifndef OS_DEBUG_HPP
#define OS_DEBUG_HPP
void OsOutputDebugString(const char* format, ...);
#endif

18
src/os/Gui.hpp Normal file
View File

@ -0,0 +1,18 @@
#ifndef OS_GUI_HPP
#define OS_GUI_HPP
#include <cstdint>
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

23
src/os/Input.hpp Normal file
View File

@ -0,0 +1,23 @@
#ifndef OS_INPUT_HPP
#define OS_INPUT_HPP
#include "os/Types.hpp"
#include <cstdint>
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

66
src/os/Queue.cpp Normal file
View File

@ -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;
}
}
}

12
src/os/Queue.hpp Normal file
View File

@ -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

40
src/os/Types.hpp Normal file
View File

@ -0,0 +1,40 @@
#ifndef OS_TYPES_HPP
#define OS_TYPES_HPP
#include <cstdint>
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

23
src/os/internal/Input.cpp Normal file
View File

@ -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

28
src/os/internal/Input.hpp Normal file
View File

@ -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

View File

@ -0,0 +1,6 @@
#include "os/internal/Queue.hpp"
OSEVENT s_queue[32];
int32_t s_queueHead;
int32_t s_queueTail;

13
src/os/internal/Queue.hpp Normal file
View File

@ -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

View File

@ -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

11
src/os/linux/Debug.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "os/Debug.hpp"
#include <cstdio>
#include <cstdarg>
void OsOutputDebugString(const char* format, ...) {
// TODO
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
return;
}

51
src/os/linux/Gui.cpp Normal file
View File

@ -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

View File

@ -1,18 +1,21 @@
#include <common/Time.hpp>
#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;
}

Some files were not shown because too many files have changed in this diff Show More