mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-10-26 13:56:05 +03:00
feat(console): hardware detection et cetera
This commit is contained in:
parent
97bbe2ea66
commit
31f215ea14
@ -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)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <storm/Error.hpp>
|
||||
#include <common/DataStore.hpp>
|
||||
|
||||
#include "console/Line.hpp"
|
||||
#include "console/Console.hpp"
|
||||
#include "world/World.hpp"
|
||||
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ void ProcessCommandLine() {
|
||||
}
|
||||
|
||||
const char* CmdLineGetString(CMDOPT opt) {
|
||||
static char buffer[260] = {0};
|
||||
static char buffer[260];
|
||||
|
||||
SCmdGetString(opt, buffer, 260);
|
||||
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
#ifndef CLIENT_GUI_HPP
|
||||
#define CLIENT_GUI_HPP
|
||||
|
||||
#include "client/gui/OsGui.hpp"
|
||||
|
||||
#endif
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -9,4 +9,6 @@ void ConsoleInitializeClientCVar(const char* a1);
|
||||
|
||||
int32_t ConsoleLoadClientCVar(const char* a1);
|
||||
|
||||
void ConsoleDestroyClientCommand();
|
||||
|
||||
#endif
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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
467
src/console/Detect.cpp
Normal 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
74
src/console/Detect.hpp
Normal 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
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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
72
src/console/Gx.cpp
Normal 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
14
src/console/Gx.hpp
Normal 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
|
||||
@ -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
59
src/console/Highlight.cpp
Normal 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
31
src/console/Highlight.hpp
Normal 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
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
12
src/console/Text.cpp
Normal 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
18
src/console/Text.hpp
Normal 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
|
||||
@ -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
|
||||
|
||||
32
src/console/command/Commands.hpp
Normal file
32
src/console/command/Commands.hpp
Normal 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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
16
src/console/command/default/GxRestart.cpp
Normal file
16
src/console/command/default/GxRestart.cpp
Normal 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);
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
641
src/console/cvar/Gx.cpp
Normal 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
43
src/console/cvar/Gx.hpp
Normal 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
|
||||
@ -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 ()
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
6
src/event/mac/Event.hpp
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef EVENT_MAC_EVENT_HPP
|
||||
#define EVENT_MAC_EVENT_HPP
|
||||
|
||||
void RunCocoaEventLoop();
|
||||
|
||||
#endif
|
||||
@ -1,4 +1,4 @@
|
||||
#include "event/mac/Event.h"
|
||||
#include "event/mac/Event.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 ()
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
58
src/os/CMakeLists.txt
Normal 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
10
src/os/Clipboard.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef OS_CLIPBOARD_HPP
|
||||
#define OS_CLIPBOARD_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
char* OsClipboardGetString();
|
||||
|
||||
int32_t OsClipboardPutString(const char*);
|
||||
|
||||
#endif
|
||||
@ -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
6
src/os/Debug.hpp
Normal 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
18
src/os/Gui.hpp
Normal 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
23
src/os/Input.hpp
Normal 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
66
src/os/Queue.cpp
Normal 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
12
src/os/Queue.hpp
Normal 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
40
src/os/Types.hpp
Normal 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
23
src/os/internal/Input.cpp
Normal 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
28
src/os/internal/Input.hpp
Normal 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
|
||||
6
src/os/internal/Queue.cpp
Normal file
6
src/os/internal/Queue.cpp
Normal 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
13
src/os/internal/Queue.hpp
Normal 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
|
||||
25
src/os/linux/Clipboard.cpp
Normal file
25
src/os/linux/Clipboard.cpp
Normal 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
11
src/os/linux/Debug.cpp
Normal 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
51
src/os/linux/Gui.cpp
Normal 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
|
||||
@ -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
Loading…
Reference in New Issue
Block a user