mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-08 10:25:59 +03:00
Merge 745dfcc129 into f1d1dad08b
This commit is contained in:
commit
c0915e66e4
@ -21,9 +21,20 @@
|
|||||||
#include <storm/Error.hpp>
|
#include <storm/Error.hpp>
|
||||||
#include <storm/Log.hpp>
|
#include <storm/Log.hpp>
|
||||||
#include <bc/os/Path.hpp>
|
#include <bc/os/Path.hpp>
|
||||||
|
#include <bc/file/File.hpp>
|
||||||
|
|
||||||
CVar* Client::g_accountListVar;
|
CVar* Client::g_accountListVar;
|
||||||
HEVENTCONTEXT Client::g_clientEventContext;
|
HEVENTCONTEXT Client::g_clientEventContext;
|
||||||
|
char Client::g_currentLocaleName[5] = {};
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t s_expansionLevel = 0;
|
||||||
|
static bool g_hasIsoLocale[12] = {};
|
||||||
|
static char* s_localeArray[12] = {
|
||||||
|
"deDE", "enGB", "enUS", "esES", "frFR", "koKR",
|
||||||
|
"zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void AsyncFileInitialize() {
|
void AsyncFileInitialize() {
|
||||||
// TODO
|
// TODO
|
||||||
@ -139,6 +150,32 @@ int32_t InitializeEngineCallback(const void* a1, void* a2) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t GetExpansionLevel() {
|
||||||
|
return s_expansionLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* UpdateInstallLocation() {
|
||||||
|
// TODO
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateInstallLocationForName(int32_t a1, size_t size, const char* filename, char* buffer, const char* locale) {
|
||||||
|
if (a1 == 2) {
|
||||||
|
auto location = UpdateInstallLocation();
|
||||||
|
if (!location) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SStrPrintf(buffer, size, "%s%s%s", location, "Data\\", filename);
|
||||||
|
} else {
|
||||||
|
SStrPrintf(buffer, size, "%s%s", "Data\\", filename);
|
||||||
|
}
|
||||||
|
for (auto i = SStrStr(buffer, "****"); i; i = SStrStr(buffer, "****")) {
|
||||||
|
size_t offset = static_cast<size_t>(i - buffer);
|
||||||
|
memcpy(&buffer[offset], locale, 4);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void SetPaths() {
|
void SetPaths() {
|
||||||
// SFile::DisableSFileCheckDisk();
|
// SFile::DisableSFileCheckDisk();
|
||||||
// SFile::EnableDirectAccess(0);
|
// SFile::EnableDirectAccess(0);
|
||||||
@ -158,12 +195,109 @@ void SetPaths() {
|
|||||||
OsSetCurrentDirectory(datadir);
|
OsSetCurrentDirectory(datadir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsCommonMpqExists() {
|
||||||
|
char path1[1024];
|
||||||
|
SStrPrintf(path1, sizeof(path1), "%s%s", "Data\\", "common.MPQ");
|
||||||
|
for (auto i = SStrStr(path1, "****"); i; i = SStrStr(path1, "****")) {
|
||||||
|
size_t offset = static_cast<size_t>(i - path1);
|
||||||
|
memcpy(&path1[offset], "----", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
char path2[1024];
|
||||||
|
SStrPrintf(path2, sizeof(path2), "%s%s", "..\\Data\\", "common.MPQ");
|
||||||
|
for (auto i = SStrStr(path2, "****"); i; i = SStrStr(path2, "****")) {
|
||||||
|
size_t offset = static_cast<size_t>(i - path2);
|
||||||
|
memcpy(&path2[offset], "----", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto location = UpdateInstallLocation();
|
||||||
|
if (location) {
|
||||||
|
char path3[1024];
|
||||||
|
SStrPrintf(path3, sizeof(path3), "%s%s%s", location, "Data\\", "common.MPQ");
|
||||||
|
for (auto i = SStrStr(path3, "****"); i; i = SStrStr(path3, "****")) {
|
||||||
|
size_t offset = static_cast<size_t>(i - path3);
|
||||||
|
memcpy(&path3[offset], "----", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Blizzard::File::Exists(path1) && !Blizzard::File::Exists(path2)) {
|
||||||
|
return Blizzard::File::Exists(path3);
|
||||||
|
}
|
||||||
|
} else if (!Blizzard::File::Exists(path1)) {
|
||||||
|
return Blizzard::File::Exists(path2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetLocaleIndex(const char* locale) {
|
||||||
|
for (size_t i = 0; i < 12; ++i) {
|
||||||
|
if (SStrCmpI(locale, s_localeArray[i], 4) == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 2; // s_localeArray[2] == "enUS"
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckAvailableLocales(char* locale) {
|
||||||
|
if (!IsCommonMpqExists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t localeIndex = 0; localeIndex < 12; ++localeIndex) {
|
||||||
|
g_hasIsoLocale[localeIndex] = false;
|
||||||
|
|
||||||
|
const char* filename = "****\\locale-****.MPQ";
|
||||||
|
|
||||||
|
char path[1024];
|
||||||
|
SStrPrintf(path, sizeof(path), "%s%s", "Data\\", filename);
|
||||||
|
for (auto i = SStrStr(path, "****"); i; i = SStrStr(path, "****")) {
|
||||||
|
size_t offset = static_cast<size_t>(i - path);
|
||||||
|
memcpy(&path[offset], s_localeArray[localeIndex], 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Blizzard::File::Exists(path)) {
|
||||||
|
g_hasIsoLocale[localeIndex] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SStrPrintf(path, sizeof(path), "%s%s", "..\\Data\\", filename);
|
||||||
|
for (auto i = SStrStr(path, "****"); i; i = SStrStr(path, "****")) {
|
||||||
|
size_t offset = static_cast<size_t>(i - path);
|
||||||
|
memcpy(&path[offset], s_localeArray[localeIndex], 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Blizzard::File::Exists(path)) {
|
||||||
|
g_hasIsoLocale[localeIndex] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UpdateInstallLocationForName(2, sizeof(path), filename, path, s_localeArray[localeIndex]) &&
|
||||||
|
Blizzard::File::Exists(path)) {
|
||||||
|
g_hasIsoLocale[localeIndex] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t localeIndex = GetLocaleIndex(locale);
|
||||||
|
for (size_t i = 0; i < 12; ++i) {
|
||||||
|
if (g_hasIsoLocale[localeIndex]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
localeIndex = (localeIndex + 1) % 12;
|
||||||
|
}
|
||||||
|
SStrCopy(locale, s_localeArray[localeIndex], STORM_MAX_STR);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocaleChangedCallback(CVar*, const char*, const char* value, void*) {
|
||||||
|
SStrCopy(Client::g_currentLocaleName, value, sizeof(Client::g_currentLocaleName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t InitializeGlobal() {
|
int32_t InitializeGlobal() {
|
||||||
// TODO
|
|
||||||
|
|
||||||
ProcessCommandLine();
|
ProcessCommandLine();
|
||||||
|
SetPaths();
|
||||||
|
|
||||||
// sub_403600("WoW.mfil");
|
// TODO:
|
||||||
|
// WowConfigureFileSystem::ReadBuildKeyFromFile("WoW.mfil");
|
||||||
|
|
||||||
// if (dword_B2FA10 != 2) {
|
// if (dword_B2FA10 != 2) {
|
||||||
// sub_403560();
|
// sub_403560();
|
||||||
@ -175,52 +309,78 @@ int32_t InitializeGlobal() {
|
|||||||
// LOBYTE(v24) = OsDirectoryExists((int)"WTF/Account") == 0;
|
// LOBYTE(v24) = OsDirectoryExists((int)"WTF/Account") == 0;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// ClientServices::LoadCDKey();
|
ClientServices::LoadCDKey();
|
||||||
|
|
||||||
SetPaths();
|
|
||||||
|
|
||||||
OpenArchives();
|
|
||||||
|
|
||||||
ConsoleInitializeClientCommand();
|
ConsoleInitializeClientCommand();
|
||||||
|
|
||||||
ConsoleInitializeClientCVar("Config.wtf");
|
ConsoleInitializeClientCVar("Config.wtf");
|
||||||
|
// TODO: CVar::ArchiveCodeRegisteredOnly();
|
||||||
// TODO
|
|
||||||
// replace enUS with detected locale
|
|
||||||
ClientServices::InitLoginServerCVars(1, "enUS");
|
|
||||||
|
|
||||||
// sub_7663F0();
|
|
||||||
|
|
||||||
// v18 = 0;
|
// v18 = 0;
|
||||||
// v19 = 0;
|
// v19 = 0;
|
||||||
// ptr = 0;
|
// ptr = 0;
|
||||||
// v21 = 0;
|
// v21 = 0;
|
||||||
|
|
||||||
// sub_406740(&v18, &CVar::Load);
|
// ::ForEveryRunOnceWTF::Execute(&v18, &CVar::Load);
|
||||||
|
|
||||||
// if (ptr) {
|
// if (ptr) {
|
||||||
// SMemFree(ptr, a_pad, -2, 0);
|
// SMemFree(ptr, a_pad, -2, 0);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// CVar::Register("dbCompress", "Database compression", 0, "-1", 0, 5, 0, 0, 0);
|
CVar::Register(
|
||||||
|
"dbCompress",
|
||||||
|
"Database compression",
|
||||||
|
0,
|
||||||
|
"-1",
|
||||||
|
nullptr,
|
||||||
|
CATEGORY::DEFAULT,
|
||||||
|
false,
|
||||||
|
nullptr,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
// v2 = CVar::Register("locale", "Set the game locale", 0, "****", &LocaleChangedCallback, 5, 0, 0, 0);
|
CVar* locale = CVar::Register(
|
||||||
|
"locale",
|
||||||
|
"Set the game locale",
|
||||||
|
0,
|
||||||
|
"****",
|
||||||
|
&LocaleChangedCallback,
|
||||||
|
CATEGORY::DEFAULT,
|
||||||
|
false,
|
||||||
|
nullptr,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
// if (!SStrCmp(v2->m_stringValue.m_str, "****", 0x7FFFFFFFu)) {
|
if (!SStrCmp(locale->GetString(), "****", STORM_MAX_STR)) {
|
||||||
// CVar::Set(v2, "enUS", 1, 0, 0, 1);
|
locale->Set("enUS", true, false, false, true);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// CVar::Register("useEnglishAudio", "override the locale and use English audio", 0, "0", 0, 5, 0, 0, 0);
|
CVar::Register(
|
||||||
|
"useEnglishAudio",
|
||||||
|
"override the locale and use English audio",
|
||||||
|
0,
|
||||||
|
"0",
|
||||||
|
nullptr,
|
||||||
|
CATEGORY::DEFAULT,
|
||||||
|
false,
|
||||||
|
nullptr,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: SFile::IsTrial() check
|
||||||
// if (sub_422140()) {
|
// if (sub_422140()) {
|
||||||
// sub_4036B0(v24, 0, a2, (int)v2, (char)v24);
|
// sub_4036B0(v24, 0, a2, (int)v2, (char)v24);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// SStrCopy(&a1a, v2->m_stringValue.m_str, 5);
|
char existingLocale[5] = {};
|
||||||
|
SStrCopy(existingLocale, locale->GetString(), sizeof(existingLocale));
|
||||||
|
CheckAvailableLocales(existingLocale);
|
||||||
|
locale->Set(existingLocale, true, false, false, true);
|
||||||
|
|
||||||
// sub_402D50(&a1a);
|
|
||||||
|
|
||||||
// CVar::Set(v2, &a1a, 1, 0, 0, 1);
|
OpenArchives();
|
||||||
|
|
||||||
|
// TODO: This method should be placed inside OpenArchives
|
||||||
|
ClientServices::InitLoginServerCVars(1, locale->GetString());
|
||||||
|
|
||||||
// SStrPrintf(dest, 260, "%s%s", *(_DWORD *)off_AB6158, v2->m_stringValue.m_str);
|
// SStrPrintf(dest, 260, "%s%s", *(_DWORD *)off_AB6158, v2->m_stringValue.m_str);
|
||||||
|
|
||||||
@ -343,19 +503,36 @@ int32_t InitializeGlobal() {
|
|||||||
void CommonMain() {
|
void CommonMain() {
|
||||||
StormInitialize();
|
StormInitialize();
|
||||||
|
|
||||||
// TODO
|
// TODO:
|
||||||
// - error log setup
|
// SErrCatchUnhandledExceptions();
|
||||||
// - misc other setup
|
// OsSystemInitialize("Blizzard Entertainment World of Warcraft", 0);
|
||||||
|
// int option = 1;
|
||||||
|
// StormSetOption(10, &option, sizeof(option));
|
||||||
|
// StormSetOption(11, &option, sizeof(option));
|
||||||
|
// OsSystemEnableCpuLog();
|
||||||
|
|
||||||
|
// SetPaths() moved into InitializeGlobal()
|
||||||
|
|
||||||
|
// int sendErrorLogs = 1;
|
||||||
|
// if (!SRegLoadValue("World of Warcraft\\Client", "SendErrorLogs", 0, &sendErrorLogs)) {
|
||||||
|
// sendErrorLogs = 1;
|
||||||
|
// SRegSaveValue("World of Warcraft\\Client", "SendErrorLogs", 0, sendErrorLogs);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// SErrSetLogTitleString("World of WarCraft (build 12340)");
|
||||||
|
// SErrSetLogTitleCallback(WowLogHeader);
|
||||||
|
// if (sendErrorLogs) {
|
||||||
|
// SErrRegisterHandler(SendErrorLog);
|
||||||
|
// }
|
||||||
|
|
||||||
if (InitializeGlobal()) {
|
if (InitializeGlobal()) {
|
||||||
EventDoMessageLoop();
|
EventDoMessageLoop();
|
||||||
|
// TODO: DestroyGlobal();
|
||||||
// TODO
|
|
||||||
// sub_406B70();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO:
|
||||||
// - misc cleanup
|
// StormDestroy();
|
||||||
|
// Misc Cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlizzardAssertCallback(const char* a1, const char* a2, const char* a3, uint32_t a4) {
|
void BlizzardAssertCallback(const char* a1, const char* a2, const char* a3, uint32_t a4) {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ class CVar;
|
|||||||
namespace Client {
|
namespace Client {
|
||||||
extern CVar* g_accountListVar;
|
extern CVar* g_accountListVar;
|
||||||
extern HEVENTCONTEXT g_clientEventContext;
|
extern HEVENTCONTEXT g_clientEventContext;
|
||||||
|
extern char g_currentLocaleName[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPostClose(int32_t a1);
|
void ClientPostClose(int32_t a1);
|
||||||
|
|||||||
@ -264,6 +264,11 @@ const char* ClientServices::GetDefaultPatchListString() {
|
|||||||
return "public-test.patch.battle.net:1119/patch";
|
return "public-test.patch.battle.net:1119/patch";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClientServices::LoadCDKey() {
|
||||||
|
// TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ClientServices::InitLoginServerCVars(int32_t overwrite, const char* locale) {
|
void ClientServices::InitLoginServerCVars(int32_t overwrite, const char* locale) {
|
||||||
if ((ClientServices::s_realmListBNVar == nullptr || ClientServices::s_realmListVar == nullptr) || overwrite != 0 ) {
|
if ((ClientServices::s_realmListBNVar == nullptr || ClientServices::s_realmListVar == nullptr) || overwrite != 0 ) {
|
||||||
ClientServices::s_decorateAccountName = CVar::Register(
|
ClientServices::s_decorateAccountName = CVar::Register(
|
||||||
|
|||||||
@ -45,6 +45,7 @@ class ClientServices : public LoginResponse {
|
|||||||
static void InitLoginServerCVars(int32_t overwrite, const char* locale);
|
static void InitLoginServerCVars(int32_t overwrite, const char* locale);
|
||||||
static const char* GetDefaultRealmlistString();
|
static const char* GetDefaultRealmlistString();
|
||||||
static const char* GetDefaultPatchListString();
|
static const char* GetDefaultPatchListString();
|
||||||
|
static bool LoadCDKey();
|
||||||
|
|
||||||
// Virtual member functions
|
// Virtual member functions
|
||||||
virtual int32_t GetLoginServerType();
|
virtual int32_t GetLoginServerType();
|
||||||
|
|||||||
@ -37,7 +37,7 @@ class CVar : public TSHashObject<CVar, HASHKEY_STRI> {
|
|||||||
int32_t GetInt();
|
int32_t GetInt();
|
||||||
const char* GetString(void);
|
const char* GetString(void);
|
||||||
void InternalSet(const char*, bool, bool, bool, bool);
|
void InternalSet(const char*, bool, bool, bool, bool);
|
||||||
bool Set(const char*, bool, bool, bool, bool);
|
bool Set(const char* value, bool setValue, bool setReset, bool setDefault, bool a6);
|
||||||
bool Reset();
|
bool Reset();
|
||||||
bool Default();
|
bool Default();
|
||||||
int32_t Update();
|
int32_t Update();
|
||||||
|
|||||||
@ -274,6 +274,7 @@ void ConsoleDeviceInitialize(const char* title) {
|
|||||||
s_requestedFormat.hwTnL = true;
|
s_requestedFormat.hwTnL = true;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
s_requestedFormat.hwCursor = true;
|
||||||
|
|
||||||
CGxFormat format;
|
CGxFormat format;
|
||||||
memcpy(&format, &s_requestedFormat, sizeof(s_requestedFormat));
|
memcpy(&format, &s_requestedFormat, sizeof(s_requestedFormat));
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "console/Command.hpp"
|
#include "console/Command.hpp"
|
||||||
#include "console/Screen.hpp"
|
#include "console/Screen.hpp"
|
||||||
#include "event/Event.hpp"
|
#include "event/Event.hpp"
|
||||||
|
#include "storm/Unicode.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
static int32_t s_historyIndex = 0;
|
static int32_t s_historyIndex = 0;
|
||||||
@ -11,24 +12,20 @@ static int32_t s_historyIndex = 0;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
int32_t OnChar(const EVENT_DATA_CHAR* data, void* param) {
|
int32_t OnChar(const EVENT_DATA_CHAR* data, void* param) {
|
||||||
char character[2];
|
char character[8] = {};
|
||||||
|
|
||||||
if (ConsoleAccessGetEnabled() && EventIsKeyDown(ConsoleGetHotKey())) {
|
if (ConsoleAccessGetEnabled() && EventIsKeyDown(ConsoleGetHotKey())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConsoleGetActive()) {
|
if (ConsoleGetActive()) {
|
||||||
character[0] = char(data->ch);
|
SUniSPutUTF8(data->ch, character);
|
||||||
character[1] = 0;
|
|
||||||
|
|
||||||
PasteInInputLine(character);
|
PasteInInputLine(character);
|
||||||
ResetHighlight();
|
ResetHighlight();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUniSPutUTF8(data->ch, character);
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -539,7 +539,10 @@ int32_t OsWindowProc(void* window, uint32_t message, uintptr_t wparam, intptr_t
|
|||||||
uint32_t character = wparam;
|
uint32_t character = wparam;
|
||||||
|
|
||||||
if (wparam >= 128) {
|
if (wparam >= 128) {
|
||||||
// TODO
|
// Workaround
|
||||||
|
wchar_t u16_character = 0;
|
||||||
|
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, reinterpret_cast<char*>(&wparam), 1, &u16_character, 1);
|
||||||
|
character = u16_character;
|
||||||
}
|
}
|
||||||
|
|
||||||
OsQueuePut(OS_INPUT_CHAR, character, LOWORD(lparam), 0, 0);
|
OsQueuePut(OS_INPUT_CHAR, character, LOWORD(lparam), 0, 0);
|
||||||
|
|||||||
@ -366,7 +366,10 @@ void CGlueMgr::PollAccountLogin(int32_t errorCode, const char* msg, int32_t comp
|
|||||||
FrameScript_SignalEvent(4, "%s", msg);
|
FrameScript_SignalEvent(4, "%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (complete) {
|
if (!complete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
if (errorCode != 2) {
|
if (errorCode != 2) {
|
||||||
// TODO
|
// TODO
|
||||||
@ -406,7 +409,6 @@ void CGlueMgr::PollAccountLogin(int32_t errorCode, const char* msg, int32_t comp
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGlueMgr::PollLoginServerLogin() {
|
void CGlueMgr::PollLoginServerLogin() {
|
||||||
|
|||||||
@ -333,7 +333,7 @@ void CGxDevice::ICursorDraw() {
|
|||||||
// Turn off everything
|
// Turn off everything
|
||||||
GxRsSet(GxRs_PolygonOffset, 0);
|
GxRsSet(GxRs_PolygonOffset, 0);
|
||||||
GxRsSet(GxRs_NormalizeNormals, 0);
|
GxRsSet(GxRs_NormalizeNormals, 0);
|
||||||
GxRsSet(GxRs_BlendingMode, 1);
|
GxRsSet(GxRs_BlendingMode, GxBlend_AlphaKey);
|
||||||
GxRsSetAlphaRef();
|
GxRsSetAlphaRef();
|
||||||
GxRsSet(GxRs_Lighting, 0);
|
GxRsSet(GxRs_Lighting, 0);
|
||||||
GxRsSet(GxRs_Fog, 0);
|
GxRsSet(GxRs_Fog, 0);
|
||||||
@ -355,6 +355,9 @@ void CGxDevice::ICursorDraw() {
|
|||||||
float cursorDepth = 1.0f;
|
float cursorDepth = 1.0f;
|
||||||
|
|
||||||
C44Matrix projection;
|
C44Matrix projection;
|
||||||
|
// Workaround for software cursor
|
||||||
|
// C44Matrix projection(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0.002, 0, -1, -1, 0, 1);
|
||||||
|
// this->XformSetProjection(projection);
|
||||||
|
|
||||||
if (!this->StereoEnabled() ||
|
if (!this->StereoEnabled() ||
|
||||||
(CGxDevice::s_uiVertexShader == 0 || !s_uiVertexShader->Valid()) ||
|
(CGxDevice::s_uiVertexShader == 0 || !s_uiVertexShader->Valid()) ||
|
||||||
|
|||||||
@ -334,11 +334,17 @@ LRESULT CGxDeviceD3d::WindowProcD3d(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
|
|||||||
|
|
||||||
case WM_SETCURSOR: {
|
case WM_SETCURSOR: {
|
||||||
if (device) {
|
if (device) {
|
||||||
if (device->m_d3dDevice && lParam == 1) {
|
if (device->m_d3dDevice && LOWORD(lParam) == HTCLIENT) {
|
||||||
SetCursor(nullptr);
|
SetCursor(nullptr);
|
||||||
BOOL show = device->m_cursorVisible && device->m_hardwareCursor ? TRUE : FALSE;
|
BOOL show = device->m_cursorVisible && device->m_hardwareCursor ? TRUE : FALSE;
|
||||||
device->m_d3dDevice->ShowCursor(show);
|
device->m_d3dDevice->ShowCursor(show);
|
||||||
|
} else {
|
||||||
|
// Uncomment when the "glove" cursor will be fixed
|
||||||
|
//break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Uncomment when the "glove" cursor will be fixed
|
||||||
|
//break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -488,8 +494,7 @@ int32_t CGxDeviceD3d::DeviceSetFormat(const CGxFormat& format) {
|
|||||||
|
|
||||||
if (this->ICreateWindow(createFormat) && this->ICreateD3dDevice(createFormat) && this->CGxDevice::DeviceSetFormat(format)) {
|
if (this->ICreateWindow(createFormat) && this->ICreateD3dDevice(createFormat) && this->CGxDevice::DeviceSetFormat(format)) {
|
||||||
this->intF64 = 1;
|
this->intF64 = 1;
|
||||||
|
this->m_hwCursorNeedsUpdate = 1;
|
||||||
// TODO
|
|
||||||
|
|
||||||
if (this->m_format.window == 0) {
|
if (this->m_format.window == 0) {
|
||||||
RECT windowRect;
|
RECT windowRect;
|
||||||
@ -1102,6 +1107,17 @@ void CGxDeviceD3d::IRsSendToHw(EGxRenderState which) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GxRs_Lighting: {
|
||||||
|
int32_t lightingEnable = 0;
|
||||||
|
|
||||||
|
if (this->MasterEnable(GxMasterEnable_Lighting)) {
|
||||||
|
lightingEnable = static_cast<int32_t>(state->m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_d3dDevice->SetRenderState(D3DRS_LIGHTING, lightingEnable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GxRs_DepthTest:
|
case GxRs_DepthTest:
|
||||||
case GxRs_DepthFunc: {
|
case GxRs_DepthFunc: {
|
||||||
auto depthTest = static_cast<uint32_t>((&this->m_appRenderStates[GxRs_DepthTest])->m_value);
|
auto depthTest = static_cast<uint32_t>((&this->m_appRenderStates[GxRs_DepthTest])->m_value);
|
||||||
@ -1249,6 +1265,11 @@ void CGxDeviceD3d::CursorSetVisible(int32_t visible) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGxDeviceD3d::CursorUnlock(uint32_t x, uint32_t y) {
|
||||||
|
CGxDevice::CursorUnlock(x, y);
|
||||||
|
this->m_hwCursorNeedsUpdate = 1;
|
||||||
|
}
|
||||||
|
|
||||||
void CGxDeviceD3d::ICursorDraw() {
|
void CGxDeviceD3d::ICursorDraw() {
|
||||||
if (!this->m_hardwareCursor) {
|
if (!this->m_hardwareCursor) {
|
||||||
this->ISceneBegin();
|
this->ISceneBegin();
|
||||||
|
|||||||
@ -252,6 +252,7 @@ class CGxDeviceD3d : public CGxDevice {
|
|||||||
virtual void ICursorDestroy();
|
virtual void ICursorDestroy();
|
||||||
virtual void ICursorDraw();
|
virtual void ICursorDraw();
|
||||||
virtual void CursorSetVisible(int32_t visible);
|
virtual void CursorSetVisible(int32_t visible);
|
||||||
|
virtual void CursorUnlock(uint32_t x, uint32_t y);
|
||||||
virtual int32_t DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat& format);
|
virtual int32_t DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat& format);
|
||||||
virtual int32_t DeviceSetFormat(const CGxFormat& format);
|
virtual int32_t DeviceSetFormat(const CGxFormat& format);
|
||||||
virtual void* DeviceWindow();
|
virtual void* DeviceWindow();
|
||||||
|
|||||||
@ -1578,7 +1578,7 @@ GLTexture* GLSDLDevice::CreateTextureCubeMap(uint32_t size, uint32_t numMipMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GLSDLDevice::Draw(GLEnum primitive, uint32_t a3, uint32_t a4) {
|
void GLSDLDevice::Draw(GLEnum primitive, uint32_t a3, uint32_t a4) {
|
||||||
// TODO
|
this->GLSDLDraw(primitive, a3, a3 + a4, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLSDLDevice::DrawIndexed(GLEnum primitive, uint32_t a3, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t count) {
|
void GLSDLDevice::DrawIndexed(GLEnum primitive, uint32_t a3, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t count) {
|
||||||
|
|||||||
@ -110,7 +110,7 @@ int32_t RealmConnection::HandleAuthChallenge(AuthenticationChallenge* challenge)
|
|||||||
// TODO switch to WDataStore
|
// TODO switch to WDataStore
|
||||||
CDataStore msg;
|
CDataStore msg;
|
||||||
|
|
||||||
uint32_t localChallenge;
|
uint32_t localChallenge = 0;
|
||||||
|
|
||||||
msg.Put(static_cast<uint32_t>(CMSG_AUTH_SESSION));
|
msg.Put(static_cast<uint32_t>(CMSG_AUTH_SESSION));
|
||||||
|
|
||||||
|
|||||||
@ -152,6 +152,13 @@ void CBackdropGenerator::LoadXML(XMLNode* node, CStatus* status) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBackdropGenerator::SetVertexColor(const CImVector& color) {
|
||||||
|
this->m_color = color;
|
||||||
|
if (this->m_backgroundTexture) {
|
||||||
|
this->m_backgroundTexture->SetVertexColor(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CBackdropGenerator::SetBorderVertexColor(const CImVector& borderColor) {
|
void CBackdropGenerator::SetBorderVertexColor(const CImVector& borderColor) {
|
||||||
this->m_borderColor = borderColor;
|
this->m_borderColor = borderColor;
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,7 @@ class CBackdropGenerator {
|
|||||||
CBackdropGenerator();
|
CBackdropGenerator();
|
||||||
void Generate(const CRect* rect);
|
void Generate(const CRect* rect);
|
||||||
void LoadXML(XMLNode* node, CStatus* status);
|
void LoadXML(XMLNode* node, CStatus* status);
|
||||||
|
void SetVertexColor(const CImVector& color);
|
||||||
void SetBorderVertexColor(const CImVector& borderColor);
|
void SetBorderVertexColor(const CImVector& borderColor);
|
||||||
void SetOutput(CSimpleFrame* frame);
|
void SetOutput(CSimpleFrame* frame);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -871,6 +871,11 @@ int32_t CSimpleEditBox::OnLayerKeyDown(const CKeyEvent& evt) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case KEY_TAB: {
|
||||||
|
// TODO correct implementation
|
||||||
|
this->RunOnTabPressedScript();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// - remaining keys
|
// - remaining keys
|
||||||
|
|
||||||
@ -994,6 +999,12 @@ void CSimpleEditBox::RunOnEnterPressedScript() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSimpleEditBox::RunOnTabPressedScript() {
|
||||||
|
if (this->m_onTabPressed.luaRef) {
|
||||||
|
this->RunScript(this->m_onTabPressed, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSimpleEditBox::RunOnTextChangedScript(int32_t changed) {
|
void CSimpleEditBox::RunOnTextChangedScript(int32_t changed) {
|
||||||
if (this->m_onTextChanged.luaRef) {
|
if (this->m_onTextChanged.luaRef) {
|
||||||
auto L = FrameScript_GetContext();
|
auto L = FrameScript_GetContext();
|
||||||
|
|||||||
@ -98,6 +98,7 @@ class CSimpleEditBox : public CSimpleFrame, CSimpleFontedFrame {
|
|||||||
void RunOnEditFocusGainedScript();
|
void RunOnEditFocusGainedScript();
|
||||||
void RunOnEditFocusLostScript();
|
void RunOnEditFocusLostScript();
|
||||||
void RunOnEnterPressedScript();
|
void RunOnEnterPressedScript();
|
||||||
|
void RunOnTabPressedScript();
|
||||||
void RunOnTextChangedScript(int32_t changed);
|
void RunOnTextChangedScript(int32_t changed);
|
||||||
void SetCursorPosition(int32_t position);
|
void SetCursorPosition(int32_t position);
|
||||||
void SetHistoryLines(int32_t a2);
|
void SetHistoryLines(int32_t a2);
|
||||||
|
|||||||
@ -176,11 +176,34 @@ int32_t CSimpleEditBox_GetTextInsets(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleEditBox_SetFocus(lua_State* L) {
|
int32_t CSimpleEditBox_SetFocus(lua_State* L) {
|
||||||
WHOA_UNIMPLEMENTED(0);
|
if (lua_type(L, 1) != LUA_TTABLE) {
|
||||||
|
luaL_error(L, "Attempt to find 'this' in non-table object (used '.' instead of ':' ?)");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawgeti(L, 1, 0);
|
||||||
|
auto object = reinterpret_cast<CSimpleEditBox*>(lua_touserdata(L, -1));
|
||||||
|
lua_settop(L, -2);
|
||||||
|
|
||||||
|
STORM_ASSERT(object);
|
||||||
|
|
||||||
|
CSimpleEditBox::SetKeyboardFocus(object);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleEditBox_ClearFocus(lua_State* L) {
|
int32_t CSimpleEditBox_ClearFocus(lua_State* L) {
|
||||||
WHOA_UNIMPLEMENTED(0);
|
if (lua_type(L, 1) != LUA_TTABLE) {
|
||||||
|
luaL_error(L, "Attempt to find 'this' in non-table object (used '.' instead of ':' ?)");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawgeti(L, 1, 0);
|
||||||
|
auto object = reinterpret_cast<CSimpleEditBox*>(lua_touserdata(L, -1));
|
||||||
|
lua_settop(L, -2);
|
||||||
|
|
||||||
|
STORM_ASSERT(object);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// CSimpleEditBox::ClearKeyboardFocus(object);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleEditBox_HasFocus(lua_State* L) {
|
int32_t CSimpleEditBox_HasFocus(lua_State* L) {
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
#include "util/Lua.hpp"
|
#include "util/Lua.hpp"
|
||||||
#include "util/Unimplemented.hpp"
|
#include "util/Unimplemented.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
|
||||||
int32_t CSimpleFontString_IsObjectType(lua_State* L) {
|
int32_t CSimpleFontString_IsObjectType(lua_State* L) {
|
||||||
WHOA_UNIMPLEMENTED(0);
|
WHOA_UNIMPLEMENTED(0);
|
||||||
@ -132,7 +134,24 @@ int32_t CSimpleFontString_SetText(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleFontString_SetFormattedText(lua_State* L) {
|
int32_t CSimpleFontString_SetFormattedText(lua_State* L) {
|
||||||
WHOA_UNIMPLEMENTED(0);
|
if (lua_type(L, 1) != LUA_TTABLE) {
|
||||||
|
luaL_error(L, "Attempt to find 'this' in non-table object (used '.' instead of ':' ?)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto type = CSimpleFontString::GetObjectType();
|
||||||
|
auto string = static_cast<CSimpleFontString*>(FrameScript_GetObjectThis(L, type));
|
||||||
|
|
||||||
|
if (!string->m_font) {
|
||||||
|
luaL_error(L, "%s:SetText(): Font not set", string->GetDisplayName());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char text[2048] = {};
|
||||||
|
FrameScript_Sprintf(L, 2, text, sizeof(text));
|
||||||
|
string->SetText(text, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleFontString_GetTextColor(lua_State* L) {
|
int32_t CSimpleFontString_GetTextColor(lua_State* L) {
|
||||||
|
|||||||
@ -1327,7 +1327,19 @@ void CSimpleFrame::SetBeingScrolled(int32_t a2, int32_t a3) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CSimpleFrame::SetFrameAlpha(uint8_t alpha) {
|
void CSimpleFrame::SetFrameAlpha(uint8_t alpha) {
|
||||||
// TODO
|
if (this->m_alpha == alpha) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_alpha = alpha;
|
||||||
|
|
||||||
|
for (auto region = this->m_regions.Head(); region; region = this->m_regions.Link(region)->Next()) {
|
||||||
|
region->OnColorChanged(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto child = this->m_children.Head(); child; child = this->m_children.Link(child)->Next()) {
|
||||||
|
child->frame->SetFrameAlpha(alpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimpleFrame::SetFrameFlag(int32_t flag, int32_t on) {
|
void CSimpleFrame::SetFrameFlag(int32_t flag, int32_t on) {
|
||||||
|
|||||||
@ -37,6 +37,7 @@ class CSimpleFrame : public CScriptRegion {
|
|||||||
float m_depth = 0.0;
|
float m_depth = 0.0;
|
||||||
FRAME_STRATA m_strata = FRAME_STRATA_MEDIUM;
|
FRAME_STRATA m_strata = FRAME_STRATA_MEDIUM;
|
||||||
int32_t m_level = 0;
|
int32_t m_level = 0;
|
||||||
|
uint8_t m_alpha = 255;
|
||||||
uint32_t m_eventmask = 0;
|
uint32_t m_eventmask = 0;
|
||||||
int32_t m_shown = 0;
|
int32_t m_shown = 0;
|
||||||
int32_t m_visible = 0;
|
int32_t m_visible = 0;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include "gx/Coordinate.hpp"
|
#include "gx/Coordinate.hpp"
|
||||||
#include "ui/CSimpleFrame.hpp"
|
#include "ui/CSimpleFrame.hpp"
|
||||||
#include "ui/FrameScript.hpp"
|
#include "ui/FrameScript.hpp"
|
||||||
|
#include "ui/CBackdropGenerator.hpp"
|
||||||
#include "util/Lua.hpp"
|
#include "util/Lua.hpp"
|
||||||
#include "util/Unimplemented.hpp"
|
#include "util/Unimplemented.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -460,7 +461,28 @@ int32_t CSimpleFrame_GetBackdropColor(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleFrame_SetBackdropColor(lua_State* L) {
|
int32_t CSimpleFrame_SetBackdropColor(lua_State* L) {
|
||||||
WHOA_UNIMPLEMENTED(0);
|
if (lua_type(L, 1) != LUA_TTABLE) {
|
||||||
|
luaL_error(L, "Attempt to find 'this' in non-table object (used '.' instead of ':' ?)");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawgeti(L, 1, 0);
|
||||||
|
auto object = reinterpret_cast<CSimpleFrame*>(lua_touserdata(L, -1));
|
||||||
|
lua_settop(L, -2);
|
||||||
|
|
||||||
|
STORM_ASSERT(object);
|
||||||
|
|
||||||
|
CImVector color;
|
||||||
|
auto red = lua_tonumber(L, 2);
|
||||||
|
auto green = lua_tonumber(L, 3);
|
||||||
|
auto blue = lua_tonumber(L, 4);
|
||||||
|
auto alpha = lua_isnumber(L, 5) ? lua_tonumber(L, 5) : 1.0;
|
||||||
|
color.Set(alpha, red, green, blue);
|
||||||
|
|
||||||
|
if (object->m_backdrop) {
|
||||||
|
object->m_backdrop->SetVertexColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleFrame_GetBackdropBorderColor(lua_State* L) {
|
int32_t CSimpleFrame_GetBackdropBorderColor(lua_State* L) {
|
||||||
@ -468,7 +490,28 @@ int32_t CSimpleFrame_GetBackdropBorderColor(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleFrame_SetBackdropBorderColor(lua_State* L) {
|
int32_t CSimpleFrame_SetBackdropBorderColor(lua_State* L) {
|
||||||
WHOA_UNIMPLEMENTED(0);
|
if (lua_type(L, 1) != LUA_TTABLE) {
|
||||||
|
luaL_error(L, "Attempt to find 'this' in non-table object (used '.' instead of ':' ?)");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawgeti(L, 1, 0);
|
||||||
|
auto object = reinterpret_cast<CSimpleFrame*>(lua_touserdata(L, -1));
|
||||||
|
lua_settop(L, -2);
|
||||||
|
|
||||||
|
STORM_ASSERT(object);
|
||||||
|
|
||||||
|
CImVector color;
|
||||||
|
auto red = lua_tonumber(L, 2);
|
||||||
|
auto green = lua_tonumber(L, 3);
|
||||||
|
auto blue = lua_tonumber(L, 4);
|
||||||
|
auto alpha = lua_isnumber(L, 5) ? lua_tonumber(L, 5) : 1.0;
|
||||||
|
color.Set(alpha, red, green, blue);
|
||||||
|
|
||||||
|
if (object->m_backdrop) {
|
||||||
|
object->m_backdrop->SetBorderVertexColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CSimpleFrame_SetDepth(lua_State* L) {
|
int32_t CSimpleFrame_SetDepth(lua_State* L) {
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include <storm/Array.hpp>
|
#include <storm/Array.hpp>
|
||||||
#include <storm/String.hpp>
|
#include <storm/String.hpp>
|
||||||
#include <tempest/Vector.hpp>
|
#include <tempest/Vector.hpp>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
const char* g_glueScriptEvents[41];
|
const char* g_glueScriptEvents[41];
|
||||||
const char* g_scriptEvents[722];
|
const char* g_scriptEvents[722];
|
||||||
@ -867,6 +868,216 @@ void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void addchar(char* buffer, size_t bufferSize, char ch) {
|
||||||
|
auto length = SStrLen(buffer);
|
||||||
|
if (length + 1 < bufferSize)
|
||||||
|
{
|
||||||
|
buffer[length++] = ch;
|
||||||
|
buffer[length] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addstring(char* buffer, size_t bufferSize, const char* source) {
|
||||||
|
uint32_t dsize = 0;
|
||||||
|
uint32_t size = 0;
|
||||||
|
|
||||||
|
dsize = SStrLen(buffer);
|
||||||
|
size = SStrLen(source);
|
||||||
|
|
||||||
|
if (dsize + size >= bufferSize) {
|
||||||
|
size = bufferSize - dsize;
|
||||||
|
// Check for space for trailing zero
|
||||||
|
if (size < 2) {
|
||||||
|
size = 0;
|
||||||
|
} else {
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size > 0)
|
||||||
|
memmove(&buffer[dsize], source, size);
|
||||||
|
|
||||||
|
buffer[dsize + size] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addstring(char* buffer, size_t bufferSize, const char* source, size_t count) {
|
||||||
|
uint32_t dsize = 0;
|
||||||
|
uint32_t size = 0;
|
||||||
|
|
||||||
|
dsize = SStrLen(buffer);
|
||||||
|
size = std::min(SStrLen(source), count);
|
||||||
|
|
||||||
|
if (dsize + size >= bufferSize) {
|
||||||
|
size = bufferSize - dsize;
|
||||||
|
// Check for space for trailing zero
|
||||||
|
if (size < 2) {
|
||||||
|
size = 0;
|
||||||
|
} else {
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size > 0)
|
||||||
|
memmove(&buffer[dsize], source, size);
|
||||||
|
|
||||||
|
buffer[dsize + size] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addquoted(lua_State* L, char* buffer, size_t bufferSize, int arg) {
|
||||||
|
size_t l;
|
||||||
|
const char* s = luaL_checklstring(L, arg, &l);
|
||||||
|
addchar(buffer, bufferSize, '"');
|
||||||
|
while (l--) {
|
||||||
|
switch (*s) {
|
||||||
|
case '"':
|
||||||
|
case '\\':
|
||||||
|
case '\n': {
|
||||||
|
addchar(buffer, bufferSize, '\\');
|
||||||
|
addchar(buffer, bufferSize, *s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\r': {
|
||||||
|
addstring(buffer, bufferSize, "\\r");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\0': {
|
||||||
|
addstring(buffer, bufferSize, "\\000");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
addchar(buffer, bufferSize, *s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
addchar(buffer, bufferSize, '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMAT_FLAGS "-+ #0"
|
||||||
|
|
||||||
|
static const char* scanformat(lua_State* L, const char* strfrmt, char* form) {
|
||||||
|
const char* flags = "-+ #0";
|
||||||
|
const char* p = strfrmt;
|
||||||
|
|
||||||
|
while (*p != '\0' && SStrChrR(FORMAT_FLAGS, *p) != NULL) {
|
||||||
|
p++; /* skip flags */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size_t)(p - strfrmt) >= sizeof(FORMAT_FLAGS)) {
|
||||||
|
luaL_error(L, "invalid format (repeated flags)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isdigit((unsigned char)(*p))) {
|
||||||
|
p++; /* skip width */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isdigit((unsigned char)(*p))) {
|
||||||
|
p++; /* (2 digits at most) */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '.') {
|
||||||
|
p++;
|
||||||
|
if (isdigit((unsigned char)(*p))) {
|
||||||
|
p++; /* skip precision */
|
||||||
|
}
|
||||||
|
if (isdigit((unsigned char)(*p))) {
|
||||||
|
p++; /* (2 digits at most) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isdigit((unsigned char)(*p))) {
|
||||||
|
luaL_error(L, "invalid format (width or precision too long)");
|
||||||
|
}
|
||||||
|
|
||||||
|
*(form++) = '%';
|
||||||
|
strncpy(form, strfrmt, p - strfrmt + 1);
|
||||||
|
form += p - strfrmt + 1;
|
||||||
|
*form = '\0';
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addintlen(char* form) {
|
||||||
|
size_t l = SStrLen(form);
|
||||||
|
char spec = form[l - 1];
|
||||||
|
strcpy(form + l - 1, LUA_INTFRMLEN);
|
||||||
|
form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
|
||||||
|
form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameScript_Sprintf(lua_State* L, int startIndex, char* buffer, uint32_t bufferSize) {
|
||||||
|
// maximum size of each formatted item (> len(format('%99.99f', -1e308)))
|
||||||
|
const size_t MAX_ITEM = 512;
|
||||||
|
|
||||||
|
// maximum size of each format specification (such as '%-099.99d')
|
||||||
|
// (+10 accounts for %99.99x plus margin of error)
|
||||||
|
const size_t MAX_FORMAT = sizeof(FORMAT_FLAGS) + sizeof(LUA_INTFRMLEN) + 10;
|
||||||
|
|
||||||
|
int arg = startIndex;
|
||||||
|
size_t sfl;
|
||||||
|
const char* strfrmt = luaL_checklstring(L, arg, &sfl);
|
||||||
|
const char* strfrmt_end = strfrmt + sfl;
|
||||||
|
while (strfrmt < strfrmt_end) {
|
||||||
|
if (*strfrmt != '%') {
|
||||||
|
addchar(buffer, bufferSize, *strfrmt++);
|
||||||
|
} else if (*++strfrmt == '%') {
|
||||||
|
addchar(buffer, bufferSize, *strfrmt++); /* %% */
|
||||||
|
} else { /* format item */
|
||||||
|
char form[MAX_FORMAT]; /* to store the format (`%...') */
|
||||||
|
char buff[MAX_ITEM]; /* to store the formatted item */
|
||||||
|
arg++;
|
||||||
|
strfrmt = scanformat(L, strfrmt, form);
|
||||||
|
switch (*strfrmt++) {
|
||||||
|
case 'c': {
|
||||||
|
sprintf(buff, form, (int)luaL_checknumber(L, arg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'd':
|
||||||
|
case 'i': {
|
||||||
|
addintlen(form);
|
||||||
|
sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'o':
|
||||||
|
case 'u':
|
||||||
|
case 'x':
|
||||||
|
case 'X': {
|
||||||
|
addintlen(form);
|
||||||
|
sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'f':
|
||||||
|
case 'g':
|
||||||
|
case 'G': {
|
||||||
|
sprintf(buff, form, (double)luaL_checknumber(L, arg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'q': {
|
||||||
|
addquoted(L, buffer, bufferSize, arg);
|
||||||
|
continue; /* skip the 'addsize' at the end */
|
||||||
|
}
|
||||||
|
case 's': {
|
||||||
|
size_t l;
|
||||||
|
const char* s = luaL_checklstring(L, arg, &l);
|
||||||
|
if (!strchr(form, '.') && l >= 100) {
|
||||||
|
/* no precision and string is too long to be formatted;
|
||||||
|
keep original string */
|
||||||
|
continue; /* skip the `addsize' at the end */
|
||||||
|
} else {
|
||||||
|
sprintf(buff, form, s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: { /* also treat cases `pnLlh' */
|
||||||
|
luaL_error(L, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"), *(strfrmt - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addstring(buffer, bufferSize, buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GlueScriptEventsInitialize() {
|
void GlueScriptEventsInitialize() {
|
||||||
g_glueScriptEvents[0] = "SET_GLUE_SCREEN";
|
g_glueScriptEvents[0] = "SET_GLUE_SCREEN";
|
||||||
g_glueScriptEvents[1] = "START_GLUE_MUSIC";
|
g_glueScriptEvents[1] = "START_GLUE_MUSIC";
|
||||||
|
|||||||
@ -100,6 +100,8 @@ void FrameScript_SignalEvent(uint32_t index, const char* format, ...);
|
|||||||
|
|
||||||
void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event);
|
void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event);
|
||||||
|
|
||||||
|
void FrameScript_Sprintf(lua_State* L, int startIndex, char* buffer, uint32_t bufferSize);
|
||||||
|
|
||||||
void GlueScriptEventsInitialize();
|
void GlueScriptEventsInitialize();
|
||||||
|
|
||||||
void ScriptEventsInitialize();
|
void ScriptEventsInitialize();
|
||||||
|
|||||||
@ -19,7 +19,15 @@ int32_t Script_IsShiftKeyDown(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t Script_GetBuildInfo(lua_State* L) {
|
int32_t Script_GetBuildInfo(lua_State* L) {
|
||||||
WHOA_UNIMPLEMENTED(0);
|
auto szVersion = FrameScript_GetText("VERSION", -1, GENDER_NOT_APPLICABLE);
|
||||||
|
auto szVersionType = FrameScript_GetText("RELEASE_BUILD", -1, GENDER_NOT_APPLICABLE);
|
||||||
|
|
||||||
|
lua_pushstring(L, szVersion);
|
||||||
|
lua_pushstring(L, szVersionType);
|
||||||
|
lua_pushstring(L, "3.3.5");
|
||||||
|
lua_pushstring(L, "12340");
|
||||||
|
lua_pushstring(L, "Jun 24 2010");
|
||||||
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Script_GetLocale(lua_State* L) {
|
int32_t Script_GetLocale(lua_State* L) {
|
||||||
@ -27,7 +35,9 @@ int32_t Script_GetLocale(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t Script_GetSavedAccountName(lua_State* L) {
|
int32_t Script_GetSavedAccountName(lua_State* L) {
|
||||||
WHOA_UNIMPLEMENTED(0);
|
// TODO
|
||||||
|
lua_pushstring(L, "");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Script_SetSavedAccountName(lua_State* L) {
|
int32_t Script_SetSavedAccountName(lua_State* L) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user