mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Merge branch 'gui_launcher' into indev
This commit is contained in:
commit
2f4f4ae838
@ -231,6 +231,33 @@ Format {fmt}
|
||||
// without including the above copyright and permission notices.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
VDF Parser
|
||||
************************************************************************************
|
||||
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Matthias Moeller 2016 m_moeller@live.de
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
Nlohmann JSON
|
||||
************************************************************************************
|
||||
|
@ -10,7 +10,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
#include "core/stdafx.h"
|
||||
#include "common/netmessages.h"
|
||||
#include "engine/sys_utils.h"
|
||||
|
||||
bool SVC_Print::Process()
|
||||
{
|
||||
|
@ -5,10 +5,12 @@
|
||||
#include <windows.h>
|
||||
#include <WinSock2.h>
|
||||
#include <comdef.h>
|
||||
#include <gdiplus.h>
|
||||
#include <shellapi.h>
|
||||
#include <Psapi.h>
|
||||
#include <setjmp.h>
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
#include <Psapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <objbase.h>
|
||||
#include <intrin.h>
|
||||
@ -34,6 +36,20 @@
|
||||
#include "thirdparty/detours/include/detours.h"
|
||||
#include "thirdparty/detours/include/idetour.h"
|
||||
|
||||
#if defined(SDKLAUNCHER)
|
||||
#include "thirdparty/cppnet/cppkore/Kore.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXTheme.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXLabel.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXListView.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXCheckBox.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXComboBox.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXTextBox.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXGroupBox.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXButton.h"
|
||||
#include "thirdparty/cppnet/cppkore/UIXRadioButton.h"
|
||||
#include "thirdparty/cppnet/cppkore/KoreTheme.h"
|
||||
#endif // SDKLAUNCHER
|
||||
|
||||
#if !defined(DEDICATED) && !defined(SDKLAUNCHER) && !defined (NETCONSOLE)
|
||||
#include "thirdparty/imgui/include/imgui.h"
|
||||
#include "thirdparty/imgui/include/imgui_stdlib.h"
|
||||
@ -65,11 +81,15 @@
|
||||
#include "public/include/memaddr.h"
|
||||
#include "public/include/module.h"
|
||||
#include "public/include/httplib.h"
|
||||
#include "public/include/vdf_parser.h"
|
||||
|
||||
#include "core/assert.h"
|
||||
#include "core/termutil.h"
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/platform.h"
|
||||
#if !defined(SDKLAUNCHER) && !defined (NETCONSOLE)
|
||||
#include "tier0/dbg.h"
|
||||
#endif // !SDKLAUNCHER && !NETCONSOLE
|
||||
|
||||
#if !defined(SDKLAUNCHER) && !defined (NETCONSOLE)
|
||||
#if !defined (DEDICATED)
|
||||
|
@ -7,3 +7,4 @@
|
||||
#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1)))
|
||||
#define IM_FMTARGS(FMT) __attribute__((format(gnu_printf, FMT, FMT+1)))
|
||||
#define IM_FMTARGS(FMT)
|
||||
#define PLATFORM_INTERFACE
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "datacache/mdlcache.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "datacache/idatacache.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
#include "public/include/studio.h"
|
||||
#include "tier1/utldict.h"
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "ebisusdk/EbisuSDK.h"
|
||||
#include "engine/sys_utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the EbisuSDK globals for dedicated to satisfy command callbacks
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "protoc/sv_rcon.pb.h"
|
||||
#include "protoc/cl_rcon.pb.h"
|
||||
#include "engine/client/cl_rcon.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "squirrel/sqvm.h"
|
||||
#include "common/igameserverdata.h"
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier0/jobthread.h"
|
||||
#include "engine/host_cmd.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
#include "rtech/rtech_game.h"
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "engine/host_cmd.h"
|
||||
#include "engine/host_state.h"
|
||||
#include "engine/sys_engine.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/modelloader.h"
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#ifndef CLIENT_DLL
|
||||
@ -252,31 +251,34 @@ FORCEINLINE void CHostState::Think(void) const
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE void CHostState::LoadConfig(void) const
|
||||
{
|
||||
if (!CommandLine()->CheckParm("-devsdk"))
|
||||
if (CommandLine()->ParmValue("-launcher", 0) < 1) // Launcher level 1 indicates everything is handled from the commandline/launcher.
|
||||
{
|
||||
if (!CommandLine()->CheckParm("-devsdk"))
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_server.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"rcon_server.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_server.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"rcon_server.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
#endif //!CLIENT_DLL
|
||||
#ifndef DEDICATED
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_client.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"rcon_client.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_client.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"rcon_client.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
#endif // !DEDICATED
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
}
|
||||
else // Development configs.
|
||||
{
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
}
|
||||
else // Development configs.
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_server_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"rcon_server_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_server_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"rcon_server_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
#endif //!CLIENT_DLL
|
||||
#ifndef DEDICATED
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_client_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"rcon_client_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_client_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"rcon_client_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
#endif // !DEDICATED
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec \"autoexec_dev.cfg\"", cmd_source_t::kCommandSrcCode);
|
||||
}
|
||||
Cbuf_Execute();
|
||||
}
|
||||
Cbuf_Execute();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#include "engine/modelloader.h"
|
||||
#include "datacache/mdlcache.h"
|
||||
#include "engine/sys_utils.h"
|
||||
|
||||
model_t* pErrorMDL = nullptr;
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "tier1/cvar.h"
|
||||
#include "vstdlib/callback.h"
|
||||
#include "mathlib/color.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/net.h"
|
||||
#include "engine/net_chan.h"
|
||||
#ifndef CLIENT_DLL
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/net.h"
|
||||
#include "engine/net_chan.h"
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "common/protocol.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/server/sv_main.h"
|
||||
#include "engine/server/server.h"
|
||||
#include "networksystem/r5net.h"
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/server/sv_main.h"
|
||||
#include "networksystem/r5net.h"
|
||||
#include "public/include/bansystem.h"
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "tier1/IConVar.h"
|
||||
#include "tier1/NetAdr2.h"
|
||||
#include "tier2/socketcreator.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/server/sv_rcon.h"
|
||||
#include "protoc/sv_rcon.pb.h"
|
||||
#include "protoc/cl_rcon.pb.h"
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/sys_dll.h"
|
||||
#include "engine/sys_utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sys_Error_Internal
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "tier1/cvar.h"
|
||||
#include "engine/sys_dll.h"
|
||||
#include "engine/sys_dll2.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "client/vengineclient_impl.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -89,268 +89,6 @@ void HCon_NPrintf(int pos, const char* fmt, ...)
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Show logs to all console interfaces
|
||||
// Input : idx -
|
||||
// *fmt - ... -
|
||||
//-----------------------------------------------------------------------------
|
||||
void DevMsg(eDLL_T idx, const char* fmt, ...)
|
||||
{
|
||||
static char szBuf[2048] = {};
|
||||
|
||||
static std::string svOut;
|
||||
static std::string svAnsiOut;
|
||||
|
||||
static std::regex rxAnsiExp("\\\033\\[.*?m");
|
||||
|
||||
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
|
||||
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
|
||||
static std::shared_ptr<spdlog::logger> sqlogger = spdlog::get("sdk_info");
|
||||
|
||||
s_LogMutex.lock();
|
||||
{/////////////////////////////
|
||||
va_list args{};
|
||||
va_start(args, fmt);
|
||||
|
||||
vsnprintf(szBuf, sizeof(szBuf), fmt, args);
|
||||
|
||||
szBuf[sizeof(szBuf) - 1] = 0;
|
||||
va_end(args);
|
||||
}/////////////////////////////
|
||||
|
||||
svOut = sDLL_T[static_cast<int>(idx)].c_str();
|
||||
svOut.append(szBuf);
|
||||
svOut = std::regex_replace(svOut, rxAnsiExp, "");
|
||||
|
||||
char szNewLine = svOut.back();
|
||||
if (szNewLine != '\n')
|
||||
{
|
||||
svOut.append("\n");
|
||||
}
|
||||
|
||||
if (!g_bSpdLog_UseAnsiClr)
|
||||
{
|
||||
wconsole->debug(svOut);
|
||||
#ifdef DEDICATED
|
||||
g_pRConServer->Send(svOut.c_str());
|
||||
#endif // DEDICATED
|
||||
}
|
||||
else
|
||||
{
|
||||
svAnsiOut = sANSI_DLL_T[static_cast<int>(idx)].c_str();
|
||||
svAnsiOut.append(szBuf);
|
||||
|
||||
char szNewLine = svAnsiOut.back();
|
||||
if (szNewLine != '\n')
|
||||
{
|
||||
svAnsiOut.append("\n");
|
||||
}
|
||||
wconsole->debug(svAnsiOut);
|
||||
#ifdef DEDICATED
|
||||
g_pRConServer->Send(svAnsiOut.c_str());
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
sqlogger->debug(svOut);
|
||||
|
||||
#ifndef DEDICATED
|
||||
iconsole->info(svOut);
|
||||
|
||||
int nLog = static_cast<int>(idx) + 3; // RUI log enum is shifted by 3 for scripts.
|
||||
LogType_t tLog = static_cast<LogType_t>(nLog);
|
||||
|
||||
ImVec4 color;
|
||||
switch (idx)
|
||||
{
|
||||
case eDLL_T::SERVER:
|
||||
color = ImVec4(0.23f, 0.47f, 0.85f, 1.00f);
|
||||
break;
|
||||
case eDLL_T::CLIENT:
|
||||
color = ImVec4(0.46f, 0.46f, 0.46f, 1.00f);
|
||||
break;
|
||||
case eDLL_T::UI:
|
||||
color = ImVec4(0.59f, 0.35f, 0.46f, 1.00f);
|
||||
break;
|
||||
case eDLL_T::ENGINE:
|
||||
color = ImVec4(0.70f, 0.70f, 0.70f, 1.00f);
|
||||
break;
|
||||
case eDLL_T::FS:
|
||||
color = ImVec4(0.32f, 0.64f, 0.72f, 1.00f);
|
||||
break;
|
||||
case eDLL_T::RTECH:
|
||||
color = ImVec4(0.36f, 0.70f, 0.35f, 1.00f);
|
||||
break;
|
||||
case eDLL_T::MS:
|
||||
color = ImVec4(0.75f, 0.41f, 0.67f, 1.00f);
|
||||
break;
|
||||
default:
|
||||
color = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
|
||||
break;
|
||||
}
|
||||
|
||||
g_pIConsole->m_ivConLog.push_back(CConLog(PrintPercentageEscape(g_spd_sys_w_oss.str()), color));
|
||||
g_pLogSystem.AddLog(tLog, g_spd_sys_w_oss.str());
|
||||
|
||||
g_spd_sys_w_oss.str("");
|
||||
g_spd_sys_w_oss.clear();
|
||||
#endif // !DEDICATED
|
||||
s_LogMutex.unlock();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Print engine and SDK errors
|
||||
// Input : idx -
|
||||
// *fmt - ... -
|
||||
//-----------------------------------------------------------------------------
|
||||
void Warning(eDLL_T idx, const char* fmt, ...)
|
||||
{
|
||||
static char szBuf[2048] = {};
|
||||
|
||||
static std::string svOut;
|
||||
static std::string svAnsiOut;
|
||||
|
||||
static std::regex rxAnsiExp("\\\033\\[.*?m");
|
||||
|
||||
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
|
||||
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
|
||||
static std::shared_ptr<spdlog::logger> sqlogger = spdlog::get("sdk_warn");
|
||||
|
||||
s_LogMutex.lock();
|
||||
{/////////////////////////////
|
||||
va_list args{};
|
||||
va_start(args, fmt);
|
||||
|
||||
vsnprintf(szBuf, sizeof(szBuf), fmt, args);
|
||||
|
||||
szBuf[sizeof(szBuf) - 1] = 0;
|
||||
va_end(args);
|
||||
}/////////////////////////////
|
||||
|
||||
svOut = sDLL_T[static_cast<int>(idx)].c_str();
|
||||
svOut.append(szBuf);
|
||||
svOut = std::regex_replace(svOut, rxAnsiExp, "");
|
||||
|
||||
char szNewLine = svOut.back();
|
||||
if (szNewLine != '\n')
|
||||
{
|
||||
svOut.append("\n");
|
||||
}
|
||||
|
||||
if (!g_bSpdLog_UseAnsiClr)
|
||||
{
|
||||
wconsole->debug(svOut);
|
||||
#ifdef DEDICATED
|
||||
g_pRConServer->Send(svOut.c_str());
|
||||
#endif // DEDICATED
|
||||
}
|
||||
else
|
||||
{
|
||||
svAnsiOut = sANSI_DLL_T[static_cast<int>(idx)].c_str();
|
||||
svAnsiOut.append(g_svYellowF.c_str());
|
||||
svAnsiOut.append(szBuf);
|
||||
|
||||
char szNewLine = svAnsiOut.back();
|
||||
if (szNewLine != '\n')
|
||||
{
|
||||
svAnsiOut.append("\n");
|
||||
}
|
||||
wconsole->debug(svAnsiOut);
|
||||
#ifdef DEDICATED
|
||||
g_pRConServer->Send(svAnsiOut.c_str());
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
sqlogger->debug(svOut);
|
||||
|
||||
#ifndef DEDICATED
|
||||
iconsole->info(svOut);
|
||||
|
||||
g_pIConsole->m_ivConLog.push_back(CConLog(PrintPercentageEscape(g_spd_sys_w_oss.str()), ImVec4(1.00f, 1.00f, 0.00f, 0.80f)));
|
||||
g_pLogSystem.AddLog(LogType_t::WARNING_C, g_spd_sys_w_oss.str());
|
||||
|
||||
g_spd_sys_w_oss.str("");
|
||||
g_spd_sys_w_oss.clear();
|
||||
#endif // !DEDICATED
|
||||
s_LogMutex.unlock();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Print engine and SDK errors
|
||||
// Input : idx -
|
||||
// *fmt - ... -
|
||||
//-----------------------------------------------------------------------------
|
||||
void Error(eDLL_T idx, const char* fmt, ...)
|
||||
{
|
||||
static char szBuf[2048] = {};
|
||||
|
||||
static std::string svOut;
|
||||
static std::string svAnsiOut;
|
||||
|
||||
static std::regex rxAnsiExp("\\\033\\[.*?m");
|
||||
|
||||
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
|
||||
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
|
||||
static std::shared_ptr<spdlog::logger> sqlogger = spdlog::get("sdk_error");
|
||||
|
||||
s_LogMutex.lock();
|
||||
{/////////////////////////////
|
||||
va_list args{};
|
||||
va_start(args, fmt);
|
||||
|
||||
vsnprintf(szBuf, sizeof(szBuf), fmt, args);
|
||||
|
||||
szBuf[sizeof(szBuf) - 1] = 0;
|
||||
va_end(args);
|
||||
}/////////////////////////////
|
||||
|
||||
svOut = sDLL_T[static_cast<int>(idx)].c_str();
|
||||
svOut.append(szBuf);
|
||||
svOut = std::regex_replace(svOut, rxAnsiExp, "");
|
||||
|
||||
char szNewLine = svOut.back();
|
||||
if (szNewLine != '\n')
|
||||
{
|
||||
svOut.append("\n");
|
||||
}
|
||||
|
||||
if (!g_bSpdLog_UseAnsiClr)
|
||||
{
|
||||
wconsole->debug(svOut);
|
||||
#ifdef DEDICATED
|
||||
g_pRConServer->Send(svOut.c_str());
|
||||
#endif // DEDICATED
|
||||
}
|
||||
else
|
||||
{
|
||||
svAnsiOut = sANSI_DLL_T[static_cast<int>(idx)].c_str();
|
||||
svAnsiOut.append(g_svRedF.c_str());
|
||||
svAnsiOut.append(szBuf);
|
||||
|
||||
char szNewLine = svAnsiOut.back();
|
||||
if (szNewLine != '\n')
|
||||
{
|
||||
svAnsiOut.append("\n");
|
||||
}
|
||||
wconsole->debug(svAnsiOut);
|
||||
#ifdef DEDICATED
|
||||
g_pRConServer->Send(svAnsiOut.c_str());
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
sqlogger->debug(svOut);
|
||||
|
||||
#ifndef DEDICATED
|
||||
iconsole->info(svOut);
|
||||
|
||||
g_pIConsole->m_ivConLog.push_back(CConLog(PrintPercentageEscape(g_spd_sys_w_oss.str()), ImVec4(1.00f, 0.00f, 0.00f, 1.00f)));
|
||||
g_pLogSystem.AddLog(LogType_t::ERROR_C, g_spd_sys_w_oss.str());
|
||||
|
||||
g_spd_sys_w_oss.str("");
|
||||
g_spd_sys_w_oss.clear();
|
||||
#endif // !DEDICATED
|
||||
s_LogMutex.unlock();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Load assets from a custom directory if file exists
|
||||
// Input : *lpFileName -
|
||||
|
@ -12,55 +12,10 @@ inline auto Sys_LoadAssetHelper = p_Sys_LoadAssetHelper.RCast<void* (*)(const CH
|
||||
|
||||
inline CMemory p_Con_NPrintf;
|
||||
inline auto Con_NPrintf = p_Con_NPrintf.RCast<void (*)(int pos, const char* fmt, ...)>();
|
||||
|
||||
inline std::mutex s_LogMutex;
|
||||
/* ==== ------- ========================================================================================================================================================= */
|
||||
|
||||
enum class eDLL_T : int
|
||||
{
|
||||
SERVER = 0, // Game DLL
|
||||
CLIENT = 1, // Game DLL
|
||||
UI = 2, // Game DLL
|
||||
ENGINE = 3, // Wrapper
|
||||
FS = 4, // File System
|
||||
RTECH = 5, // RTech API
|
||||
MS = 6, // Material System
|
||||
NETCON = 7, // Net Console
|
||||
NONE = 8
|
||||
};
|
||||
|
||||
const string sDLL_T[9] =
|
||||
{
|
||||
"Native(S):",
|
||||
"Native(C):",
|
||||
"Native(U):",
|
||||
"Native(E):",
|
||||
"Native(F):",
|
||||
"Native(R):",
|
||||
"Native(M):",
|
||||
"Netcon(X):",
|
||||
""
|
||||
};
|
||||
|
||||
const static string sANSI_DLL_T[9] =
|
||||
{
|
||||
"\033[38;2;059;120;218mNative(S):",
|
||||
"\033[38;2;118;118;118mNative(C):",
|
||||
"\033[38;2;151;090;118mNative(U):",
|
||||
"\033[38;2;204;204;204mNative(E):",
|
||||
"\033[38;2;097;214;214mNative(F):",
|
||||
"\033[38;2;092;181;089mNative(R):",
|
||||
"\033[38;2;192;105;173mNative(M):",
|
||||
"\033[38;2;204;204;204mNetcon(X):",
|
||||
""
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void HSys_Error(char* fmt, ...);
|
||||
void DevMsg(eDLL_T idx, const char* fmt, ...);
|
||||
void Warning(eDLL_T idx, const char* fmt, ...);
|
||||
void Error(eDLL_T idx, const char* fmt, ...);
|
||||
|
||||
void SysUtils_Attach();
|
||||
void SysUtils_Detach();
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
//=============================================================================//
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "game/server/ai_network.h"
|
||||
|
||||
int g_DebugConnectNode1 = -1;
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "public/include/edict.h"
|
||||
#include "public/include/utility.h"
|
||||
#include "engine/host_state.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "game/server/ai_node.h"
|
||||
#include "game/server/ai_network.h"
|
||||
#include "game/server/ai_networkmanager.h"
|
||||
@ -31,8 +30,8 @@ CAI_NetworkBuilder::BuildFile
|
||||
*/
|
||||
void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
|
||||
{
|
||||
string svMeshDir = "maps\\navmesh\\";
|
||||
string svGraphDir = "maps\\graphs\\";
|
||||
const string svMeshDir = "maps\\navmesh\\";
|
||||
const string svGraphDir = "maps\\graphs\\";
|
||||
|
||||
fs::path fsMeshPath(svMeshDir + g_pHostState->m_levelName + "_" + HULL_SIZE[3] + ".nm");
|
||||
fs::path fsGraphPath(svGraphDir + g_pHostState->m_levelName + ".ain");
|
||||
|
@ -21,7 +21,6 @@ History:
|
||||
#include "windows/console.h"
|
||||
#include "windows/resource.h"
|
||||
#include "engine/net.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/host_state.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "engine/server/server.h"
|
||||
|
@ -5,7 +5,6 @@
|
||||
//===========================================================================//
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "materialsystem/cmaterialsystem.h"
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
class Vector3;
|
||||
class QAngle;
|
||||
typedef float vec_t;
|
||||
typedef float vec3_t[3];
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* _vector.h
|
||||
|
@ -21,7 +21,7 @@
|
||||
void KeepAliveToPylon()
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
if (g_pHostState->m_bActiveGame && sv_pylonvisibility->GetBool()) // Check for active game.
|
||||
if (g_pHostState->m_bActiveGame && sv_pylonVisibility->GetBool()) // Check for active game.
|
||||
{
|
||||
std::string m_szHostToken = std::string();
|
||||
std::string m_szHostRequestMessage = std::string();
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "networksystem/r5net.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/net.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/client/client.h"
|
||||
#include "public/include/bansystem.h"
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "public/include/binstream.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -21,6 +21,7 @@ string ConvertToUnixPath(const string& svInput);
|
||||
string Base64Encode(const string& svInput);
|
||||
string Base64Decode(const string& svInput);
|
||||
|
||||
bool StringIsDigit(const string& svInput);
|
||||
bool CompareStringAlphabetically(const string& svA, const string& svB);
|
||||
bool CompareStringLexicographically(const string& svA, const string& svB);
|
||||
|
||||
|
712
r5dev/public/include/vdf_parser.h
Normal file
712
r5dev/public/include/vdf_parser.h
Normal file
@ -0,0 +1,712 @@
|
||||
//MIT License
|
||||
//
|
||||
//Copyright(c) 2016 Matthias Moeller
|
||||
//
|
||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//of this software and associated documentation files(the "Software"), to deal
|
||||
//in the Software without restriction, including without limitation the rights
|
||||
//to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
//copies of the Software, and to permit persons to whom the Software is
|
||||
//furnished to do so, subject to the following conditions :
|
||||
//
|
||||
//The above copyright notice and this permission notice shall be included in all
|
||||
//copies or substantial portions of the Software.
|
||||
//
|
||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
//SOFTWARE.
|
||||
|
||||
#ifndef __TYTI_STEAM_VDF_PARSER_H__
|
||||
#define __TYTI_STEAM_VDF_PARSER_H__
|
||||
#pragma warning( disable : 4996 )
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
|
||||
#include <system_error>
|
||||
#include <exception>
|
||||
|
||||
//for wstring support
|
||||
#include <locale>
|
||||
#include <string>
|
||||
|
||||
// internal
|
||||
#include <stack>
|
||||
|
||||
//VS < 2015 has only partial C++11 support
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#ifndef CONSTEXPR
|
||||
#define CONSTEXPR
|
||||
#endif
|
||||
|
||||
#ifndef NOEXCEPT
|
||||
#define NOEXCEPT
|
||||
#endif
|
||||
#else
|
||||
#ifndef CONSTEXPR
|
||||
#define CONSTEXPR constexpr
|
||||
#define TYTI_UNDEF_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#ifndef NOEXCEPT
|
||||
#define NOEXCEPT noexcept
|
||||
#define TYTI_UNDEF_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#endif
|
||||
namespace vdf
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Helper functions selecting the right encoding (char/wchar_T)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
struct literal_macro_help
|
||||
{
|
||||
static CONSTEXPR const char* result(const char* c, const wchar_t*) NOEXCEPT
|
||||
{
|
||||
return c;
|
||||
}
|
||||
static CONSTEXPR const char result(const char c, const wchar_t) NOEXCEPT
|
||||
{
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct literal_macro_help<wchar_t>
|
||||
{
|
||||
static CONSTEXPR const wchar_t* result(const char*, const wchar_t* wc) NOEXCEPT
|
||||
{
|
||||
return wc;
|
||||
}
|
||||
static CONSTEXPR const wchar_t result(const char, const wchar_t wc) NOEXCEPT
|
||||
{
|
||||
return wc;
|
||||
}
|
||||
};
|
||||
#define TYTI_L(type, text) vdf::detail::literal_macro_help<type>::result(text, L##text)
|
||||
|
||||
inline std::string string_converter(const std::string& w) NOEXCEPT
|
||||
{
|
||||
return w;
|
||||
}
|
||||
|
||||
// utility wrapper to adapt locale-bound facets for wstring/wbuffer convert
|
||||
// from cppreference
|
||||
template <class Facet>
|
||||
struct deletable_facet : Facet
|
||||
{
|
||||
template <class... Args>
|
||||
deletable_facet(Args &&... args) : Facet(std::forward<Args>(args)...) {}
|
||||
~deletable_facet() {}
|
||||
};
|
||||
|
||||
inline std::string string_converter(const std::wstring& w) //todo: use us-locale
|
||||
{
|
||||
std::wstring_convert<deletable_facet<std::codecvt<wchar_t, char, std::mbstate_t>>> conv1;
|
||||
return conv1.to_bytes(w);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Writer helper functions
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename charT>
|
||||
class tabs
|
||||
{
|
||||
const size_t t;
|
||||
|
||||
public:
|
||||
explicit CONSTEXPR tabs(size_t i) NOEXCEPT : t(i) {}
|
||||
std::basic_string<charT> print() const { return std::basic_string<charT>(t, TYTI_L(charT, '\t')); }
|
||||
inline CONSTEXPR tabs operator+(size_t i) const NOEXCEPT
|
||||
{
|
||||
return tabs(t + i);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename oStreamT>
|
||||
oStreamT& operator<<(oStreamT& s, const tabs<typename oStreamT::char_type> t)
|
||||
{
|
||||
s << t.print();
|
||||
return s;
|
||||
}
|
||||
} // end namespace detail
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Interface
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// custom objects and their corresponding write functions
|
||||
|
||||
/// basic object node. Every object has a name and can contains attributes saved as key_value pairs or childrens
|
||||
template <typename CharT>
|
||||
struct basic_object
|
||||
{
|
||||
typedef CharT char_type;
|
||||
std::basic_string<char_type> name;
|
||||
std::unordered_map<std::basic_string<char_type>, std::basic_string<char_type>> attribs;
|
||||
std::unordered_map<std::basic_string<char_type>, std::shared_ptr<basic_object<char_type>>> childs;
|
||||
|
||||
void add_attribute(std::basic_string<char_type> key, std::basic_string<char_type> value)
|
||||
{
|
||||
attribs.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
void add_child(std::unique_ptr<basic_object<char_type>> child)
|
||||
{
|
||||
std::shared_ptr<basic_object<char_type>> obj{ child.release() };
|
||||
childs.emplace(obj->name, obj);
|
||||
}
|
||||
void set_name(std::basic_string<char_type> n)
|
||||
{
|
||||
name = std::move(n);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
struct basic_multikey_object
|
||||
{
|
||||
typedef CharT char_type;
|
||||
std::basic_string<char_type> name;
|
||||
std::unordered_multimap<std::basic_string<char_type>, std::basic_string<char_type>> attribs;
|
||||
std::unordered_multimap<std::basic_string<char_type>, std::shared_ptr<basic_multikey_object<char_type>>> childs;
|
||||
|
||||
void add_attribute(std::basic_string<char_type> key, std::basic_string<char_type> value)
|
||||
{
|
||||
attribs.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
void add_child(std::unique_ptr<basic_multikey_object<char_type>> child)
|
||||
{
|
||||
std::shared_ptr<basic_multikey_object<char_type>> obj{ child.release() };
|
||||
childs.emplace(obj->name, obj);
|
||||
}
|
||||
void set_name(std::basic_string<char_type> n)
|
||||
{
|
||||
name = std::move(n);
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_object<char> object;
|
||||
typedef basic_object<wchar_t> wobject;
|
||||
typedef basic_multikey_object<char> multikey_object;
|
||||
typedef basic_multikey_object<wchar_t> wmultikey_object;
|
||||
|
||||
struct Options
|
||||
{
|
||||
bool strip_escape_symbols;
|
||||
bool ignore_all_platform_conditionals;
|
||||
bool ignore_includes;
|
||||
|
||||
Options() : strip_escape_symbols(true), ignore_all_platform_conditionals(false), ignore_includes(false) {}
|
||||
};
|
||||
|
||||
//forward decls
|
||||
//forward decl
|
||||
template <typename OutputT, typename iStreamT>
|
||||
OutputT read(iStreamT& inStream, const Options& opt = Options{});
|
||||
|
||||
/** \brief writes given object tree in vdf format to given stream.
|
||||
Output is prettyfied, using tabs
|
||||
*/
|
||||
template <typename oStreamT, typename T>
|
||||
void write(oStreamT& s, const T& r,
|
||||
const detail::tabs<typename oStreamT::char_type> tab = detail::tabs<typename oStreamT::char_type>(0))
|
||||
{
|
||||
typedef typename oStreamT::char_type charT;
|
||||
using namespace detail;
|
||||
s << tab << TYTI_L(charT, '"') << r.name << TYTI_L(charT, "\"\n") << tab << TYTI_L(charT, "{\n");
|
||||
for (const auto& i : r.attribs)
|
||||
s << tab + 1 << TYTI_L(charT, '"') << i.first << TYTI_L(charT, "\"\t\t\"") << i.second << TYTI_L(charT, "\"\n");
|
||||
for (const auto& i : r.childs)
|
||||
if (i.second)
|
||||
write(s, *i.second, tab + 1);
|
||||
s << tab << TYTI_L(charT, "}\n");
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename iStreamT>
|
||||
std::basic_string<typename iStreamT::char_type> read_file(iStreamT& inStream)
|
||||
{
|
||||
// cache the file
|
||||
typedef typename iStreamT::char_type charT;
|
||||
std::basic_string<charT> str;
|
||||
inStream.seekg(0, std::ios::end);
|
||||
str.resize(static_cast<size_t>(inStream.tellg()));
|
||||
if (str.empty())
|
||||
return str;
|
||||
|
||||
inStream.seekg(0, std::ios::beg);
|
||||
inStream.read(&str[0], str.size());
|
||||
return str;
|
||||
}
|
||||
|
||||
/** \brief Read VDF formatted sequences defined by the range [first, last).
|
||||
If the file is mailformatted, parser will try to read it until it can.
|
||||
@param first begin iterator
|
||||
@param end end iterator
|
||||
@param exclude_files list of files which cant be included anymore.
|
||||
prevents circular includes
|
||||
|
||||
can thow:
|
||||
- "std::runtime_error" if a parsing error occured
|
||||
- "std::bad_alloc" if not enough memory coup be allocated
|
||||
*/
|
||||
template <typename OutputT, typename IterT>
|
||||
std::vector<std::unique_ptr<OutputT>> read_internal(IterT first, const IterT last,
|
||||
std::unordered_set<std::basic_string<typename std::iterator_traits<IterT>::value_type>>& exclude_files,
|
||||
const Options& opt)
|
||||
{
|
||||
static_assert(std::is_default_constructible<OutputT>::value,
|
||||
"Output Type must be default constructible (provide constructor without arguments)");
|
||||
static_assert(std::is_move_constructible<OutputT>::value,
|
||||
"Output Type must be move constructible");
|
||||
|
||||
typedef typename std::iterator_traits<IterT>::value_type charT;
|
||||
|
||||
const std::basic_string<charT> comment_end_str = TYTI_L(charT, "*/");
|
||||
const std::basic_string<charT> whitespaces = TYTI_L(charT, " \n\v\f\r\t");
|
||||
|
||||
#ifdef WIN32
|
||||
std::function<bool(const std::basic_string<charT>&)> is_platform_str = [](const std::basic_string<charT>& in) {
|
||||
return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$WINDOWS");
|
||||
};
|
||||
#elif __APPLE__
|
||||
// WIN32 stands for pc in general
|
||||
std::function<bool(const std::basic_string<charT>&)> is_platform_str = [](const std::basic_string<charT>& in) {
|
||||
return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || in == TYTI_L(charT, "$OSX");
|
||||
};
|
||||
|
||||
#elif __linux__
|
||||
// WIN32 stands for pc in general
|
||||
std::function<bool(const std::basic_string<charT>&)> is_platform_str = [](const std::basic_string<charT>& in) {
|
||||
return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || in == TYTI_L(charT, "$LINUX");
|
||||
};
|
||||
#else
|
||||
std::function<bool(const std::basic_string<charT>&)> is_platform_str = [](const std::basic_string<charT>& in) {
|
||||
return false;
|
||||
};
|
||||
#endif
|
||||
|
||||
if (opt.ignore_all_platform_conditionals)
|
||||
is_platform_str = [](const std::basic_string<charT>&) {
|
||||
return false;
|
||||
};
|
||||
|
||||
// function for skipping a comment block
|
||||
// iter: iterator poition to the position after a '/'
|
||||
auto skip_comments = [&comment_end_str](IterT iter, const IterT& last) -> IterT {
|
||||
++iter;
|
||||
if (iter != last)
|
||||
{
|
||||
if (*iter == TYTI_L(charT, '/'))
|
||||
{
|
||||
// line comment, skip whole line
|
||||
iter = std::find(iter + 1, last, TYTI_L(charT, '\n'));
|
||||
}
|
||||
|
||||
if (*iter == '*')
|
||||
{
|
||||
// block comment, skip until next occurance of "*\"
|
||||
iter = std::search(iter + 1, last, std::begin(comment_end_str), std::end(comment_end_str));
|
||||
iter += 2;
|
||||
}
|
||||
}
|
||||
return iter;
|
||||
};
|
||||
|
||||
auto end_quote = [](IterT iter, const IterT& last) -> IterT {
|
||||
const auto begin = iter;
|
||||
auto last_esc = iter;
|
||||
do
|
||||
{
|
||||
++iter;
|
||||
iter = std::find(iter, last, TYTI_L(charT, '\"'));
|
||||
if (iter == last)
|
||||
break;
|
||||
|
||||
last_esc = std::prev(iter);
|
||||
while (last_esc != begin && *last_esc == '\\')
|
||||
--last_esc;
|
||||
} while (!(std::distance(last_esc, iter) % 2));
|
||||
if (iter == last)
|
||||
throw std::runtime_error{ "quote was opened but not closed." };
|
||||
return iter;
|
||||
};
|
||||
|
||||
auto end_word = [&whitespaces](IterT iter, const IterT& last) -> IterT {
|
||||
const auto begin = iter;
|
||||
auto last_esc = iter;
|
||||
do
|
||||
{
|
||||
++iter;
|
||||
iter = std::find_first_of(iter, last, std::begin(whitespaces), std::end(whitespaces));
|
||||
if (iter == last)
|
||||
break;
|
||||
|
||||
last_esc = std::prev(iter);
|
||||
while (last_esc != begin && *last_esc == '\\')
|
||||
--last_esc;
|
||||
} while (!(std::distance(last_esc, iter) % 2));
|
||||
//if (iter == last)
|
||||
// throw std::runtime_error{ "word wasnt properly ended" };
|
||||
return iter;
|
||||
};
|
||||
|
||||
auto skip_whitespaces = [&whitespaces](IterT iter, const IterT& last) -> IterT {
|
||||
iter = std::find_if_not(iter, last, [&whitespaces](charT c) {
|
||||
// return true if whitespace
|
||||
return std::any_of(std::begin(whitespaces), std::end(whitespaces), [c](charT pc) { return pc == c; });
|
||||
});
|
||||
return iter;
|
||||
};
|
||||
|
||||
std::function<void(std::basic_string<charT>&)> strip_escape_symbols = [](std::basic_string<charT>& s) {
|
||||
auto quote_searcher = [&s](size_t pos) { return s.find(TYTI_L(charT, "\\\""), pos); };
|
||||
auto p = quote_searcher(0);
|
||||
while (p != s.npos)
|
||||
{
|
||||
s.replace(p, 2, TYTI_L(charT, "\""));
|
||||
p = quote_searcher(p);
|
||||
}
|
||||
auto searcher = [&s](size_t pos) { return s.find(TYTI_L(charT, "\\\\"), pos); };
|
||||
p = searcher(0);
|
||||
while (p != s.npos)
|
||||
{
|
||||
s.replace(p, 2, TYTI_L(charT, "\\"));
|
||||
p = searcher(p);
|
||||
}
|
||||
};
|
||||
|
||||
if (!opt.strip_escape_symbols)
|
||||
strip_escape_symbols = [](std::basic_string<charT>&) {};
|
||||
|
||||
auto conditional_fullfilled = [&skip_whitespaces, &is_platform_str](IterT& iter, const IterT& last) {
|
||||
iter = skip_whitespaces(iter, last);
|
||||
if (*iter == '[')
|
||||
{
|
||||
++iter;
|
||||
const auto end = std::find(iter, last, ']');
|
||||
const bool negate = *iter == '!';
|
||||
if (negate)
|
||||
++iter;
|
||||
auto conditional = std::basic_string<charT>(iter, end);
|
||||
|
||||
const bool is_platform = is_platform_str(conditional);
|
||||
iter = end + 1;
|
||||
|
||||
return static_cast<bool>(is_platform ^ negate);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
//read header
|
||||
// first, quoted name
|
||||
std::unique_ptr<OutputT> curObj = nullptr;
|
||||
std::vector<std::unique_ptr<OutputT>> roots;
|
||||
std::stack<std::unique_ptr<OutputT>> lvls;
|
||||
auto curIter = first;
|
||||
|
||||
while (curIter != last && *curIter != '\0')
|
||||
{
|
||||
//find first starting attrib/child, or ending
|
||||
curIter = skip_whitespaces(curIter, last);
|
||||
if (curIter == last || *curIter == '\0')
|
||||
break;
|
||||
if (*curIter == TYTI_L(charT, '/'))
|
||||
{
|
||||
curIter = skip_comments(curIter, last);
|
||||
}
|
||||
else if (*curIter != TYTI_L(charT, '}'))
|
||||
{
|
||||
|
||||
// get key
|
||||
const auto keyEnd = (*curIter == TYTI_L(charT, '\"')) ? end_quote(curIter, last) : end_word(curIter, last);
|
||||
if (*curIter == TYTI_L(charT, '\"'))
|
||||
++curIter;
|
||||
std::basic_string<charT> key(curIter, keyEnd);
|
||||
strip_escape_symbols(key);
|
||||
curIter = keyEnd + ((*keyEnd == TYTI_L(charT, '\"')) ? 1 : 0);
|
||||
|
||||
curIter = skip_whitespaces(curIter, last);
|
||||
|
||||
auto conditional = conditional_fullfilled(curIter, last);
|
||||
if (!conditional)
|
||||
continue;
|
||||
|
||||
while (*curIter == TYTI_L(charT, '/'))
|
||||
{
|
||||
|
||||
curIter = skip_comments(curIter, last);
|
||||
if (curIter == last || *curIter == '}')
|
||||
throw std::runtime_error{ "key declared, but no value" };
|
||||
curIter = skip_whitespaces(curIter, last);
|
||||
if (curIter == last || *curIter == '}')
|
||||
throw std::runtime_error{ "key declared, but no value" };
|
||||
}
|
||||
// get value
|
||||
if (*curIter != '{')
|
||||
{
|
||||
const auto valueEnd = (*curIter == TYTI_L(charT, '\"')) ? end_quote(curIter, last) : end_word(curIter, last);
|
||||
if (*curIter == TYTI_L(charT, '\"'))
|
||||
++curIter;
|
||||
|
||||
auto value = std::basic_string<charT>(curIter, valueEnd);
|
||||
strip_escape_symbols(value);
|
||||
curIter = valueEnd + ((*valueEnd == TYTI_L(charT, '\"')) ? 1 : 0);
|
||||
|
||||
auto conditional = conditional_fullfilled(curIter, last);
|
||||
if (!conditional)
|
||||
continue;
|
||||
|
||||
// process value
|
||||
if (key != TYTI_L(charT, "#include") && key != TYTI_L(charT, "#base"))
|
||||
{
|
||||
curObj->add_attribute(std::move(key), std::move(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!opt.ignore_includes && exclude_files.find(value) == exclude_files.end())
|
||||
{
|
||||
exclude_files.insert(value);
|
||||
std::basic_ifstream<charT> i(detail::string_converter(value));
|
||||
auto str = read_file(i);
|
||||
auto file_objs = read_internal<OutputT>(str.begin(), str.end(), exclude_files, opt);
|
||||
for (auto& n : file_objs)
|
||||
{
|
||||
if (curObj)
|
||||
curObj->add_child(std::move(n));
|
||||
else
|
||||
roots.push_back(std::move(n));
|
||||
}
|
||||
exclude_files.erase(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*curIter == '{')
|
||||
{
|
||||
if (curObj)
|
||||
lvls.push(std::move(curObj));
|
||||
curObj = std::make_unique<OutputT>();
|
||||
curObj->set_name(std::move(key));
|
||||
++curIter;
|
||||
}
|
||||
}
|
||||
//end of new object
|
||||
else if (*curIter == TYTI_L(charT, '}'))
|
||||
{
|
||||
if (!lvls.empty())
|
||||
{
|
||||
//get object before
|
||||
std::unique_ptr<OutputT> prev{ std::move(lvls.top()) };
|
||||
lvls.pop();
|
||||
|
||||
// add finished obj to obj before and release it from processing
|
||||
prev->add_child(std::move(curObj));
|
||||
curObj = std::move(prev);
|
||||
}
|
||||
else
|
||||
{
|
||||
roots.push_back(std::move(curObj));
|
||||
curObj.reset();
|
||||
}
|
||||
++curIter;
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/** \brief Read VDF formatted sequences defined by the range [first, last).
|
||||
If the file is mailformatted, parser will try to read it until it can.
|
||||
@param first begin iterator
|
||||
@param end end iterator
|
||||
|
||||
can thow:
|
||||
- "std::runtime_error" if a parsing error occured
|
||||
- "std::bad_alloc" if not enough memory coup be allocated
|
||||
*/
|
||||
template <typename OutputT, typename IterT>
|
||||
OutputT read(IterT first, const IterT last, const Options& opt = Options{})
|
||||
{
|
||||
auto exclude_files = std::unordered_set<std::basic_string<typename std::iterator_traits<IterT>::value_type>>{};
|
||||
auto roots = detail::read_internal<OutputT>(first, last, exclude_files, opt);
|
||||
|
||||
OutputT result;
|
||||
if (roots.size() > 1)
|
||||
{
|
||||
for (auto& i : roots)
|
||||
result.add_child(std::move(i));
|
||||
}
|
||||
else if (roots.size() == 1)
|
||||
result = std::move(*roots[0]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Read VDF formatted sequences defined by the range [first, last).
|
||||
If the file is mailformatted, parser will try to read it until it can.
|
||||
@param first begin iterator
|
||||
@param end end iterator
|
||||
@param ec output bool. 0 if ok, otherwise, holds an system error code
|
||||
|
||||
Possible error codes:
|
||||
std::errc::protocol_error: file is mailformatted
|
||||
std::errc::not_enough_memory: not enough space
|
||||
std::errc::invalid_argument: iterators throws e.g. out of range
|
||||
*/
|
||||
template <typename OutputT, typename IterT>
|
||||
OutputT read(IterT first, IterT last, std::error_code& ec, const Options& opt = Options{}) NOEXCEPT
|
||||
|
||||
{
|
||||
ec.clear();
|
||||
OutputT r{};
|
||||
try
|
||||
{
|
||||
r = read<OutputT>(first, last, opt);
|
||||
}
|
||||
catch (std::runtime_error&)
|
||||
{
|
||||
ec = std::make_error_code(std::errc::protocol_error);
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
ec = std::make_error_code(std::errc::not_enough_memory);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ec = std::make_error_code(std::errc::invalid_argument);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/** \brief Read VDF formatted sequences defined by the range [first, last).
|
||||
If the file is mailformatted, parser will try to read it until it can.
|
||||
@param first begin iterator
|
||||
@param end end iterator
|
||||
@param ok output bool. true, if parser successed, false, if parser failed
|
||||
*/
|
||||
template <typename OutputT, typename IterT>
|
||||
OutputT read(IterT first, const IterT last, bool* ok, const Options& opt = Options{}) NOEXCEPT
|
||||
{
|
||||
std::error_code ec;
|
||||
auto r = read<OutputT>(first, last, ec, opt);
|
||||
if (ok)
|
||||
*ok = !ec;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename IterT>
|
||||
inline auto read(IterT first, const IterT last, bool* ok, const Options& opt = Options{}) NOEXCEPT -> basic_object<typename std::iterator_traits<IterT>::value_type>
|
||||
{
|
||||
return read<basic_object<typename std::iterator_traits<IterT>::value_type>>(first, last, ok, opt);
|
||||
}
|
||||
|
||||
template <typename IterT>
|
||||
inline auto read(IterT first, IterT last, std::error_code& ec, const Options& opt = Options{}) NOEXCEPT
|
||||
-> basic_object<typename std::iterator_traits<IterT>::value_type>
|
||||
{
|
||||
return read<basic_object<typename std::iterator_traits<IterT>::value_type>>(first, last, ec, opt);
|
||||
}
|
||||
|
||||
template <typename IterT>
|
||||
inline auto read(IterT first, const IterT last, const Options& opt = Options{})
|
||||
-> basic_object<typename std::iterator_traits<IterT>::value_type>
|
||||
{
|
||||
return read<basic_object<typename std::iterator_traits<IterT>::value_type>>(first, last, opt);
|
||||
}
|
||||
|
||||
/** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data.
|
||||
throws "std::bad_alloc" if file buffer could not be allocated
|
||||
*/
|
||||
template <typename OutputT, typename iStreamT>
|
||||
OutputT read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{})
|
||||
{
|
||||
// cache the file
|
||||
typedef typename iStreamT::char_type charT;
|
||||
std::basic_string<charT> str = detail::read_file(inStream);
|
||||
|
||||
// parse it
|
||||
return read<OutputT>(str.begin(), str.end(), ec, opt);
|
||||
}
|
||||
|
||||
template <typename iStreamT>
|
||||
inline basic_object<typename iStreamT::char_type> read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{})
|
||||
{
|
||||
return read<basic_object<typename iStreamT::char_type>>(inStream, ec, opt);
|
||||
}
|
||||
|
||||
/** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data.
|
||||
throws "std::bad_alloc" if file buffer could not be allocated
|
||||
ok == false, if a parsing error occured
|
||||
*/
|
||||
template <typename OutputT, typename iStreamT>
|
||||
OutputT read(iStreamT& inStream, bool* ok, const Options& opt = Options{})
|
||||
{
|
||||
std::error_code ec;
|
||||
const auto r = read<OutputT>(inStream, ec, opt);
|
||||
if (ok)
|
||||
*ok = !ec;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename iStreamT>
|
||||
inline basic_object<typename iStreamT::char_type> read(iStreamT& inStream, bool* ok, const Options& opt = Options{})
|
||||
{
|
||||
return read<basic_object<typename iStreamT::char_type>>(inStream, ok, opt);
|
||||
}
|
||||
|
||||
/** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data.
|
||||
throws "std::bad_alloc" if file buffer could not be allocated
|
||||
throws "std::runtime_error" if a parsing error occured
|
||||
*/
|
||||
template <typename OutputT, typename iStreamT>
|
||||
OutputT read(iStreamT& inStream, const Options& opt)
|
||||
{
|
||||
|
||||
// cache the file
|
||||
typedef typename iStreamT::char_type charT;
|
||||
std::basic_string<charT> str = detail::read_file(inStream);
|
||||
// parse it
|
||||
return read<OutputT>(str.begin(), str.end(), opt);
|
||||
}
|
||||
|
||||
template <typename iStreamT>
|
||||
inline basic_object<typename iStreamT::char_type> read(iStreamT& inStream, const Options& opt = Options{})
|
||||
{
|
||||
return read<basic_object<typename iStreamT::char_type>>(inStream, opt);
|
||||
}
|
||||
|
||||
} // namespace vdf
|
||||
|
||||
#ifndef TYTI_NO_L_UNDEF
|
||||
#undef TYTI_L
|
||||
#endif
|
||||
|
||||
#ifdef TYTI_UNDEF_CONSTEXPR
|
||||
#undef CONSTEXPR
|
||||
#undef TYTI_NO_L_UNDEF
|
||||
#endif
|
||||
|
||||
#ifdef TYTI_UNDEF_NOTHROW
|
||||
#undef NOTHROW
|
||||
#undef TYTI_UNDEF_NOTHROW
|
||||
#endif
|
||||
|
||||
#endif //__TYTI_STEAM_VDF_PARSER_H__
|
@ -343,6 +343,20 @@ string Base64Decode(const string& svInput)
|
||||
return results;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For checking if a string is a number.
|
||||
bool StringIsDigit(const string& svInput)
|
||||
{
|
||||
for (char const& c : svInput)
|
||||
{
|
||||
if (std::isdigit(c) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For comparing input strings alphabetically.
|
||||
bool CompareStringAlphabetically(const string& svA, const string& svB)
|
||||
|
@ -5,7 +5,6 @@
|
||||
//=============================================================================//
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/host_cmd.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/host_state.h"
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#include "rtech/rtech_game.h"
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
|
||||
/******************************************************************************
|
||||
|
973
r5dev/sdklauncher/basepanel.cpp
Normal file
973
r5dev/sdklauncher/basepanel.cpp
Normal file
@ -0,0 +1,973 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "core/stdafx.h"
|
||||
#include "sdklauncher.h"
|
||||
#include "basepanel.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: creates the surface layout
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::Init()
|
||||
{
|
||||
// START DESIGNER CODE
|
||||
const INT WindowX = 800;
|
||||
const INT WindowY = 350;
|
||||
|
||||
this->SuspendLayout();
|
||||
this->SetAutoScaleDimensions({ 6, 13 });
|
||||
this->SetAutoScaleMode(Forms::AutoScaleMode::Font);
|
||||
this->SetText("SDK Launcher");
|
||||
this->SetClientSize({ WindowX, WindowY });
|
||||
this->SetFormBorderStyle(Forms::FormBorderStyle::FixedSingle);
|
||||
this->SetStartPosition(Forms::FormStartPosition::CenterParent);
|
||||
this->SetMinimizeBox(false);
|
||||
this->SetMaximizeBox(false);
|
||||
this->SetBackColor(Drawing::Color(47, 54, 61));
|
||||
|
||||
// ########################################################################
|
||||
// GAME
|
||||
// ########################################################################
|
||||
this->m_GameGroup = new UIX::UIXGroupBox();
|
||||
this->m_GameGroup->SetSize({ 458, 84 });
|
||||
this->m_GameGroup->SetLocation({ 12, 10 });
|
||||
this->m_GameGroup->SetTabIndex(0);
|
||||
this->m_GameGroup->SetText("Game");
|
||||
this->m_GameGroup->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->AddControl(this->m_GameGroup);
|
||||
|
||||
this->m_GameGroupExt = new UIX::UIXGroupBox();
|
||||
this->m_GameGroupExt->SetSize({ 458, 55 });
|
||||
this->m_GameGroupExt->SetLocation({ 12, 93 });
|
||||
this->m_GameGroupExt->SetTabIndex(0);
|
||||
this->m_GameGroupExt->SetText("");
|
||||
this->m_GameGroupExt->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->AddControl(this->m_GameGroupExt);
|
||||
|
||||
this->m_MapLabel = new UIX::UIXLabel();
|
||||
this->m_MapLabel->SetSize({ 50, 25 });
|
||||
this->m_MapLabel->SetLocation({ 365, 28 });
|
||||
this->m_MapLabel->SetTabIndex(0);
|
||||
this->m_MapLabel->SetText("Map");
|
||||
this->m_MapLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_MapLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
|
||||
this->m_GameGroup->AddControl(this->m_MapLabel);
|
||||
|
||||
this->m_MapCombo = new UIX::UIXComboBox();
|
||||
this->m_MapCombo->SetSize({ 347, 25 });
|
||||
this->m_MapCombo->SetLocation({ 15, 25 });
|
||||
this->m_MapCombo->SetTabIndex(0);
|
||||
this->m_MapCombo->SetSelectedIndex(0);
|
||||
this->m_MapCombo->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_MapCombo->SetDropDownStyle(Forms::ComboBoxStyle::DropDownList);
|
||||
this->m_GameGroup->AddControl(this->m_MapCombo);
|
||||
|
||||
this->m_PlaylistLabel = new UIX::UIXLabel();
|
||||
this->m_PlaylistLabel->SetSize({ 50, 25 });
|
||||
this->m_PlaylistLabel->SetLocation({ 365, 53 });
|
||||
this->m_PlaylistLabel->SetTabIndex(0);
|
||||
this->m_PlaylistLabel->SetText("Playlist");
|
||||
this->m_PlaylistLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_PlaylistLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
|
||||
this->m_GameGroup->AddControl(this->m_PlaylistLabel);
|
||||
|
||||
this->m_PlaylistCombo = new UIX::UIXComboBox();
|
||||
this->m_PlaylistCombo->SetSize({ 347, 25 });
|
||||
this->m_PlaylistCombo->SetLocation({ 15, 50 });
|
||||
this->m_PlaylistCombo->SetTabIndex(0);
|
||||
this->m_PlaylistCombo->SetSelectedIndex(0);
|
||||
this->m_PlaylistCombo->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_PlaylistCombo->SetDropDownStyle(Forms::ComboBoxStyle::DropDownList);
|
||||
this->m_GameGroup->AddControl(this->m_PlaylistCombo);
|
||||
|
||||
this->m_CheatsToggle = new UIX::UIXCheckBox();
|
||||
this->m_CheatsToggle->SetSize({ 110, 18 });
|
||||
this->m_CheatsToggle->SetLocation({ 15, 7 });
|
||||
this->m_CheatsToggle->SetTabIndex(0);
|
||||
this->m_CheatsToggle->SetText("Enable cheats");
|
||||
this->m_CheatsToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_GameGroupExt->AddControl(this->m_CheatsToggle);
|
||||
|
||||
this->m_DevelopmentToggle = new UIX::UIXCheckBox();
|
||||
this->m_DevelopmentToggle->SetSize({ 150, 18 });
|
||||
this->m_DevelopmentToggle->SetLocation({ 130, 7 });
|
||||
this->m_DevelopmentToggle->SetTabIndex(0);
|
||||
this->m_DevelopmentToggle->SetText("Enable development");
|
||||
this->m_DevelopmentToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_GameGroupExt->AddControl(this->m_DevelopmentToggle);
|
||||
|
||||
this->m_ConsoleToggle = new UIX::UIXCheckBox();
|
||||
this->m_ConsoleToggle->SetSize({ 150, 18 });
|
||||
this->m_ConsoleToggle->SetLocation({ 290, 7 });
|
||||
this->m_ConsoleToggle->SetTabIndex(0);
|
||||
this->m_ConsoleToggle->SetText("Show console");
|
||||
this->m_ConsoleToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_GameGroupExt->AddControl(this->m_ConsoleToggle);
|
||||
|
||||
this->m_ColorConsoleToggle = new UIX::UIXCheckBox();
|
||||
this->m_ColorConsoleToggle->SetSize({ 105, 18 });
|
||||
this->m_ColorConsoleToggle->SetLocation({ 15, 30 });
|
||||
this->m_ColorConsoleToggle->SetTabIndex(0);
|
||||
this->m_ColorConsoleToggle->SetChecked(true);
|
||||
this->m_ColorConsoleToggle->SetText("Color console");
|
||||
this->m_ColorConsoleToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_GameGroupExt->AddControl(this->m_ColorConsoleToggle);
|
||||
|
||||
this->m_PlaylistFileTextBox = new UIX::UIXTextBox();
|
||||
this->m_PlaylistFileTextBox->SetSize({ 178, 18 });
|
||||
this->m_PlaylistFileTextBox->SetLocation({ 130, 30 });
|
||||
this->m_PlaylistFileTextBox->SetTabIndex(0);
|
||||
this->m_PlaylistFileTextBox->SetText("playlists_r5_patch.txt");
|
||||
this->m_PlaylistFileTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_PlaylistFileTextBox->LostFocus += &ReloadPlaylists;
|
||||
this->m_GameGroupExt->AddControl(this->m_PlaylistFileTextBox);
|
||||
|
||||
this->m_PlaylistFileLabel = new UIX::UIXLabel();
|
||||
this->m_PlaylistFileLabel->SetSize({ 50, 18 });
|
||||
this->m_PlaylistFileLabel->SetLocation({ 311, 32 });
|
||||
this->m_PlaylistFileLabel->SetTabIndex(0);
|
||||
this->m_PlaylistFileLabel->SetText("Playlist file");
|
||||
this->m_PlaylistFileLabel->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left);
|
||||
this->m_GameGroupExt->AddControl(this->m_PlaylistFileLabel);
|
||||
|
||||
// ########################################################################
|
||||
// MAIN
|
||||
// ########################################################################
|
||||
this->m_MainGroup = new UIX::UIXGroupBox();
|
||||
this->m_MainGroup->SetSize({ 308, 84 });
|
||||
this->m_MainGroup->SetLocation({ 480, 10 });
|
||||
this->m_MainGroup->SetTabIndex(0);
|
||||
this->m_MainGroup->SetText("Main");
|
||||
this->m_MainGroup->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->AddControl(this->m_MainGroup);
|
||||
|
||||
this->m_MainGroupExt = new UIX::UIXGroupBox();
|
||||
this->m_MainGroupExt->SetSize({ 308, 55 });
|
||||
this->m_MainGroupExt->SetLocation({ 480, 93 });
|
||||
this->m_MainGroupExt->SetTabIndex(0);
|
||||
this->m_MainGroupExt->SetText("");
|
||||
this->m_MainGroupExt->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->AddControl(this->m_MainGroupExt);
|
||||
|
||||
this->m_ModeCombo = new UIX::UIXComboBox();
|
||||
this->m_ModeCombo->SetSize({ 82, 25 });
|
||||
this->m_ModeCombo->SetLocation({ 15, 25 });
|
||||
this->m_ModeCombo->SetTabIndex(0);
|
||||
this->m_ModeCombo->SetSelectedIndex(0);
|
||||
this->m_ModeCombo->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_ModeCombo->SetDropDownStyle(Forms::ComboBoxStyle::DropDownList);
|
||||
this->m_MainGroup->AddControl(this->m_ModeCombo);
|
||||
|
||||
this->m_ModeLabel = new UIX::UIXLabel();
|
||||
this->m_ModeLabel->SetSize({ 50, 25 });
|
||||
this->m_ModeLabel->SetLocation({ 100, 28 });
|
||||
this->m_ModeLabel->SetTabIndex(0);
|
||||
this->m_ModeLabel->SetText("Mode");
|
||||
this->m_ModeLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_ModeLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
|
||||
this->m_MainGroup->AddControl(this->m_ModeLabel);
|
||||
|
||||
this->m_HostNameTextBox = new UIX::UIXTextBox();
|
||||
this->m_HostNameTextBox->SetSize({ 80, 21 });
|
||||
this->m_HostNameTextBox->SetLocation({ 150, 25 });
|
||||
this->m_HostNameTextBox->SetTabIndex(0);
|
||||
this->m_HostNameTextBox->SetText("");
|
||||
this->m_HostNameTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_MainGroup->AddControl(this->m_HostNameTextBox);
|
||||
|
||||
this->m_HostNameLabel = new UIX::UIXLabel();
|
||||
this->m_HostNameLabel->SetSize({ 70, 21 });
|
||||
this->m_HostNameLabel->SetLocation({ 233, 28 });
|
||||
this->m_HostNameLabel->SetTabIndex(0);
|
||||
this->m_HostNameLabel->SetText("Host name");
|
||||
this->m_HostNameLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_MainGroup->AddControl(this->m_HostNameLabel);
|
||||
|
||||
this->m_VisibilityCombo = new UIX::UIXComboBox();
|
||||
this->m_VisibilityCombo->SetSize({ 82, 25 });
|
||||
this->m_VisibilityCombo->SetLocation({ 15, 50 });
|
||||
this->m_VisibilityCombo->SetTabIndex(0);
|
||||
this->m_VisibilityCombo->SetSelectedIndex(0);
|
||||
this->m_VisibilityCombo->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_VisibilityCombo->SetDropDownStyle(Forms::ComboBoxStyle::DropDownList);
|
||||
this->m_MainGroup->AddControl(this->m_VisibilityCombo);
|
||||
|
||||
this->m_VisibilityLabel = new UIX::UIXLabel();
|
||||
this->m_VisibilityLabel->SetSize({ 70, 21 });
|
||||
this->m_VisibilityLabel->SetLocation({ 100, 53 });
|
||||
this->m_VisibilityLabel->SetTabIndex(0);
|
||||
this->m_VisibilityLabel->SetText("Visibility");
|
||||
this->m_VisibilityLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_MainGroup->AddControl(this->m_VisibilityLabel);
|
||||
|
||||
this->m_LaunchArgsTextBox = new UIX::UIXTextBox();
|
||||
this->m_LaunchArgsTextBox->SetSize({ 80, 21 });
|
||||
this->m_LaunchArgsTextBox->SetLocation({ 150, 50 });
|
||||
this->m_LaunchArgsTextBox->SetTabIndex(0);
|
||||
this->m_LaunchArgsTextBox->SetText("");
|
||||
this->m_LaunchArgsTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_MainGroup->AddControl(this->m_LaunchArgsTextBox);
|
||||
|
||||
this->m_LaunchArgsLabel = new UIX::UIXLabel();
|
||||
this->m_LaunchArgsLabel->SetSize({ 70, 21 });
|
||||
this->m_LaunchArgsLabel->SetLocation({ 233, 53 });
|
||||
this->m_LaunchArgsLabel->SetTabIndex(0);
|
||||
this->m_LaunchArgsLabel->SetText("Command line");
|
||||
this->m_LaunchArgsLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_MainGroup->AddControl(this->m_LaunchArgsLabel);
|
||||
|
||||
this->m_CleanSDK = new UIX::UIXButton();
|
||||
this->m_CleanSDK->SetSize({ 110, 18 });
|
||||
this->m_CleanSDK->SetLocation({ 15, 7 });
|
||||
this->m_CleanSDK->SetTabIndex(0);
|
||||
this->m_CleanSDK->SetText("Clean SDK");
|
||||
this->m_CleanSDK->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_CleanSDK->Click += &CleanSDK;
|
||||
this->m_MainGroupExt->AddControl(this->m_CleanSDK);
|
||||
|
||||
this->m_UpdateSDK = new UIX::UIXButton();
|
||||
this->m_UpdateSDK->SetSize({ 110, 18 });
|
||||
this->m_UpdateSDK->SetLocation({ 15, 30 });
|
||||
this->m_UpdateSDK->SetTabIndex(0);
|
||||
this->m_UpdateSDK->SetEnabled(false); // !TODO: Implement updater
|
||||
this->m_UpdateSDK->SetText("Update SDK");
|
||||
this->m_UpdateSDK->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_MainGroupExt->AddControl(this->m_UpdateSDK);
|
||||
|
||||
this->m_LaunchSDK = new UIX::UIXButton();
|
||||
this->m_LaunchSDK->SetSize({ 170, 41 });
|
||||
this->m_LaunchSDK->SetLocation({ 130, 7 });
|
||||
this->m_LaunchSDK->SetTabIndex(0);
|
||||
this->m_LaunchSDK->SetText("Launch game");
|
||||
this->m_LaunchSDK->SetBackColor(Drawing::Color(3, 102, 214));
|
||||
this->m_LaunchSDK->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_LaunchSDK->Click += &LaunchGame;
|
||||
this->m_MainGroupExt->AddControl(this->m_LaunchSDK);
|
||||
|
||||
// ########################################################################
|
||||
// ENGINE
|
||||
// ########################################################################
|
||||
this->m_EngineBaseGroup = new UIX::UIXGroupBox();
|
||||
this->m_EngineBaseGroup->SetSize({ 337, 73 });
|
||||
this->m_EngineBaseGroup->SetLocation({ 12, 158 });
|
||||
this->m_EngineBaseGroup->SetTabIndex(0);
|
||||
this->m_EngineBaseGroup->SetText("Engine");
|
||||
this->m_EngineBaseGroup->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->AddControl(this->m_EngineBaseGroup);
|
||||
|
||||
this->m_EngineNetworkGroup = new UIX::UIXGroupBox();
|
||||
this->m_EngineNetworkGroup->SetSize({ 337, 55 });
|
||||
this->m_EngineNetworkGroup->SetLocation({ 12, 230 });
|
||||
this->m_EngineNetworkGroup->SetTabIndex(0);
|
||||
this->m_EngineNetworkGroup->SetText("");
|
||||
this->m_EngineNetworkGroup->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->AddControl(this->m_EngineNetworkGroup);
|
||||
|
||||
this->m_EngineVideoGroup = new UIX::UIXGroupBox();
|
||||
this->m_EngineVideoGroup->SetSize({ 337, 55 });
|
||||
this->m_EngineVideoGroup->SetLocation({ 12, 284 });
|
||||
this->m_EngineVideoGroup->SetTabIndex(0);
|
||||
this->m_EngineVideoGroup->SetText("");
|
||||
this->m_EngineVideoGroup->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->AddControl(this->m_EngineVideoGroup);
|
||||
|
||||
this->m_ReservedCoresTextBox = new UIX::UIXTextBox();
|
||||
this->m_ReservedCoresTextBox->SetSize({ 18, 18 });
|
||||
this->m_ReservedCoresTextBox->SetLocation({ 15, 25 });
|
||||
this->m_ReservedCoresTextBox->SetTabIndex(0);
|
||||
this->m_ReservedCoresTextBox->SetReadOnly(false);
|
||||
this->m_ReservedCoresTextBox->SetText("0");
|
||||
this->m_ReservedCoresTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineBaseGroup->AddControl(this->m_ReservedCoresTextBox);
|
||||
|
||||
this->m_ReservedCoresLabel = new UIX::UIXLabel();
|
||||
this->m_ReservedCoresLabel->SetSize({ 125, 18 });
|
||||
this->m_ReservedCoresLabel->SetLocation({ 36, 27 });
|
||||
this->m_ReservedCoresLabel->SetTabIndex(0);
|
||||
this->m_ReservedCoresLabel->SetText("Reserved cores");
|
||||
this->m_ReservedCoresLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_ReservedCoresLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
|
||||
this->m_EngineBaseGroup->AddControl(this->m_ReservedCoresLabel);
|
||||
|
||||
this->m_WorkerThreadsTextBox = new UIX::UIXTextBox();
|
||||
this->m_WorkerThreadsTextBox->SetSize({ 18, 18 });
|
||||
this->m_WorkerThreadsTextBox->SetLocation({ 155, 25 });
|
||||
this->m_WorkerThreadsTextBox->SetTabIndex(0);
|
||||
this->m_WorkerThreadsTextBox->SetReadOnly(false);
|
||||
this->m_WorkerThreadsTextBox->SetText("28");
|
||||
this->m_WorkerThreadsTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineBaseGroup->AddControl(this->m_WorkerThreadsTextBox);
|
||||
|
||||
this->m_WorkerThreadsLabel = new UIX::UIXLabel();
|
||||
this->m_WorkerThreadsLabel->SetSize({ 125, 18 });
|
||||
this->m_WorkerThreadsLabel->SetLocation({ 176, 27 });
|
||||
this->m_WorkerThreadsLabel->SetTabIndex(0);
|
||||
this->m_WorkerThreadsLabel->SetText("Worker threads");
|
||||
this->m_WorkerThreadsLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_WorkerThreadsLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
|
||||
this->m_EngineBaseGroup->AddControl(this->m_WorkerThreadsLabel);
|
||||
|
||||
this->m_SingleCoreDediToggle = new UIX::UIXCheckBox();
|
||||
this->m_SingleCoreDediToggle->SetSize({ 125, 18 });
|
||||
this->m_SingleCoreDediToggle->SetLocation({ 15, 48 });
|
||||
this->m_SingleCoreDediToggle->SetTabIndex(0);
|
||||
this->m_SingleCoreDediToggle->SetText("Single-core server");
|
||||
this->m_SingleCoreDediToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineBaseGroup->AddControl(this->m_SingleCoreDediToggle);
|
||||
|
||||
this->m_NoAsyncJobsToggle = new UIX::UIXCheckBox();
|
||||
this->m_NoAsyncJobsToggle->SetSize({ 125, 18 });
|
||||
this->m_NoAsyncJobsToggle->SetLocation({ 155, 48 });
|
||||
this->m_NoAsyncJobsToggle->SetTabIndex(2);
|
||||
this->m_NoAsyncJobsToggle->SetText("Synchronize jobs");
|
||||
this->m_NoAsyncJobsToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineBaseGroup->AddControl(this->m_NoAsyncJobsToggle);
|
||||
|
||||
this->m_NetEncryptionToggle = new UIX::UIXCheckBox();
|
||||
this->m_NetEncryptionToggle->SetSize({ 125, 18 });
|
||||
this->m_NetEncryptionToggle->SetLocation({ 15, 7 });
|
||||
this->m_NetEncryptionToggle->SetTabIndex(0);
|
||||
this->m_NetEncryptionToggle->SetChecked(true);
|
||||
this->m_NetEncryptionToggle->SetText("Net encryption");
|
||||
this->m_NetEncryptionToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineNetworkGroup->AddControl(this->m_NetEncryptionToggle);
|
||||
|
||||
this->m_NetRandomKeyToggle = new UIX::UIXCheckBox();
|
||||
this->m_NetRandomKeyToggle->SetSize({ 125, 18 });
|
||||
this->m_NetRandomKeyToggle->SetLocation({ 155, 7 });
|
||||
this->m_NetRandomKeyToggle->SetTabIndex(0);
|
||||
this->m_NetRandomKeyToggle->SetChecked(true);
|
||||
this->m_NetRandomKeyToggle->SetText("Net random key");
|
||||
this->m_NetRandomKeyToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineNetworkGroup->AddControl(this->m_NetRandomKeyToggle);
|
||||
|
||||
|
||||
this->m_NoQueuedPacketThread = new UIX::UIXCheckBox();
|
||||
this->m_NoQueuedPacketThread->SetSize({ 125, 18 });
|
||||
this->m_NoQueuedPacketThread->SetLocation({ 15, 30 });
|
||||
this->m_NoQueuedPacketThread->SetTabIndex(2);
|
||||
this->m_NoQueuedPacketThread->SetText("No queued packets");
|
||||
this->m_NoQueuedPacketThread->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineNetworkGroup->AddControl(this->m_NoQueuedPacketThread);
|
||||
|
||||
this->m_NoTimeOutToggle = new UIX::UIXCheckBox();
|
||||
this->m_NoTimeOutToggle->SetSize({ 125, 18 });
|
||||
this->m_NoTimeOutToggle->SetLocation({ 155, 30 });
|
||||
this->m_NoTimeOutToggle->SetTabIndex(0);
|
||||
this->m_NoTimeOutToggle->SetText("No time out");
|
||||
this->m_NoTimeOutToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineNetworkGroup->AddControl(this->m_NoTimeOutToggle);
|
||||
|
||||
|
||||
this->m_WindowedToggle = new UIX::UIXCheckBox();
|
||||
this->m_WindowedToggle->SetSize({ 105, 18 });
|
||||
this->m_WindowedToggle->SetLocation({ 15, 7 });
|
||||
this->m_WindowedToggle->SetTabIndex(0);
|
||||
this->m_WindowedToggle->SetChecked(true);
|
||||
this->m_WindowedToggle->SetText("Windowed");
|
||||
this->m_WindowedToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineVideoGroup->AddControl(this->m_WindowedToggle);
|
||||
|
||||
this->m_NoBorderToggle = new UIX::UIXCheckBox();
|
||||
this->m_NoBorderToggle->SetSize({ 150, 18 });
|
||||
this->m_NoBorderToggle->SetLocation({ 155, 7 });
|
||||
this->m_NoBorderToggle->SetTabIndex(0);
|
||||
this->m_NoBorderToggle->SetText("No border");
|
||||
this->m_NoBorderToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineVideoGroup->AddControl(this->m_NoBorderToggle);
|
||||
|
||||
this->m_FpsTextBox = new UIX::UIXTextBox();
|
||||
this->m_FpsTextBox->SetSize({ 25, 18 });
|
||||
this->m_FpsTextBox->SetLocation({ 15, 30 });
|
||||
this->m_FpsTextBox->SetTabIndex(0);
|
||||
this->m_FpsTextBox->SetReadOnly(false);
|
||||
this->m_FpsTextBox->SetText("-1");
|
||||
this->m_FpsTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_EngineVideoGroup->AddControl(this->m_FpsTextBox);
|
||||
|
||||
this->m_FpsLabel = new UIX::UIXLabel();
|
||||
this->m_FpsLabel->SetSize({ 125, 18 });
|
||||
this->m_FpsLabel->SetLocation({ 43, 32 });
|
||||
this->m_FpsLabel->SetTabIndex(0);
|
||||
this->m_FpsLabel->SetText("Max FPS");
|
||||
this->m_FpsLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_FpsLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
|
||||
this->m_EngineVideoGroup->AddControl(this->m_FpsLabel);
|
||||
|
||||
|
||||
this->m_WidthTextBox = new UIX::UIXTextBox();
|
||||
this->m_WidthTextBox->SetSize({ 50, 18 });
|
||||
this->m_WidthTextBox->SetLocation({ 100, 30 });
|
||||
this->m_WidthTextBox->SetTabIndex(0);
|
||||
this->m_WidthTextBox->SetReadOnly(false);
|
||||
this->m_WidthTextBox->SetText("");
|
||||
this->m_WidthTextBox->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Right);
|
||||
this->m_EngineVideoGroup->AddControl(this->m_WidthTextBox);
|
||||
|
||||
this->m_HeightTextBox = new UIX::UIXTextBox();
|
||||
this->m_HeightTextBox->SetSize({ 50, 18 });
|
||||
this->m_HeightTextBox->SetLocation({ 149, 30 });
|
||||
this->m_HeightTextBox->SetTabIndex(0);
|
||||
this->m_HeightTextBox->SetReadOnly(false);
|
||||
this->m_HeightTextBox->SetText("");
|
||||
this->m_HeightTextBox->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Right);
|
||||
this->m_EngineVideoGroup->AddControl(this->m_HeightTextBox);
|
||||
|
||||
this->m_ResolutionLabel = new UIX::UIXLabel();
|
||||
this->m_ResolutionLabel->SetSize({ 125, 18 });
|
||||
this->m_ResolutionLabel->SetLocation({ 202, 32 });
|
||||
this->m_ResolutionLabel->SetTabIndex(0);
|
||||
this->m_ResolutionLabel->SetText("Resolution (width | height)");
|
||||
this->m_ResolutionLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_ResolutionLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
|
||||
this->m_EngineVideoGroup->AddControl(this->m_ResolutionLabel);
|
||||
|
||||
// ########################################################################
|
||||
// CONSOLE
|
||||
// ########################################################################
|
||||
this->m_ConsoleGroup = new UIX::UIXGroupBox();
|
||||
this->m_ConsoleGroup->SetSize({ 429, 15 });
|
||||
this->m_ConsoleGroup->SetLocation({ 359, 158 });
|
||||
this->m_ConsoleGroup->SetTabIndex(0);
|
||||
this->m_ConsoleGroup->SetText("Console");
|
||||
this->m_ConsoleGroup->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right);
|
||||
this->AddControl(this->m_ConsoleGroup);
|
||||
|
||||
this->m_ConsoleGroupExt = new UIX::UIXGroupBox();
|
||||
this->m_ConsoleGroupExt->SetSize({ 429, 167 });
|
||||
this->m_ConsoleGroupExt->SetLocation({ 359, 172 });
|
||||
this->m_ConsoleGroupExt->SetTabIndex(0);
|
||||
this->m_ConsoleGroupExt->SetText("");
|
||||
this->m_ConsoleGroupExt->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right);
|
||||
this->AddControl(this->m_ConsoleGroupExt);
|
||||
|
||||
this->m_ConsoleListView = new UIX::UIXListView();
|
||||
this->m_ConsoleListView->SetSize({ 427, 189 });
|
||||
this->m_ConsoleListView->SetLocation({ 1, -23 }); // Hide columns
|
||||
this->m_ConsoleListView->SetTabIndex(0);
|
||||
this->m_ConsoleListView->SetBackColor(Drawing::Color(29, 33, 37));
|
||||
this->m_ConsoleListView->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right);
|
||||
this->m_ConsoleListView->SetView(Forms::View::Details);
|
||||
this->m_ConsoleListView->SetVirtualMode(true);
|
||||
this->m_ConsoleListView->SetFullRowSelect(true);
|
||||
this->m_ConsoleGroupExt->AddControl(this->m_ConsoleListView);
|
||||
this->m_ConsoleListView->Columns.Add({ "index", 40 });
|
||||
this->m_ConsoleListView->Columns.Add({ "buffer", 387 });
|
||||
this->m_ConsoleListView->MouseClick += &VirtualItemToClipboard;
|
||||
this->m_ConsoleListView->RetrieveVirtualItem += &GetVirtualItem;
|
||||
|
||||
this->ResumeLayout(false);
|
||||
this->PerformLayout();
|
||||
|
||||
// END DESIGNER CODE
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: post-init surface setup
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::Setup()
|
||||
{
|
||||
this->ParseMaps();
|
||||
this->ParsePlaylists();
|
||||
|
||||
this->m_ModeCombo->Items.Add("Host");
|
||||
this->m_ModeCombo->Items.Add("Server");
|
||||
this->m_ModeCombo->Items.Add("Client");
|
||||
|
||||
this->m_VisibilityCombo->Items.Add("Public");
|
||||
this->m_VisibilityCombo->Items.Add("Hidden");
|
||||
this->m_VisibilityCombo->Items.Add("Offline");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: removes redundant files from the game install
|
||||
// Input : *pSender -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::CleanSDK(Forms::Control* pSender)
|
||||
{
|
||||
CUIBaseSurface* pSurface = reinterpret_cast<CUIBaseSurface*>(pSender->FindForm());
|
||||
pSurface->m_LogList.push_back(LogList_t(spdlog::level::info, "Running cleaner for SDK installation\n"));
|
||||
pSurface->m_ConsoleListView->SetVirtualListSize(static_cast<int32_t>(pSurface->m_LogList.size()));
|
||||
|
||||
std::system("platform\\clean_sdk.bat");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: launches the game with the SDK
|
||||
// Input : *pSender -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::LaunchGame(Forms::Control* pSender)
|
||||
{
|
||||
string svParameter = "-launcher -dev ";
|
||||
eLaunchMode launchMode = eLaunchMode::LM_NONE;
|
||||
|
||||
launchMode = g_pLauncher->GetMainSurface()->BuildParameter(svParameter);
|
||||
|
||||
if (g_pLauncher->Setup(launchMode, svParameter))
|
||||
g_pLauncher->Launch();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: parses all available maps from the main vpk directory
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::ParseMaps()
|
||||
{
|
||||
std::regex rgArchiveRegex{ R"([^_]*_(.*)(.bsp.pak000_dir).*)" };
|
||||
std::smatch smRegexMatches;
|
||||
for (const auto& dEntry : fs::directory_iterator("vpk"))
|
||||
{
|
||||
std::string svFileName = dEntry.path().string();
|
||||
std::regex_search(svFileName, smRegexMatches, rgArchiveRegex);
|
||||
|
||||
if (smRegexMatches.size() > 0)
|
||||
{
|
||||
if (strcmp(smRegexMatches[1].str().c_str(), "frontend") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(smRegexMatches[1].str().c_str(), "mp_common") == 0)
|
||||
{
|
||||
this->m_MapCombo->Items.Add("mp_lobby");
|
||||
continue;
|
||||
}
|
||||
|
||||
this->m_MapCombo->Items.Add(smRegexMatches[1].str().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: parses all playlists from user selected playlist file
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::ParsePlaylists()
|
||||
{
|
||||
const string svBaseDir = "platform\\";
|
||||
fs::path fsPlaylistPath(svBaseDir + this->m_PlaylistFileTextBox->Text().ToCString());
|
||||
|
||||
if (fs::exists(fsPlaylistPath))
|
||||
{
|
||||
bool bOk{ };
|
||||
std::ifstream iFile(fsPlaylistPath);
|
||||
vdf::object vRoot = vdf::read(iFile, &bOk);
|
||||
|
||||
if (bOk)
|
||||
{
|
||||
const auto& vcPlaylists = vRoot.childs.at("Playlists");
|
||||
for (auto [id, it] = std::tuple{ 1, vcPlaylists->childs.begin()}; it != vcPlaylists->childs.end(); id++, it++)
|
||||
{
|
||||
this->m_PlaylistCombo->Items.Add(it->first.c_str());
|
||||
if (strcmp(it->first.c_str(), "dev_default"))
|
||||
{
|
||||
this->m_PlaylistCombo->SetSelectedIndex(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: clears the form and reloads the playlist
|
||||
// Input : *pSender -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::ReloadPlaylists(Forms::Control* pSender)
|
||||
{
|
||||
CUIBaseSurface* pSurface = reinterpret_cast<CUIBaseSurface*>(pSender->FindForm());
|
||||
|
||||
pSurface->m_PlaylistCombo->Items.Clear();
|
||||
pSurface->m_PlaylistCombo->OnSizeChanged();
|
||||
pSurface->ParsePlaylists();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: copies selected virtual items to clipboard
|
||||
// Input : &pEventArgs -
|
||||
// Input : *pSender -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::VirtualItemToClipboard(const std::unique_ptr<MouseEventArgs>& pEventArgs, Forms::Control* pSender)
|
||||
{
|
||||
if (pEventArgs->Button != Forms::MouseButtons::Right)
|
||||
return;
|
||||
|
||||
CUIBaseSurface* pSurface = reinterpret_cast<CUIBaseSurface*>(pSender->FindForm());
|
||||
List<uint32_t> lSelected = pSurface->m_ConsoleListView->SelectedIndices();
|
||||
|
||||
if (!lSelected.Count())
|
||||
return;
|
||||
|
||||
string svClipBoard;
|
||||
for (uint32_t i = 0; i < lSelected.Count(); i++)
|
||||
svClipBoard.append(pSurface->m_LogList[i].m_svText);
|
||||
|
||||
clip::set_text(svClipBoard);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets and handles the virtual item
|
||||
// Input : &pEventArgs -
|
||||
// *pSender -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUIBaseSurface::GetVirtualItem(const std::unique_ptr<Forms::RetrieveVirtualItemEventArgs>& pEventArgs, Forms::Control* pSender)
|
||||
{
|
||||
CUIBaseSurface* pSurface = reinterpret_cast<CUIBaseSurface*>(pSender->FindForm());
|
||||
if (static_cast<int>(pSurface->m_LogList.size()) <= 0)
|
||||
return;
|
||||
|
||||
pEventArgs->Style.ForeColor = Drawing::Color::White;
|
||||
pEventArgs->Style.BackColor = pSender->BackColor();
|
||||
pSurface->m_ConsoleListView->SetVirtualListSize(static_cast<int32_t>(pSurface->m_LogList.size()));
|
||||
|
||||
static const Drawing::Color cColor[] =
|
||||
{
|
||||
Drawing::Color(255, 255, 255), // Trace
|
||||
Drawing::Color(0, 120, 215), // Debug
|
||||
Drawing::Color(92, 236, 89), // Info
|
||||
Drawing::Color(236, 203, 0), // Warn
|
||||
Drawing::Color(236, 28, 0), // Error
|
||||
Drawing::Color(236, 28, 0), // Critical
|
||||
Drawing::Color(255, 255, 255), // General
|
||||
};
|
||||
static const String svLevel[] =
|
||||
{
|
||||
"trace",
|
||||
"debug",
|
||||
"info",
|
||||
"warning",
|
||||
"error",
|
||||
"critical",
|
||||
"general",
|
||||
};
|
||||
|
||||
switch (pEventArgs->SubItemIndex)
|
||||
{
|
||||
case 0:
|
||||
pEventArgs->Style.ForeColor = cColor[pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel];
|
||||
pEventArgs->Text = svLevel[pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel];
|
||||
break;
|
||||
case 1:
|
||||
pEventArgs->Text = pSurface->m_LogList[pEventArgs->ItemIndex].m_svText;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: clears the form and reloads the playlist
|
||||
// Input : &svParameters -
|
||||
// Output : eLaunchMode [HOST - SERVER - CLIENT - NONE]
|
||||
//-----------------------------------------------------------------------------
|
||||
eLaunchMode CUIBaseSurface::BuildParameter(string& svParameters)
|
||||
{
|
||||
eLaunchMode results = eLaunchMode::LM_NONE;
|
||||
|
||||
switch (static_cast<eMode>(this->m_ModeCombo->SelectedIndex()))
|
||||
{
|
||||
case eMode::HOST:
|
||||
{
|
||||
// GAME ###############################################################
|
||||
if (!String::IsNullOrEmpty(this->m_MapCombo->Text()))
|
||||
{
|
||||
svParameters.append("+map \"" + this->m_MapCombo->Text() + "\" ");
|
||||
}
|
||||
if (!String::IsNullOrEmpty(this->m_PlaylistCombo->Text()))
|
||||
{
|
||||
svParameters.append("+launchplaylist \"" + this->m_PlaylistCombo->Text() + "\" ");
|
||||
}
|
||||
if (this->m_DevelopmentToggle->Checked())
|
||||
{
|
||||
svParameters.append("-devsdk ");
|
||||
results = eLaunchMode::LM_HOST_DEBUG;
|
||||
}
|
||||
else
|
||||
results = eLaunchMode::LM_HOST;
|
||||
|
||||
if (this->m_CheatsToggle->Checked())
|
||||
svParameters.append("+sv_cheats \"1\" ");
|
||||
|
||||
if (this->m_ConsoleToggle->Checked())
|
||||
svParameters.append("-wconsole ");
|
||||
|
||||
if (this->m_ColorConsoleToggle->Checked())
|
||||
svParameters.append("-ansiclr ");
|
||||
|
||||
if (!String::IsNullOrEmpty(this->m_PlaylistFileTextBox->Text()))
|
||||
svParameters.append("-playlistfile \"" + this->m_PlaylistFileTextBox->Text() + "\" ");
|
||||
|
||||
// ENGINE ###############################################################
|
||||
if (StringIsDigit(this->m_ReservedCoresTextBox->Text().ToCString()))
|
||||
svParameters.append("-numreservedcores \"" + this->m_ReservedCoresTextBox->Text() + "\" ");
|
||||
//else error;
|
||||
|
||||
if (StringIsDigit(this->m_WorkerThreadsTextBox->Text().ToCString()))
|
||||
svParameters.append("-numworkerthreads \"" + this->m_WorkerThreadsTextBox->Text() + "\" ");
|
||||
//else error;
|
||||
|
||||
if (this->m_SingleCoreDediToggle->Checked())
|
||||
svParameters.append("+sv_single_core_dedi \"1\" ");
|
||||
|
||||
if (this->m_NoAsyncJobsToggle->Checked())
|
||||
{
|
||||
svParameters.append("-noasync ");
|
||||
svParameters.append("+async_serialize \"0\" ");
|
||||
svParameters.append("+buildcubemaps_async \"0\" ");
|
||||
svParameters.append("+sv_asyncAIInit \"0\" ");
|
||||
svParameters.append("+sv_asyncSendSnapshot \"0\" ");
|
||||
svParameters.append("+sv_scriptCompileAsync \"0\" ");
|
||||
svParameters.append("+cl_scriptCompileAsync \"0\" ");
|
||||
svParameters.append("+cl_async_bone_setup \"0\" ");
|
||||
svParameters.append("+cl_updatedirty_async \"0\" ");
|
||||
svParameters.append("+mat_syncGPU \"1\" ");
|
||||
svParameters.append("+mat_sync_rt \"1\" ");
|
||||
svParameters.append("+mat_sync_rt_flushes_gpu \"1\" ");
|
||||
svParameters.append("+net_async_sendto \"0\" ");
|
||||
svParameters.append("+physics_async_sv \"0\" ");
|
||||
svParameters.append("+physics_async_cl \"0\" ");
|
||||
}
|
||||
|
||||
if (this->m_NetEncryptionToggle->Checked())
|
||||
svParameters.append("+net_encryptionEnable \"1\" ");
|
||||
|
||||
if (this->m_NetRandomKeyToggle->Checked())
|
||||
svParameters.append("+net_useRandomKey \"1\" ");
|
||||
|
||||
if (this->m_NoQueuedPacketThread->Checked())
|
||||
svParameters.append("+net_queued_packet_thread \"0\" ");
|
||||
|
||||
if (this->m_NoTimeOutToggle->Checked())
|
||||
svParameters.append("-notimeout ");
|
||||
|
||||
if (this->m_WindowedToggle->Checked())
|
||||
svParameters.append("-windowed ");
|
||||
|
||||
if (this->m_NoBorderToggle->Checked())
|
||||
svParameters.append("-noborder ");
|
||||
|
||||
if (StringIsDigit(this->m_FpsTextBox->Text().ToCString()))
|
||||
svParameters.append("+fps_max \"" + this->m_FpsTextBox->Text() + "\" ");
|
||||
|
||||
if (!String::IsNullOrEmpty(this->m_WidthTextBox->Text()))
|
||||
svParameters.append("-w \"" + this->m_WidthTextBox->Text() + "\" ");
|
||||
|
||||
if (!String::IsNullOrEmpty(this->m_HeightTextBox->Text()))
|
||||
svParameters.append("-h \"" + this->m_HeightTextBox->Text() + "\" ");
|
||||
|
||||
// MAIN ###############################################################
|
||||
if (!String::IsNullOrEmpty(this->m_HostNameTextBox->Text()))
|
||||
{
|
||||
svParameters.append("+sv_pylonHostName \"" + this->m_HostNameTextBox->Text() + "\" ");
|
||||
|
||||
switch (static_cast<eVisibility>(this->m_VisibilityCombo->SelectedIndex()))
|
||||
{
|
||||
case eVisibility::PUBLIC:
|
||||
{
|
||||
svParameters.append("+sv_pylonVisibility \"2\" ");
|
||||
break;
|
||||
}
|
||||
case eVisibility::HIDDEN:
|
||||
{
|
||||
svParameters.append("+sv_pylonVisibility \"1\" ");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
svParameters.append("+sv_pylonVisibility \"0\" ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!String::IsNullOrEmpty(this->m_LaunchArgsTextBox->Text()))
|
||||
svParameters.append(this->m_LaunchArgsTextBox->Text());
|
||||
|
||||
return results;
|
||||
}
|
||||
case eMode::SERVER:
|
||||
{
|
||||
// GAME ###############################################################
|
||||
if (!String::IsNullOrEmpty(this->m_MapCombo->Text()))
|
||||
{
|
||||
svParameters.append("+map \"" + this->m_MapCombo->Text() + "\" ");
|
||||
}
|
||||
if (!String::IsNullOrEmpty(this->m_PlaylistCombo->Text()))
|
||||
{
|
||||
svParameters.append("+launchplaylist \"" + this->m_PlaylistCombo->Text() + "\" ");
|
||||
}
|
||||
if (this->m_DevelopmentToggle->Checked())
|
||||
{
|
||||
svParameters.append("-devsdk ");
|
||||
results = eLaunchMode::LM_SERVER_DEBUG;
|
||||
}
|
||||
else
|
||||
results = eLaunchMode::LM_SERVER;
|
||||
|
||||
if (this->m_CheatsToggle->Checked())
|
||||
svParameters.append("+sv_cheats \"1\" ");
|
||||
|
||||
if (this->m_ConsoleToggle->Checked())
|
||||
svParameters.append("-wconsole ");
|
||||
|
||||
if (this->m_ColorConsoleToggle->Checked())
|
||||
svParameters.append("-ansiclr ");
|
||||
|
||||
if (!String::IsNullOrEmpty(this->m_PlaylistFileTextBox->Text()))
|
||||
svParameters.append("-playlistfile \"" + this->m_PlaylistFileTextBox->Text() + "\" ");
|
||||
|
||||
// ENGINE ###############################################################
|
||||
if (StringIsDigit(this->m_ReservedCoresTextBox->Text().ToCString()))
|
||||
svParameters.append("-numreservedcores \"" + this->m_ReservedCoresTextBox->Text() + "\" ");
|
||||
//else error;
|
||||
|
||||
if (StringIsDigit(this->m_WorkerThreadsTextBox->Text().ToCString()))
|
||||
svParameters.append("-numworkerthreads \"" + this->m_WorkerThreadsTextBox->Text() + "\" ");
|
||||
//else error;
|
||||
|
||||
if (this->m_SingleCoreDediToggle->Checked())
|
||||
svParameters.append("+sv_single_core_dedi \"1\" ");
|
||||
|
||||
if (this->m_NoAsyncJobsToggle->Checked())
|
||||
{
|
||||
svParameters.append("-noasync ");
|
||||
svParameters.append("+async_serialize \"0\" ");
|
||||
svParameters.append("+sv_asyncAIInit \"0\" ");
|
||||
svParameters.append("+sv_asyncSendSnapshot \"0\" ");
|
||||
svParameters.append("+sv_scriptCompileAsync \"0\" ");
|
||||
svParameters.append("+physics_async_sv \"0\" ");
|
||||
}
|
||||
|
||||
if (this->m_NetEncryptionToggle->Checked())
|
||||
svParameters.append("+net_encryptionEnable \"1\" ");
|
||||
|
||||
if (this->m_NetRandomKeyToggle->Checked())
|
||||
svParameters.append("+net_useRandomKey \"1\" ");
|
||||
|
||||
if (this->m_NoQueuedPacketThread->Checked())
|
||||
svParameters.append("+net_queued_packet_thread \"0\" ");
|
||||
|
||||
if (this->m_NoTimeOutToggle->Checked())
|
||||
svParameters.append("-notimeout ");
|
||||
|
||||
// MAIN ###############################################################
|
||||
if (!String::IsNullOrEmpty(this->m_HostNameTextBox->Text()))
|
||||
{
|
||||
svParameters.append("+sv_pylonHostName \"" + this->m_HostNameTextBox->Text() + "\" ");
|
||||
|
||||
switch (static_cast<eVisibility>(this->m_VisibilityCombo->SelectedIndex()))
|
||||
{
|
||||
case eVisibility::PUBLIC:
|
||||
{
|
||||
svParameters.append("+sv_pylonVisibility \"2\" ");
|
||||
break;
|
||||
}
|
||||
case eVisibility::HIDDEN:
|
||||
{
|
||||
svParameters.append("+sv_pylonVisibility \"1\" ");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
svParameters.append("+sv_pylonVisibility \"0\" ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!String::IsNullOrEmpty(this->m_LaunchArgsTextBox->Text()))
|
||||
svParameters.append(this->m_LaunchArgsTextBox->Text());
|
||||
|
||||
return results;
|
||||
}
|
||||
case eMode::CLIENT:
|
||||
{
|
||||
// GAME ###############################################################
|
||||
if (this->m_DevelopmentToggle->Checked())
|
||||
{
|
||||
svParameters.append("-devsdk ");
|
||||
results = eLaunchMode::LM_CLIENT_DEBUG;
|
||||
}
|
||||
else
|
||||
results = eLaunchMode::LM_CLIENT;
|
||||
|
||||
if (this->m_CheatsToggle->Checked())
|
||||
svParameters.append("+sv_cheats \"1\" ");
|
||||
|
||||
if (this->m_ConsoleToggle->Checked())
|
||||
svParameters.append("-wconsole ");
|
||||
|
||||
if (this->m_ColorConsoleToggle->Checked())
|
||||
svParameters.append("-ansiclr ");
|
||||
|
||||
if (!String::IsNullOrEmpty(this->m_PlaylistFileTextBox->Text()))
|
||||
svParameters.append("-playlistfile \"" + this->m_PlaylistFileTextBox->Text() + "\" ");
|
||||
|
||||
// ENGINE ###############################################################
|
||||
if (StringIsDigit(this->m_ReservedCoresTextBox->Text().ToCString()))
|
||||
svParameters.append("-numreservedcores \"" + this->m_ReservedCoresTextBox->Text() + "\" ");
|
||||
//else error;
|
||||
|
||||
if (StringIsDigit(this->m_WorkerThreadsTextBox->Text().ToCString()))
|
||||
svParameters.append("-numworkerthreads \"" + this->m_WorkerThreadsTextBox->Text() + "\" ");
|
||||
//else error;
|
||||
|
||||
if (this->m_SingleCoreDediToggle->Checked())
|
||||
svParameters.append("+sv_single_core_dedi \"1\" ");
|
||||
|
||||
if (this->m_NoAsyncJobsToggle->Checked())
|
||||
{
|
||||
svParameters.append("-noasync ");
|
||||
svParameters.append("+async_serialize \"0\" ");
|
||||
svParameters.append("+buildcubemaps_async \"0\" ");
|
||||
svParameters.append("+cl_scriptCompileAsync \"0\" ");
|
||||
svParameters.append("+cl_async_bone_setup \"0\" ");
|
||||
svParameters.append("+cl_updatedirty_async \"0\" ");
|
||||
svParameters.append("+mat_syncGPU \"1\" ");
|
||||
svParameters.append("+mat_sync_rt \"1\" ");
|
||||
svParameters.append("+mat_sync_rt_flushes_gpu \"1\" ");
|
||||
svParameters.append("+net_async_sendto \"0\" ");
|
||||
svParameters.append("+physics_async_cl \"0\" ");
|
||||
}
|
||||
|
||||
if (this->m_NetEncryptionToggle->Checked())
|
||||
svParameters.append("+net_encryptionEnable \"1\" ");
|
||||
|
||||
if (this->m_NetRandomKeyToggle->Checked())
|
||||
svParameters.append("+net_useRandomKey \"1\" ");
|
||||
|
||||
if (this->m_NoQueuedPacketThread->Checked())
|
||||
svParameters.append("+net_queued_packet_thread \"0\" ");
|
||||
|
||||
if (this->m_NoTimeOutToggle->Checked())
|
||||
svParameters.append("-notimeout ");
|
||||
|
||||
if (this->m_WindowedToggle->Checked())
|
||||
svParameters.append("-windowed ");
|
||||
|
||||
if (this->m_NoBorderToggle->Checked())
|
||||
svParameters.append("-noborder ");
|
||||
|
||||
if (StringIsDigit(this->m_FpsTextBox->Text().ToCString()))
|
||||
svParameters.append("+fps_max \"" + this->m_FpsTextBox->Text() + "\" ");
|
||||
|
||||
if (!String::IsNullOrEmpty(this->m_WidthTextBox->Text()))
|
||||
svParameters.append("-w \"" + this->m_WidthTextBox->Text() + "\" ");
|
||||
|
||||
if (!String::IsNullOrEmpty(this->m_HeightTextBox->Text()))
|
||||
svParameters.append("-h \"" + this->m_HeightTextBox->Text() + "\" ");
|
||||
|
||||
// MAIN ###############################################################
|
||||
if (!String::IsNullOrEmpty(this->m_LaunchArgsTextBox->Text()))
|
||||
svParameters.append(this->m_LaunchArgsTextBox->Text());
|
||||
|
||||
return results;
|
||||
}
|
||||
default:
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CUIBaseSurface::CUIBaseSurface() : Forms::Form()
|
||||
{
|
||||
this->Init();
|
||||
this->Setup();
|
||||
}
|
||||
CUIBaseSurface* g_pMainUI;
|
103
r5dev/sdklauncher/basepanel.h
Normal file
103
r5dev/sdklauncher/basepanel.h
Normal file
@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
#include "sdklauncher_const.h"
|
||||
|
||||
struct LogList_t
|
||||
{
|
||||
LogList_t(spdlog::level::level_enum nLevel, String svText)
|
||||
{
|
||||
m_nLevel = nLevel;
|
||||
m_svText = svText;
|
||||
}
|
||||
|
||||
spdlog::level::level_enum m_nLevel;
|
||||
String m_svText;
|
||||
};
|
||||
|
||||
class CUIBaseSurface : public Forms::Form
|
||||
{
|
||||
public:
|
||||
CUIBaseSurface();
|
||||
virtual ~CUIBaseSurface() = default;
|
||||
|
||||
std::vector<LogList_t> m_LogList;
|
||||
UIX::UIXListView* m_ConsoleListView;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Setup();
|
||||
void ParseMaps();
|
||||
void ParsePlaylists();
|
||||
|
||||
static void LaunchGame(Forms::Control* pSender);
|
||||
static void CleanSDK(Forms::Control* pSender);
|
||||
static void ReloadPlaylists(Forms::Control* pSender);
|
||||
static void VirtualItemToClipboard(const std::unique_ptr<MouseEventArgs>& pEventArgs, Forms::Control* pSender);
|
||||
static void GetVirtualItem(const std::unique_ptr<Forms::RetrieveVirtualItemEventArgs>& pEventArgs, Forms::Control* pSender);
|
||||
eLaunchMode BuildParameter(string& svParameter);
|
||||
|
||||
enum class eMode
|
||||
{
|
||||
NONE = -1,
|
||||
HOST,
|
||||
SERVER,
|
||||
CLIENT,
|
||||
};
|
||||
enum class eVisibility
|
||||
{
|
||||
PUBLIC,
|
||||
HIDDEN,
|
||||
};
|
||||
|
||||
UIX::UIXTextBox* m_WidthTextBox;
|
||||
UIX::UIXTextBox* m_HeightTextBox;
|
||||
UIX::UIXTextBox* m_WorkerThreadsTextBox;
|
||||
UIX::UIXTextBox* m_ReservedCoresTextBox;
|
||||
UIX::UIXTextBox* m_FpsTextBox;
|
||||
UIX::UIXTextBox* m_PlaylistFileTextBox;
|
||||
UIX::UIXTextBox* m_HostNameTextBox;
|
||||
UIX::UIXTextBox* m_LaunchArgsTextBox;
|
||||
// Labels
|
||||
UIX::UIXLabel* m_WorkerThreadsLabel;
|
||||
UIX::UIXLabel* m_ReservedCoresLabel;
|
||||
UIX::UIXLabel* m_MapLabel;
|
||||
UIX::UIXLabel* m_PlaylistLabel;
|
||||
UIX::UIXLabel* m_ModeLabel;
|
||||
UIX::UIXLabel* m_FpsLabel;
|
||||
UIX::UIXLabel* m_ResolutionLabel;
|
||||
UIX::UIXLabel* m_PlaylistFileLabel;
|
||||
UIX::UIXLabel* m_HostNameLabel;
|
||||
UIX::UIXLabel* m_VisibilityLabel;
|
||||
UIX::UIXLabel* m_LaunchArgsLabel;
|
||||
// Boxes
|
||||
UIX::UIXGroupBox* m_GameGroup;
|
||||
UIX::UIXGroupBox* m_MainGroup;
|
||||
UIX::UIXGroupBox* m_GameGroupExt;
|
||||
UIX::UIXGroupBox* m_MainGroupExt;
|
||||
UIX::UIXGroupBox* m_ConsoleGroupExt;
|
||||
UIX::UIXGroupBox* m_ConsoleGroup;
|
||||
UIX::UIXGroupBox* m_EngineBaseGroup;
|
||||
UIX::UIXGroupBox* m_EngineNetworkGroup;
|
||||
UIX::UIXGroupBox* m_EngineVideoGroup;
|
||||
// Toggles
|
||||
UIX::UIXCheckBox* m_CheatsToggle;
|
||||
UIX::UIXCheckBox* m_DevelopmentToggle;
|
||||
UIX::UIXCheckBox* m_ConsoleToggle;
|
||||
UIX::UIXCheckBox* m_WindowedToggle;
|
||||
UIX::UIXCheckBox* m_NoBorderToggle;
|
||||
UIX::UIXCheckBox* m_SingleCoreDediToggle;
|
||||
UIX::UIXCheckBox* m_NoAsyncJobsToggle;
|
||||
UIX::UIXCheckBox* m_NetEncryptionToggle;
|
||||
UIX::UIXCheckBox* m_NetRandomKeyToggle;
|
||||
UIX::UIXCheckBox* m_NoQueuedPacketThread;
|
||||
UIX::UIXCheckBox* m_NoTimeOutToggle;
|
||||
UIX::UIXCheckBox* m_ColorConsoleToggle;
|
||||
// Combo
|
||||
UIX::UIXComboBox* m_MapCombo;
|
||||
UIX::UIXComboBox* m_PlaylistCombo;
|
||||
UIX::UIXComboBox* m_ModeCombo;
|
||||
UIX::UIXComboBox* m_VisibilityCombo;
|
||||
// Buttons
|
||||
UIX::UIXButton* m_CleanSDK;
|
||||
UIX::UIXButton* m_UpdateSDK;
|
||||
UIX::UIXButton* m_LaunchSDK;
|
||||
};
|
@ -1,147 +1,552 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "basepanel.h"
|
||||
#include "sdklauncher_const.h"
|
||||
#include "sdklauncher.h"
|
||||
#include <objidl.h>
|
||||
#include "gdiplus.h"
|
||||
#include "shellapi.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose switch case:
|
||||
// * Launch the game in user specified mode and state.
|
||||
// * Load specified command line arguments from a file on the disk.
|
||||
// * Format the file paths for the game exe and specified hook dll.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool LaunchR5Apex(eLaunchMode lMode, eLaunchState lState)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Purpose: initializes the user interface
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void CLauncher::InitSurface()
|
||||
{
|
||||
Forms::Application::EnableVisualStyles();
|
||||
UIX::UIXTheme::InitializeRenderer(new Themes::KoreTheme());
|
||||
|
||||
g_pLauncher->m_pSurface = new CUIBaseSurface();
|
||||
Forms::Application::Run(g_pLauncher->m_pSurface);
|
||||
UIX::UIXTheme::ShutdownRenderer();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Purpose: initializes the console (release builds only)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void CLauncher::InitConsole()
|
||||
{
|
||||
AllocConsole();
|
||||
freopen("conin$", "r", stdin);
|
||||
freopen("conout$", "w", stdout);
|
||||
freopen("conout$", "w", stderr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Purpose: initializes the logger
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void CLauncher::InitLogger()
|
||||
{
|
||||
wconsole->set_pattern("[%^%l%$] %v");
|
||||
wconsole->set_level(spdlog::level::trace);
|
||||
spdlog::set_default_logger(wconsole); // Set as default.
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Purpose: handles user input pre-init
|
||||
// Input : argc -
|
||||
// *argv -
|
||||
// Output : exit_code (-1 if EP should continue to HandleInput)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int CLauncher::HandleCmdLine(int argc, char* argv[])
|
||||
{
|
||||
for (int i = 1; i < __argc; ++i)
|
||||
{
|
||||
std::string arg = __argv[i];
|
||||
if ((arg == "-debug") || (arg == "-dbg"))
|
||||
{
|
||||
if (g_pLauncher->Setup(eLaunchMode::LM_HOST_DEBUG, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((arg == "-release") || (arg == "-rel"))
|
||||
{
|
||||
if (g_pLauncher->Setup(eLaunchMode::LM_HOST, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((arg == "-dedicated_dev") || (arg == "-dedid"))
|
||||
{
|
||||
if (g_pLauncher->Setup(eLaunchMode::LM_SERVER_DEBUG, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((arg == "-dedicated") || (arg == "-dedi"))
|
||||
{
|
||||
if (g_pLauncher->Setup(eLaunchMode::LM_SERVER, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((arg == "-client_dev") || (arg == "-cld"))
|
||||
{
|
||||
if (g_pLauncher->Setup(eLaunchMode::LM_CLIENT_DEBUG, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((arg == "-client") || (arg == "-cl"))
|
||||
{
|
||||
if (g_pLauncher->Setup(eLaunchMode::LM_CLIENT, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Purpose: handles user input post-init
|
||||
// Output : exit_code
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int CLauncher::HandleInput()
|
||||
{
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "If a DEBUG option has been choosen as launch parameter, do not broadcast servers to the Server Browser!\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "All FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ConVar's/ConCommand's will be enabled.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Connected clients will be able to set and execute anything flagged FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY.\n");
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEBUG HOST [0] for research and development purposes.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RELEASE HOST [1] for playing the game and creating servers.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEBUG SERVER [2] for research and development purposes.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RELEASE SERVER [3] for running and hosting dedicated servers.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEBUG CLIENT [4] for research and development purposes.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RELEASE CLIENT [5] for running client only builds against remote servers.\n");
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '0' for 'DEBUG HOST'.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '1' for 'RELEASE HOST'.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '2' for 'DEBUG SERVER'.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '3' for 'RELEASE SERVER'.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '4' for 'DEBUG CLIENT'.\n");
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '5' for 'RELEASE CLIENT'.\n");
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
std::cout << "User input: ";
|
||||
|
||||
std::string input = std::string();
|
||||
if (std::cin >> input)
|
||||
{
|
||||
try
|
||||
{
|
||||
eLaunchMode mode = static_cast<eLaunchMode>(std::stoi(input));
|
||||
switch (mode)
|
||||
{
|
||||
case eLaunchMode::LM_HOST_DEBUG:
|
||||
{
|
||||
if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
case eLaunchMode::LM_HOST:
|
||||
{
|
||||
if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
case eLaunchMode::LM_SERVER_DEBUG:
|
||||
{
|
||||
if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
case eLaunchMode::LM_SERVER:
|
||||
{
|
||||
if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
case eLaunchMode::LM_CLIENT_DEBUG:
|
||||
{
|
||||
if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
case eLaunchMode::LM_CLIENT:
|
||||
{
|
||||
if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS))
|
||||
{
|
||||
if (g_pLauncher->Launch())
|
||||
{
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
default:
|
||||
{
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::err, "Invalid mode (range 0-5).\n");
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::err, "SDK Launcher only takes numerical input. Error: {:s}.\n", e.what());
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::err, "SDK Launcher requires numerical input.\n");
|
||||
|
||||
Sleep(2000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Purpose: setup for game dll's and configurations
|
||||
// Input : lMode -
|
||||
// lState -
|
||||
// Output : true on success, false otherwise
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState)
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Initialize strings.
|
||||
std::string svWorkerDll = std::string();
|
||||
std::string svGameDir = std::string();
|
||||
std::string svCmdLineArgs = std::string();
|
||||
std::string svStartCmdLine = std::string();
|
||||
std::string svCurrentDir = std::filesystem::current_path().u8string();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Determine launch mode.
|
||||
switch (lMode)
|
||||
{
|
||||
case eLaunchMode::LM_DEBUG_GAME:
|
||||
case eLaunchMode::LM_HOST_DEBUG:
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_debug.cfg";
|
||||
std::ifstream cfgFile(cfgPath);
|
||||
if (cfgFile.good() && cfgFile)
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_debug.cfg"; // Get cfg path for debug startup.
|
||||
std::ifstream cfgFile(cfgPath); // Read the cfg file.
|
||||
if (cfgFile.good() && cfgFile) // Does the cfg file exist?
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf(); // Read ifstream buffer into stringstream.
|
||||
svCmdLineArgs = ss.str() + "-launcher"; // Get all the contents of the cfg file.
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::error("File 'platform\\cfg\\startup_debug.cfg' does not exist!\n");
|
||||
cfgFile.close();
|
||||
return false;
|
||||
}
|
||||
cfgFile.close(); // Close cfg file.
|
||||
|
||||
svWorkerDll = svCurrentDir + "\\gamesdk.dll"; // Get path to worker dll.
|
||||
svGameDir = svCurrentDir + "\\r5apex.exe"; // Get path to game executeable.
|
||||
svStartCmdLine = svCurrentDir + "\\r5apex.exe " + svCmdLineArgs; // Setup startup command line string.
|
||||
|
||||
spdlog::info("*** LAUNCHING GAME [DEBUG] ***\n");
|
||||
break;
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf();
|
||||
svCmdLineArgs = ss.str() + "-launcher";
|
||||
}
|
||||
case eLaunchMode::LM_RELEASE_GAME:
|
||||
else
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_retail.cfg"; // Get cfg path for release startup.
|
||||
std::ifstream cfgFile(cfgPath); // Read the cfg file.
|
||||
if (cfgFile.good() && cfgFile) // Does the cfg file exist?
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf(); // Read ifstream buffer into stringstream.
|
||||
svCmdLineArgs = ss.str() + "-launcher"; // Get all the contents of the cfg file.
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::error("File 'platform\\cfg\\startup_retail.cfg' does not exist!\n");
|
||||
cfgFile.close();
|
||||
return false;
|
||||
}
|
||||
cfgFile.close(); // Close cfg file.
|
||||
|
||||
svWorkerDll = svCurrentDir + "\\gamesdk.dll"; // Get path to worker dll.
|
||||
svGameDir = svCurrentDir + "\\r5apex.exe"; // Get path to game executeable.
|
||||
svStartCmdLine = svCurrentDir + "\\r5apex.exe " + svCmdLineArgs; // Setup startup command line string.
|
||||
|
||||
spdlog::info("*** LAUNCHING GAME [RELEASE] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_DEBUG_DEDI:
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_dedi_debug.cfg"; // Get cfg path for dedicated startup.
|
||||
std::ifstream cfgFile(cfgPath); // Read the cfg file.
|
||||
if (cfgFile.good() && cfgFile) // Does the cfg file exist?
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf(); // Read ifstream buffer into stringstream.
|
||||
svCmdLineArgs = ss.str() + "-launcher"; // Get all the contents of the cfg file.
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::error("File 'platform\\cfg\\startup_dedi_debug.cfg' does not exist!\n");
|
||||
cfgFile.close();
|
||||
return false;
|
||||
}
|
||||
cfgFile.close(); // Close cfg file.
|
||||
|
||||
svWorkerDll = svCurrentDir + "\\dedicated.dll"; // Get path to worker dll.
|
||||
svGameDir = svCurrentDir + "\\r5apex_ds.exe"; // Get path to game executeable.
|
||||
svStartCmdLine = svCurrentDir + "\\r5apex_ds.exe " + svCmdLineArgs; // Setup startup command line string.
|
||||
|
||||
spdlog::info("*** LAUNCHING DEDICATED [DEBUG] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_RELEASE_DEDI:
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_dedi_retail.cfg"; // Get cfg path for dedicated startup.
|
||||
std::ifstream cfgFile(cfgPath); // Read the cfg file.
|
||||
if (cfgFile.good() && cfgFile) // Does the cfg file exist?
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf(); // Read ifstream buffer into stringstream.
|
||||
svCmdLineArgs = ss.str(); // Get all the contents of the cfg file.
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::error("File 'platform\\cfg\\startup_dedi_retail.cfg' does not exist!\n");
|
||||
cfgFile.close();
|
||||
return false;
|
||||
}
|
||||
cfgFile.close(); // Close cfg file.
|
||||
|
||||
svWorkerDll = svCurrentDir + "\\dedicated.dll"; // Get path to worker dll.
|
||||
svGameDir = svCurrentDir + "\\r5apex_ds.exe"; // Get path to game executeable.
|
||||
svStartCmdLine = svCurrentDir + "\\r5apex_ds.exe " + svCmdLineArgs; // Setup startup command line string.
|
||||
|
||||
spdlog::info("*** LAUNCHING DEDICATED [RELEASE] ***\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
spdlog::error("*** NO LAUNCH MODE SPECIFIED ***\n");
|
||||
AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_debug.cfg' does not exist!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_svWorkerDll = m_svCurrentDir + "\\gamesdk.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCmdLineArgs;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [DEBUG] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_HOST:
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_retail.cfg";
|
||||
std::ifstream cfgFile(cfgPath);
|
||||
if (cfgFile.good() && cfgFile)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf();
|
||||
svCmdLineArgs = ss.str() + "-launcher";
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_retail.cfg' does not exist!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_svWorkerDll = m_svCurrentDir + "\\gamesdk.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCmdLineArgs;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [RELEASE] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_SERVER_DEBUG:
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_dedi_debug.cfg";
|
||||
std::ifstream cfgFile(cfgPath);
|
||||
if (cfgFile.good() && cfgFile)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf();
|
||||
svCmdLineArgs = ss.str() + "-launcher";
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_dedi_debug.cfg' does not exist!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_svWorkerDll = m_svCurrentDir + "\\dedicated.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex_ds.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex_ds.exe " + svCmdLineArgs;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHING DEDICATED [DEBUG] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_SERVER:
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_dedi_retail.cfg";
|
||||
std::ifstream cfgFile(cfgPath);
|
||||
if (cfgFile.good() && cfgFile)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf();
|
||||
svCmdLineArgs = ss.str(); +"-launcher";
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_dedi_retail.cfg' does not exist!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_svWorkerDll = m_svCurrentDir + "\\dedicated.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex_ds.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex_ds.exe " + svCmdLineArgs;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHING DEDICATED [RELEASE] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_CLIENT_DEBUG:
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_client_debug.cfg";
|
||||
std::ifstream cfgFile(cfgPath);
|
||||
if (cfgFile.good() && cfgFile)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf();
|
||||
svCmdLineArgs = ss.str(); +"-launcher";
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_client_debug.cfg' does not exist!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_svWorkerDll = m_svCurrentDir + "\\bin\\client.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCmdLineArgs;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [DEBUG] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_CLIENT:
|
||||
{
|
||||
fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_client_retail.cfg";
|
||||
std::ifstream cfgFile(cfgPath);
|
||||
if (cfgFile.good() && cfgFile)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cfgFile.rdbuf();
|
||||
svCmdLineArgs = ss.str(); +"-launcher";
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_client_retail.cfg' does not exist!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_svWorkerDll = m_svCurrentDir + "\\bin\\client.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCmdLineArgs;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [RELEASE] ***\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
AddLog(spdlog::level::level_enum::err, "*** NO LAUNCH MODE SPECIFIED ***\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Print the file paths and arguments.
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
spdlog::debug("- CWD: {}\n", svCurrentDir);
|
||||
spdlog::debug("- EXE: {}\n", svGameDir);
|
||||
spdlog::debug("- DLL: {}\n", svWorkerDll);
|
||||
spdlog::debug("- CLI: {}\n", svCmdLineArgs);
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::debug, "- CWD: {:s}\n", m_svCurrentDir);
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::debug, "- EXE: {:s}\n", m_svGameExe);
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::debug, "- DLL: {:s}\n", m_svWorkerDll);
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::debug, "- CLI: {:s}\n", svCmdLineArgs);
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Purpose: setup for game dll's and configurations
|
||||
// Input : lMode -
|
||||
// &svCommandLine -
|
||||
// Output : true on success, false otherwise
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool CLauncher::Setup(eLaunchMode lMode, const string& svCommandLine)
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
switch (lMode)
|
||||
{
|
||||
case eLaunchMode::LM_HOST_DEBUG:
|
||||
{
|
||||
m_svWorkerDll = m_svCurrentDir + "\\gamesdk.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCommandLine;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR HOST [DEBUG] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_HOST:
|
||||
{
|
||||
m_svWorkerDll = m_svCurrentDir + "\\gamesdk.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCommandLine;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR HOST [RELEASE] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_SERVER_DEBUG:
|
||||
{
|
||||
m_svWorkerDll = m_svCurrentDir + "\\dedicated.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex_ds.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex_ds.exe " + svCommandLine;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR DEDICATED [DEBUG] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_SERVER:
|
||||
{
|
||||
m_svWorkerDll = m_svCurrentDir + "\\dedicated.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex_ds.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex_ds.exe " + svCommandLine;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR DEDICATED [RELEASE] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_CLIENT_DEBUG:
|
||||
{
|
||||
m_svWorkerDll = m_svCurrentDir + "\\bin\\client.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCommandLine;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR CLIENT [DEBUG] ***\n");
|
||||
break;
|
||||
}
|
||||
case eLaunchMode::LM_CLIENT:
|
||||
{
|
||||
m_svWorkerDll = m_svCurrentDir + "\\bin\\client.dll";
|
||||
m_svGameExe = m_svCurrentDir + "\\r5apex.exe";
|
||||
m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCommandLine;
|
||||
|
||||
AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR CLIENT [RELEASE] ***\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
AddLog(spdlog::level::level_enum::err, "*** INVALID LAUNCH MODE SPECIFIED ***\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Print the file paths and arguments.
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::debug, "- CWD: {:s}\n", m_svCurrentDir);
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::debug, "- EXE: {:s}\n", m_svGameExe);
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::debug, "- DLL: {:s}\n", m_svWorkerDll);
|
||||
g_pLauncher->AddLog(spdlog::level::level_enum::debug, "- CLI: {:s}\n", svCommandLine);
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Purpose: launhes the game with results from the setup
|
||||
// Output : true on success, false otherwise
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool CLauncher::Launch() const
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Build our list of dlls to inject.
|
||||
LPCSTR DllsToInject[1] =
|
||||
{
|
||||
svWorkerDll.c_str()
|
||||
m_svWorkerDll.c_str()
|
||||
};
|
||||
|
||||
STARTUPINFOA StartupInfo = { 0 };
|
||||
@ -154,14 +559,14 @@ bool LaunchR5Apex(eLaunchMode lMode, eLaunchState lState)
|
||||
// Create the game process in a suspended state with our dll.
|
||||
BOOL result = DetourCreateProcessWithDllsA
|
||||
(
|
||||
svGameDir.c_str(), // lpApplicationName
|
||||
(LPSTR)svStartCmdLine.c_str(), // lpCommandLine
|
||||
m_svGameExe.c_str(), // lpApplicationName
|
||||
(LPSTR)m_svCmdLine.c_str(), // lpCommandLine
|
||||
NULL, // lpProcessAttributes
|
||||
NULL, // lpThreadAttributes
|
||||
FALSE, // bInheritHandles
|
||||
CREATE_SUSPENDED, // dwCreationFlags
|
||||
NULL, // lpEnvironment
|
||||
svCurrentDir.c_str(), // lpCurrentDirectory
|
||||
m_svCurrentDir.c_str(), // lpCurrentDirectory
|
||||
&StartupInfo, // lpStartupInfo
|
||||
&ProcInfo, // lpProcessInformation
|
||||
sizeof(DllsToInject) / sizeof(LPCSTR), // nDlls
|
||||
@ -194,104 +599,19 @@ bool LaunchR5Apex(eLaunchMode lMode, eLaunchState lState)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int main(int argc, char* argv[], char* envp[])
|
||||
{
|
||||
spdlog::set_pattern("[%^%l%$] %v");
|
||||
spdlog::set_level(spdlog::level::trace);
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
g_pLauncher->InitLogger();
|
||||
if (__argc < 2)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
if ((arg == "-debug") || (arg == "-dbg"))
|
||||
{
|
||||
LaunchR5Apex(eLaunchMode::LM_DEBUG_GAME, eLaunchState::LS_CHEATS);
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if ((arg == "-release") || (arg == "-rel"))
|
||||
{
|
||||
LaunchR5Apex(eLaunchMode::LM_RELEASE_GAME, eLaunchState::LS_CHEATS);
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if ((arg == "-dedicated_dev") || (arg == "-dedid"))
|
||||
{
|
||||
LaunchR5Apex(eLaunchMode::LM_DEBUG_DEDI, eLaunchState::LS_CHEATS);
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if ((arg == "-dedicated") || (arg == "-dedi"))
|
||||
{
|
||||
LaunchR5Apex(eLaunchMode::LM_RELEASE_DEDI, eLaunchState::LS_CHEATS);
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
FreeConsole();
|
||||
g_pLauncher->InitSurface();
|
||||
}
|
||||
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
spdlog::warn("If a DEBUG option has been choosen as launch parameter, do not broadcast servers to the Server Browser!\n");
|
||||
spdlog::warn("All FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ConVar's/ConCommand's will be enabled.\n");
|
||||
spdlog::warn("Connected clients will be able to set and execute anything flagged FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY.\n");
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
spdlog::warn("Use DEBUG GAME [1] for research and development purposes.\n");
|
||||
spdlog::warn("Use RELEASE GAME [2] for playing the game and creating servers.\n");
|
||||
spdlog::warn("Use DEBUG DEDICATED [3] for research and development purposes.\n");
|
||||
spdlog::warn("Use RELEASE DEDICATED [4] for running and hosting dedicated servers.\n");
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
spdlog::info("Enter '1' for 'DEBUG GAME'.\n");
|
||||
spdlog::info("Enter '2' for 'RELEASE GAME'.\n");
|
||||
spdlog::info("Enter '3' for 'DEBUG DEDICATED'.\n");
|
||||
spdlog::info("Enter '4' for 'RELEASE DEDICATED'.\n");
|
||||
std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
std::cout << "User input: ";
|
||||
|
||||
std::string input = std::string();
|
||||
if (std::cin >> input)
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
eLaunchMode mode = (eLaunchMode)std::stoi(input);
|
||||
switch (mode)
|
||||
{
|
||||
case eLaunchMode::LM_DEBUG_GAME:
|
||||
{
|
||||
LaunchR5Apex(eLaunchMode::LM_DEBUG_GAME, eLaunchState::LS_CHEATS);
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
case eLaunchMode::LM_RELEASE_GAME:
|
||||
{
|
||||
LaunchR5Apex(eLaunchMode::LM_RELEASE_GAME, eLaunchState::LS_CHEATS);
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
case eLaunchMode::LM_DEBUG_DEDI:
|
||||
{
|
||||
LaunchR5Apex(eLaunchMode::LM_DEBUG_DEDI, eLaunchState::LS_CHEATS);
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
case eLaunchMode::LM_RELEASE_DEDI:
|
||||
{
|
||||
LaunchR5Apex(eLaunchMode::LM_RELEASE_DEDI, eLaunchState::LS_CHEATS);
|
||||
Sleep(2000);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
default:
|
||||
{
|
||||
spdlog::error("R5Reloaded requires '1' for DEBUG GAME mode, '2' for RELEASE GAME mode, '3' for DEBUG DEDICATED mode, '4' for RELEASE DEDICATED mode.\n");
|
||||
Sleep(5000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
spdlog::error("R5Reloaded only takes numerical input to launch. Error: {}.\n", e.what());
|
||||
Sleep(5000);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
spdlog::error("R5Reloaded requires numerical input to launch.\n");
|
||||
int results = g_pLauncher->HandleCmdLine(__argc, __argv);
|
||||
if (results != -1)
|
||||
return results;
|
||||
|
||||
Sleep(5000);
|
||||
return EXIT_FAILURE;
|
||||
return g_pLauncher->HandleInput();
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -1,24 +1,52 @@
|
||||
#pragma once
|
||||
#include "basepanel.h"
|
||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Launch and inject specified dll based on launchmode
|
||||
//-----------------------------------------------------------------------------
|
||||
enum class eLaunchMode : int
|
||||
class CLauncher
|
||||
{
|
||||
LM_NULL,
|
||||
LM_DEBUG_GAME, // Debug worker DLL.
|
||||
LM_RELEASE_GAME, // Release worker DLL.
|
||||
LM_DEBUG_DEDI, // Debug dedicated DLL.
|
||||
LM_RELEASE_DEDI // Release dedicated DLL.
|
||||
};
|
||||
public:
|
||||
CLauncher()
|
||||
{
|
||||
m_svCurrentDir = fs::current_path().u8string();
|
||||
}
|
||||
~CLauncher()
|
||||
{
|
||||
delete[] m_pSurface;
|
||||
}
|
||||
template <typename T, typename ...P>
|
||||
void AddLog(spdlog::level::level_enum nLevel, T&& svFormat, P &&... vParams)
|
||||
{
|
||||
String svBuffer = fmt::format(std::forward<T>(svFormat), std::forward<P>(vParams)...).c_str();
|
||||
wconsole->log(nLevel, svBuffer.ToCString());
|
||||
wconsole->flush();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [TODO] Launch with FCVAR_DEVELOPMENTONLY and FCVAR_CHEATS disabled/enabled
|
||||
//-----------------------------------------------------------------------------
|
||||
enum class eLaunchState : int
|
||||
{
|
||||
LS_NULL,
|
||||
LS_NOCHEATS, // Disabled cheats
|
||||
LS_CHEATS, // Enable cheats
|
||||
LS_DEBUG // Enable debug
|
||||
if (m_pSurface)
|
||||
{
|
||||
m_pSurface->m_LogList.push_back(LogList_t(nLevel, svBuffer));
|
||||
m_pSurface->m_ConsoleListView->SetVirtualListSize(static_cast<int32_t>(m_pSurface->m_LogList.size()));
|
||||
m_pSurface->m_ConsoleListView->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void InitSurface();
|
||||
void InitConsole();
|
||||
void InitLogger();
|
||||
int HandleCmdLine(int argc, char* argv[]);
|
||||
int HandleInput();
|
||||
|
||||
bool Setup(eLaunchMode lMode, eLaunchState lState);
|
||||
bool Setup(eLaunchMode lMode, const string& svCommandLine);
|
||||
bool Launch() const;
|
||||
|
||||
CUIBaseSurface* GetMainSurface() const { return m_pSurface; }
|
||||
|
||||
private:
|
||||
CUIBaseSurface* m_pSurface = nullptr;
|
||||
std::shared_ptr<spdlog::logger> wconsole = spdlog::stdout_color_mt("win_console");
|
||||
|
||||
string m_svWorkerDll;
|
||||
string m_svGameExe;
|
||||
string m_svCmdLine;
|
||||
string m_svCurrentDir;
|
||||
};
|
||||
inline CLauncher* g_pLauncher = new CLauncher();
|
36
r5dev/sdklauncher/sdklauncher_const.h
Normal file
36
r5dev/sdklauncher/sdklauncher_const.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Launch and inject specified dll based on launchmode
|
||||
//-----------------------------------------------------------------------------
|
||||
//enum class eLaunchMode : int
|
||||
//{
|
||||
// LM_NULL,
|
||||
// LM_DEBUG_GAME, // Debug worker DLL.
|
||||
// LM_RELEASE_GAME, // Release worker DLL.
|
||||
// LM_DEBUG_DEDI, // Debug dedicated DLL.
|
||||
// LM_RELEASE_DEDI // Release dedicated DLL.
|
||||
//};
|
||||
|
||||
|
||||
enum class eLaunchMode : int
|
||||
{
|
||||
LM_NONE = -1,
|
||||
LM_HOST_DEBUG,
|
||||
LM_HOST,
|
||||
LM_SERVER_DEBUG,
|
||||
LM_SERVER,
|
||||
LM_CLIENT_DEBUG,
|
||||
LM_CLIENT,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [TODO] Launch with FCVAR_DEVELOPMENTONLY and FCVAR_CHEATS disabled/enabled
|
||||
//-----------------------------------------------------------------------------
|
||||
enum class eLaunchState : int
|
||||
{
|
||||
LS_NULL,
|
||||
LS_NOCHEATS, // Disabled cheats
|
||||
LS_CHEATS, // Enable cheats
|
||||
LS_DEBUG // Enable debug
|
||||
};
|
@ -7,7 +7,6 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "common/protocol.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/client/client.h"
|
||||
#include "server/vengineserver_impl.h"
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
//=============================================================================//
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "engine/server/server.h"
|
||||
#endif // CLIENT_DLL
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "tier0/commandline.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "tier1/IConVar.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#ifdef DEDICATED
|
||||
#include "engine/server/sv_rcon.h"
|
||||
#else // DEDICATED
|
||||
|
674
r5dev/thirdparty/cppnet/LICENSE.md
vendored
Normal file
674
r5dev/thirdparty/cppnet/LICENSE.md
vendored
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
2
r5dev/thirdparty/cppnet/README.md
vendored
Normal file
2
r5dev/thirdparty/cppnet/README.md
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# cppnet
|
||||
It's .NET for C++17
|
3
r5dev/thirdparty/cppnet/cppkore/Action.h
vendored
Normal file
3
r5dev/thirdparty/cppnet/cppkore/Action.h
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
typedef void(*Action)();
|
45
r5dev/thirdparty/cppnet/cppkore/Adler32.cpp
vendored
Normal file
45
r5dev/thirdparty/cppnet/cppkore/Adler32.cpp
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
#include "stdafx.h"
|
||||
#include "Adler32.h"
|
||||
|
||||
uint32_t Hashing::Adler32::ComputeHash(uint32_t adler, const void* ptr, size_t buflen)
|
||||
{
|
||||
if (!ptr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const uint8_t* buffer = static_cast<const uint8_t*>(ptr);
|
||||
|
||||
const unsigned long ADLER_MOD = 65521;
|
||||
unsigned long s1 = adler & 0xffff, s2 = adler >> 16;
|
||||
size_t blocklen;
|
||||
unsigned long i;
|
||||
|
||||
blocklen = buflen % 5552;
|
||||
while (buflen)
|
||||
{
|
||||
for (i = 0; i + 7 < blocklen; i += 8)
|
||||
{
|
||||
s1 += buffer[0], s2 += s1;
|
||||
s1 += buffer[1], s2 += s1;
|
||||
s1 += buffer[2], s2 += s1;
|
||||
s1 += buffer[3], s2 += s1;
|
||||
s1 += buffer[4], s2 += s1;
|
||||
s1 += buffer[5], s2 += s1;
|
||||
s1 += buffer[6], s2 += s1;
|
||||
s1 += buffer[7], s2 += s1;
|
||||
|
||||
buffer += 8;
|
||||
}
|
||||
|
||||
for (; i < blocklen; ++i)
|
||||
{
|
||||
s1 += *buffer++, s2 += s1;
|
||||
}
|
||||
|
||||
s1 %= ADLER_MOD, s2 %= ADLER_MOD;
|
||||
buflen -= blocklen;
|
||||
blocklen = 5552;
|
||||
}
|
||||
return (s2 << 16) + s1;
|
||||
}
|
12
r5dev/thirdparty/cppnet/cppkore/Adler32.h
vendored
Normal file
12
r5dev/thirdparty/cppnet/cppkore/Adler32.h
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace Hashing
|
||||
{
|
||||
// Mark Adler's compact Adler32 hashing algorithm
|
||||
// Originally from the public domain stb.h header.
|
||||
class Adler32
|
||||
{
|
||||
public:
|
||||
static uint32_t ComputeHash(uint32_t adler, const void* ptr, size_t buflen);
|
||||
};
|
||||
}
|
30
r5dev/thirdparty/cppnet/cppkore/AnchorStyles.h
vendored
Normal file
30
r5dev/thirdparty/cppnet/cppkore/AnchorStyles.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies how a control anchors to the edges of its container.
|
||||
enum class AnchorStyles
|
||||
{
|
||||
// The control is anchored to the top edge of its container.
|
||||
Top = 0x1,
|
||||
// The control is anchored to the bottom edge of its container.
|
||||
Bottom = 0x2,
|
||||
// The control is anchored to the left edge of its container.
|
||||
Left = 0x4,
|
||||
// The control is anchored to the right edge of its container.
|
||||
Right = 0x8,
|
||||
// The control is not anchored to any edges of its container.
|
||||
None = 0x0
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr AnchorStyles operator|(AnchorStyles Lhs, AnchorStyles Rhs)
|
||||
{
|
||||
return static_cast<AnchorStyles>(static_cast<std::underlying_type<AnchorStyles>::type>(Lhs) | static_cast<std::underlying_type<AnchorStyles>::type>(Rhs));
|
||||
};
|
||||
}
|
128
r5dev/thirdparty/cppnet/cppkore/Animation.cpp
vendored
Normal file
128
r5dev/thirdparty/cppnet/cppkore/Animation.cpp
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
#include "stdafx.h"
|
||||
#include "Animation.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
Animation::Animation()
|
||||
: Animation(0)
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(uint32_t BoneCount)
|
||||
: Animation(BoneCount, 30.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(uint32_t BoneCount, float FrameRate)
|
||||
: Bones(BoneCount), Looping(false), FrameRate(FrameRate), Name("error"), TransformSpace(AnimationTransformSpace::Local), RotationInterpolation(AnimationRotationInterpolation::Quaternion)
|
||||
{
|
||||
}
|
||||
|
||||
List<Curve>& Animation::GetNodeCurves(const String& NodeName)
|
||||
{
|
||||
if (Curves.ContainsKey(NodeName))
|
||||
return Curves[NodeName];
|
||||
|
||||
Curves.Add(NodeName, List<Curve>());
|
||||
return Curves[NodeName];
|
||||
}
|
||||
|
||||
void Animation::AddNotification(const String& Name, uint32_t Frame)
|
||||
{
|
||||
if (Notificiations.ContainsKey(Name))
|
||||
Notificiations[Name].EmplaceBack(Frame);
|
||||
|
||||
Notificiations.Add(Name, List<uint32_t>());
|
||||
Notificiations[Name].EmplaceBack(Frame);
|
||||
}
|
||||
|
||||
const uint32_t Animation::FrameCount(bool Legacy) const
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
|
||||
for (auto& Kvp : Curves)
|
||||
{
|
||||
for (auto& Curve : Kvp.Value())
|
||||
{
|
||||
if (Legacy)
|
||||
{
|
||||
// Used for animation types which do not support non-bone like curves
|
||||
// So we only have quaternion rotation, translations, and scales
|
||||
if (Curve.Property == CurveProperty::RotateQuaternion || (Curve.Property >= CurveProperty::TranslateX && Curve.Property <= CurveProperty::TranslateZ) || (Curve.Property >= CurveProperty::ScaleX && Curve.Property <= CurveProperty::ScaleZ))
|
||||
{
|
||||
for (auto& Keyframe : Curve.Keyframes)
|
||||
Result = max(Result, Keyframe.Frame.Integer32);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Support all curves
|
||||
for (auto& Keyframe : Curve.Keyframes)
|
||||
Result = max(Result, Keyframe.Frame.Integer32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& NoteTrack : Notificiations)
|
||||
for (auto& Note : NoteTrack.Value())
|
||||
Result = max(Result, Note);
|
||||
|
||||
// Frame count is the length of the animation in frames
|
||||
// Frames start at index 0, so we add one to get the count
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
const uint32_t Animation::NotificationCount() const
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
|
||||
for (auto& NoteTrack : Notificiations)
|
||||
Result += NoteTrack.Value().Count();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void Animation::Scale(float Factor)
|
||||
{
|
||||
for (auto& Kvp : Curves)
|
||||
{
|
||||
for (auto& Curve : Kvp.Value())
|
||||
{
|
||||
// Translation keyframes are scaled here...
|
||||
if (Curve.Property >= CurveProperty::TranslateX && Curve.Property <= CurveProperty::TranslateZ)
|
||||
{
|
||||
for (auto& Keyframe : Curve.Keyframes)
|
||||
{
|
||||
Keyframe.Value.Float *= Factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Bone : Bones)
|
||||
{
|
||||
if (Bone.GetFlag(BoneFlags::HasLocalSpaceMatrices))
|
||||
{
|
||||
Bone.SetLocalPosition(Bone.LocalPosition() * Factor);
|
||||
}
|
||||
if (Bone.GetFlag(BoneFlags::HasGlobalSpaceMatrices))
|
||||
{
|
||||
Bone.SetGlobalPosition(Bone.GlobalPosition() * Factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::RemoveEmptyNodes()
|
||||
{
|
||||
for (auto& Kvp : Curves)
|
||||
{
|
||||
for (int32_t i = ((int32_t)Kvp.Value().Count() - 1); i >= 0; i--)
|
||||
{
|
||||
if (Kvp.Value()[i].Keyframes.Count() == 0)
|
||||
{
|
||||
Kvp.Value().RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
r5dev/thirdparty/cppnet/cppkore/Animation.h
vendored
Normal file
62
r5dev/thirdparty/cppnet/cppkore/Animation.h
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include "ListBase.h"
|
||||
#include "DictionaryBase.h"
|
||||
|
||||
// The separate anim parts
|
||||
#include "Bone.h"
|
||||
#include "Vector3.h"
|
||||
#include "Quaternion.h"
|
||||
#include "AnimationTypes.h"
|
||||
#include "Curve.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// A container class that holds 3D animation data.
|
||||
class Animation
|
||||
{
|
||||
public:
|
||||
// Initialize a blank 3D animation without any known counts.
|
||||
Animation();
|
||||
// Initialize a 3D animation with the given count for bones.
|
||||
Animation(uint32_t BoneCount);
|
||||
// Initialize a 3D animation with the given bone count and framerate.
|
||||
Animation(uint32_t BoneCount, float FrameRate);
|
||||
|
||||
// The name of the animation
|
||||
String Name;
|
||||
|
||||
// A collection of 3D bones for this animation. (May or may not represent the actual skeleton)
|
||||
List<Bone> Bones;
|
||||
// The collection of curves that make up this animation.
|
||||
Dictionary<String, List<Curve>> Curves;
|
||||
// A collection of notifications that may occur.
|
||||
Dictionary<String, List<uint32_t>> Notificiations;
|
||||
|
||||
// Gets a reference to a list of node curves.
|
||||
List<Curve>& GetNodeCurves(const String& NodeName);
|
||||
// Adds a notification to the animation.
|
||||
void AddNotification(const String& Name, uint32_t Frame);
|
||||
|
||||
// Gets the count of frames in the animation.
|
||||
const uint32_t FrameCount(bool Legacy = false) const;
|
||||
// Gets the count of notifications in the animation.
|
||||
const uint32_t NotificationCount() const;
|
||||
|
||||
// Specifies if this animation should loop.
|
||||
bool Looping;
|
||||
// The framerate of this animation.
|
||||
float FrameRate;
|
||||
// The transformation space of this animation.
|
||||
AnimationTransformSpace TransformSpace;
|
||||
// The rotation interpolation mode.
|
||||
AnimationRotationInterpolation RotationInterpolation;
|
||||
|
||||
// Scales the animation with the given factor.
|
||||
void Scale(float Factor);
|
||||
// Removes nodes without keyframes.
|
||||
void RemoveEmptyNodes();
|
||||
};
|
||||
}
|
33
r5dev/thirdparty/cppnet/cppkore/AnimationTypes.h
vendored
Normal file
33
r5dev/thirdparty/cppnet/cppkore/AnimationTypes.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// This enumeration represents the possible animation types
|
||||
enum class AnimationCurveMode
|
||||
{
|
||||
// Animation translations are set to this exact value each frame.
|
||||
Absolute = 0,
|
||||
// Animation values are added on to the scene values.
|
||||
Additive = 1,
|
||||
// Animation values are relative to rest position in the model.
|
||||
Relative = 2
|
||||
};
|
||||
|
||||
// This enumeration represents the possible transform spaces
|
||||
enum class AnimationTransformSpace
|
||||
{
|
||||
// All of the curve nodes are in local object space
|
||||
Local = 0,
|
||||
// All of the curve nodes are in world space
|
||||
World = 1,
|
||||
};
|
||||
|
||||
// This enumeration represents the interpolation options
|
||||
enum class AnimationRotationInterpolation
|
||||
{
|
||||
Quaternion = 0,
|
||||
Euler = 1,
|
||||
};
|
||||
}
|
15
r5dev/thirdparty/cppnet/cppkore/Appearence.h
vendored
Normal file
15
r5dev/thirdparty/cppnet/cppkore/Appearence.h
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the appearance of a control.
|
||||
enum class Appearence
|
||||
{
|
||||
// The default appearance defined by the control.
|
||||
Normal = 0,
|
||||
// The appearance of a Windows button.
|
||||
Button = 1
|
||||
};
|
||||
}
|
116
r5dev/thirdparty/cppnet/cppkore/Application.cpp
vendored
Normal file
116
r5dev/thirdparty/cppnet/cppkore/Application.cpp
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
#include "stdafx.h"
|
||||
#include "Application.h"
|
||||
|
||||
// We're an application, so, we require GDI+, ComCtl32
|
||||
#pragma comment(lib, "Gdiplus.lib")
|
||||
#pragma comment(lib, "Comctl32.lib")
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// We haven't initialized it yet...
|
||||
std::atomic<bool> Application::IsGdipInitialized = false;
|
||||
ULONG_PTR Application::GdipToken = NULL;
|
||||
|
||||
void Application::Run(Form* MainWindow)
|
||||
{
|
||||
if (MainWindow == nullptr)
|
||||
return;
|
||||
|
||||
// Initialize COM
|
||||
OleInitialize(NULL);
|
||||
|
||||
#if _DEBUG
|
||||
if (!IsGdipInitialized)
|
||||
printf("-- Warning: GDI+ has not been initialized before Application::Run() --\n");
|
||||
#endif
|
||||
|
||||
// Execute on the main loop
|
||||
Application::RunMainLoop(MainWindow);
|
||||
|
||||
if (MainWindow)
|
||||
delete MainWindow;
|
||||
|
||||
// Shutdown COM
|
||||
OleUninitialize();
|
||||
}
|
||||
|
||||
void Application::RunDialog(Form* MainDialog)
|
||||
{
|
||||
// We must disable the owner dialog so that we can properly be the focus
|
||||
auto HwndOwner = GetWindowLongPtr(MainDialog->GetHandle(), GWLP_HWNDPARENT);
|
||||
if (HwndOwner != NULL)
|
||||
{
|
||||
if (IsWindowEnabled((HWND)HwndOwner))
|
||||
EnableWindow((HWND)HwndOwner, false);
|
||||
}
|
||||
|
||||
RunMainLoop(MainDialog);
|
||||
|
||||
// We must re-enable the owner window
|
||||
if (HwndOwner != NULL)
|
||||
EnableWindow((HWND)HwndOwner, true);
|
||||
}
|
||||
|
||||
void Application::EnableVisualStyles()
|
||||
{
|
||||
SetProcessDPIAware();
|
||||
if (!IsGdipInitialized)
|
||||
InitializeGdip();
|
||||
}
|
||||
|
||||
void Application::RunMainLoop(Form* MainWindow)
|
||||
{
|
||||
bool ContinueLoop = true;
|
||||
|
||||
//
|
||||
// Initialize the main window before starting the message pump...
|
||||
//
|
||||
|
||||
MainWindow->Show();
|
||||
|
||||
//
|
||||
// Loop until any of the conditions are met...
|
||||
//
|
||||
|
||||
MSG nMSG;
|
||||
while (ContinueLoop)
|
||||
{
|
||||
auto Peeked = PeekMessage(&nMSG, NULL, 0, 0, PM_NOREMOVE);
|
||||
|
||||
if (Peeked)
|
||||
{
|
||||
if (!GetMessage(&nMSG, NULL, 0, 0))
|
||||
continue;
|
||||
|
||||
TranslateMessage(&nMSG);
|
||||
DispatchMessage(&nMSG);
|
||||
|
||||
if (MainWindow)
|
||||
ContinueLoop = !MainWindow->CheckCloseDialog(false);
|
||||
}
|
||||
else if (MainWindow == nullptr || MainWindow->GetState(ControlStates::StateDisposed))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (!PeekMessage(&nMSG, NULL, 0, 0, PM_NOREMOVE))
|
||||
{
|
||||
WaitMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::InitializeGdip()
|
||||
{
|
||||
IsGdipInitialized = true;
|
||||
|
||||
Gdiplus::GdiplusStartupInput gdipStartup;
|
||||
Gdiplus::GdiplusStartup(&GdipToken, &gdipStartup, NULL);
|
||||
}
|
||||
|
||||
void Application::ShutdownGdip()
|
||||
{
|
||||
IsGdipInitialized = false;
|
||||
|
||||
Gdiplus::GdiplusShutdown(GdipToken);
|
||||
}
|
||||
}
|
37
r5dev/thirdparty/cppnet/cppkore/Application.h
vendored
Normal file
37
r5dev/thirdparty/cppnet/cppkore/Application.h
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include "Form.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides static methods and properties to manage an application.
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
// Begins running a standard application message loop on the current
|
||||
// thread, and makes the specified form visible.
|
||||
static void Run(Form* MainWindow);
|
||||
|
||||
// Begins running a dialog application loop on the
|
||||
// current thread, you MUST clean up the dialog after use.
|
||||
static void RunDialog(Form* MainDialog);
|
||||
|
||||
// Enables the use of visual style components and initializes GDI+.
|
||||
static void EnableVisualStyles();
|
||||
|
||||
private:
|
||||
// Runs the main window loop.
|
||||
static void RunMainLoop(Form* MainWindow);
|
||||
|
||||
// Whether or not GDI+ has been initialized
|
||||
static std::atomic<bool> IsGdipInitialized;
|
||||
// The token for GDI+
|
||||
static ULONG_PTR GdipToken;
|
||||
|
||||
// Internal cleanup routines
|
||||
static void InitializeGdip();
|
||||
static void ShutdownGdip();
|
||||
};
|
||||
}
|
720
r5dev/thirdparty/cppnet/cppkore/AssetRenderer.cpp
vendored
Normal file
720
r5dev/thirdparty/cppnet/cppkore/AssetRenderer.cpp
vendored
Normal file
@ -0,0 +1,720 @@
|
||||
#include "stdafx.h"
|
||||
#include <thread>
|
||||
#include "AssetRenderer.h"
|
||||
#include "Path.h"
|
||||
#include "Thread.h"
|
||||
|
||||
// Include the internal font, and shaders
|
||||
#include "FontArial.h"
|
||||
#include "ModelFragmentShader.h"
|
||||
#include "ModelVertexShader.h"
|
||||
|
||||
// We need to include the OpenGL classes
|
||||
#include "Mangler.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
AssetRenderer::AssetRenderer()
|
||||
: OpenGLViewport(), _Camera(0.5f* (float)MathHelper::PI, 0.45f* (float)MathHelper::PI, 100.f), _UseWireframe(false), _ShowBones(true), _ShowMaterials(true), _DrawingMode(DrawMode::Model), _DrawInformation{}, _BonePointBuffer(0), _BonePointCount(0), _DrawTexture(0)
|
||||
{
|
||||
}
|
||||
|
||||
AssetRenderer::~AssetRenderer()
|
||||
{
|
||||
ClearViewModel();
|
||||
ClearViewTexture();
|
||||
}
|
||||
|
||||
void AssetRenderer::SetViewModel(const Model& Model)
|
||||
{
|
||||
this->_DrawingMode = DrawMode::Model;
|
||||
ClearViewModel();
|
||||
ClearViewTexture();
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
auto Draw = DrawObject();
|
||||
|
||||
glGenVertexArrays(1, &Draw.VertexArrayObject);
|
||||
glBindVertexArray(Draw.VertexArrayObject);
|
||||
|
||||
// We'll take the POSITION, NORMAL, COLOR, and first UV pair...
|
||||
const uint32_t Stride = sizeof(Vector3) + sizeof(Vector3) + sizeof(VertexColor) + sizeof(Vector2);
|
||||
auto VertexBuffer = std::make_unique<uint8_t[]>((uint64_t)Submesh.Vertices.Count() * Stride);
|
||||
|
||||
uint64_t Offset = 0;
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
std::memcpy(&VertexBuffer.get()[Offset], &Vertex.Position(), Stride);
|
||||
Offset += Stride;
|
||||
}
|
||||
|
||||
glGenBuffers(1, &Draw.VertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, Draw.VertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, (Stride * (uint64_t)Submesh.Vertices.Count()), VertexBuffer.get(), GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &Draw.FaceBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Draw.FaceBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (uint64_t)Submesh.Faces.Count() * 3 * sizeof(uint32_t), &Submesh.Faces[0], GL_STATIC_DRAW);
|
||||
|
||||
wglSwapIntervalEXT(1);
|
||||
|
||||
Draw.FaceCount = Submesh.Faces.Count();
|
||||
Draw.VertexCount = Submesh.Vertices.Count();
|
||||
|
||||
if (Submesh.MaterialIndices.Count() > 0 && this->_MaterialStreamer != nullptr && Model.Materials.Count() != 0)
|
||||
{
|
||||
Assets::Material& Material = Model.Materials[Submesh.MaterialIndices[0]];
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
||||
{
|
||||
auto MaterialDiffuseMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Albedo].second);
|
||||
if (MaterialDiffuseMap != nullptr)
|
||||
{
|
||||
glGenTextures(1, &Draw.Material.AlbedoMap);
|
||||
this->LoadDXTextureOGL(*MaterialDiffuseMap.get(), Draw.Material.AlbedoMap);
|
||||
}
|
||||
}
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Normal))
|
||||
{
|
||||
auto MaterialNormalMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Normal].second);
|
||||
if (MaterialNormalMap != nullptr)
|
||||
{
|
||||
glGenTextures(1, &Draw.Material.NormalMap);
|
||||
this->LoadDXTextureOGL(*MaterialNormalMap.get(), Draw.Material.NormalMap);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Gloss))
|
||||
{
|
||||
auto MaterialGlossMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Gloss].second);
|
||||
if (MaterialGlossMap != nullptr)
|
||||
{
|
||||
glGenTextures(1, &Draw.Material.RoughnessMap);
|
||||
this->LoadDXTextureOGL(*MaterialGlossMap.get(), Draw.Material.RoughnessMap);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Specular))
|
||||
{
|
||||
auto MaterialSpecMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Specular].second);
|
||||
if (MaterialSpecMap != nullptr)
|
||||
{
|
||||
glGenTextures(1, &Draw.Material.MetallicMap);
|
||||
this->LoadDXTextureOGL(*MaterialSpecMap.get(), Draw.Material.MetallicMap);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Draw.LoadedMaterial = true;
|
||||
}
|
||||
|
||||
this->_DrawObjects.Emplace(Draw);
|
||||
this->_DrawInformation.VertexCount += Submesh.Vertices.Count();
|
||||
this->_DrawInformation.TriangleCount += Submesh.Faces.Count();
|
||||
}
|
||||
|
||||
glGenBuffers(1, &this->_BonePointBuffer);
|
||||
List<Math::Vector3> Positions;
|
||||
|
||||
for (int32_t i = (int32_t)Model.Bones.Count() - 1; i >= 0; i--)
|
||||
{
|
||||
auto& CurrentBone = Model.Bones[i];
|
||||
|
||||
Positions.EmplaceBack(Math::Matrix::TransformVector(CurrentBone.GlobalPosition(), this->_Camera.GetModelMatrix()));
|
||||
|
||||
if (CurrentBone.Parent() > -1)
|
||||
Positions.EmplaceBack(Math::Matrix::TransformVector(Model.Bones[CurrentBone.Parent()].GlobalPosition(), this->_Camera.GetModelMatrix()));
|
||||
else
|
||||
Positions.EmplaceBack(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
this->_BonePointCount = Positions.Count();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->_BonePointBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Math::Vector3) * Positions.Count(), &Positions[0], GL_STATIC_DRAW);
|
||||
|
||||
this->_DrawInformation.BoneCount = Model.Bones.Count();
|
||||
this->_DrawInformation.MeshCount = Model.Meshes.Count();
|
||||
|
||||
// Trigger a resize, then redraw, first redraw needs invalidation...
|
||||
this->OnResize();
|
||||
this->Invalidate();
|
||||
}
|
||||
|
||||
void AssetRenderer::SetAssetName(const String& Name)
|
||||
{
|
||||
this->_DrawInformation.AssetName = Name;
|
||||
this->Redraw();
|
||||
}
|
||||
|
||||
void AssetRenderer::ClearViewModel()
|
||||
{
|
||||
for (auto& Draw : _DrawObjects)
|
||||
{
|
||||
glDeleteVertexArrays(1, &Draw.VertexArrayObject);
|
||||
glDeleteBuffers(1, &Draw.VertexBuffer);
|
||||
glDeleteBuffers(1, &Draw.FaceBuffer);
|
||||
|
||||
if (Draw.LoadedMaterial)
|
||||
{
|
||||
glDeleteTextures(1, &Draw.Material.AlbedoMap);
|
||||
glDeleteTextures(1, &Draw.Material.AmbientOccluionMap);
|
||||
glDeleteTextures(1, &Draw.Material.MetallicMap);
|
||||
glDeleteTextures(1, &Draw.Material.NormalMap);
|
||||
glDeleteTextures(1, &Draw.Material.RoughnessMap);
|
||||
}
|
||||
}
|
||||
|
||||
glDeleteBuffers(1, &this->_BonePointBuffer);
|
||||
this->_BonePointBuffer = 0;
|
||||
this->_BonePointCount = 0;
|
||||
|
||||
_DrawObjects.Clear();
|
||||
_DrawInformation = {};
|
||||
}
|
||||
|
||||
void AssetRenderer::SetMaterialStreamer(MaterialStreamCallback Callback)
|
||||
{
|
||||
this->_MaterialStreamer = std::move(Callback);
|
||||
}
|
||||
|
||||
void AssetRenderer::SetViewTexture(const Texture& Texture)
|
||||
{
|
||||
this->_DrawingMode = DrawMode::Texture;
|
||||
ClearViewTexture();
|
||||
ClearViewModel();
|
||||
|
||||
glGenTextures(1, &this->_DrawTexture);
|
||||
|
||||
// Load into the draw texture slot
|
||||
this->LoadDXTextureOGL((Assets::Texture&)Texture, this->_DrawTexture);
|
||||
|
||||
this->_DrawInformation.Width = Texture.Width();
|
||||
this->_DrawInformation.Height = Texture.Height();
|
||||
|
||||
// Determine best fit scale to fit the image
|
||||
float Scale = min((float)this->_ClientWidth / (float)Texture.Width(), (float)this->_ClientHeight / (float)Texture.Height());
|
||||
this->_DrawInformation.Scale = min(100, (int)(Scale * 100));
|
||||
}
|
||||
|
||||
void AssetRenderer::ClearViewTexture()
|
||||
{
|
||||
glDeleteTextures(1, &this->_DrawTexture);
|
||||
_DrawInformation = {};
|
||||
}
|
||||
|
||||
void AssetRenderer::SetUseWireframe(bool Value)
|
||||
{
|
||||
if (Value != this->_UseWireframe)
|
||||
{
|
||||
this->_UseWireframe = Value;
|
||||
this->Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRenderer::SetShowBones(bool Value)
|
||||
{
|
||||
if (Value != this->_ShowBones)
|
||||
{
|
||||
this->_ShowBones = Value;
|
||||
this->Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRenderer::SetShowMaterials(bool Value)
|
||||
{
|
||||
if (Value != this->_ShowMaterials)
|
||||
{
|
||||
this->_ShowMaterials = Value;
|
||||
this->Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRenderer::SetZUpAxis(bool ZUp)
|
||||
{
|
||||
if (ZUp)
|
||||
this->_Camera.SetUpAxis(RenderViewCameraUpAxis::Z);
|
||||
else
|
||||
this->_Camera.SetUpAxis(RenderViewCameraUpAxis::Y);
|
||||
|
||||
if (this->GetState(Forms::ControlStates::StateCreated))
|
||||
this->Redraw();
|
||||
}
|
||||
|
||||
void AssetRenderer::ResetView()
|
||||
{
|
||||
this->_Camera.Reset(0.5f * (float)MathHelper::PI, 0.45f * (float)MathHelper::PI, 100.f);
|
||||
this->Redraw();
|
||||
}
|
||||
|
||||
void AssetRenderer::ZoomModelToView()
|
||||
{
|
||||
// Using the bounding box, we need to
|
||||
// TODO: Implement this zoom code
|
||||
}
|
||||
|
||||
void AssetRenderer::OnRender()
|
||||
{
|
||||
// Clear the frame
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
this->RenderBackground();
|
||||
|
||||
switch (this->_DrawingMode)
|
||||
{
|
||||
case DrawMode::Model:
|
||||
this->RenderGrid();
|
||||
this->RenderModel();
|
||||
break;
|
||||
case DrawMode::Texture:
|
||||
this->RenderTexture();
|
||||
break;
|
||||
}
|
||||
|
||||
this->RenderHUD();
|
||||
|
||||
// Render the frame
|
||||
SwapBuffers(this->_DCHandle);
|
||||
}
|
||||
|
||||
void AssetRenderer::OnResize()
|
||||
{
|
||||
glViewport(0, 0, this->_ClientWidth, this->_ClientHeight);
|
||||
|
||||
// Update the projection matrix
|
||||
this->_Camera.UpdateProjectionMatrix(45.f, (float)this->_ClientWidth, (float)this->_ClientHeight, .1f, 10000.f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(this->_Camera.GetProjectionMatrix().GetMatrix());
|
||||
|
||||
// Switch back to the modelview matrix
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// Ask the control to do the resize event
|
||||
OpenGLViewport::OnResize();
|
||||
}
|
||||
|
||||
void AssetRenderer::OnHandleCreated()
|
||||
{
|
||||
OpenGLViewport::OnHandleCreated();
|
||||
|
||||
// Now, the opengl context is completely valid, we can initialize our font / shaders
|
||||
this->_RenderFont.LoadFont(FontArial_PTRF, sizeof(FontArial_PTRF));
|
||||
|
||||
#if _DEBUG
|
||||
// Grab the root path of the libraries...
|
||||
auto CppNetPath = IO::Path::GetDirectoryName(IO::Path::GetDirectoryName(__FILE__));
|
||||
auto Vert = IO::Path::Combine(CppNetPath, "cppkore_shaders\\preview.vert");
|
||||
auto Frag = IO::Path::Combine(CppNetPath, "cppkore_shaders\\preview.frag");
|
||||
printf("-- NOTICE: Using debug shaders from disk --\n");
|
||||
printf("Vertex: %s\nFrag: %s\n", Vert.ToCString(), Frag.ToCString());
|
||||
this->_ModelShader.LoadShader(Vert, Frag);
|
||||
#else
|
||||
this->_ModelShader.LoadShader(ModelVertexShader_Src, ModelFragmentShader_Src);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AssetRenderer::OnKeyUp(const std::unique_ptr<Forms::KeyEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->KeyCode() == Forms::Keys::W)
|
||||
{
|
||||
this->SetUseWireframe(!this->_UseWireframe);
|
||||
}
|
||||
else if (EventArgs->KeyCode() == Forms::Keys::B)
|
||||
{
|
||||
this->SetShowBones(!this->_ShowBones);
|
||||
}
|
||||
else if (EventArgs->KeyCode() == Forms::Keys::T)
|
||||
{
|
||||
this->SetShowMaterials(!this->_ShowMaterials);
|
||||
}
|
||||
|
||||
OpenGLViewport::OnKeyUp(EventArgs);
|
||||
}
|
||||
|
||||
void AssetRenderer::OnMouseDown(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs)
|
||||
{
|
||||
this->_TargetMousePosition = Vector2((float)EventArgs->X, (float)EventArgs->Y);
|
||||
OpenGLViewport::OnMouseDown(EventArgs);
|
||||
}
|
||||
|
||||
void AssetRenderer::OnMouseMove(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs)
|
||||
{
|
||||
auto IsAltKey = (GetKeyState(VK_MENU) & 0x8000);
|
||||
|
||||
if (EventArgs->Button == Forms::MouseButtons::Left && IsAltKey)
|
||||
{
|
||||
float dPhi = ((float)(this->_TargetMousePosition.Y - EventArgs->Y) / 200.f);
|
||||
float dTheta = ((float)(this->_TargetMousePosition.X - EventArgs->X) / 200.f);
|
||||
|
||||
this->_Camera.Rotate(dTheta, dPhi);
|
||||
this->Redraw();
|
||||
}
|
||||
else if (EventArgs->Button == Forms::MouseButtons::Middle && IsAltKey)
|
||||
{
|
||||
float dx = ((float)(this->_TargetMousePosition.X - EventArgs->X));
|
||||
float dy = ((float)(this->_TargetMousePosition.Y - EventArgs->Y));
|
||||
|
||||
this->_Camera.Pan(dx * .1f, dy * .1f);
|
||||
this->Redraw();
|
||||
}
|
||||
else if (EventArgs->Button == Forms::MouseButtons::Right && IsAltKey)
|
||||
{
|
||||
float dx = ((float)(this->_TargetMousePosition.X - EventArgs->X) / 2.f);
|
||||
|
||||
this->_Camera.Zoom(-dx);
|
||||
this->Redraw();
|
||||
}
|
||||
|
||||
this->_TargetMousePosition = Vector2((float)EventArgs->X, (float)EventArgs->Y);
|
||||
|
||||
OpenGLViewport::OnMouseMove(EventArgs);
|
||||
}
|
||||
|
||||
void AssetRenderer::OnMouseWheel(const std::unique_ptr<Forms::HandledMouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (this->_DrawingMode == DrawMode::Texture)
|
||||
{
|
||||
if (EventArgs->Delta > 0)
|
||||
this->_DrawInformation.Scale += 3;
|
||||
else
|
||||
this->_DrawInformation.Scale -= 3;
|
||||
this->_DrawInformation.Scale = max(min(200, this->_DrawInformation.Scale), 0);
|
||||
}
|
||||
else if (this->_DrawingMode == DrawMode::Model)
|
||||
{
|
||||
this->_Camera.Zoom((float)EventArgs->Delta * .04f);
|
||||
}
|
||||
|
||||
this->Redraw();
|
||||
|
||||
OpenGLViewport::OnMouseWheel(EventArgs);
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderBackground()
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(this->_BackColor.GetR() / 255.f, this->_BackColor.GetG() / 255.f, this->_BackColor.GetB() / 255.f);
|
||||
|
||||
glVertex2f(-1.0, -1.0);
|
||||
glVertex2f(1.0, -1.0);
|
||||
glVertex2f(1.0, 1.0);
|
||||
glVertex2f(-1.0, 1.0);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderGrid()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(this->_Camera.GetProjectionMatrix().GetMatrix());
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(this->_Camera.GetViewMatrix().GetMatrix());
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glLineWidth(1.f);
|
||||
|
||||
auto Size = 5.0f;
|
||||
auto MinSize = -Size;
|
||||
auto Step = 0.5f;
|
||||
|
||||
for (GLfloat i = MinSize; i <= Size; i += Step)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
glColor3f(0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor3f(.70f, .70f, .70f);
|
||||
}
|
||||
|
||||
glVertex3f(i, 0, Size); glVertex3f(i, 0, MinSize);
|
||||
glVertex3f(Size, 0, i); glVertex3f(MinSize, 0, i);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderModel()
|
||||
{
|
||||
this->_ModelShader.Use();
|
||||
|
||||
if (_UseWireframe)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
// Calculate and load the matrix
|
||||
auto Model = this->_Camera.GetModelMatrix();
|
||||
auto View = this->_Camera.GetViewMatrix();
|
||||
auto Proj = this->_Camera.GetProjectionMatrix();
|
||||
|
||||
const uint32_t Stride = sizeof(Vector3) + sizeof(Vector3) + sizeof(VertexColor) + sizeof(Vector2);
|
||||
|
||||
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("model"), 1, GL_FALSE, Model.GetMatrix());
|
||||
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("view"), 1, GL_FALSE, View.GetMatrix());
|
||||
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("projection"), 1, GL_FALSE, Proj.GetMatrix());
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
for (auto& Draw : this->_DrawObjects)
|
||||
{
|
||||
|
||||
if (Draw.LoadedMaterial && this->_ShowMaterials)
|
||||
{
|
||||
const GLint DiffuseLoaded = 1;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseLoaded"), 1, &DiffuseLoaded);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
const GLint DiffuseLoaded = 0;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseLoaded"), 1, &DiffuseLoaded);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, Draw.Material.AlbedoMap);
|
||||
|
||||
const GLint DiffuseSlot = 0;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseTexture"), 1, &DiffuseSlot);
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, Draw.Material.NormalMap);
|
||||
|
||||
|
||||
const GLint NormalSlot = 1;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("normalTexture"), 1, &NormalSlot);
|
||||
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, Draw.Material.RoughnessMap);
|
||||
|
||||
|
||||
const GLint GlossSlot = 2;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("glossTexture"), 1, &GlossSlot);
|
||||
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, Draw.Material.MetallicMap);
|
||||
|
||||
|
||||
const GLint SpecularSlot = 3;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("specularTexture"), 1, &SpecularSlot);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, Draw.VertexBuffer);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, Stride, (void*)0);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, Stride, (void*)12);
|
||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, Stride, (void*)24);
|
||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, Stride, (void*)28);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Draw.FaceBuffer);
|
||||
glDrawElements(GL_TRIANGLES, Draw.FaceCount * 3, GL_UNSIGNED_INT, (void*)0);
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glDisableVertexAttribArray(2);
|
||||
glDisableVertexAttribArray(3);
|
||||
|
||||
this->_ModelShader.Detatch();
|
||||
|
||||
if (this->_ShowBones)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glColor3f(18 / 255.f, 0, 54 / 255.f);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->_BonePointBuffer);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, this->_BonePointCount);
|
||||
}
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderTexture()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(Matrix::CreateOrthographic(0, (float)this->_ClientWidth, (float)this->_ClientHeight, 0, -1, 1).GetMatrix());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
float Scale = (float)this->_DrawInformation.Scale / 100.f;
|
||||
|
||||
float ImageWidth = this->_DrawInformation.Width * Scale;
|
||||
float ImageHeight = this->_DrawInformation.Height * Scale;
|
||||
|
||||
float Width = (ImageWidth);
|
||||
float Height = (ImageHeight);
|
||||
float X = (this->_ClientWidth - (float)Width) / 2.0f;
|
||||
float Y = (this->_ClientHeight - (float)Height) / 2.0f;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_DrawTexture);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2i(0, 0); glVertex2f(X, Y);
|
||||
glTexCoord2i(0, 1); glVertex2f(X, Y + Height);
|
||||
glTexCoord2i(1, 1); glVertex2f(X + Width, Y + Height);
|
||||
glTexCoord2i(1, 0); glVertex2f(X + Width, Y);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderHUD()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(Matrix::CreateOrthographic(0, (float)this->_ClientWidth, (float)this->_ClientHeight, 0, -1, 1).GetMatrix());
|
||||
|
||||
// Scale the font size for dpi aware controls
|
||||
auto Screen = GetDC(nullptr);
|
||||
auto Ratio = GetDeviceCaps(Screen, LOGPIXELSX);
|
||||
ReleaseDC(nullptr, Screen);
|
||||
|
||||
// We based layout on stock 96 dpi, which is 100% scaling on windows
|
||||
// so scale linearly based on that
|
||||
const auto Scale = (1.0f - (96.f / (float)Ratio)) + 1.0f;
|
||||
const auto FontScale = 0.7f * Scale;
|
||||
|
||||
switch (this->_DrawingMode)
|
||||
{
|
||||
case DrawMode::Model:
|
||||
glColor4f(3 / 255.f, 169 / 255.f, 244 / 255.f, 1);
|
||||
|
||||
_RenderFont.RenderString("Model", 22, 22, FontScale); _RenderFont.RenderString(":", 80, 22, FontScale);
|
||||
_RenderFont.RenderString("Meshes", 22, 38, FontScale); _RenderFont.RenderString(":", 80, 38, FontScale);
|
||||
_RenderFont.RenderString("Verts", 22, 54, FontScale); _RenderFont.RenderString(":", 80, 54, FontScale);
|
||||
_RenderFont.RenderString("Tris", 22, 70, FontScale); _RenderFont.RenderString(":", 80, 70, FontScale);
|
||||
_RenderFont.RenderString("Bones", 22, 86, FontScale); _RenderFont.RenderString(":", 80, 86, FontScale);
|
||||
|
||||
glColor4f(35 / 255.f, 206 / 255.f, 107 / 255.f, 1);
|
||||
|
||||
_RenderFont.RenderString(String((this->_ShowBones) ? "Hide Bones (b), " : "Draw Bones (b), ") + String((this->_ShowMaterials) ? "Shaded View (t), " : "Material View (t), ") + String((this->_UseWireframe) ? "Hide Wireframe (w)" : "Draw Wireframe (w)"), 22, this->_Height - 44.f, FontScale);
|
||||
|
||||
glColor4f(0.9f, 0.9f, 0.9f, 1);
|
||||
|
||||
_RenderFont.RenderString((this->_DrawInformation.AssetName == "") ? String("N/A") : this->_DrawInformation.AssetName, 96, 22, FontScale);
|
||||
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.MeshCount), 96, 38, FontScale);
|
||||
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.VertexCount), 96, 54, FontScale);
|
||||
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.TriangleCount), 96, 70, FontScale);
|
||||
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.BoneCount), 96, 86, FontScale);
|
||||
break;
|
||||
case DrawMode::Texture:
|
||||
glColor4f(3 / 255.f, 169 / 255.f, 244 / 255.f, 1);
|
||||
|
||||
_RenderFont.RenderString("Image", 22, 22, FontScale); _RenderFont.RenderString(":", 80, 22, FontScale);
|
||||
_RenderFont.RenderString("Width", 22, 38, FontScale); _RenderFont.RenderString(":", 80, 38, FontScale);
|
||||
_RenderFont.RenderString("Height", 22, 54, FontScale); _RenderFont.RenderString(":", 80, 54, FontScale);
|
||||
_RenderFont.RenderString("Scale", 22, 70, FontScale); _RenderFont.RenderString(":", 80, 70, FontScale);
|
||||
|
||||
glColor4f(0.9f, 0.9f, 0.9f, 1);
|
||||
|
||||
_RenderFont.RenderString((this->_DrawInformation.AssetName == "") ? String("N/A") : this->_DrawInformation.AssetName, 96, 22, FontScale);
|
||||
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.Width), 96, 38, FontScale);
|
||||
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.Height), 96, 54, FontScale);
|
||||
_RenderFont.RenderString(String::Format("%d%%", this->_DrawInformation.Scale), 96, 70, FontScale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRenderer::LoadDXTextureOGL(Texture& Texture, const uint32_t TextureSlot)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, TextureSlot);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
switch (Texture.Format())
|
||||
{
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC6H_UF16:
|
||||
Texture.ConvertToFormat(DXGI_FORMAT_BC1_UNORM);
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC2_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC2_UNORM_SRGB:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC3_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC3_UNORM_SRGB:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC4_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC4_SNORM:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RED_RGTC1, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC5_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC5_SNORM:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RG_RGTC2, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC7_UNORM:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_R8_UNORM:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, Texture.Width(), Texture.Height(), 0, GL_RED, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_R8G8_UNORM:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, Texture.Width(), Texture.Height(), 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Texture.Width(), Texture.Height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
||||
break;
|
||||
default:
|
||||
#if _DEBUG
|
||||
printf("Unsupported DXGI->OGL mapping\n");
|
||||
__debugbreak();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DrawObject::DrawObject()
|
||||
: VertexArrayObject(0), VertexBuffer(0), FaceBuffer(0), LoadedMaterial(false), FaceCount(0), VertexCount(0), Material{(uint32_t)-1, (uint32_t)-1, (uint32_t)-1, (uint32_t)-1, (uint32_t)-1}
|
||||
{
|
||||
}
|
||||
}
|
165
r5dev/thirdparty/cppnet/cppkore/AssetRenderer.h
vendored
Normal file
165
r5dev/thirdparty/cppnet/cppkore/AssetRenderer.h
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include "Model.h"
|
||||
#include "Animation.h"
|
||||
#include "Texture.h"
|
||||
#include "ListBase.h"
|
||||
#include "OpenGLViewport.h"
|
||||
#include "RenderViewCamera.h"
|
||||
#include "RenderShader.h"
|
||||
#include "RenderFont.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// A 3D uniform buffer object
|
||||
struct DrawObjectMaterial
|
||||
{
|
||||
uint32_t AlbedoMap;
|
||||
uint32_t NormalMap;
|
||||
uint32_t MetallicMap;
|
||||
uint32_t RoughnessMap;
|
||||
uint32_t AmbientOccluionMap;
|
||||
};
|
||||
|
||||
// A 3D buffer object that is being drawn.
|
||||
struct DrawObject
|
||||
{
|
||||
uint32_t VertexArrayObject;
|
||||
uint32_t VertexBuffer;
|
||||
uint32_t FaceBuffer;
|
||||
|
||||
bool LoadedMaterial;
|
||||
DrawObjectMaterial Material;
|
||||
|
||||
uint32_t FaceCount;
|
||||
uint32_t VertexCount;
|
||||
|
||||
DrawObject();
|
||||
};
|
||||
|
||||
enum class DrawMode
|
||||
{
|
||||
Model,
|
||||
Animation,
|
||||
Texture
|
||||
};
|
||||
|
||||
// A 3D asset renderer control.
|
||||
class AssetRenderer : public Forms::OpenGLViewport
|
||||
{
|
||||
public:
|
||||
AssetRenderer();
|
||||
virtual ~AssetRenderer();
|
||||
|
||||
// Special function to stream in a material image
|
||||
using MaterialStreamCallback = std::function<std::unique_ptr<Texture>(const String, const uint64_t)>;
|
||||
|
||||
// Clears the current model, if any, and assigns the new one
|
||||
void SetViewModel(const Model& Model);
|
||||
// Clears the current model
|
||||
void ClearViewModel();
|
||||
|
||||
// Applies a custom material streamer routine
|
||||
void SetMaterialStreamer(MaterialStreamCallback Callback);
|
||||
|
||||
// Clears the current texture, if any, and assigns the new one
|
||||
void SetViewTexture(const Texture& Texture);
|
||||
// Clears the current texture
|
||||
void ClearViewTexture();
|
||||
|
||||
// Sets the name of the model
|
||||
void SetAssetName(const String& Name);
|
||||
|
||||
// Enable or disable wireframe rendering
|
||||
void SetUseWireframe(bool Value);
|
||||
// Enable or disable bone rendering
|
||||
void SetShowBones(bool Value);
|
||||
// Enable or disable material rendering
|
||||
void SetShowMaterials(bool Value);
|
||||
|
||||
// Changes the up axis
|
||||
void SetZUpAxis(bool ZUp);
|
||||
|
||||
// Resets the current view to the default view
|
||||
void ResetView();
|
||||
// Brings the current model into view
|
||||
void ZoomModelToView();
|
||||
|
||||
// We must define base events here
|
||||
virtual void OnRender();
|
||||
virtual void OnResize();
|
||||
virtual void OnHandleCreated();
|
||||
virtual void OnKeyUp(const std::unique_ptr<Forms::KeyEventArgs>& EventArgs);
|
||||
virtual void OnMouseDown(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseMove(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseWheel(const std::unique_ptr<Forms::HandledMouseEventArgs>& EventArgs);
|
||||
|
||||
private:
|
||||
// Internal buffers
|
||||
List<DrawObject> _DrawObjects;
|
||||
|
||||
// Internal buffer for texture mode
|
||||
uint32_t _DrawTexture;
|
||||
|
||||
// Internal bone point buffer
|
||||
uint32_t _BonePointBuffer;
|
||||
// Internal bone point count
|
||||
uint32_t _BonePointCount;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t VertexCount;
|
||||
uint32_t TriangleCount;
|
||||
uint32_t MeshCount;
|
||||
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
|
||||
int32_t Scale;
|
||||
|
||||
String AssetName;
|
||||
|
||||
uint32_t BoneCount;
|
||||
} _DrawInformation;
|
||||
|
||||
DrawMode _DrawingMode;
|
||||
|
||||
// The target mouse position
|
||||
Vector2 _TargetMousePosition;
|
||||
|
||||
// Function to handle streaming in material images
|
||||
MaterialStreamCallback _MaterialStreamer;
|
||||
|
||||
// The view camera instance
|
||||
RenderViewCamera _Camera;
|
||||
// The shader for the model
|
||||
RenderShader _ModelShader;
|
||||
// The render font instance
|
||||
RenderFont _RenderFont;
|
||||
|
||||
// Whether or not to use wireframe mode
|
||||
bool _UseWireframe;
|
||||
// Whether or not to show bones
|
||||
bool _ShowBones;
|
||||
// Whether or not to render with materials
|
||||
bool _ShowMaterials;
|
||||
|
||||
// Internal routine to render the gradient background
|
||||
void RenderBackground();
|
||||
// Internal routine to render the grid
|
||||
void RenderGrid();
|
||||
// Internal routine to render the model
|
||||
void RenderModel();
|
||||
// Internal routine to render the texture
|
||||
void RenderTexture();
|
||||
// Internal routine to render the hud
|
||||
void RenderHUD();
|
||||
|
||||
// Internal routine to load a texture to an index
|
||||
void LoadDXTextureOGL(Texture& Texture, const uint32_t TextureSlot);
|
||||
};
|
||||
}
|
75
r5dev/thirdparty/cppnet/cppkore/AtomicListBase.h
vendored
Normal file
75
r5dev/thirdparty/cppnet/cppkore/AtomicListBase.h
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include "ListBase.h"
|
||||
|
||||
template<typename T>
|
||||
class AtomicListBase
|
||||
{
|
||||
public:
|
||||
AtomicListBase();
|
||||
~AtomicListBase() = default;
|
||||
|
||||
void Enqueue(T& Item);
|
||||
bool Dequeue(T& Item);
|
||||
|
||||
bool IsEmpty() const;
|
||||
uint32_t Count() const;
|
||||
|
||||
private:
|
||||
List<T> _List;
|
||||
|
||||
std::atomic<uint32_t> _SyncCount;
|
||||
std::mutex _SyncContext;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline AtomicListBase<T>::AtomicListBase()
|
||||
: _SyncCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void AtomicListBase<T>::Enqueue(T& Item)
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(this->_SyncContext);
|
||||
this->_List.EmplaceBack(Item);
|
||||
}
|
||||
|
||||
this->_SyncCount++;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicListBase<T>::Dequeue(T& Item)
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(this->_SyncContext);
|
||||
const auto Length = this->_List.Count();
|
||||
|
||||
if (Length > 0)
|
||||
{
|
||||
Item = this->_List[Length - 1];
|
||||
this->_List.RemoveAt(Length - 1);
|
||||
|
||||
this->_SyncCount--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicListBase<T>::IsEmpty() const
|
||||
{
|
||||
return (this->_SyncCount == 0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline uint32_t AtomicListBase<T>::Count() const
|
||||
{
|
||||
return this->_SyncCount;
|
||||
}
|
132
r5dev/thirdparty/cppnet/cppkore/AtomicQueueBase.h
vendored
Normal file
132
r5dev/thirdparty/cppnet/cppkore/AtomicQueueBase.h
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include "ListBase.h"
|
||||
|
||||
struct AtomicSyncContext
|
||||
{
|
||||
std::atomic<uint32_t> _declspec(align(std::hardware_constructive_interference_size)) Head;
|
||||
std::atomic<uint32_t> _declspec(align(std::hardware_constructive_interference_size)) Tail;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class AtomicQueueBase
|
||||
{
|
||||
public:
|
||||
AtomicQueueBase();
|
||||
~AtomicQueueBase() = default;
|
||||
|
||||
bool Enqueue(T& Item, uint32_t Count = 1);
|
||||
bool Dequeue(T& Item, uint32_t Count = 1);
|
||||
|
||||
bool IsEmpty() const;
|
||||
uint32_t Count() const;
|
||||
|
||||
private:
|
||||
AtomicSyncContext _Writer;
|
||||
AtomicSyncContext _Reader;
|
||||
|
||||
constexpr static uint32_t BufferSize = (2 << 10);
|
||||
constexpr static uint32_t Mask = BufferSize - 1;
|
||||
|
||||
std::atomic_flag _SpinLock;
|
||||
T alignas(std::hardware_constructive_interference_size) _Buffer[BufferSize];
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline AtomicQueueBase<T>::AtomicQueueBase()
|
||||
: _Writer{ 0, 0 }, _Reader{ 0, 0 }, _Buffer{}, _SpinLock()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicQueueBase<T>::Enqueue(T& Item, uint32_t Count)
|
||||
{
|
||||
uint32_t NextHead, EndTail, NewHead;
|
||||
|
||||
// The queue can fail to insert if it's already full, so you must check the result..
|
||||
bool Success = false;
|
||||
do {
|
||||
NextHead = _Writer.Head.load(std::memory_order_acquire);
|
||||
EndTail = _Reader.Tail.load(std::memory_order_acquire);
|
||||
|
||||
// Check if queue is full, yield time slice to other threads
|
||||
if ((NextHead - EndTail + 1) > Mask)
|
||||
return false;
|
||||
|
||||
NewHead = NextHead + Count;
|
||||
Success = _Writer.Head.compare_exchange_weak(NextHead, NewHead, std::memory_order_release);
|
||||
} while (!Success);
|
||||
|
||||
_Buffer[NextHead & Mask] = Item;
|
||||
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
while (_Writer.Tail.load(std::memory_order_acquire) != NextHead)
|
||||
{
|
||||
// Spin lock wait
|
||||
while (_SpinLock.test_and_set(std::memory_order_acquire));
|
||||
}
|
||||
|
||||
// Set the value and unlock the spin
|
||||
_Writer.Tail.store(NewHead, std::memory_order_release);
|
||||
_SpinLock.clear(std::memory_order_release);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicQueueBase<T>::Dequeue(T& Item, uint32_t Count)
|
||||
{
|
||||
uint32_t Head, Tail, Next;
|
||||
|
||||
bool Success = false;
|
||||
do {
|
||||
Tail = _Reader.Head.load(std::memory_order_acquire);
|
||||
Head = _Writer.Tail.load(std::memory_order_acquire);
|
||||
|
||||
// Check if the queue is empty, in that case, no result
|
||||
if (Head == Tail)
|
||||
return false;
|
||||
|
||||
Next = Tail + Count;
|
||||
Success = _Reader.Head.compare_exchange_weak(Tail, Next, std::memory_order_release);
|
||||
} while (!Success);
|
||||
|
||||
Item = _Buffer[Tail & Mask];
|
||||
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
while (_Reader.Tail.load(std::memory_order_acquire) != Tail)
|
||||
{
|
||||
// Spin lock wait
|
||||
while (_SpinLock.test_and_set(std::memory_order_acquire));
|
||||
}
|
||||
|
||||
_Reader.Tail.store(Next, std::memory_order_release);
|
||||
_SpinLock.clear(std::memory_order_release);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicQueueBase<T>::IsEmpty() const
|
||||
{
|
||||
uint32_t Tail = _Reader.Head.load(std::memory_order_acquire);
|
||||
uint32_t Head = _Writer.Tail.load(std::memory_order_acquire);
|
||||
|
||||
// Check if the queue is empty, in that case, no result
|
||||
if (Head == Tail)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline uint32_t AtomicQueueBase<T>::Count() const
|
||||
{
|
||||
// We need to subtract where we are writing to
|
||||
uint32_t Tail = _Reader.Head.load(std::memory_order_acquire);
|
||||
uint32_t Head = _Writer.Tail.load(std::memory_order_acquire);
|
||||
|
||||
return (Head - Tail);
|
||||
}
|
13
r5dev/thirdparty/cppnet/cppkore/AutoScaleMode.h
vendored
Normal file
13
r5dev/thirdparty/cppnet/cppkore/AutoScaleMode.h
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the auto scaling mode used by a container control.
|
||||
enum class AutoScaleMode
|
||||
{
|
||||
None,
|
||||
Font,
|
||||
Dpi,
|
||||
Inherit
|
||||
};
|
||||
}
|
517
r5dev/thirdparty/cppnet/cppkore/AutodeskMaya.cpp
vendored
Normal file
517
r5dev/thirdparty/cppnet/cppkore/AutodeskMaya.cpp
vendored
Normal file
@ -0,0 +1,517 @@
|
||||
#include "stdafx.h"
|
||||
#include "AutodeskMaya.h"
|
||||
|
||||
#include "File.h"
|
||||
#include "Path.h"
|
||||
#include "CRC32.h"
|
||||
#include "StreamWriter.h"
|
||||
#include "DictionaryBase.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
bool AutodeskMaya::ExportAnimation(const Animation& Animation, const String& Path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AutodeskMaya::ExportModel(const Model& Model, const String& Path)
|
||||
{
|
||||
auto Writer = IO::StreamWriter(IO::File::Create(Path));
|
||||
auto FileName = IO::Path::GetFileNameWithoutExtension(Path);
|
||||
auto Hash = Hashing::CRC32::HashString(FileName);
|
||||
|
||||
Writer.WriteLine(
|
||||
"//Maya ASCII 8.5 scene\n\n"
|
||||
"requires maya \"8.5\";\ncurrentUnit -l centimeter -a degree -t film;\nfileInfo \"application\" \"maya\";\nfileInfo \"product\" \"Maya Unlimited 8.5\";\nfileInfo \"version\" \"8.5\";\nfileInfo \"cutIdentifier\" \"200612162224-692032\";"
|
||||
"createNode transform -s -n \"persp\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 48.186233840145825 37.816674066853686 41.0540421364379 ;\n\tsetAttr \".r\" -type \"double3\" -29.738352729603015 49.400000000000432 0 ;\ncreateNode camera -s -n \"perspShape\" -p \"persp\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".fl\" 34.999999999999993;\n\tsetAttr \".fcp\" 10000;\n\tsetAttr \".coi\" 73.724849603665149;\n\tsetAttr \".imn\" -type \"string\" \"persp\";\n\tsetAttr \".den\" -type \"string\" \"persp_depth\";\n\tsetAttr \".man\" -type \"string\" \"persp_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -p %camera\";\ncreateNode transform -s -n \"top\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 0 100.1 0 ;\n\tsetAttr \".r\" -type \"double3\" -89.999999999999986 0 0 ;\ncreateNode camera -s -n \"topShape\" -p \"top\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"top\";\n\tsetAttr \".den\" -type \"string\" \"top_depth\";\n\tsetAttr \".man\" -type \"string\" \"top_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -t %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -s -n \"front\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 0 0 100.1 ;\ncreateNode camera -s -n \"frontShape\" -p \"front\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"front\";\n\tsetAttr \".den\" -type \"string\" \"front_depth\";\n\tsetAttr \".man\" -type \"string\" \"front_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -f %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -s -n \"side\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 100.1 0 0 ;\n\tsetAttr \".r\" -type \"double3\" 0 89.999999999999986 0 ;\ncreateNode camera -s -n \"sideShape\" -p \"side\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"side\";\n\tsetAttr \".den\" -type \"string\" \"side_depth\";\n\tsetAttr \".man\" -type \"string\" \"side_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -s %camera\";\n\tsetAttr \".o\" yes;\ncreateNode lightLinker -n \"lightLinker1\";\n\tsetAttr -s 9 \".lnk\";\n\tsetAttr -s 9 \".slnk\";\ncreateNode displayLayerManager -n \"layerManager\";\ncreateNode displayLayer -n \"defaultLayer\";\ncreateNode renderLayerManager -n \"renderLayerManager\";\ncreateNode renderLayer -n \"defaultRenderLayer\";\n\tsetAttr \".g\" yes;\ncreateNode script -n \"sceneConfigurationScriptNode\";\n\tsetAttr \".b\" -type \"string\" \"playbackOptions -min 1 -max 24 -ast 1 -aet 48 \";\n\tsetAttr \".st\" 6;\nselect -ne :time1;\n\tsetAttr \".o\" 1;\nselect -ne :renderPartition;\n\tsetAttr -s 2 \".st\";\nselect -ne :renderGlobalsList1;\nselect -ne :defaultShaderList1;\n\tsetAttr -s 2 \".s\";\nselect -ne :postProcessList1;\n\tsetAttr -s 2 \".p\";\nselect -ne :lightList1;\nselect -ne :initialShadingGroup;\n\tsetAttr \".ro\" yes;\nselect -ne :initialParticleSE;\n\tsetAttr \".ro\" yes;\nselect -ne :hardwareRenderGlobals;\n\tsetAttr \".ctrs\" 256;\n\tsetAttr \".btrs\" 512;\nselect -ne :defaultHardwareRenderGlobals;\n\tsetAttr \".fn\" -type \"string\" \"im\";\n\tsetAttr \".res\" -type \"string\" \"ntsc_4d 646 485 1.333\";\nselect -ne :ikSystem;\n\tsetAttr -s 4 \".sol\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[0].llnk\";\nconnectAttr \":initialShadingGroup.msg\" \"lightLinker1.lnk[0].olnk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[1].llnk\";\nconnectAttr \":initialParticleSE.msg\" \"lightLinker1.lnk[1].olnk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[0].sllk\";\nconnectAttr \":initialShadingGroup.msg\" \"lightLinker1.slnk[0].solk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[1].sllk\";\nconnectAttr \":initialParticleSE.msg\" \"lightLinker1.slnk[1].solk\";\nconnectAttr \"layerManager.dli[0]\" \"defaultLayer.id\";\nconnectAttr \"renderLayerManager.rlmi[0]\" \"defaultRenderLayer.rlid\";\nconnectAttr \"lightLinker1.msg\" \":lightList1.ln\" -na;"
|
||||
);
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"createNode transform -n \"%s\";\n"
|
||||
"setAttr \".ove\" yes;",
|
||||
(char*)FileName
|
||||
);
|
||||
|
||||
uint32_t SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
Writer.WriteLineFmt(
|
||||
"createNode transform -n \"KoreMesh_%08x_%02d\" -p \"%s\";\n"
|
||||
"setAttr \".rp\" -type \"double3\" 0.000000 0.000000 0.000000 ;\nsetAttr \".sp\" -type \"double3\" 0.000000 0.000000 0.000000 ;\n"
|
||||
"createNode mesh -n \"MeshShape_%d\" -p \"KoreMesh_%08x_%02d\";\n"
|
||||
"setAttr -k off \".v\";\nsetAttr \".vir\" yes;\nsetAttr \".vif\" yes;\n"
|
||||
"setAttr -s %d \".uvst\";",
|
||||
Hash, SubmeshIndex, (char*)FileName,
|
||||
SubmeshIndex, Hash, SubmeshIndex,
|
||||
Submesh.Vertices.UVLayerCount()
|
||||
);
|
||||
|
||||
for (uint8_t i = 1; i < Submesh.Vertices.UVLayerCount() + 1; i++)
|
||||
{
|
||||
if (Submesh.Vertices.Count() == 1)
|
||||
{
|
||||
Writer.WriteFmt(
|
||||
"setAttr \".uvst[%d].uvsn\" -type \"string\" \"map%d\";\n"
|
||||
"setAttr -s 1 \".uvst[0].uvsp[0]\" -type \"float2\"",
|
||||
(i - 1), i
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Writer.WriteFmt(
|
||||
"setAttr \".uvst[%d].uvsn\" -type \"string\" \"map%d\";\n"
|
||||
"setAttr -s %d \".uvst[0].uvsp[0:%d]\" -type \"float2\"",
|
||||
(i - 1), i,
|
||||
Submesh.Vertices.Count(), (Submesh.Vertices.Count() - 1)
|
||||
);
|
||||
}
|
||||
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
auto& Layer = Vertex.UVLayers(i - 1);
|
||||
Writer.WriteFmt(" %f %f", Layer.U, (1 - Layer.V));
|
||||
}
|
||||
|
||||
Writer.Write(";\n");
|
||||
}
|
||||
|
||||
Writer.WriteFmt(
|
||||
"setAttr \".cuvs\" -type \"string\" \"map1\";\nsetAttr \".dcol\" yes;\nsetAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";\nsetAttr \".ccls\" -type \"string\" \"colorSet1\";\nsetAttr \".clst[0].clsn\" -type \"string\" \"colorSet1\";\n"
|
||||
"setAttr -s %d \".clst[0].clsp\";\n"
|
||||
"setAttr \".clst[0].clsp[0:%d]\"",
|
||||
(Submesh.Faces.Count() * 3),
|
||||
(Submesh.Faces.Count() * 3) - 1
|
||||
);
|
||||
|
||||
for (auto& Face : Submesh.Faces)
|
||||
{
|
||||
auto& Vertex1 = Submesh.Vertices[Face[2]].Color();
|
||||
auto& Vertex2 = Submesh.Vertices[Face[1]].Color();
|
||||
auto& Vertex3 = Submesh.Vertices[Face[0]].Color();
|
||||
|
||||
Writer.WriteFmt(
|
||||
" %f %f %f %f"
|
||||
" %f %f %f %f"
|
||||
" %f %f %f %f",
|
||||
Vertex1[0] / 255.f, Vertex1[1] / 255.f, Vertex1[2] / 255.f, Vertex1[3] / 255.f,
|
||||
Vertex2[0] / 255.f, Vertex2[1] / 255.f, Vertex2[2] / 255.f, Vertex2[3] / 255.f,
|
||||
Vertex3[0] / 255.f, Vertex3[1] / 255.f, Vertex3[2] / 255.f, Vertex3[3] / 255.f
|
||||
);
|
||||
}
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
";\n"
|
||||
"setAttr \".covm[0]\" 0 1 1;\nsetAttr \".cdvm[0]\" 0 1 1;\nsetAttr -s %d \".vt\";",
|
||||
Submesh.Vertices.Count()
|
||||
);
|
||||
|
||||
if (Submesh.Vertices.Count() == 1)
|
||||
Writer.Write("setAttr \".vt[0]\"");
|
||||
else
|
||||
Writer.WriteFmt("setAttr \".vt[0:%d]\"", Submesh.Vertices.Count() - 1);
|
||||
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
auto& Position = Vertex.Position();
|
||||
Writer.WriteFmt(" %f %f %f", Position.X, Position.Y, Position.Z);
|
||||
}
|
||||
|
||||
Writer.WriteFmt(
|
||||
";\n"
|
||||
"setAttr -s %d \".ed\";\n"
|
||||
"setAttr \".ed[0:%d]\"",
|
||||
(Submesh.Faces.Count() * 3),
|
||||
(Submesh.Faces.Count() * 3) - 1
|
||||
);
|
||||
|
||||
for (auto& Face : Submesh.Faces)
|
||||
Writer.WriteFmt(" %d %d 0 %d %d 0 %d %d 0", Face[2], Face[1], Face[1], Face[0], Face[0], Face[2]);
|
||||
|
||||
Writer.WriteFmt(
|
||||
";\n"
|
||||
"setAttr -s %d \".n\";\n"
|
||||
"setAttr \".n[0:%d]\" -type \"float3\"",
|
||||
(Submesh.Faces.Count() * 3),
|
||||
(Submesh.Faces.Count() * 3) - 1
|
||||
);
|
||||
|
||||
for (auto& Face : Submesh.Faces)
|
||||
{
|
||||
auto& Vertex1 = Submesh.Vertices[Face[2]].Normal();
|
||||
auto& Vertex2 = Submesh.Vertices[Face[1]].Normal();
|
||||
auto& Vertex3 = Submesh.Vertices[Face[0]].Normal();
|
||||
|
||||
Writer.WriteFmt(
|
||||
" %f %f %f"
|
||||
" %f %f %f"
|
||||
" %f %f %f",
|
||||
Vertex1.X, Vertex1.Y, Vertex1.Z,
|
||||
Vertex2.X, Vertex2.Y, Vertex2.Z,
|
||||
Vertex3.X, Vertex3.Y, Vertex3.Z
|
||||
);
|
||||
}
|
||||
|
||||
Writer.WriteLine(";");
|
||||
|
||||
if (Submesh.Faces.Count() == 1)
|
||||
Writer.WriteFmt("setAttr -s %d \".fc[0]\" -type \"polyFaces\"", Submesh.Faces.Count());
|
||||
else
|
||||
Writer.WriteFmt("setAttr -s %d \".fc[0:%d]\" -type \"polyFaces\"", Submesh.Faces.Count(), Submesh.Faces.Count() - 1);
|
||||
|
||||
uint32_t FaceIndex = 0;
|
||||
|
||||
for (auto& Face : Submesh.Faces)
|
||||
{
|
||||
Writer.WriteFmt(" f 3 %d %d %d", FaceIndex, (FaceIndex + 1), (FaceIndex + 2));
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
Writer.WriteFmt(" mu %d 3 %d %d %d", i, Face[2], Face[1], Face[0]);
|
||||
|
||||
Writer.WriteFmt(" mc 0 3 %d %d %d", FaceIndex, (FaceIndex + 1), (FaceIndex + 2));
|
||||
|
||||
FaceIndex += 3;
|
||||
}
|
||||
|
||||
Writer.WriteLine(
|
||||
";\n"
|
||||
"setAttr \".cd\" -type \"dataPolyComponent\" Index_Data Edge 0 ;\nsetAttr \".cvd\" -type \"dataPolyComponent\" Index_Data Vertex 0 ;\nsetAttr \".hfd\" -type \"dataPolyComponent\" Index_Data Face 0 ;"
|
||||
);
|
||||
|
||||
SubmeshIndex++;
|
||||
}
|
||||
|
||||
Writer.Write("\n");
|
||||
|
||||
for (auto& Material : Model.Materials)
|
||||
{
|
||||
auto MaterialName = (char*)Material.Name;
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"createNode shadingEngine -n \"%sSG\";\n"
|
||||
"setAttr \".ihi\" 0;\n"
|
||||
"setAttr \".ro\" yes;\n"
|
||||
"createNode materialInfo -n \"%sMI\";\r\ncreateNode lambert -n \"%s\";\n"
|
||||
"createNode place2dTexture -n \"%sP2DT\";",
|
||||
MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName
|
||||
);
|
||||
|
||||
auto DiffuseTexture = (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
||||
? MaterialSlotType::Albedo : (Material.Slots.ContainsKey(MaterialSlotType::Diffuse) ? MaterialSlotType::Diffuse : MaterialSlotType::Invalid);
|
||||
|
||||
if (DiffuseTexture != MaterialSlotType::Invalid)
|
||||
{
|
||||
Writer.WriteLineFmt(
|
||||
"createNode file -n \"%sFILE\";\n"
|
||||
"setAttr \".ftn\" -type \"string\" \"%s\";",
|
||||
MaterialName,
|
||||
(char*)String(Material.Slots[DiffuseTexture].first).Replace("\\", "\\\\")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t LightConnectionIndex = 2;
|
||||
|
||||
for (auto& Material : Model.Materials)
|
||||
{
|
||||
auto MaterialName = (char*)Material.Name;
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"connectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[%d].llnk\";\n"
|
||||
"connectAttr \"%sSG.msg\" \"lightLinker1.lnk[%d].olnk\";\n"
|
||||
"connectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[%d].sllk\";\n"
|
||||
"connectAttr \"%sSG.msg\" \"lightLinker1.slnk[%d].solk\";\n"
|
||||
"connectAttr \"%s.oc\" \"%sSG.ss\";\n"
|
||||
"connectAttr \"%sSG.msg\" \"%sMI.sg\";\n"
|
||||
"connectAttr \"%s.msg\" \"%sMI.m\";",
|
||||
LightConnectionIndex,
|
||||
MaterialName, LightConnectionIndex,
|
||||
LightConnectionIndex,
|
||||
MaterialName, LightConnectionIndex,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName
|
||||
);
|
||||
|
||||
auto DiffuseTexture = (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
||||
? MaterialSlotType::Albedo : (Material.Slots.ContainsKey(MaterialSlotType::Diffuse) ? MaterialSlotType::Diffuse : MaterialSlotType::Invalid);
|
||||
|
||||
if (DiffuseTexture != MaterialSlotType::Invalid)
|
||||
{
|
||||
Writer.WriteLineFmt(
|
||||
"connectAttr \"%sFILE.msg\" \"%sMI.t\" -na;\n"
|
||||
"connectAttr \"%sFILE.oc\" \"%s.c\";\n"
|
||||
"connectAttr \"%sP2DT.c\" \"%sFILE.c\";\n"
|
||||
"connectAttr \"%sP2DT.tf\" \"%sFILE.tf\";\n"
|
||||
"connectAttr \"%sP2DT.rf\" \"%sFILE.rf\";\n"
|
||||
"connectAttr \"%sP2DT.mu\" \"%sFILE.mu\";\n"
|
||||
"connectAttr \"%sP2DT.mv\" \"%sFILE.mv\";\n"
|
||||
"connectAttr \"%sP2DT.s\" \"%sFILE.s\";\n"
|
||||
"connectAttr \"%sP2DT.wu\" \"%sFILE.wu\";\n"
|
||||
"connectAttr \"%sP2DT.wv\" \"%sFILE.wv\";\n"
|
||||
"connectAttr \"%sP2DT.re\" \"%sFILE.re\";\n"
|
||||
"connectAttr \"%sP2DT.of\" \"%sFILE.of\";\n"
|
||||
"connectAttr \"%sP2DT.r\" \"%sFILE.ro\";\n"
|
||||
"connectAttr \"%sP2DT.n\" \"%sFILE.n\";\n"
|
||||
"connectAttr \"%sP2DT.vt1\" \"%sFILE.vt1\";\n"
|
||||
"connectAttr \"%sP2DT.vt2\" \"%sFILE.vt2\";\n"
|
||||
"connectAttr \"%sP2DT.vt3\" \"%sFILE.vt3\";\n"
|
||||
"connectAttr \"%sP2DT.vc1\" \"%sFILE.vc1\";\n"
|
||||
"connectAttr \"%sP2DT.o\" \"%sFILE.uv\";\n"
|
||||
"connectAttr \"%sP2DT.ofs\" \"%sFILE.fs\";\n",
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName
|
||||
);
|
||||
}
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"connectAttr \"%sSG.pa\" \":renderPartition.st\" -na;\n"
|
||||
"connectAttr \"%s.msg\" \":defaultShaderList1.s\" -na;\n"
|
||||
"connectAttr \"%sP2DT.msg\" \":defaultRenderUtilityList1.u\" -na;\n"
|
||||
"connectAttr \"%sFILE.msg\" \":defaultTextureList1.tx\" -na;\n",
|
||||
MaterialName,
|
||||
MaterialName,
|
||||
MaterialName,
|
||||
MaterialName
|
||||
);
|
||||
|
||||
LightConnectionIndex++;
|
||||
}
|
||||
|
||||
SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
Writer.WriteLineFmt(
|
||||
"setAttr -s %d \"MeshShape_%d.iog\";",
|
||||
Submesh.Vertices.UVLayerCount(), SubmeshIndex
|
||||
);
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
{
|
||||
if (Submesh.MaterialIndices[i] < 0)
|
||||
continue;
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"connectAttr \"MeshShape_%d.iog[%d]\" \"%sSG.dsm\" -na;",
|
||||
SubmeshIndex, i, (char*)Model.Materials[Submesh.MaterialIndices[i]].Name
|
||||
);
|
||||
}
|
||||
|
||||
SubmeshIndex++;
|
||||
}
|
||||
|
||||
Writer.WriteLine(
|
||||
"createNode transform -n \"Joints\";\nsetAttr \".ove\" yes;\n"
|
||||
);
|
||||
|
||||
for (auto& Bone : Model.Bones)
|
||||
{
|
||||
if (Bone.Parent() == -1)
|
||||
Writer.WriteLineFmt("createNode joint -n \"%s\" -p \"Joints\";", (char*)Bone.Name());
|
||||
else
|
||||
Writer.WriteLineFmt("createNode joint -n \"%s\" -p \"%s\";", (char*)Bone.Name(), (char*)Model.Bones[Bone.Parent()].Name());
|
||||
|
||||
if (Bone.GetFlag(BoneFlags::HasLocalSpaceMatrices))
|
||||
{
|
||||
auto Rotation = Bone.LocalRotation().ToEulerAngles();
|
||||
|
||||
auto& Position = Bone.LocalPosition();
|
||||
auto& Scale = Bone.Scale();
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"addAttr -ci true -sn \"liw\" -ln \"lockInfluenceWeights\" -bt \"lock\" -min 0 -max 1 -at \"bool\";\n"
|
||||
"setAttr \".uoc\" yes;\n"
|
||||
"setAttr \".ove\" yes;\n"
|
||||
"setAttr \".t\" -type \"double3\" %f %f %f ;\n"
|
||||
"setAttr \".mnrl\" -type \"double3\" -360 -360 -360 ;\n"
|
||||
"setAttr \".mxrl\" -type \"double3\" 360 360 360 ;\n"
|
||||
"setAttr \".radi\" 0.50;\n"
|
||||
"setAttr \".jo\" -type \"double3\" %f %f %f;\n"
|
||||
"setAttr \".scale\" -type \"double3\" %f %f %f;\n",
|
||||
Position.X, Position.Y, Position.Z,
|
||||
Rotation.X, Rotation.Y, Rotation.Z,
|
||||
Scale.X, Scale.Y, Scale.Z
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto Rotation = Bone.GlobalRotation().ToEulerAngles();
|
||||
|
||||
auto& Position = Bone.GlobalPosition();
|
||||
auto& Scale = Bone.Scale();
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"addAttr -ci true -sn \"liw\" -ln \"lockInfluenceWeights\" -bt \"lock\" -min 0 -max 1 -at \"bool\";\n"
|
||||
"setAttr \".uoc\" yes;\n"
|
||||
"setAttr \".ove\" yes;\n"
|
||||
"setAttr \".it\" no;\n"
|
||||
"setAttr \".t\" -type \"double3\" %f %f %f ;\n"
|
||||
"setAttr \".mnrl\" -type \"double3\" -360 -360 -360 ;\n"
|
||||
"setAttr \".mxrl\" -type \"double3\" 360 360 360 ;\n"
|
||||
"setAttr \".radi\" 0.50;\n"
|
||||
"setAttr \".jo\" -type \"double3\" %f %f %f;\n"
|
||||
"setAttr \".scale\" -type \"double3\" %f %f %f;\n",
|
||||
Position.X, Position.Y, Position.Z,
|
||||
Rotation.X, Rotation.Y, Rotation.Z,
|
||||
Scale.X, Scale.Y, Scale.Z
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
auto Binder = IO::StreamWriter(IO::File::Create(IO::Path::Combine(IO::Path::GetDirectoryName(Path), FileName + "_BIND.mel")));
|
||||
|
||||
Binder.WriteLine(
|
||||
"/*\n* Autodesk Maya Bind Script\n*/\n"
|
||||
);
|
||||
|
||||
SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
Binder.WriteLineFmt(
|
||||
"global proc KoreMesh_%08x_%02d_BindFunc()\n{\n"
|
||||
" select -r KoreMesh_%08x_%02d;",
|
||||
Hash, SubmeshIndex,
|
||||
Hash, SubmeshIndex
|
||||
);
|
||||
|
||||
auto MaximumInfluence = Submesh.Vertices.WeightCount();
|
||||
|
||||
uint32_t BoneMapIndex = 0;
|
||||
Dictionary<uint32_t, uint8_t> BoneMap;
|
||||
Dictionary<uint32_t, uint32_t> ReverseBoneMap;
|
||||
List<String> BoneNames;
|
||||
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
for (uint8_t i = 0; i < Vertex.WeightCount(); i++)
|
||||
{
|
||||
auto& Weight = Vertex.Weights(i);
|
||||
|
||||
if (BoneMap.Add(Weight.Bone, 0))
|
||||
{
|
||||
BoneNames.Add(Model.Bones[Weight.Bone].Name());
|
||||
ReverseBoneMap.Add(BoneMapIndex, Weight.Bone);
|
||||
BoneMapIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& BoneName : BoneNames)
|
||||
Binder.WriteLineFmt(" select -add %s;", (char*)BoneName);
|
||||
|
||||
Binder.WriteLineFmt(
|
||||
" newSkinCluster \"-toSelectedBones -mi %d -omi true -dr 5.0 -rui false\";\n"
|
||||
" string $clu = findRelatedSkinCluster(\"KoreMesh_%08x_%02d\");",
|
||||
MaximumInfluence,
|
||||
Hash, SubmeshIndex
|
||||
);
|
||||
|
||||
// If we are a complex skin, we need a weight matrix
|
||||
if (BoneNames.Count() > 1)
|
||||
{
|
||||
Binder.WriteFmt(" int $NV = %d;\n matrix $WM[%d][%d] = <<", Submesh.Vertices.Count(), Submesh.Vertices.Count(), BoneNames.Count());
|
||||
|
||||
for (uint32_t i = 0; i < Submesh.Vertices.Count(); i++)
|
||||
{
|
||||
auto Vertex = Submesh.Vertices[i];
|
||||
|
||||
if (i != 0)
|
||||
Binder.Write(";");
|
||||
|
||||
for (uint32_t b = 0; b < BoneNames.Count(); b++)
|
||||
{
|
||||
if (b != 0)
|
||||
Binder.Write(",");
|
||||
|
||||
float WeightValue = 0.0f;
|
||||
|
||||
for (uint8_t w = 0; w < Vertex.WeightCount(); w++)
|
||||
{
|
||||
if (Vertex.Weights(w).Bone == ReverseBoneMap[b])
|
||||
{
|
||||
WeightValue = Vertex.Weights(w).Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WeightValue == 0.0f || WeightValue == 1.0f)
|
||||
Binder.WriteFmt("%d", (uint32_t)WeightValue);
|
||||
else
|
||||
Binder.WriteFmt("%f", WeightValue);
|
||||
}
|
||||
}
|
||||
|
||||
Binder.WriteLine(">>;");
|
||||
Binder.Write(" for ($i = 0; $i < $NV; $i++) {");
|
||||
|
||||
Binder.WriteFmt(" setAttr($clu + \".weightList[\" + $i + \"].weights[0:%d]\")", BoneNames.Count() - 1);
|
||||
|
||||
for (uint32_t i = 0; i < BoneNames.Count(); i++)
|
||||
Binder.WriteFmt(" $WM[$i][%d]", i);
|
||||
|
||||
Binder.WriteLine("; }");
|
||||
}
|
||||
|
||||
Binder.WriteLine("}\n");
|
||||
SubmeshIndex++;
|
||||
}
|
||||
|
||||
Binder.WriteLine("global proc RunAdvancedScript()\n{");
|
||||
|
||||
SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
Binder.WriteLineFmt(" catch(KoreMesh_%08x_%02d_BindFunc());", Hash, SubmeshIndex++);
|
||||
|
||||
Binder.WriteLine("}\n\nglobal proc NamespacePurge()\n{\n string $allNodes[] = `ls`;\n for($node in $allNodes) {\n string $buffer[];\n tokenize $node \":\" $buffer;\n string $newName = $buffer[size($buffer)-1];\n catchQuiet(`rename $node $newName`);\n }\n}\n\nprint(\"Currently binding the current model, please wait...\\n\");\nNamespacePurge();\nRunAdvancedScript();\nprint(\"The model has been binded.\\n\");\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
imstring AutodeskMaya::ModelExtension()
|
||||
{
|
||||
return ".ma";
|
||||
}
|
||||
|
||||
imstring AutodeskMaya::AnimationExtension()
|
||||
{
|
||||
return ".anim";
|
||||
}
|
||||
|
||||
ExporterScale AutodeskMaya::ExportScale()
|
||||
{
|
||||
return ExporterScale::CM;
|
||||
}
|
||||
|
||||
bool AutodeskMaya::SupportsAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AutodeskMaya::SupportsModels()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
33
r5dev/thirdparty/cppnet/cppkore/AutodeskMaya.h
vendored
Normal file
33
r5dev/thirdparty/cppnet/cppkore/AutodeskMaya.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Exporter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
// The Autodesk Maya exporter
|
||||
class AutodeskMaya : public Exporter
|
||||
{
|
||||
public:
|
||||
AutodeskMaya() = default;
|
||||
~AutodeskMaya() = default;
|
||||
|
||||
// Exports the given animation to the provided path.
|
||||
virtual bool ExportAnimation(const Animation& Animation, const String& Path);
|
||||
// Exports the given model to the provided path.
|
||||
virtual bool ExportModel(const Model& Model, const String& Path);
|
||||
|
||||
// Gets the file extension for this exporters model format.
|
||||
virtual imstring ModelExtension();
|
||||
// Gets the file extension for this exporters animation format.
|
||||
virtual imstring AnimationExtension();
|
||||
|
||||
// Gets the required scaling constant for this exporter.
|
||||
virtual ExporterScale ExportScale();
|
||||
|
||||
// Gets whether or not the exporter supports animation exporting.
|
||||
virtual bool SupportsAnimations();
|
||||
// Gets whether or not the exporter supports model exporting.
|
||||
virtual bool SupportsModels();
|
||||
};
|
||||
}
|
251
r5dev/thirdparty/cppnet/cppkore/BinaryReader.cpp
vendored
Normal file
251
r5dev/thirdparty/cppnet/cppkore/BinaryReader.cpp
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
#include "stdafx.h"
|
||||
#include "BinaryReader.h"
|
||||
#include "Pattern.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
BinaryReader::BinaryReader()
|
||||
: BinaryReader(nullptr, false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(std::unique_ptr<Stream> Stream)
|
||||
: BinaryReader(std::move(Stream), false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(std::unique_ptr<Stream> Stream, bool LeaveOpen)
|
||||
{
|
||||
this->BaseStream = std::move(Stream);
|
||||
this->_LeaveOpen = LeaveOpen;
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(Stream* Stream)
|
||||
: BinaryReader(Stream, false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(Stream* Stream, bool LeaveOpen)
|
||||
{
|
||||
this->BaseStream.reset(Stream);
|
||||
this->_LeaveOpen = LeaveOpen;
|
||||
}
|
||||
|
||||
BinaryReader::~BinaryReader()
|
||||
{
|
||||
this->Close();
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> BinaryReader::Read(uint64_t Count, uint64_t& Result)
|
||||
{
|
||||
auto Buffer = std::make_unique<uint8_t[]>(Count);
|
||||
|
||||
Result = Read(Buffer.get(), 0, Count);
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
uint64_t BinaryReader::Read(uint8_t* Buffer, uint64_t Index, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
return this->BaseStream->Read(Buffer, Index, Count);
|
||||
}
|
||||
|
||||
uint64_t BinaryReader::Read(void* Buffer, uint64_t Index, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
return this->BaseStream->Read((uint8_t*)Buffer, Index, Count);
|
||||
}
|
||||
|
||||
String BinaryReader::ReadCString()
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
String Buffer = "";
|
||||
|
||||
char Cur = this->Read<char>();
|
||||
while ((uint8_t)Cur > 0)
|
||||
{
|
||||
Buffer += Cur;
|
||||
Cur = this->Read<char>();
|
||||
}
|
||||
|
||||
return std::move(Buffer);
|
||||
}
|
||||
|
||||
WString BinaryReader::ReadWCString()
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
WString Buffer = L"";
|
||||
|
||||
wchar_t Cur = this->Read<wchar_t>();
|
||||
while (Cur != (wchar_t)'\0')
|
||||
{
|
||||
Buffer += Cur;
|
||||
Cur = this->Read<wchar_t>();
|
||||
}
|
||||
|
||||
return std::move(Buffer);
|
||||
}
|
||||
|
||||
String BinaryReader::ReadSizeString(uint64_t Size)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto Buffer = String((uint32_t)Size, '\0');
|
||||
this->BaseStream->Read((uint8_t*)&Buffer[0], 0, Size);
|
||||
|
||||
return std::move(Buffer);
|
||||
}
|
||||
|
||||
String BinaryReader::ReadNetString()
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto Buffer = String(this->ReadVarInt(), '\0');
|
||||
this->BaseStream->Read((uint8_t*)&Buffer[0], 0, (uint64_t)Buffer.Length());
|
||||
|
||||
return std::move(Buffer);
|
||||
}
|
||||
|
||||
uint32_t BinaryReader::ReadVarInt()
|
||||
{
|
||||
uint32_t Count = 0, Shift = 0;
|
||||
uint8_t Byte;
|
||||
|
||||
do
|
||||
{
|
||||
if (Shift == 5 * 7)
|
||||
return 0;
|
||||
|
||||
Byte = this->Read<uint8_t>();
|
||||
Count |= (Byte & 0x7F) << Shift;
|
||||
Shift += 7;
|
||||
} while ((Byte & 0x80) != 0);
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
int64_t BinaryReader::SignatureScan(const String& Signature)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto Sig = Data::Pattern(Signature);
|
||||
auto Position = this->BaseStream->GetPosition();
|
||||
auto Length = this->BaseStream->GetLength();
|
||||
auto ChunkSize = (0x5F5E100 + (0x5F5E100 % Sig.DataSize()));
|
||||
|
||||
uint64_t SearchResult = -1, ReadResult = 0, DataRead = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto StartPosition = this->BaseStream->GetPosition();
|
||||
auto Buffer = this->Read(ChunkSize, ReadResult);
|
||||
|
||||
auto ChunkResult = Sig.Search(Buffer.get(), 0, ReadResult);
|
||||
if (ChunkResult > -1)
|
||||
{
|
||||
return (DataRead + ChunkResult + StartPosition);
|
||||
}
|
||||
DataRead += ReadResult;
|
||||
|
||||
if (ReadResult < ChunkSize)
|
||||
break;
|
||||
}
|
||||
|
||||
return SearchResult;
|
||||
}
|
||||
|
||||
int64_t BinaryReader::SignatureScan(const String& Signature, uint64_t Offset, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
uint64_t ReadResult = 0;
|
||||
auto Sig = Data::Pattern(Signature);
|
||||
this->BaseStream->SetPosition(Offset);
|
||||
auto Buffer = this->Read(Count, ReadResult);
|
||||
|
||||
auto SearchResult = Sig.Search(Buffer.get(), 0, ReadResult);
|
||||
|
||||
if (SearchResult > -1)
|
||||
return (SearchResult + Offset);
|
||||
|
||||
return SearchResult;
|
||||
}
|
||||
|
||||
List<int64_t> BinaryReader::SignatureScanAll(const String & Signature)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto ResultList = List<int64_t>();
|
||||
|
||||
auto Sig = Data::Pattern(Signature);
|
||||
auto Position = this->BaseStream->GetPosition();
|
||||
auto Length = this->BaseStream->GetLength();
|
||||
auto ChunkSize = (0x5F5E100 + (0x5F5E100 % Sig.DataSize()));
|
||||
|
||||
uint64_t SearchResult = -1, ReadResult = 0, DataRead = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto StartPosition = this->BaseStream->GetPosition();
|
||||
auto Buffer = this->Read(ChunkSize, ReadResult);
|
||||
|
||||
auto ChunkResult = Sig.SearchAll(Buffer.get(), 0, ReadResult);
|
||||
|
||||
for (auto& Result : ChunkResult)
|
||||
ResultList.EmplaceBack(Result + DataRead + StartPosition);
|
||||
|
||||
DataRead += ReadResult;
|
||||
|
||||
if (ReadResult < ChunkSize)
|
||||
break;
|
||||
}
|
||||
|
||||
return ResultList;
|
||||
}
|
||||
|
||||
List<int64_t> BinaryReader::SignatureScanAll(const String & Signature, uint64_t Offset, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
uint64_t ReadResult = 0;
|
||||
auto Sig = Data::Pattern(Signature);
|
||||
this->BaseStream->SetPosition(Offset);
|
||||
auto Buffer = this->Read(Count, ReadResult);
|
||||
|
||||
auto ResultList = Sig.SearchAll(Buffer.get(), 0, ReadResult);
|
||||
|
||||
for (auto& Result : ResultList)
|
||||
Result += Offset;
|
||||
|
||||
return ResultList;
|
||||
}
|
||||
|
||||
Stream* BinaryReader::GetBaseStream() const
|
||||
{
|
||||
return this->BaseStream.get();
|
||||
}
|
||||
|
||||
void BinaryReader::Close()
|
||||
{
|
||||
// Forcefully reset the stream
|
||||
if (this->_LeaveOpen)
|
||||
this->BaseStream.release();
|
||||
else
|
||||
this->BaseStream.reset();
|
||||
}
|
||||
}
|
72
r5dev/thirdparty/cppnet/cppkore/BinaryReader.h
vendored
Normal file
72
r5dev/thirdparty/cppnet/cppkore/BinaryReader.h
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "Stream.h"
|
||||
#include "ListBase.h"
|
||||
#include "StringBase.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
// BinaryReader supports reading binary data streams
|
||||
class BinaryReader
|
||||
{
|
||||
public:
|
||||
BinaryReader();
|
||||
BinaryReader(std::unique_ptr<Stream> Stream);
|
||||
BinaryReader(std::unique_ptr<Stream> Stream, bool LeaveOpen);
|
||||
BinaryReader(Stream* Stream);
|
||||
BinaryReader(Stream* Stream, bool LeaveOpen);
|
||||
~BinaryReader();
|
||||
|
||||
template <class T>
|
||||
// Reads data of type T from the stream
|
||||
T Read() const
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
T ResultValue{};
|
||||
this->BaseStream->Read((uint8_t*)&ResultValue, 0, sizeof(T));
|
||||
|
||||
return ResultValue;
|
||||
}
|
||||
|
||||
// Reads data from the stream
|
||||
std::unique_ptr<uint8_t[]> Read(uint64_t Count, uint64_t& Result);
|
||||
// Reads data from the stream to the specified buffer
|
||||
uint64_t Read(uint8_t* Buffer, uint64_t Index, uint64_t Count);
|
||||
// Reads data from the stream to the specified buffer
|
||||
uint64_t Read(void* Buffer, uint64_t Index, uint64_t Count);
|
||||
|
||||
// Reads a null-terminated string from the stream
|
||||
String ReadCString();
|
||||
// Reads a wide null-terminated string from the stream
|
||||
WString ReadWCString();
|
||||
// Reads a size-string from the stream
|
||||
String ReadSizeString(uint64_t Size);
|
||||
// Reads a .NET string from the stream
|
||||
String ReadNetString();
|
||||
|
||||
// Reads an integer encoded into 7 bits, top bit = read more
|
||||
uint32_t ReadVarInt();
|
||||
|
||||
// Scan the stream for a given signature
|
||||
int64_t SignatureScan(const String& Signature);
|
||||
// Scan the stream for a given signature
|
||||
int64_t SignatureScan(const String& Signature, uint64_t Offset, uint64_t Count);
|
||||
|
||||
// Scan the process for a given signature (All occurences)
|
||||
List<int64_t> SignatureScanAll(const String& Signature);
|
||||
// Scan the process for a given signature (All occurences)
|
||||
List<int64_t> SignatureScanAll(const String& Signature, uint64_t Offset, uint64_t Count);
|
||||
|
||||
// Get the underlying stream
|
||||
Stream* GetBaseStream() const;
|
||||
// Close the BinaryReader and underlying stream
|
||||
void Close();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Stream> BaseStream;
|
||||
bool _LeaveOpen;
|
||||
};
|
||||
}
|
145
r5dev/thirdparty/cppnet/cppkore/BinaryWriter.cpp
vendored
Normal file
145
r5dev/thirdparty/cppnet/cppkore/BinaryWriter.cpp
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
#include "stdafx.h"
|
||||
#include "BinaryWriter.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
BinaryWriter::BinaryWriter()
|
||||
: BinaryWriter(nullptr, false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(std::unique_ptr<Stream> Stream)
|
||||
: BinaryWriter(std::move(Stream), false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(std::unique_ptr<Stream> Stream, bool LeaveOpen)
|
||||
{
|
||||
this->BaseStream = std::move(Stream);
|
||||
this->_LeaveOpen = LeaveOpen;
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(Stream* Stream)
|
||||
: BinaryWriter(Stream, false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(Stream * Stream, bool LeaveOpen)
|
||||
{
|
||||
this->BaseStream.reset(Stream);
|
||||
this->_LeaveOpen = LeaveOpen;
|
||||
}
|
||||
|
||||
BinaryWriter::~BinaryWriter()
|
||||
{
|
||||
this->Close();
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(std::unique_ptr<uint8_t[]>& Buffer, uint64_t Count)
|
||||
{
|
||||
this->Write(Buffer.get(), 0, Count);
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint8_t* Buffer, uint64_t Index, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
this->BaseStream->Write(Buffer, Index, Count);
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(void* Buffer, uint64_t Index, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Buffer, Index, Count);
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteCString(const String& Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
uint8_t NullBuffer = 0x0;
|
||||
auto ValueLength = Value.Length();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Value.begin(), 0, ValueLength);
|
||||
|
||||
if (ValueLength == 0 || Value[ValueLength - 1] != '\0')
|
||||
this->BaseStream->Write(&NullBuffer, 0, 1);
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteWCString(const WString& Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
uint16_t NullBuffer = 0x0;
|
||||
auto ValueLength = Value.Length();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Value.begin(), 0, ValueLength * sizeof(wchar_t));
|
||||
|
||||
if (ValueLength == 0 || Value[ValueLength - 1] != (wchar_t)'\0')
|
||||
this->BaseStream->Write((uint8_t*)&NullBuffer, 0, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteSizeString(const String& Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Value.begin(), 0, Value.Length());
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteNetString(const String& Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto ValueSize = (uint32_t)Value.Length();
|
||||
this->WriteVarInt(ValueSize);
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Value.begin(), 0, ValueSize);
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteVarInt(uint32_t Value)
|
||||
{
|
||||
// Write out 7 bits per byte, highest bit = keep reading
|
||||
while (Value >= 0x80)
|
||||
{
|
||||
this->Write<uint8_t>((uint8_t)(Value | 0x80));
|
||||
Value >>= 7;
|
||||
}
|
||||
|
||||
this->Write<uint8_t>((uint8_t)Value);
|
||||
}
|
||||
|
||||
void BinaryWriter::Pad(uint64_t Count)
|
||||
{
|
||||
char Padding[0x1000]{};
|
||||
|
||||
while (Count > 0)
|
||||
{
|
||||
auto Want = (Count > 0x1000) ? 0x1000 : Count;
|
||||
|
||||
Write(Padding, 0, Want);
|
||||
|
||||
Count -= Want;
|
||||
}
|
||||
}
|
||||
|
||||
Stream* BinaryWriter::GetBaseStream() const
|
||||
{
|
||||
return this->BaseStream.get();
|
||||
}
|
||||
|
||||
void BinaryWriter::Close()
|
||||
{
|
||||
// Forcefully reset the stream
|
||||
if (this->_LeaveOpen)
|
||||
this->BaseStream.release();
|
||||
else
|
||||
this->BaseStream.reset();
|
||||
}
|
||||
}
|
61
r5dev/thirdparty/cppnet/cppkore/BinaryWriter.h
vendored
Normal file
61
r5dev/thirdparty/cppnet/cppkore/BinaryWriter.h
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "Stream.h"
|
||||
#include "StringBase.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
// BinaryWriter supports writing to binary data streams
|
||||
class BinaryWriter
|
||||
{
|
||||
public:
|
||||
BinaryWriter();
|
||||
BinaryWriter(std::unique_ptr<Stream> Stream);
|
||||
BinaryWriter(std::unique_ptr<Stream> Stream, bool LeaveOpen);
|
||||
BinaryWriter(Stream* Stream);
|
||||
BinaryWriter(Stream* Stream, bool LeaveOpen);
|
||||
~BinaryWriter();
|
||||
|
||||
template<class T>
|
||||
// Writes data of type T to the stream
|
||||
void Write(T Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)&Value, 0, sizeof(T));
|
||||
}
|
||||
|
||||
// Writes data to the stream
|
||||
void Write(std::unique_ptr<uint8_t[]>& Buffer, uint64_t Count);
|
||||
// Writes data to the stream to the specified buffer
|
||||
void Write(uint8_t* Buffer, uint64_t Index, uint64_t Count);
|
||||
// Writes data to the stream to the specified buffer
|
||||
void Write(void* Buffer, uint64_t Index, uint64_t Count);
|
||||
|
||||
// Writes a null-terminated string to the stream
|
||||
void WriteCString(const String& Value);
|
||||
// Writes a wide null-terminated string to the stream
|
||||
void WriteWCString(const WString& Value);
|
||||
// Writes a already predetermined size string to the stream
|
||||
void WriteSizeString(const String& Value);
|
||||
// Writes a .NET string to the stream
|
||||
void WriteNetString(const String& Value);
|
||||
|
||||
// Writes an integer encoded into 7 bits, top bit = read more
|
||||
void WriteVarInt(uint32_t Value);
|
||||
|
||||
// Writes padding bytes (0x0) to the stream
|
||||
void Pad(uint64_t Count);
|
||||
|
||||
// Get the underlying stream
|
||||
Stream* GetBaseStream() const;
|
||||
// Close the BinaryWriter and underlying stream
|
||||
void Close();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Stream> BaseStream;
|
||||
bool _LeaveOpen;
|
||||
};
|
||||
}
|
140
r5dev/thirdparty/cppnet/cppkore/Bone.cpp
vendored
Normal file
140
r5dev/thirdparty/cppnet/cppkore/Bone.cpp
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
#include "stdafx.h"
|
||||
#include "Bone.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
Bone::Bone()
|
||||
: _Parent(-1), _Flags(BoneFlags::HasLocalSpaceMatrices), _LocalSpacePosition(0, 0, 0), _LocalSpaceRotation(0, 0, 0, 1), _GlobalSpacePosition(0, 0, 0), _GlobalSpaceRotation(0, 0, 0, 1), _Scale(1, 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
Bone::Bone(const String& Name)
|
||||
: Bone(Name, -1, { 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0, 1 }, { 1, 1, 1 }, BoneFlags::HasLocalSpaceMatrices)
|
||||
{
|
||||
}
|
||||
|
||||
Bone::Bone(const String& Name, int32_t ParentIndex)
|
||||
: Bone(Name, ParentIndex, { 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0, 1 }, { 1, 1, 1 }, BoneFlags::HasLocalSpaceMatrices)
|
||||
{
|
||||
}
|
||||
|
||||
Bone::Bone(const String& Name, int32_t ParentIndex, Vector3 Position, Quaternion Rotation, BoneFlags Flags)
|
||||
: Bone(Name, ParentIndex)
|
||||
{
|
||||
if (((int)Flags & (int)BoneFlags::HasLocalSpaceMatrices) == (int)BoneFlags::HasLocalSpaceMatrices)
|
||||
{
|
||||
this->_LocalSpacePosition = Position;
|
||||
this->_LocalSpaceRotation = Rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_GlobalSpacePosition = Position;
|
||||
this->_GlobalSpaceRotation = Rotation;
|
||||
}
|
||||
|
||||
this->_Flags = Flags;
|
||||
}
|
||||
|
||||
Bone::Bone(const String & Name, int32_t ParentIndex, Vector3 Position, Quaternion Rotation, Vector3 Scale, BoneFlags Flags)
|
||||
: Bone(Name, ParentIndex)
|
||||
{
|
||||
if (((int)Flags & (int)BoneFlags::HasLocalSpaceMatrices) == (int)BoneFlags::HasLocalSpaceMatrices)
|
||||
{
|
||||
this->_LocalSpacePosition = Position;
|
||||
this->_LocalSpaceRotation = Rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_GlobalSpacePosition = Position;
|
||||
this->_GlobalSpaceRotation = Rotation;
|
||||
}
|
||||
|
||||
this->_Scale = Scale;
|
||||
this->_Flags = Flags;
|
||||
}
|
||||
|
||||
Bone::Bone(const String& Name, int32_t ParentIndex, Vector3 LocalPosition, Quaternion LocalRotation, Vector3 GlobalPosition, Quaternion GlobalRotation, Vector3 Scale, BoneFlags Flags)
|
||||
: _Name(Name), _Parent(ParentIndex), _LocalSpacePosition(LocalPosition), _LocalSpaceRotation(LocalRotation), _GlobalSpacePosition(GlobalPosition), _GlobalSpaceRotation(GlobalRotation), _Scale(Scale), _Flags(Flags)
|
||||
{
|
||||
}
|
||||
|
||||
bool Bone::GetFlag(BoneFlags Flag)
|
||||
{
|
||||
return ((int)this->_Flags & (int)Flag) == (int)Flag;
|
||||
}
|
||||
|
||||
void Bone::SetFlag(BoneFlags Flags, bool Value)
|
||||
{
|
||||
this->_Flags = Value ? (BoneFlags)((int)this->_Flags | (int)Flags) : (BoneFlags)((int)this->_Flags & ~(int)Flags);
|
||||
}
|
||||
|
||||
const String& Bone::Name() const
|
||||
{
|
||||
return this->_Name;
|
||||
}
|
||||
|
||||
void Bone::SetName(const String& Value)
|
||||
{
|
||||
this->_Name = Value;
|
||||
}
|
||||
|
||||
const int32_t& Bone::Parent() const
|
||||
{
|
||||
return this->_Parent;
|
||||
}
|
||||
|
||||
void Bone::SetParent(int32_t Value)
|
||||
{
|
||||
this->_Parent = Value;
|
||||
}
|
||||
|
||||
const Vector3& Bone::LocalPosition() const
|
||||
{
|
||||
return this->_LocalSpacePosition;
|
||||
}
|
||||
|
||||
void Bone::SetLocalPosition(Vector3 Value)
|
||||
{
|
||||
this->_LocalSpacePosition = Value;
|
||||
}
|
||||
|
||||
const Quaternion& Bone::LocalRotation() const
|
||||
{
|
||||
return this->_LocalSpaceRotation;
|
||||
}
|
||||
|
||||
void Bone::SetLocalRotation(Quaternion Value)
|
||||
{
|
||||
this->_LocalSpaceRotation = Value;
|
||||
}
|
||||
|
||||
const Vector3& Bone::GlobalPosition() const
|
||||
{
|
||||
return this->_GlobalSpacePosition;
|
||||
}
|
||||
|
||||
void Bone::SetGlobalPosition(Vector3 Value)
|
||||
{
|
||||
this->_GlobalSpacePosition = Value;
|
||||
}
|
||||
|
||||
const Quaternion& Bone::GlobalRotation() const
|
||||
{
|
||||
return this->_GlobalSpaceRotation;
|
||||
}
|
||||
|
||||
void Bone::SetGlobalRotation(Quaternion Value)
|
||||
{
|
||||
this->_GlobalSpaceRotation = Value;
|
||||
}
|
||||
|
||||
const Vector3& Bone::Scale() const
|
||||
{
|
||||
return this->_Scale;
|
||||
}
|
||||
|
||||
void Bone::SetScale(Vector3 Value)
|
||||
{
|
||||
this->_Scale = Value;
|
||||
}
|
||||
}
|
93
r5dev/thirdparty/cppnet/cppkore/Bone.h
vendored
Normal file
93
r5dev/thirdparty/cppnet/cppkore/Bone.h
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "StringBase.h"
|
||||
#include "MathHelper.h"
|
||||
#include "Vector3.h"
|
||||
#include "Quaternion.h"
|
||||
#include "BoneFlags.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
using namespace Math; // All of the matrices classes are in Math::*
|
||||
|
||||
// A container class that holds 3D bone data.
|
||||
class Bone
|
||||
{
|
||||
public:
|
||||
// Initialize a blank 3D bone.
|
||||
Bone();
|
||||
// Initialize a 3D bone with it's tag name.
|
||||
Bone(const String& Name);
|
||||
// Initialize a 3D bone with it's tag name, and parent index.
|
||||
Bone(const String& Name, int32_t ParentIndex);
|
||||
// Initialize a 3D bone with it's tag name, parent index, and transposition matrix.
|
||||
Bone(const String& Name, int32_t ParentIndex, Vector3 Position, Quaternion Rotation, BoneFlags Flags = BoneFlags::HasLocalSpaceMatrices);
|
||||
// Initialize a 3D bone with it's tag name, parent index, transposition matrix, and scale transform.
|
||||
Bone(const String& Name, int32_t ParentIndex, Vector3 Position, Quaternion Rotation, Vector3 Scale, BoneFlags Flags = (BoneFlags::HasLocalSpaceMatrices | BoneFlags::HasScale));
|
||||
// Initialize a 3D bone with it's tag name, parent index, local and global transposition matrix, and scale transform.
|
||||
Bone(const String& Name, int32_t ParentIndex, Vector3 LocalPosition, Quaternion LocalRotation, Vector3 GlobalPosition, Quaternion GlobalRotation, Vector3 Scale, BoneFlags Flags = (BoneFlags::HasGlobalSpaceMatrices | BoneFlags::HasLocalSpaceMatrices | BoneFlags::HasScale));
|
||||
// Destroy all 3D bone resources.
|
||||
~Bone() = default;
|
||||
|
||||
// Ensure that our bone is not copied or assigned to for performance reasons.
|
||||
Bone(const Bone&) = delete;
|
||||
|
||||
// Gets bone specific flags.
|
||||
bool GetFlag(BoneFlags Flag);
|
||||
// Sets bone specific flags.
|
||||
void SetFlag(BoneFlags Flags, bool Value);
|
||||
|
||||
// Gets the tag name assigned to the bone.
|
||||
const String& Name() const;
|
||||
// Sets the tag name assigned to the bone.
|
||||
void SetName(const String& Value);
|
||||
|
||||
// Gets the parent bone index.
|
||||
const int32_t& Parent() const;
|
||||
// Sets the parent bone index.
|
||||
void SetParent(int32_t Value);
|
||||
|
||||
// Gets the local space position.
|
||||
const Vector3& LocalPosition() const;
|
||||
// Sets the local space position.
|
||||
void SetLocalPosition(Vector3 Value);
|
||||
|
||||
// Gets the local space rotation.
|
||||
const Quaternion& LocalRotation() const;
|
||||
// Sets the local space rotation.
|
||||
void SetLocalRotation(Quaternion Value);
|
||||
|
||||
// Gets the global space position.
|
||||
const Vector3& GlobalPosition() const;
|
||||
// Sets the global space position.
|
||||
void SetGlobalPosition(Vector3 Value);
|
||||
|
||||
// Gets the global space rotation.
|
||||
const Quaternion& GlobalRotation() const;
|
||||
// Sets the global space rotation.
|
||||
void SetGlobalRotation(Quaternion Value);
|
||||
|
||||
// Gets the scale transform.
|
||||
const Vector3& Scale() const;
|
||||
// Sets the scale transform.
|
||||
void SetScale(Vector3 Value);
|
||||
|
||||
private:
|
||||
// Internal tag name
|
||||
String _Name;
|
||||
|
||||
// Internal parent index
|
||||
int32_t _Parent;
|
||||
|
||||
// Internal flags for this bone
|
||||
BoneFlags _Flags;
|
||||
|
||||
// Internal 3D matrix information for this bone
|
||||
Vector3 _LocalSpacePosition;
|
||||
Vector3 _GlobalSpacePosition;
|
||||
Quaternion _LocalSpaceRotation;
|
||||
Quaternion _GlobalSpaceRotation;
|
||||
Vector3 _Scale;
|
||||
};
|
||||
}
|
26
r5dev/thirdparty/cppnet/cppkore/BoneFlags.h
vendored
Normal file
26
r5dev/thirdparty/cppnet/cppkore/BoneFlags.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// This enumeration represents the possible bone flags.
|
||||
enum class BoneFlags : uint8_t
|
||||
{
|
||||
// Whether or not the bone has local space transforms
|
||||
HasLocalSpaceMatrices = 0x1,
|
||||
// Whether or not the bone has global space transforms
|
||||
HasGlobalSpaceMatrices = 0x2,
|
||||
// Whether or not the bone has a scale transform
|
||||
HasScale = 0x4
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr BoneFlags operator|(BoneFlags Lhs, BoneFlags Rhs)
|
||||
{
|
||||
return static_cast<BoneFlags>(static_cast<std::underlying_type<BoneFlags>::type>(Lhs) | static_cast<std::underlying_type<BoneFlags>::type>(Rhs));
|
||||
};
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/BorderStyle.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/BorderStyle.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the border style for a control or form.
|
||||
enum class BorderStyle
|
||||
{
|
||||
// No border.
|
||||
None = 0,
|
||||
// A single-line border.
|
||||
FixedSingle = 1,
|
||||
// A three-dimensional border.
|
||||
Fixed3D = 2
|
||||
};
|
||||
}
|
21
r5dev/thirdparty/cppnet/cppkore/BoundsSpecified.h
vendored
Normal file
21
r5dev/thirdparty/cppnet/cppkore/BoundsSpecified.h
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the bounds of the control to
|
||||
// use when defining a control's size and position.
|
||||
enum class BoundsSpecified : uint32_t
|
||||
{
|
||||
X = 0x1,
|
||||
Y = 0x2,
|
||||
Width = 0x4,
|
||||
Height = 0x8,
|
||||
Location = X | Y,
|
||||
Size = Width | Height,
|
||||
All = Location | Size,
|
||||
None = 0,
|
||||
};
|
||||
}
|
27
r5dev/thirdparty/cppnet/cppkore/BufferedGraphics.cpp
vendored
Normal file
27
r5dev/thirdparty/cppnet/cppkore/BufferedGraphics.cpp
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
#include "stdafx.h"
|
||||
#include "BufferedGraphics.h"
|
||||
|
||||
namespace Drawing
|
||||
{
|
||||
BufferedGraphics::BufferedGraphics(HDC TargetDC, Drawing::Rectangle TargetRectangle)
|
||||
: _TargetDC(TargetDC), Rectangle(TargetRectangle)
|
||||
{
|
||||
this->Buffer = std::make_unique<Drawing::Bitmap>(TargetRectangle.Width, TargetRectangle.Height);
|
||||
this->Graphics = std::make_unique<Drawing::Graphics>(this->Buffer.get());
|
||||
}
|
||||
|
||||
void BufferedGraphics::Render()
|
||||
{
|
||||
// Render the buffer to the target
|
||||
auto Gfx = Gdiplus::Graphics::FromHDC(this->_TargetDC);
|
||||
Gfx->DrawImage(this->Buffer.get(), this->Rectangle);
|
||||
|
||||
// Clean up the graphics object
|
||||
delete Gfx;
|
||||
}
|
||||
|
||||
Drawing::Rectangle BufferedGraphics::Region()
|
||||
{
|
||||
return Drawing::Rectangle(0, 0, this->Rectangle.Width, this->Rectangle.Height);
|
||||
}
|
||||
}
|
32
r5dev/thirdparty/cppnet/cppkore/BufferedGraphics.h
vendored
Normal file
32
r5dev/thirdparty/cppnet/cppkore/BufferedGraphics.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "DrawingBase.h"
|
||||
|
||||
namespace Drawing
|
||||
{
|
||||
class BufferedGraphics
|
||||
{
|
||||
public:
|
||||
BufferedGraphics(HDC TargetDC, Drawing::Rectangle TargetRectangle);
|
||||
~BufferedGraphics() = default;
|
||||
|
||||
// Renders the buffered graphics to the target surface
|
||||
void Render();
|
||||
|
||||
// Gets the size of the region
|
||||
Drawing::Rectangle Region();
|
||||
|
||||
// The graphics instance for this instance
|
||||
std::unique_ptr<Drawing::Graphics> Graphics;
|
||||
|
||||
private:
|
||||
// Internal buffer to draw to
|
||||
std::unique_ptr<Drawing::Bitmap> Buffer;
|
||||
// Internal target handle
|
||||
HDC _TargetDC;
|
||||
|
||||
// Internal size of the buffer region
|
||||
Drawing::Rectangle Rectangle;
|
||||
};
|
||||
}
|
104
r5dev/thirdparty/cppnet/cppkore/Button.cpp
vendored
Normal file
104
r5dev/thirdparty/cppnet/cppkore/Button.cpp
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
#include "stdafx.h"
|
||||
#include "Button.h"
|
||||
#include "Form.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
Button::Button()
|
||||
: ButtonBase(), _DialogResult(DialogResult::None)
|
||||
{
|
||||
SetStyle(ControlStyles::StandardClick | ControlStyles::StandardDoubleClick, false);
|
||||
|
||||
// We are a button control
|
||||
this->_RTTI = ControlTypes::Button;
|
||||
}
|
||||
|
||||
DialogResult Button::GetDialogResult()
|
||||
{
|
||||
return this->_DialogResult;
|
||||
}
|
||||
|
||||
void Button::SetDialogResult(DialogResult Value)
|
||||
{
|
||||
this->_DialogResult = Value;
|
||||
}
|
||||
|
||||
void Button::PerformClick()
|
||||
{
|
||||
if (CanSelect())
|
||||
{
|
||||
ResetFlagsAndPaint();
|
||||
OnClick();
|
||||
}
|
||||
}
|
||||
|
||||
void Button::NotifyDefault(bool Value)
|
||||
{
|
||||
if (IsDefault() != Value)
|
||||
SetIsDefault(Value);
|
||||
}
|
||||
|
||||
void Button::OnClick()
|
||||
{
|
||||
auto Form = this->FindForm();
|
||||
|
||||
if (Form != nullptr)
|
||||
((Forms::Form*)Form)->SetDialogResult(this->_DialogResult);
|
||||
|
||||
// Call base event last
|
||||
ButtonBase::OnClick();
|
||||
}
|
||||
|
||||
void Button::OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->Button == MouseButtons::Left && GetFlag(ButtonFlags::FlagMousePressed))
|
||||
{
|
||||
auto isMouseDown = GetFlag(ButtonFlags::FlagMouseDown);
|
||||
|
||||
if (GetStyle(ControlStyles::UserPaint))
|
||||
{
|
||||
this->ResetFlagsAndPaint();
|
||||
}
|
||||
|
||||
if (isMouseDown)
|
||||
{
|
||||
auto Pt = PointToScreen({ (INT)EventArgs->X, (INT)EventArgs->Y });
|
||||
|
||||
POINT nPt;
|
||||
nPt.x = Pt.X;
|
||||
nPt.y = Pt.Y;
|
||||
|
||||
if (WindowFromPoint(nPt) == this->_Handle)
|
||||
{
|
||||
if (GetStyle(ControlStyles::UserPaint))
|
||||
OnClick();
|
||||
|
||||
OnMouseClick(EventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
ButtonBase::OnMouseUp(EventArgs);
|
||||
}
|
||||
|
||||
CreateParams Button::GetCreateParams()
|
||||
{
|
||||
auto Cp = ButtonBase::GetCreateParams();
|
||||
|
||||
Cp.ClassName = "BUTTON";
|
||||
|
||||
if (GetStyle(ControlStyles::UserPaint))
|
||||
Cp.Style |= BS_OWNERDRAW;
|
||||
else
|
||||
{
|
||||
Cp.Style |= BS_MULTILINE;
|
||||
Cp.Style |= BS_PUSHBUTTON;
|
||||
|
||||
if (this->IsDefault())
|
||||
Cp.Style |= BS_DEFPUSHBUTTON;
|
||||
}
|
||||
|
||||
return Cp;
|
||||
}
|
||||
}
|
42
r5dev/thirdparty/cppnet/cppkore/Button.h
vendored
Normal file
42
r5dev/thirdparty/cppnet/cppkore/Button.h
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Control.h"
|
||||
#include "ButtonBase.h"
|
||||
#include "DialogResult.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Represents a Windows button.
|
||||
class Button : public ButtonBase
|
||||
{
|
||||
public:
|
||||
Button();
|
||||
virtual ~Button() = default;
|
||||
|
||||
// Gets a value that is returned to the
|
||||
// parent form when the button is clicked.
|
||||
DialogResult GetDialogResult();
|
||||
// Sets a value that is returned to the
|
||||
// parent form when the button is clicked.
|
||||
void SetDialogResult(DialogResult Value);
|
||||
|
||||
// Generates a click event for a button.
|
||||
void PerformClick();
|
||||
|
||||
// Changes the default action status.
|
||||
void NotifyDefault(bool Value);
|
||||
|
||||
// We must define base events here
|
||||
virtual void OnClick();
|
||||
virtual void OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
|
||||
protected:
|
||||
// Get custom control creation parameters for this instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
|
||||
private:
|
||||
// Internal cached dialog result that this button represents
|
||||
DialogResult _DialogResult;
|
||||
};
|
||||
}
|
330
r5dev/thirdparty/cppnet/cppkore/ButtonBase.cpp
vendored
Normal file
330
r5dev/thirdparty/cppnet/cppkore/ButtonBase.cpp
vendored
Normal file
@ -0,0 +1,330 @@
|
||||
#include "stdafx.h"
|
||||
#include "ButtonBase.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ButtonBase::ButtonBase()
|
||||
: Control(), _OwnerDraw(false), _Flags((ButtonFlags)0), _FlatStyle(FlatStyle::Standard), _TextAlign(Drawing::ContentAlignment::MiddleCenter)
|
||||
{
|
||||
SetStyle(ControlStyles::SupportsTransparentBackColor |
|
||||
ControlStyles::Opaque |
|
||||
ControlStyles::ResizeRedraw |
|
||||
ControlStyles::OptimizedDoubleBuffer |
|
||||
ControlStyles::CacheText |
|
||||
ControlStyles::StandardClick, true);
|
||||
|
||||
SetStyle(ControlStyles::UserMouse |
|
||||
ControlStyles::UserPaint, this->_OwnerDraw);
|
||||
}
|
||||
|
||||
bool ButtonBase::OwnerDraw()
|
||||
{
|
||||
return this->_OwnerDraw;
|
||||
}
|
||||
|
||||
void ButtonBase::SetOwnerDraw(bool Value)
|
||||
{
|
||||
this->_OwnerDraw = Value;
|
||||
|
||||
SetStyle(ControlStyles::UserMouse | ControlStyles::UserPaint, Value);
|
||||
|
||||
UpdateStyles();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
Drawing::ContentAlignment ButtonBase::TextAlign()
|
||||
{
|
||||
return this->_TextAlign;
|
||||
}
|
||||
|
||||
void ButtonBase::SetTextAlign(Drawing::ContentAlignment Value)
|
||||
{
|
||||
this->_TextAlign = Value;
|
||||
|
||||
if (this->_OwnerDraw)
|
||||
Invalidate();
|
||||
else
|
||||
UpdateStyles();
|
||||
}
|
||||
|
||||
FlatStyle ButtonBase::GetFlatStyle()
|
||||
{
|
||||
return this->_FlatStyle;
|
||||
}
|
||||
|
||||
void ButtonBase::SetFlatStyle(FlatStyle Value)
|
||||
{
|
||||
this->_FlatStyle = Value;
|
||||
|
||||
Invalidate();
|
||||
|
||||
// Force update styles...
|
||||
SetStyle(ControlStyles::UserMouse | ControlStyles::UserPaint, this->_OwnerDraw);
|
||||
UpdateStyles();
|
||||
}
|
||||
|
||||
bool ButtonBase::IsDefault()
|
||||
{
|
||||
return GetFlag(ButtonFlags::FlagIsDefault);
|
||||
}
|
||||
|
||||
void ButtonBase::SetIsDefault(bool Value)
|
||||
{
|
||||
if (IsDefault() != Value)
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagIsDefault, Value);
|
||||
|
||||
if (this->_OwnerDraw)
|
||||
Invalidate();
|
||||
else
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
bool ButtonBase::GetFlag(ButtonFlags Flag)
|
||||
{
|
||||
return ((int)this->_Flags & (int)Flag) == (int)Flag;
|
||||
}
|
||||
|
||||
void ButtonBase::SetFlag(ButtonFlags Flags, bool Value)
|
||||
{
|
||||
this->_Flags = Value ? (ButtonFlags)((int)this->_Flags | (int)Flags) : (ButtonFlags)((int)this->_Flags & ~(int)Flags);
|
||||
}
|
||||
|
||||
void ButtonBase::OnLostFocus()
|
||||
{
|
||||
Control::OnLostFocus();
|
||||
|
||||
// Hitting tab while holding down the space key
|
||||
SetFlag(ButtonFlags::FlagMouseDown, false);
|
||||
SetCapture(false);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ButtonBase::OnGotFocus()
|
||||
{
|
||||
Control::OnGotFocus();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseEnter()
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseOver, true);
|
||||
Invalidate();
|
||||
|
||||
// Call base event last
|
||||
Control::OnMouseEnter();
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseLeave()
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseOver, false);
|
||||
Invalidate();
|
||||
|
||||
// Call base event last
|
||||
Control::OnMouseLeave();
|
||||
}
|
||||
|
||||
void ButtonBase::OnEnabledChanged()
|
||||
{
|
||||
Control::OnEnabledChanged();
|
||||
|
||||
if (!Enabled())
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown | ButtonFlags::FlagMouseOver, false);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonBase::OnTextChanged()
|
||||
{
|
||||
Control::OnTextChanged();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseMove(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->Button != MouseButtons::None && GetFlag(ButtonFlags::FlagMousePressed))
|
||||
{
|
||||
auto CRect = this->ClientRectangle();
|
||||
|
||||
if (!CRect.Contains(EventArgs->X, EventArgs->Y))
|
||||
{
|
||||
if (GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown, false);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown, true);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
Control::OnMouseMove(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseDown(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->Button == MouseButtons::Left)
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown | ButtonFlags::FlagMousePressed, true);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
Control::OnMouseDown(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
// Call base event last
|
||||
Control::OnMouseUp(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::OnKeyUp(const std::unique_ptr<KeyEventArgs>& EventArgs)
|
||||
{
|
||||
if (GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
if (this->_OwnerDraw)
|
||||
ResetFlagsAndPaint();
|
||||
else
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMousePressed | ButtonFlags::FlagMouseDown, false);
|
||||
SendMessageA(this->_Handle, BM_SETSTATE, 0, 0);
|
||||
}
|
||||
|
||||
if (EventArgs->KeyCode() == Keys::Enter || EventArgs->KeyCode() == Keys::Space)
|
||||
OnClick();
|
||||
|
||||
EventArgs->SetHandled(true);
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
Control::OnKeyUp(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::OnKeyDown(const std::unique_ptr<KeyEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->KeyData() == Keys::Space)
|
||||
{
|
||||
if (!GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown, true);
|
||||
|
||||
if (!this->_OwnerDraw)
|
||||
SendMessageA(this->_Handle, BM_SETSTATE, 1, 0);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
EventArgs->SetHandled(true);
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
Control::OnKeyDown(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::WndProc(Message& Msg)
|
||||
{
|
||||
switch (Msg.Msg)
|
||||
{
|
||||
case BM_CLICK:
|
||||
OnClick();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->_OwnerDraw)
|
||||
{
|
||||
switch (Msg.Msg)
|
||||
{
|
||||
case BM_SETSTATE:
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
case WM_CANCELMODE:
|
||||
case WM_CAPTURECHANGED:
|
||||
|
||||
if (!GetFlag(ButtonFlags::FlagInButtonUp) && GetFlag(ButtonFlags::FlagMousePressed))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMousePressed, false);
|
||||
|
||||
if (GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown, false);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
Control::WndProc(Msg);
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
|
||||
SetFlag(ButtonFlags::FlagInButtonUp, true);
|
||||
Control::WndProc(Msg);
|
||||
SetFlag(ButtonFlags::FlagInButtonUp, false);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Control::WndProc(Msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Msg.Msg == (WM_REFLECT + WM_COMMAND) && HIWORD(Msg.WParam) == BN_CLICKED)
|
||||
OnClick();
|
||||
else
|
||||
Control::WndProc(Msg);
|
||||
}
|
||||
}
|
||||
|
||||
CreateParams ButtonBase::GetCreateParams()
|
||||
{
|
||||
auto Cp = Control::GetCreateParams();
|
||||
|
||||
if (!this->_OwnerDraw)
|
||||
{
|
||||
Cp.ExStyle &= ~WS_EX_RIGHT; // Messes up the BM_ Alignment flags
|
||||
|
||||
Cp.Style |= BS_MULTILINE;
|
||||
|
||||
if (IsDefault())
|
||||
Cp.Style |= BS_DEFPUSHBUTTON;
|
||||
|
||||
if (((int)this->_TextAlign & (int)Drawing::AnyLeftAlign) != 0)
|
||||
Cp.Style |= BS_LEFT;
|
||||
else if (((int)this->_TextAlign & (int)Drawing::AnyRightAlign) != 0)
|
||||
Cp.Style |= BS_RIGHT;
|
||||
else
|
||||
Cp.Style |= BS_CENTER;
|
||||
|
||||
if (((int)this->_TextAlign & (int)Drawing::AnyTopAlign) != 0)
|
||||
Cp.Style |= BS_TOP;
|
||||
else if (((int)this->_TextAlign & (int)Drawing::AnyBottomAlign) != 0)
|
||||
Cp.Style |= BS_BOTTOM;
|
||||
else
|
||||
Cp.Style |= BS_VCENTER;
|
||||
}
|
||||
|
||||
return Cp;
|
||||
}
|
||||
|
||||
void ButtonBase::ResetFlagsAndPaint()
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMousePressed | ButtonFlags::FlagMouseDown, false);
|
||||
Invalidate();
|
||||
Update();
|
||||
}
|
||||
}
|
76
r5dev/thirdparty/cppnet/cppkore/ButtonBase.h
vendored
Normal file
76
r5dev/thirdparty/cppnet/cppkore/ButtonBase.h
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Control.h"
|
||||
#include "FlatStyle.h"
|
||||
#include "ButtonFlags.h"
|
||||
#include "ContentAlignment.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Implements the basic functionality required by a button control.
|
||||
class ButtonBase : public Control
|
||||
{
|
||||
public:
|
||||
virtual ~ButtonBase() = default;
|
||||
|
||||
// Gets the drawing mode of the button control.
|
||||
bool OwnerDraw();
|
||||
// Sets the drawing mode of the button control.
|
||||
void SetOwnerDraw(bool Value);
|
||||
|
||||
// Gets the alignment of the text on the button control.
|
||||
Drawing::ContentAlignment TextAlign();
|
||||
// Sets the alignment of the text on the button control.
|
||||
void SetTextAlign(Drawing::ContentAlignment Value);
|
||||
|
||||
// Gets the flat style appearance of the button control.
|
||||
FlatStyle GetFlatStyle();
|
||||
// Sets the flat style appearance of the button control.
|
||||
void SetFlatStyle(FlatStyle Value);
|
||||
|
||||
// Get whether or not this control is the default response.
|
||||
bool IsDefault();
|
||||
// Sets whether or not this control is the default response.
|
||||
void SetIsDefault(bool Value);
|
||||
|
||||
// We must define base events here
|
||||
virtual void OnLostFocus();
|
||||
virtual void OnGotFocus();
|
||||
virtual void OnMouseEnter();
|
||||
virtual void OnMouseLeave();
|
||||
virtual void OnEnabledChanged();
|
||||
virtual void OnTextChanged();
|
||||
virtual void OnMouseMove(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseDown(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnKeyUp(const std::unique_ptr<KeyEventArgs>& EventArgs);
|
||||
virtual void OnKeyDown(const std::unique_ptr<KeyEventArgs>& EventArgs);
|
||||
|
||||
// Override WndProc for specific button messages.
|
||||
virtual void WndProc(Message& Msg);
|
||||
|
||||
protected:
|
||||
ButtonBase();
|
||||
|
||||
// Get custom control creation parameters for this instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
|
||||
// Used for quick re-painting of the button after the pressed state.
|
||||
void ResetFlagsAndPaint();
|
||||
|
||||
// Gets button specific flags
|
||||
bool GetFlag(ButtonFlags Flag);
|
||||
// Sets button specific flags
|
||||
void SetFlag(ButtonFlags Flags, bool Value);
|
||||
|
||||
// Whether or not the control will draw itself
|
||||
bool _OwnerDraw;
|
||||
// Control specific flags
|
||||
ButtonFlags _Flags;
|
||||
// Controls the style of the control
|
||||
FlatStyle _FlatStyle;
|
||||
// Controls the alignment of text on the control
|
||||
Drawing::ContentAlignment _TextAlign;
|
||||
};
|
||||
}
|
29
r5dev/thirdparty/cppnet/cppkore/ButtonFlags.h
vendored
Normal file
29
r5dev/thirdparty/cppnet/cppkore/ButtonFlags.h
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// This enumeration represents the ButtonBase flags...
|
||||
enum class ButtonFlags
|
||||
{
|
||||
FlagMouseOver = 0x0001,
|
||||
FlagMouseDown = 0x0002,
|
||||
FlagMousePressed = 0x0004,
|
||||
FlagInButtonUp = 0x0008,
|
||||
FlagCurrentlyAnimating = 0x0010,
|
||||
FlagAutoEllipsis = 0x0020,
|
||||
FlagIsDefault = 0x0040,
|
||||
FlagUseMnemonic = 0x0080,
|
||||
FlagShowToolTip = 0x0100,
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr ButtonFlags operator|(ButtonFlags Lhs, ButtonFlags Rhs)
|
||||
{
|
||||
return static_cast<ButtonFlags>(static_cast<std::underlying_type<ButtonFlags>::type>(Lhs) | static_cast<std::underlying_type<ButtonFlags>::type>(Rhs));
|
||||
};
|
||||
}
|
69
r5dev/thirdparty/cppnet/cppkore/CRC32.cpp
vendored
Normal file
69
r5dev/thirdparty/cppnet/cppkore/CRC32.cpp
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
#include "stdafx.h"
|
||||
#include "CRC32.h"
|
||||
|
||||
namespace Hashing
|
||||
{
|
||||
// The table of precalculated CRC32 primes.
|
||||
static constexpr uint32_t CRC32LookupTable[] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
uint32_t CRC32::HashString(const String& Input, uint32_t Seed)
|
||||
{
|
||||
return ComputeHash((uint8_t*)(char*)Input, 0, Input.Length(), Seed);
|
||||
}
|
||||
|
||||
uint32_t CRC32::ComputeHash(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint32_t Seed)
|
||||
{
|
||||
auto pCur = (uint8_t*)(Input + InputOffset);
|
||||
|
||||
uint32_t _crc = ~Seed;
|
||||
for (; InputLength--; ++pCur)
|
||||
_crc = (_crc >> 8) ^ CRC32LookupTable[(_crc ^ *pCur) & 0xFF];
|
||||
|
||||
return (~_crc);
|
||||
}
|
||||
}
|
26
r5dev/thirdparty/cppnet/cppkore/CRC32.h
vendored
Normal file
26
r5dev/thirdparty/cppnet/cppkore/CRC32.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "StringBase.h"
|
||||
|
||||
namespace Hashing
|
||||
{
|
||||
// A hashing algo that implements CRC32.
|
||||
class CRC32
|
||||
{
|
||||
public:
|
||||
|
||||
// Computes the hash code of the integral value using CRC32 algo.
|
||||
template<class Tinput>
|
||||
static uint32_t HashValue(Tinput Input, uint32_t Seed = 0)
|
||||
{
|
||||
return ComputeHash((uint8_t*)&Input, 0, sizeof(Tinput), Seed);
|
||||
}
|
||||
|
||||
// Computes the hash code of the input string using CRC32 algo.
|
||||
static uint32_t HashString(const String& Input, uint32_t Seed = 0);
|
||||
|
||||
// Computes the hash code using the CRC32 algo.
|
||||
static uint32_t ComputeHash(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint32_t Seed = 0);
|
||||
};
|
||||
}
|
10
r5dev/thirdparty/cppnet/cppkore/CacheVirtualItemsEventArgs.cpp
vendored
Normal file
10
r5dev/thirdparty/cppnet/cppkore/CacheVirtualItemsEventArgs.cpp
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "CacheVirtualItemsEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
CacheVirtualItemsEventArgs::CacheVirtualItemsEventArgs(int32_t Start, int32_t End)
|
||||
: StartIndex(Start), EndIndex(End)
|
||||
{
|
||||
}
|
||||
}
|
19
r5dev/thirdparty/cppnet/cppkore/CacheVirtualItemsEventArgs.h
vendored
Normal file
19
r5dev/thirdparty/cppnet/cppkore/CacheVirtualItemsEventArgs.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides data for the CacheVirtualItems event.
|
||||
class CacheVirtualItemsEventArgs
|
||||
{
|
||||
public:
|
||||
CacheVirtualItemsEventArgs(int32_t Start, int32_t End);
|
||||
~CacheVirtualItemsEventArgs() = default;
|
||||
|
||||
// The start of the cache index.
|
||||
int32_t StartIndex;
|
||||
// The end of the cache index.
|
||||
int32_t EndIndex;
|
||||
};
|
||||
}
|
15
r5dev/thirdparty/cppnet/cppkore/CancelEventArgs.cpp
vendored
Normal file
15
r5dev/thirdparty/cppnet/cppkore/CancelEventArgs.cpp
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
#include "stdafx.h"
|
||||
#include "CancelEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
CancelEventArgs::CancelEventArgs()
|
||||
: CancelEventArgs(false)
|
||||
{
|
||||
}
|
||||
|
||||
CancelEventArgs::CancelEventArgs(bool Cancel)
|
||||
: Cancel(Cancel)
|
||||
{
|
||||
}
|
||||
}
|
18
r5dev/thirdparty/cppnet/cppkore/CancelEventArgs.h
vendored
Normal file
18
r5dev/thirdparty/cppnet/cppkore/CancelEventArgs.h
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides data for the cancel event.
|
||||
class CancelEventArgs
|
||||
{
|
||||
public:
|
||||
CancelEventArgs();
|
||||
CancelEventArgs(bool Cancel);
|
||||
~CancelEventArgs() = default;
|
||||
|
||||
// Gets or sets a value indicating whether the operation should be cancelled.
|
||||
bool Cancel;
|
||||
};
|
||||
}
|
402
r5dev/thirdparty/cppnet/cppkore/CastAsset.cpp
vendored
Normal file
402
r5dev/thirdparty/cppnet/cppkore/CastAsset.cpp
vendored
Normal file
@ -0,0 +1,402 @@
|
||||
#include "stdafx.h"
|
||||
#include "CastAsset.h"
|
||||
#include "CastNode.h"
|
||||
#include "File.h"
|
||||
#include "XXHash.h"
|
||||
#include "BinaryWriter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
struct CastHeader
|
||||
{
|
||||
uint32_t Magic; // char[4] cast (0x74736163)
|
||||
uint32_t Version; // 0x1
|
||||
uint32_t RootNodes; // Number of root nodes, which contain various sub nodes if necessary
|
||||
uint32_t Flags; // Reserved for flags, or padding, whichever is needed
|
||||
};
|
||||
|
||||
static_assert(sizeof(CastHeader) == 0x10, "Cast header size mismatch");
|
||||
|
||||
|
||||
bool CastAsset::ExportAnimation(const Animation& Animation, const String& Path)
|
||||
{
|
||||
auto Writer = IO::BinaryWriter(IO::File::Create(Path));
|
||||
|
||||
// Magic, version 1, one root node, no flags.
|
||||
Writer.Write<CastHeader>({ 0x74736163, 0x1, 0x1, 0x0 });
|
||||
|
||||
// This is the base of the virtual scene
|
||||
auto Root = CastNode(CastId::Root);
|
||||
auto& AnimNode = Root.Children.Emplace(CastId::Animation, Hashing::XXHash::HashString("animation"));
|
||||
auto& SkeletonNode = AnimNode.Children.Emplace(CastId::Skeleton, Hashing::XXHash::HashString("skeleton"));
|
||||
|
||||
AnimNode.Properties.Emplace(CastPropertyId::Float, "fr").AddFloat(Animation.FrameRate);
|
||||
AnimNode.Properties.Emplace(CastPropertyId::Byte, "lo").AddByte((uint8_t)Animation.Looping);
|
||||
|
||||
for (auto& Bone : Animation.Bones)
|
||||
{
|
||||
auto& BoneNode = SkeletonNode.Children.Emplace(CastId::Bone);
|
||||
|
||||
BoneNode.Properties.Emplace(CastPropertyId::String, "n").SetString(Bone.Name());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Integer32, "p").AddInteger32(Bone.Parent());
|
||||
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasLocalSpaceMatrices))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "lp").AddVector3(Bone.LocalPosition());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector4, "lr").AddVector4(Bone.LocalRotation());
|
||||
}
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasGlobalSpaceMatrices))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "wp").AddVector3(Bone.GlobalPosition());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector4, "wr").AddVector4(Bone.GlobalRotation());
|
||||
}
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasScale))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "s").AddVector3(Bone.Scale());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Kvp : Animation.Curves)
|
||||
{
|
||||
for (auto& Curve : Kvp.Value())
|
||||
{
|
||||
auto& CurveNode = AnimNode.Children.Emplace(CastId::Curve, 0);
|
||||
|
||||
CurveNode.Properties.Emplace(CastPropertyId::String, "nn").SetString(Curve.Name);
|
||||
|
||||
constexpr const char* PropertyNameMap[] = {
|
||||
"ex",
|
||||
"rq",
|
||||
"rx",
|
||||
"ry",
|
||||
"rz",
|
||||
"tx",
|
||||
"ty",
|
||||
"tz",
|
||||
"sx",
|
||||
"sy",
|
||||
"sz",
|
||||
"vb"
|
||||
};
|
||||
|
||||
constexpr const char* ModeNameMap[] = {
|
||||
"absolute",
|
||||
"additive",
|
||||
"relative"
|
||||
};
|
||||
|
||||
CurveNode.Properties.Emplace(CastPropertyId::String, "kp").SetString(PropertyNameMap[(uint32_t)Curve.Property]);
|
||||
CurveNode.Properties.Emplace(CastPropertyId::String, "m").SetString(ModeNameMap[(uint32_t)Curve.Mode]);
|
||||
|
||||
auto KeyframeValueProperty = CastPropertyId::Float;
|
||||
|
||||
switch (Curve.Property)
|
||||
{
|
||||
case CurveProperty::RotateQuaternion:
|
||||
KeyframeValueProperty = CastPropertyId::Vector4;
|
||||
break;
|
||||
|
||||
case CurveProperty::RotateX:
|
||||
case CurveProperty::RotateY:
|
||||
case CurveProperty::RotateZ:
|
||||
case CurveProperty::TranslateX:
|
||||
case CurveProperty::TranslateY:
|
||||
case CurveProperty::TranslateZ:
|
||||
case CurveProperty::ScaleX:
|
||||
case CurveProperty::ScaleY:
|
||||
case CurveProperty::ScaleZ:
|
||||
KeyframeValueProperty = CastPropertyId::Float;
|
||||
break;
|
||||
|
||||
case CurveProperty::Visibility:
|
||||
KeyframeValueProperty = CastPropertyId::Byte;
|
||||
break;
|
||||
}
|
||||
|
||||
auto KeyframeFrameProperty = CastPropertyId::Float;
|
||||
|
||||
if (Curve.IsFrameIntegral())
|
||||
{
|
||||
uint32_t LargestFrameIndex = 0;
|
||||
for (auto& KeyFrame : Curve.Keyframes)
|
||||
LargestFrameIndex = max(LargestFrameIndex, KeyFrame.Frame.Integer32);
|
||||
|
||||
if (LargestFrameIndex <= 0xFF)
|
||||
KeyframeFrameProperty = CastPropertyId::Byte;
|
||||
else if (LargestFrameIndex <= 0xFFFF)
|
||||
KeyframeFrameProperty = CastPropertyId::Short;
|
||||
else
|
||||
KeyframeFrameProperty = CastPropertyId::Integer32;
|
||||
}
|
||||
|
||||
auto& KeyFrameBuffer = CurveNode.Properties.Emplace(KeyframeFrameProperty, "kb");
|
||||
auto& KeyValueBuffer = CurveNode.Properties.Emplace(KeyframeValueProperty, "kv");
|
||||
|
||||
for (auto& KeyFrame : Curve.Keyframes)
|
||||
{
|
||||
switch (KeyframeFrameProperty)
|
||||
{
|
||||
case CastPropertyId::Float:
|
||||
KeyFrameBuffer.AddFloat(KeyFrame.Frame.Float);
|
||||
break;
|
||||
case CastPropertyId::Byte:
|
||||
KeyFrameBuffer.AddByte((uint8_t)KeyFrame.Frame.Integer32);
|
||||
break;
|
||||
case CastPropertyId::Short:
|
||||
KeyFrameBuffer.AddShort((uint16_t)KeyFrame.Frame.Integer32);
|
||||
break;
|
||||
case CastPropertyId::Integer32:
|
||||
KeyFrameBuffer.AddInteger32(KeyFrame.Frame.Integer32);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Curve.Property)
|
||||
{
|
||||
case CurveProperty::RotateQuaternion:
|
||||
KeyValueBuffer.AddVector4(KeyFrame.Value.Vector4);
|
||||
break;
|
||||
|
||||
case CurveProperty::RotateX:
|
||||
case CurveProperty::RotateY:
|
||||
case CurveProperty::RotateZ:
|
||||
case CurveProperty::TranslateX:
|
||||
case CurveProperty::TranslateY:
|
||||
case CurveProperty::TranslateZ:
|
||||
case CurveProperty::ScaleX:
|
||||
case CurveProperty::ScaleY:
|
||||
case CurveProperty::ScaleZ:
|
||||
KeyValueBuffer.AddFloat(KeyFrame.Value.Float);
|
||||
break;
|
||||
|
||||
case CurveProperty::Visibility:
|
||||
KeyValueBuffer.AddByte(KeyFrame.Value.Byte);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Notetrack : Animation.Notificiations)
|
||||
{
|
||||
auto& TrackNode = AnimNode.Children.Emplace(CastId::NotificationTrack, Hashing::XXHash::HashString(Notetrack.Key()));
|
||||
|
||||
TrackNode.Properties.Emplace(CastPropertyId::String, "n").SetString(Notetrack.Key());
|
||||
|
||||
auto& KeyBuffer = TrackNode.Properties.Emplace(CastPropertyId::Integer32, "kb");
|
||||
|
||||
for (auto& Key : Notetrack.Value())
|
||||
KeyBuffer.AddInteger32(Key);
|
||||
}
|
||||
|
||||
// Finally, serialize the node to the disk
|
||||
Root.Write(Writer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastAsset::ExportModel(const Model& Model, const String& Path)
|
||||
{
|
||||
auto Writer = IO::BinaryWriter(IO::File::Create(Path));
|
||||
|
||||
// Magic, version 1, one root node, no flags.
|
||||
Writer.Write<CastHeader>({ 0x74736163, 0x1, 0x1, 0x0 });
|
||||
|
||||
// This is the base of the virtual scene
|
||||
auto Root = CastNode(CastId::Root);
|
||||
auto& ModelNode = Root.Children.Emplace(CastId::Model, Hashing::XXHash::HashString("model"));
|
||||
auto& SkeletonNode = ModelNode.Children.Emplace(CastId::Skeleton, Hashing::XXHash::HashString("skeleton"));
|
||||
|
||||
auto BoneCount = Model.Bones.Count();
|
||||
|
||||
for (auto& Bone : Model.Bones)
|
||||
{
|
||||
auto& BoneNode = SkeletonNode.Children.Emplace(CastId::Bone);
|
||||
|
||||
BoneNode.Properties.Emplace(CastPropertyId::String, "n").SetString(Bone.Name());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Integer32, "p").AddInteger32(Bone.Parent());
|
||||
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasLocalSpaceMatrices))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "lp").AddVector3(Bone.LocalPosition());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector4, "lr").AddVector4(Bone.LocalRotation());
|
||||
}
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasGlobalSpaceMatrices))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "wp").AddVector3(Bone.GlobalPosition());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector4, "wr").AddVector4(Bone.GlobalRotation());
|
||||
}
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasScale))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "s").AddVector3(Bone.Scale());
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<uint32_t, uint64_t> MaterialHashMap;
|
||||
uint32_t MaterialIndex = 0;
|
||||
|
||||
for (auto& Mat : Model.Materials)
|
||||
{
|
||||
auto& MatNode = ModelNode.Children.Emplace(CastId::Material, Hashing::XXHash::HashString(Mat.Name));
|
||||
|
||||
MatNode.Properties.Emplace(CastPropertyId::String, "n").SetString(Mat.Name);
|
||||
MatNode.Properties.Emplace(CastPropertyId::String, "t").SetString("pbr");
|
||||
|
||||
for (auto& Kvp : Mat.Slots)
|
||||
{
|
||||
auto FileHash = Hashing::XXHash::HashString(Kvp.second.first);
|
||||
MatNode.Children.Emplace(CastId::File, FileHash).Properties.Emplace(CastPropertyId::String, "p").SetString(Kvp.second.first);
|
||||
|
||||
// Cast material property mapping
|
||||
constexpr const char* MaterialSlotNames[] =
|
||||
{
|
||||
"extra", // Invalid
|
||||
"albedo",
|
||||
"diffuse",
|
||||
"normal",
|
||||
"specular",
|
||||
"emissive",
|
||||
"gloss",
|
||||
"roughness",
|
||||
"ao",
|
||||
"cavity"
|
||||
};
|
||||
|
||||
MatNode.Properties.Emplace(CastPropertyId::Integer64, MaterialSlotNames[(uint32_t)Kvp.first]).AddInteger64(FileHash);
|
||||
}
|
||||
|
||||
MaterialHashMap.Add(MaterialIndex++, MatNode.Hash);
|
||||
}
|
||||
|
||||
uint32_t MeshIndex = 0;
|
||||
|
||||
for (auto& Mesh : Model.Meshes)
|
||||
{
|
||||
auto& MeshNode = ModelNode.Children.Emplace(CastId::Mesh, Hashing::XXHash::HashString(String::Format("mesh%02d", MeshIndex++)));
|
||||
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Vector3, "vp");
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Vector3, "vn");
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Integer32, "vc");
|
||||
|
||||
auto VertexCount = Mesh.Vertices.Count();
|
||||
|
||||
if (VertexCount <= 0xFF)
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Byte, "f");
|
||||
else if (VertexCount <= 0xFFFF)
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Short, "f");
|
||||
else
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Integer32, "f");
|
||||
|
||||
// Configure the uv layer count, and maximum influence
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Byte, "ul").AddByte((uint8_t)Mesh.Vertices.UVLayerCount());
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Byte, "mi").AddByte((uint8_t)Mesh.Vertices.WeightCount());
|
||||
|
||||
if (BoneCount <= 0xFF)
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Byte, "wb");
|
||||
else if (BoneCount <= 0xFFFF)
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Short, "wb");
|
||||
else
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Integer32, "wb");
|
||||
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Float, "wv");
|
||||
|
||||
List<CastProperty*> UVLayers;
|
||||
|
||||
for (uint8_t i = 0; i < Mesh.Vertices.UVLayerCount(); i++)
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Vector2, String::Format("u%d", i));
|
||||
|
||||
auto& VertexPositions = MeshNode.Properties[0];
|
||||
auto& VertexNormals = MeshNode.Properties[1];
|
||||
auto& VertexColors = MeshNode.Properties[2];
|
||||
auto& FaceIndices = MeshNode.Properties[3];
|
||||
auto& VertexWeightBones = MeshNode.Properties[6];
|
||||
auto& VertexWeightValues = MeshNode.Properties[7];
|
||||
|
||||
for (auto& Layer : MeshNode.Properties)
|
||||
{
|
||||
if (Layer.Name != "ul" && Layer.Name.StartsWith("u"))
|
||||
UVLayers.Add(&Layer);
|
||||
}
|
||||
|
||||
for (auto& Vertex : Mesh.Vertices)
|
||||
{
|
||||
VertexPositions.AddVector3(Vertex.Position());
|
||||
VertexNormals.AddVector3(Vertex.Normal());
|
||||
VertexColors.AddInteger32(*(uint32_t*)&Vertex.Color());
|
||||
|
||||
for (uint8_t i = 0; i < Mesh.Vertices.WeightCount(); i++)
|
||||
{
|
||||
if (BoneCount <= 0xFF)
|
||||
VertexWeightBones.AddByte((uint8_t)Vertex.Weights(i).Bone);
|
||||
else if (BoneCount <= 0xFFFF)
|
||||
VertexWeightBones.AddShort((uint16_t)Vertex.Weights(i).Bone);
|
||||
else
|
||||
VertexWeightBones.AddInteger32(Vertex.Weights(i).Bone);
|
||||
|
||||
VertexWeightValues.AddFloat(Vertex.Weights(i).Value);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < Mesh.Vertices.UVLayerCount(); i++)
|
||||
{
|
||||
UVLayers[i]->AddVector2(Vertex.UVLayers(i));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Face : Mesh.Faces)
|
||||
{
|
||||
if (VertexCount <= 0xFF)
|
||||
{
|
||||
FaceIndices.AddByte((uint8_t)Face[2]);
|
||||
FaceIndices.AddByte((uint8_t)Face[1]);
|
||||
FaceIndices.AddByte((uint8_t)Face[0]);
|
||||
}
|
||||
else if (VertexCount <= 0xFFFF)
|
||||
{
|
||||
FaceIndices.AddShort((uint16_t)Face[2]);
|
||||
FaceIndices.AddShort((uint16_t)Face[1]);
|
||||
FaceIndices.AddShort((uint16_t)Face[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
FaceIndices.AddInteger32(Face[2]);
|
||||
FaceIndices.AddInteger32(Face[1]);
|
||||
FaceIndices.AddInteger32(Face[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (Mesh.MaterialIndices.Count() > 0 && Mesh.MaterialIndices[0] > -1)
|
||||
{
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Integer64, "m").AddInteger64(MaterialHashMap[Mesh.MaterialIndices[0]]);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, serialize the node to the disk
|
||||
Root.Write(Writer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
imstring CastAsset::ModelExtension()
|
||||
{
|
||||
return ".cast";
|
||||
}
|
||||
|
||||
imstring CastAsset::AnimationExtension()
|
||||
{
|
||||
return ".cast";
|
||||
}
|
||||
|
||||
ExporterScale CastAsset::ExportScale()
|
||||
{
|
||||
return ExporterScale::Default;
|
||||
}
|
||||
|
||||
bool CastAsset::SupportsAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastAsset::SupportsModels()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
32
r5dev/thirdparty/cppnet/cppkore/CastAsset.h
vendored
Normal file
32
r5dev/thirdparty/cppnet/cppkore/CastAsset.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Exporter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
class CastAsset : public Exporter
|
||||
{
|
||||
public:
|
||||
CastAsset() = default;
|
||||
~CastAsset() = default;
|
||||
|
||||
// Exports the given animation to the provided path.
|
||||
virtual bool ExportAnimation(const Animation& Animation, const String& Path);
|
||||
// Exports the given model to the provided path.
|
||||
virtual bool ExportModel(const Model& Model, const String& Path);
|
||||
|
||||
// Gets the file extension for this exporters model format.
|
||||
virtual imstring ModelExtension();
|
||||
// Gets the file extension for this exporters animation format.
|
||||
virtual imstring AnimationExtension();
|
||||
|
||||
// Gets the required scaling constant for this exporter.
|
||||
virtual ExporterScale ExportScale();
|
||||
|
||||
// Gets whether or not the exporter supports animation exporting.
|
||||
virtual bool SupportsAnimations();
|
||||
// Gets whether or not the exporter supports model exporting.
|
||||
virtual bool SupportsModels();
|
||||
};
|
||||
}
|
222
r5dev/thirdparty/cppnet/cppkore/CastNode.cpp
vendored
Normal file
222
r5dev/thirdparty/cppnet/cppkore/CastNode.cpp
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
#include "stdafx.h"
|
||||
#include "CastNode.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
CastProperty::CastProperty()
|
||||
: Identifier(CastPropertyId::Byte)
|
||||
{
|
||||
}
|
||||
|
||||
CastProperty::CastProperty(CastPropertyId Id, const char* Name)
|
||||
: Identifier(Id), Name(Name)
|
||||
{
|
||||
// All property names are lower-case
|
||||
this->Name = this->Name.ToLower();
|
||||
}
|
||||
|
||||
const uint32_t CastProperty::Length() const
|
||||
{
|
||||
switch (this->Identifier)
|
||||
{
|
||||
case CastPropertyId::Byte: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(uint8_t) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Short: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(uint16_t) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Integer32: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(uint32_t) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Integer64: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(uint64_t) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Float: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(float) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Double: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(double) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Vector2 : return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(Math::Vector2) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Vector3: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(Math::Vector3) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Vector4: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(Math::Quaternion) * this->IntegralValues.Count());
|
||||
case CastPropertyId::String: return sizeof(CastPropertyHeader) + this->Name.Length() + (StringValue.Length() + sizeof(uint8_t));
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CastProperty::Write(IO::BinaryWriter& Writer) const
|
||||
{
|
||||
auto Size = (this->Identifier == CastPropertyId::String) ? 1 : this->IntegralValues.Count();
|
||||
Writer.Write<CastPropertyHeader>({this->Identifier, (uint16_t)this->Name.Length(), Size});
|
||||
Writer.Write(&this->Name[0], 0, this->Name.Length());
|
||||
|
||||
switch (this->Identifier)
|
||||
{
|
||||
case CastPropertyId::Byte:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<uint8_t>(Value.Byte);
|
||||
break;
|
||||
case CastPropertyId::Short:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<uint16_t>(Value.Short);
|
||||
break;
|
||||
case CastPropertyId::Integer32:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<uint32_t>(Value.Integer32);
|
||||
break;
|
||||
case CastPropertyId::Integer64:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<uint64_t>(Value.Integer64);
|
||||
break;
|
||||
case CastPropertyId::Float:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<float>(Value.Float);
|
||||
break;
|
||||
case CastPropertyId::Double:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<double>(Value.Double);
|
||||
break;
|
||||
case CastPropertyId::Vector2:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<Math::Vector2>(Value.Vector2);
|
||||
break;
|
||||
case CastPropertyId::Vector3:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<Math::Vector3>(Value.Vector3);
|
||||
break;
|
||||
case CastPropertyId::Vector4:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<Math::Quaternion>(Value.Vector4);
|
||||
break;
|
||||
case CastPropertyId::String:
|
||||
Writer.WriteCString(this->StringValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CastProperty::AddByte(uint8_t Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddShort(uint16_t Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddInteger32(uint32_t Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddInteger64(uint64_t Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddFloat(float Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddDouble(double Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddVector2(Math::Vector2 Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddVector3(Math::Vector3 Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddVector4(Math::Quaternion Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::SetString(const String& Value)
|
||||
{
|
||||
this->StringValue = Value;
|
||||
}
|
||||
|
||||
CastNode::CastNode()
|
||||
: Identifier(CastId::Root), Hash(0)
|
||||
{
|
||||
}
|
||||
|
||||
CastNode::CastNode(CastId Id)
|
||||
: Identifier(Id), Hash(0)
|
||||
{
|
||||
}
|
||||
|
||||
CastNode::CastNode(CastId Id, uint64_t Hash)
|
||||
: Identifier(Id), Hash(Hash)
|
||||
{
|
||||
}
|
||||
|
||||
const uint32_t CastNode::Length() const
|
||||
{
|
||||
uint32_t Result = sizeof(CastNodeHeader);
|
||||
|
||||
for (auto& Child : this->Children)
|
||||
Result += Child.Length();
|
||||
for (auto& Property : this->Properties)
|
||||
Result += Property.Length();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void CastNode::Write(IO::BinaryWriter& Writer) const
|
||||
{
|
||||
Writer.Write<CastNodeHeader>({this->Identifier, this->Length(), this->Hash, this->Properties.Count(), this->Children.Count()});
|
||||
|
||||
for (auto& Prop : Properties)
|
||||
Prop.Write(Writer);
|
||||
for (auto& Child : Children)
|
||||
Child.Write(Writer);
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion()
|
||||
: Vector4(0,0,0,0)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(uint8_t Value)
|
||||
: Byte(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(uint16_t Value)
|
||||
: Short(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(uint32_t Value)
|
||||
: Integer32(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(uint64_t Value)
|
||||
: Integer64(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(float Value)
|
||||
: Float(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(double Value)
|
||||
: Double(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(Math::Vector2 Value)
|
||||
: Vector2(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(Math::Vector3 Value)
|
||||
: Vector3(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(Math::Quaternion Value)
|
||||
: Vector4(Value)
|
||||
{
|
||||
}
|
||||
}
|
146
r5dev/thirdparty/cppnet/cppkore/CastNode.h
vendored
Normal file
146
r5dev/thirdparty/cppnet/cppkore/CastNode.h
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Quaternion.h"
|
||||
#include "StringBase.h"
|
||||
#include "ListBase.h"
|
||||
#include "BinaryWriter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
enum class CastId : uint32_t
|
||||
{
|
||||
Root = 0x746F6F72,
|
||||
Model = 0x6C646F6D,
|
||||
Mesh = 0x6873656D,
|
||||
Skeleton = 0x6C656B73,
|
||||
Bone = 0x656E6F62,
|
||||
Animation = 0x6D696E61,
|
||||
Curve = 0x76727563,
|
||||
NotificationTrack = 0x6669746E,
|
||||
Material = 0x6C74616D,
|
||||
File = 0x656C6966,
|
||||
};
|
||||
|
||||
enum class CastPropertyId : uint16_t
|
||||
{
|
||||
Byte = 'b', // <uint8_t>
|
||||
Short = 'h', // <uint16_t>
|
||||
Integer32 = 'i', // <uint32_t>
|
||||
Integer64 = 'l', // <uint64_t>
|
||||
|
||||
Float = 'f', // <float>
|
||||
Double = 'd', // <double>
|
||||
|
||||
String = 's', // Null terminated UTF-8 string
|
||||
|
||||
Vector2 = 'v2', // Float precision vector XY
|
||||
Vector3 = 'v3', // Float precision vector XYZ
|
||||
Vector4 = 'v4' // Float precision vector XYZW
|
||||
};
|
||||
|
||||
struct CastNodeHeader
|
||||
{
|
||||
CastId Identifier; // Used to signify which class this node uses
|
||||
uint32_t NodeSize; // Size of all data and sub data following the node
|
||||
uint64_t NodeHash; // Unique hash, like an id, used to link nodes together
|
||||
uint32_t PropertyCount; // The count of properties
|
||||
uint32_t ChildCount; // The count of direct children nodes
|
||||
|
||||
// We must read until the node size hits, and that means we are done.
|
||||
// The nodes are in a stack layout, so it's easy to load, FILO order.
|
||||
};
|
||||
|
||||
struct CastPropertyHeader
|
||||
{
|
||||
CastPropertyId Identifier; // The element type of this property
|
||||
uint16_t NameSize; // The size of the name of this property
|
||||
uint32_t ArrayLength; // The number of elements this property contains (1 for single)
|
||||
|
||||
// Following is UTF-8 string lowercase, size of namesize, NOT null terminated
|
||||
// cast_property[ArrayLength] array of data
|
||||
};
|
||||
|
||||
union CastPropertyUnion
|
||||
{
|
||||
uint8_t Byte;
|
||||
uint16_t Short;
|
||||
uint32_t Integer32;
|
||||
uint64_t Integer64;
|
||||
|
||||
float Float;
|
||||
double Double;
|
||||
|
||||
Math::Vector2 Vector2;
|
||||
Math::Vector3 Vector3;
|
||||
Math::Quaternion Vector4;
|
||||
|
||||
CastPropertyUnion();
|
||||
|
||||
explicit CastPropertyUnion(uint8_t Value);
|
||||
explicit CastPropertyUnion(uint16_t Value);
|
||||
explicit CastPropertyUnion(uint32_t Value);
|
||||
explicit CastPropertyUnion(uint64_t Value);
|
||||
explicit CastPropertyUnion(float Value);
|
||||
explicit CastPropertyUnion(double Value);
|
||||
explicit CastPropertyUnion(Math::Vector2 Value);
|
||||
explicit CastPropertyUnion(Math::Vector3 Value);
|
||||
explicit CastPropertyUnion(Math::Quaternion Value);
|
||||
};
|
||||
|
||||
static_assert(sizeof(CastNodeHeader) == 0x18, "CastNode header size mismatch");
|
||||
static_assert(sizeof(CastPropertyHeader) == 0x8, "CastProperty header size mismatch");
|
||||
static_assert(sizeof(CastPropertyUnion) == 0x10, "CastProperty union size mismatch");
|
||||
|
||||
class CastProperty
|
||||
{
|
||||
public:
|
||||
CastProperty();
|
||||
explicit CastProperty(CastPropertyId Id, const char* Name);
|
||||
|
||||
const uint32_t Length() const;
|
||||
|
||||
void Write(IO::BinaryWriter& Writer) const;
|
||||
|
||||
void AddByte(uint8_t Value);
|
||||
void AddShort(uint16_t Value);
|
||||
void AddInteger32(uint32_t Value);
|
||||
void AddInteger64(uint64_t Value);
|
||||
|
||||
void AddFloat(float Value);
|
||||
void AddDouble(double Value);
|
||||
|
||||
void AddVector2(Math::Vector2 Value);
|
||||
void AddVector3(Math::Vector3 Value);
|
||||
void AddVector4(Math::Quaternion Value);
|
||||
|
||||
void SetString(const String& Value);
|
||||
|
||||
CastPropertyId Identifier;
|
||||
String Name;
|
||||
|
||||
private:
|
||||
List<CastPropertyUnion> IntegralValues;
|
||||
String StringValue;
|
||||
};
|
||||
|
||||
class CastNode
|
||||
{
|
||||
public:
|
||||
CastNode();
|
||||
CastNode(CastId Id);
|
||||
CastNode(CastId Id, uint64_t Hash);
|
||||
|
||||
const uint32_t Length() const;
|
||||
|
||||
void Write(IO::BinaryWriter& Writer) const;
|
||||
|
||||
CastId Identifier;
|
||||
uint64_t Hash;
|
||||
|
||||
List<CastProperty> Properties;
|
||||
List<CastNode> Children;
|
||||
};
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/CharacterCasing.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/CharacterCasing.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the case of characters in a Textbox control.
|
||||
enum class CharacterCasing
|
||||
{
|
||||
// The case of characters is left unchanged.
|
||||
Normal = 0,
|
||||
// Converts all characters to uppercase.
|
||||
Upper = 1,
|
||||
// Converts all characters to lowercase.
|
||||
Lower = 2,
|
||||
};
|
||||
}
|
188
r5dev/thirdparty/cppnet/cppkore/CheckBox.cpp
vendored
Normal file
188
r5dev/thirdparty/cppnet/cppkore/CheckBox.cpp
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
#include "stdafx.h"
|
||||
#include "CheckBox.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
CheckBox::CheckBox()
|
||||
: ButtonBase(), _AutoCheck(true), _ThreeState(false), _Appearence(Appearence::Normal), _CheckState(CheckState::Unchecked)
|
||||
{
|
||||
SetStyle(ControlStyles::StandardClick | ControlStyles::StandardDoubleClick, false);
|
||||
this->SetTextAlign(Drawing::ContentAlignment::MiddleLeft);
|
||||
|
||||
// We are a checkbox control
|
||||
this->_RTTI = ControlTypes::CheckBox;
|
||||
}
|
||||
|
||||
Appearence CheckBox::GetAppearence()
|
||||
{
|
||||
return this->_Appearence;
|
||||
}
|
||||
|
||||
void CheckBox::SetAppearence(Appearence Value)
|
||||
{
|
||||
if (this->_Appearence != Value)
|
||||
{
|
||||
this->_Appearence = Value;
|
||||
|
||||
if (this->_OwnerDraw)
|
||||
Refresh();
|
||||
else
|
||||
UpdateStyles();
|
||||
|
||||
OnAppearenceChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckBox::AutoCheck()
|
||||
{
|
||||
return this->_AutoCheck;
|
||||
}
|
||||
|
||||
void CheckBox::SetAutoCheck(bool Value)
|
||||
{
|
||||
this->_AutoCheck = Value;
|
||||
}
|
||||
|
||||
bool CheckBox::Checked()
|
||||
{
|
||||
return _CheckState != CheckState::Unchecked;
|
||||
}
|
||||
|
||||
void CheckBox::SetChecked(bool Value)
|
||||
{
|
||||
this->SetCheckState((Value) ? CheckState::Checked : CheckState::Unchecked);
|
||||
}
|
||||
|
||||
CheckState CheckBox::GetCheckState()
|
||||
{
|
||||
return _CheckState;
|
||||
}
|
||||
|
||||
void CheckBox::SetCheckState(CheckState Value)
|
||||
{
|
||||
if (_CheckState != Value)
|
||||
{
|
||||
bool oChecked = Checked();
|
||||
|
||||
_CheckState = Value;
|
||||
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, BM_SETCHECK, (int)_CheckState, 0);
|
||||
|
||||
if (oChecked != Checked())
|
||||
{
|
||||
OnCheckedChanged();
|
||||
}
|
||||
|
||||
OnCheckStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckBox::ThreeState()
|
||||
{
|
||||
return _ThreeState;
|
||||
}
|
||||
|
||||
void CheckBox::SetThreeState(bool Value)
|
||||
{
|
||||
_ThreeState = Value;
|
||||
}
|
||||
|
||||
void CheckBox::OnClick()
|
||||
{
|
||||
if (_AutoCheck)
|
||||
{
|
||||
switch (_CheckState)
|
||||
{
|
||||
case CheckState::Unchecked:
|
||||
SetCheckState(CheckState::Checked);
|
||||
break;
|
||||
case CheckState::Checked:
|
||||
if (_ThreeState)
|
||||
SetCheckState(CheckState::Indeterminate);
|
||||
else
|
||||
SetCheckState(CheckState::Unchecked);
|
||||
break;
|
||||
default:
|
||||
SetCheckState(CheckState::Unchecked);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
ButtonBase::OnClick();
|
||||
}
|
||||
|
||||
void CheckBox::OnAppearenceChanged()
|
||||
{
|
||||
AppearenceChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void CheckBox::OnCheckedChanged()
|
||||
{
|
||||
CheckedChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void CheckBox::OnCheckStateChanged()
|
||||
{
|
||||
if (this->_OwnerDraw)
|
||||
Refresh();
|
||||
|
||||
CheckStateChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void CheckBox::OnHandleCreated()
|
||||
{
|
||||
SendMessageA(this->_Handle, BM_SETCHECK, (int)_CheckState, NULL);
|
||||
|
||||
// We must call base event last
|
||||
Control::OnHandleCreated();
|
||||
}
|
||||
|
||||
void CheckBox::OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->Button == MouseButtons::Left && GetFlag(ButtonFlags::FlagMousePressed))
|
||||
{
|
||||
if (GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
auto Pt = PointToScreen({ (INT)EventArgs->X, (INT)EventArgs->Y });
|
||||
|
||||
POINT nPt;
|
||||
nPt.x = Pt.X;
|
||||
nPt.y = Pt.Y;
|
||||
|
||||
if (WindowFromPoint(nPt) == this->_Handle)
|
||||
{
|
||||
ResetFlagsAndPaint();
|
||||
|
||||
if (this->Capture())
|
||||
OnClick();
|
||||
|
||||
OnMouseClick(EventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
ButtonBase::OnMouseUp(EventArgs);
|
||||
}
|
||||
|
||||
CreateParams CheckBox::GetCreateParams()
|
||||
{
|
||||
auto Cp = ButtonBase::GetCreateParams();
|
||||
|
||||
Cp.ClassName = "BUTTON";
|
||||
|
||||
if (GetStyle(ControlStyles::UserPaint))
|
||||
Cp.Style |= BS_OWNERDRAW;
|
||||
else
|
||||
{
|
||||
Cp.Style |= BS_3STATE;
|
||||
|
||||
if (this->_Appearence == Appearence::Button)
|
||||
Cp.Style |= BS_PUSHLIKE;
|
||||
}
|
||||
|
||||
return Cp;
|
||||
}
|
||||
}
|
72
r5dev/thirdparty/cppnet/cppkore/CheckBox.h
vendored
Normal file
72
r5dev/thirdparty/cppnet/cppkore/CheckBox.h
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Control.h"
|
||||
#include "Appearence.h"
|
||||
#include "ButtonBase.h"
|
||||
#include "CheckState.h"
|
||||
#include "ContentAlignment.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Represents a Windows check box.
|
||||
class CheckBox : public ButtonBase
|
||||
{
|
||||
public:
|
||||
CheckBox();
|
||||
virtual ~CheckBox() = default;
|
||||
|
||||
// Gets the value that determines the appearance of a check box control.
|
||||
Appearence GetAppearence();
|
||||
// Sets the value that determines the appearance of a check box control.
|
||||
void SetAppearence(Appearence Value);
|
||||
|
||||
// Gets a value indicating whether the check box automatically checks itself.
|
||||
bool AutoCheck();
|
||||
// Sets a value indicating whether the check box automatically checks itself.
|
||||
void SetAutoCheck(bool Value);
|
||||
|
||||
// Gets a value indicating whether the check box is checked.
|
||||
bool Checked();
|
||||
// Sets a value indicating whether the check box is checked.
|
||||
void SetChecked(bool Value);
|
||||
|
||||
// Gets a value indicating whether the check box is checked.
|
||||
CheckState GetCheckState();
|
||||
// Sets a value indicating whether the check box is checked.
|
||||
void SetCheckState(CheckState Value);
|
||||
|
||||
// Gets a value indicating whether the check box will allow three check states rather than two.
|
||||
bool ThreeState();
|
||||
// Sets a value indicating whether the check box will allow three check states rather than two.
|
||||
void SetThreeState(bool Value);
|
||||
|
||||
// We must define base events here
|
||||
virtual void OnClick();
|
||||
virtual void OnAppearenceChanged();
|
||||
virtual void OnCheckedChanged();
|
||||
virtual void OnCheckStateChanged();
|
||||
virtual void OnHandleCreated();
|
||||
virtual void OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
|
||||
// We must define event handlers here
|
||||
EventBase<void(*)(Control*)> AppearenceChanged;
|
||||
EventBase<void(*)(Control*)> CheckedChanged;
|
||||
EventBase<void(*)(Control*)> CheckStateChanged;
|
||||
|
||||
protected:
|
||||
// Get custom control creation parameters for this instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
|
||||
private:
|
||||
// Whether or not the control handles checking itself.
|
||||
bool _AutoCheck;
|
||||
// Whether or not the control handles three checked states.
|
||||
bool _ThreeState;
|
||||
|
||||
// The appearence of the control.
|
||||
Appearence _Appearence;
|
||||
// The checked state of the control.
|
||||
CheckState _CheckState;
|
||||
};
|
||||
}
|
92
r5dev/thirdparty/cppnet/cppkore/CheckBoxImage.h
vendored
Normal file
92
r5dev/thirdparty/cppnet/cppkore/CheckBoxImage.h
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
#pragma once
|
||||
|
||||
constexpr const unsigned char CheckBoxImage_Src[] =
|
||||
{
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x10, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x59, 0xFF, 0xFF,
|
||||
0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x49, 0xFF, 0xFF,
|
||||
0xFF, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
|
||||
0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3B, 0xFF, 0xFF,
|
||||
0xFF, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x5B, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x2F, 0xFF, 0xFF,
|
||||
0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF,
|
||||
0xFF, 0x7E, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x24, 0xFF, 0xFF,
|
||||
0xFF, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF,
|
||||
0xFF, 0x56, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x37, 0xFF, 0xFF,
|
||||
0xFF, 0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xFF, 0xFF,
|
||||
0xFF, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xD4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x44, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x44, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF,
|
||||
0xFF, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0xFF, 0xFF,
|
||||
0xFF, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x53, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x5B, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xEB, 0xFF, 0xFF, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x63, 0xFF, 0xFF,
|
||||
0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x6C, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF,
|
||||
0xFF, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
19
r5dev/thirdparty/cppnet/cppkore/CheckState.h
vendored
Normal file
19
r5dev/thirdparty/cppnet/cppkore/CheckState.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the state of a control,
|
||||
// such as a check box, that can be checked, unchecked, or
|
||||
// set to an indeterminate state.
|
||||
enum class CheckState
|
||||
{
|
||||
// The control is unchecked.
|
||||
Unchecked = 0,
|
||||
// The control is checked.
|
||||
Checked = 1,
|
||||
// The control is indeterminate. An indeterminate control generally has a shaded appearance.
|
||||
Indeterminate = 2
|
||||
};
|
||||
}
|
25
r5dev/thirdparty/cppnet/cppkore/CloseReason.h
vendored
Normal file
25
r5dev/thirdparty/cppnet/cppkore/CloseReason.h
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the reason for the Form Closing.
|
||||
enum class CloseReason
|
||||
{
|
||||
// No reason for closure of the Form.
|
||||
None = 0,
|
||||
// In the process of shutting down, Windows has closed the application.
|
||||
WindowsShutDown = 1,
|
||||
// The parent form of this MDI form is closing.
|
||||
MdiFormClosing = 2,
|
||||
// The user has clicked the close button on the form window, selected Close from the window's control menu or hit Alt + F4
|
||||
UserClosing = 3,
|
||||
// The Microsoft Windows Task Manager is closing the application.
|
||||
TaskManagerClosing = 4,
|
||||
// A form is closing because its owner is closing.
|
||||
FormOwnerClosing = 5,
|
||||
// A form is closing because Application.Exit() was called.
|
||||
ApplicationExitCall = 6
|
||||
};
|
||||
}
|
251
r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.cpp
vendored
Normal file
251
r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.cpp
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
#include "stdafx.h"
|
||||
#include "CoDXAssetExport.h"
|
||||
|
||||
#include "File.h"
|
||||
#include "Path.h"
|
||||
#include "Matrix.h"
|
||||
#include "StreamWriter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
bool CoDXAssetExport::ExportAnimation(const Animation& Animation, const String& Path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CoDXAssetExport::ExportModel(const Model& Model, const String& Path)
|
||||
{
|
||||
auto Writer = IO::StreamWriter(IO::File::Create(Path));
|
||||
|
||||
Writer.WriteLine(
|
||||
"MODEL\nVERSION 6\n"
|
||||
);
|
||||
|
||||
Writer.WriteLineFmt("NUMBONES %d", Model.Bones.Count());
|
||||
|
||||
uint32_t BoneIndex = 0;
|
||||
|
||||
for (auto& Bone : Model.Bones)
|
||||
{
|
||||
Writer.WriteLineFmt("BONE %d %d \"%s\"", BoneIndex, Bone.Parent(), (char*)Bone.Name());
|
||||
BoneIndex++;
|
||||
}
|
||||
|
||||
Writer.Write("\n");
|
||||
BoneIndex = 0;
|
||||
|
||||
for (auto& Bone : Model.Bones)
|
||||
{
|
||||
auto Rotation = ::Math::Matrix::CreateFromQuaternion(Bone.GlobalRotation());
|
||||
|
||||
auto& Position = Bone.GlobalPosition();
|
||||
auto& Scale = Bone.Scale();
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"BONE %d\n"
|
||||
"OFFSET %f, %f, %f\n"
|
||||
"SCALE %f, %f, %f\n"
|
||||
"X %f, %f, %f\n"
|
||||
"Y %f, %f, %f\n"
|
||||
"Z %f, %f, %f\n",
|
||||
BoneIndex,
|
||||
Position.X, Position.Y, Position.Z,
|
||||
Scale.X, Scale.Y, Scale.Z,
|
||||
MathHelper::Clamp(Rotation.Mat(0, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(0, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(0, 2), -1.f, 1.f),
|
||||
MathHelper::Clamp(Rotation.Mat(1, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(1, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(1, 2), -1.f, 1.f),
|
||||
MathHelper::Clamp(Rotation.Mat(2, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(2, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(2, 2), -1.f, 1.f)
|
||||
);
|
||||
|
||||
BoneIndex++;
|
||||
}
|
||||
|
||||
auto TotalVertexCount = Model.VertexCount();
|
||||
auto TotalFaceCount = Model.FaceCount();
|
||||
|
||||
if (TotalVertexCount > UINT16_MAX)
|
||||
Writer.WriteLineFmt("NUMVERTS32 %d", TotalVertexCount);
|
||||
else
|
||||
Writer.WriteLineFmt("NUMVERTS %d", TotalVertexCount);
|
||||
|
||||
uint32_t VertexIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
auto& Position = Vertex.Position();
|
||||
|
||||
if (TotalVertexCount > UINT16_MAX)
|
||||
Writer.WriteLineFmt(
|
||||
"VERT32 %d\n"
|
||||
"OFFSET %f, %f, %f",
|
||||
VertexIndex,
|
||||
Position.X, Position.Y, Position.Z
|
||||
);
|
||||
else
|
||||
Writer.WriteLineFmt(
|
||||
"VERT %d\n"
|
||||
"OFFSET %f, %f, %f",
|
||||
VertexIndex,
|
||||
Position.X, Position.Y, Position.Z
|
||||
);
|
||||
|
||||
if (Vertex.WeightCount() == 1)
|
||||
Writer.WriteLineFmt(
|
||||
"BONES 1\n"
|
||||
"BONE %d 1.0\n",
|
||||
Vertex.Weights(0).Bone
|
||||
);
|
||||
else
|
||||
{
|
||||
Writer.WriteLineFmt("BONES %d", Vertex.WeightCount());
|
||||
|
||||
for (uint8_t i = 0; i < Vertex.WeightCount(); i++)
|
||||
Writer.WriteLineFmt("BONE %d %f", Vertex.Weights(i).Bone, Vertex.Weights(i).Value);
|
||||
|
||||
Writer.Write("\n");
|
||||
}
|
||||
|
||||
VertexIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
Writer.WriteLineFmt("NUMFACES %d", TotalFaceCount);
|
||||
|
||||
uint32_t SubmeshIndex = 0;
|
||||
VertexIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
for (auto& Face : Submesh.Faces)
|
||||
{
|
||||
if (SubmeshIndex > UINT8_MAX || Submesh.MaterialIndices[0] > UINT8_MAX)
|
||||
Writer.WriteLineFmt("TRI16 %d %d 0 0", SubmeshIndex, Submesh.MaterialIndices[0]);
|
||||
else
|
||||
Writer.WriteLineFmt("TRI %d %d 0 0", SubmeshIndex, Submesh.MaterialIndices[0]);
|
||||
|
||||
//
|
||||
// Face vertex [2]
|
||||
//
|
||||
|
||||
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[2] + VertexIndex));
|
||||
|
||||
auto& Face1Normal = Submesh.Vertices[Face[2]].Normal();
|
||||
auto& Face1Color = Submesh.Vertices[Face[2]].Color();
|
||||
|
||||
Writer.WriteFmt(
|
||||
"NORMAL %f %f %f\n"
|
||||
"COLOR %f %f %f %f\n"
|
||||
"UV %d",
|
||||
Face1Normal.X, Face1Normal.Y, Face1Normal.Z,
|
||||
Face1Color[0], Face1Color[1], Face1Color[2], Face1Color[3],
|
||||
Submesh.Vertices.UVLayerCount()
|
||||
);
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[2]].UVLayers(i).U, Submesh.Vertices[Face[2]].UVLayers(i).V);
|
||||
Writer.Write("\n");
|
||||
|
||||
//
|
||||
// Face vertex [0]
|
||||
//
|
||||
|
||||
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[0] + VertexIndex));
|
||||
|
||||
auto& Face2Normal = Submesh.Vertices[Face[0]].Normal();
|
||||
auto& Face2Color = Submesh.Vertices[Face[0]].Color();
|
||||
|
||||
Writer.WriteFmt(
|
||||
"NORMAL %f %f %f\n"
|
||||
"COLOR %f %f %f %f\n"
|
||||
"UV %d",
|
||||
Face2Normal.X, Face2Normal.Y, Face2Normal.Z,
|
||||
Face2Color[0], Face2Color[1], Face2Color[2], Face2Color[3],
|
||||
Submesh.Vertices.UVLayerCount()
|
||||
);
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[0]].UVLayers(i).U, Submesh.Vertices[Face[0]].UVLayers(i).V);
|
||||
Writer.Write("\n");
|
||||
|
||||
//
|
||||
// Face vertex [1]
|
||||
//
|
||||
|
||||
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[1] + VertexIndex));
|
||||
|
||||
auto& Face3Normal = Submesh.Vertices[Face[1]].Normal();
|
||||
auto& Face3Color = Submesh.Vertices[Face[1]].Color();
|
||||
|
||||
Writer.WriteFmt(
|
||||
"NORMAL %f %f %f\n"
|
||||
"COLOR %f %f %f %f\n"
|
||||
"UV %d",
|
||||
Face3Normal.X, Face3Normal.Y, Face3Normal.Z,
|
||||
Face3Color[0], Face3Color[1], Face3Color[2], Face3Color[3],
|
||||
Submesh.Vertices.UVLayerCount()
|
||||
);
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[1]].UVLayers(i).U, Submesh.Vertices[Face[1]].UVLayers(i).V);
|
||||
Writer.Write("\n");
|
||||
}
|
||||
|
||||
VertexIndex += Submesh.Vertices.Count();
|
||||
SubmeshIndex++;
|
||||
}
|
||||
|
||||
Writer.WriteLineFmt("\nNUMOBJECTS %d", Model.Meshes.Count());
|
||||
SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
Writer.WriteLineFmt("OBJECT %d \"KoreMesh_%d\"", SubmeshIndex, SubmeshIndex++);
|
||||
Writer.Write("\n");
|
||||
|
||||
Writer.WriteLineFmt("NUMMATERIALS %d", Model.Materials.Count());
|
||||
|
||||
uint32_t MaterialIndex = 0;
|
||||
|
||||
for (auto& Material : Model.Materials)
|
||||
{
|
||||
Writer.WriteFmt("MATERIAL %d \"%s\" \"Phong\" \"", MaterialIndex, (char*)Material.Name);
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
||||
Writer.WriteFmt("color:%s", (char*)Material.Slots[MaterialSlotType::Albedo].first);
|
||||
else if (Material.Slots.ContainsKey(MaterialSlotType::Diffuse))
|
||||
Writer.WriteFmt("color:%s", (char*)Material.Slots[MaterialSlotType::Diffuse].first);
|
||||
|
||||
Writer.WriteLine("\"\nCOLOR 0.000000 0.000000 0.000000 1.000000\nTRANSPARENCY 0.000000 0.000000 0.000000 1.000000\nAMBIENTCOLOR 1.000000 1.000000 1.000000 1.000000\nINCANDESCENCE 0.000000 0.000000 0.000000 1.000000\nCOEFFS 0.800000 0.000000\nGLOW 0.000000 0\nREFRACTIVE 6 1.000000\nSPECULARCOLOR 0.500000 0.500000 0.500000 1.000000\nREFLECTIVECOLOR 0.000000 0.000000 0.000000 1.000000\nREFLECTIVE 1 0.500000\nBLINN -1.000000 -1.000000\nPHONG 20.000000");
|
||||
|
||||
MaterialIndex++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
imstring CoDXAssetExport::ModelExtension()
|
||||
{
|
||||
return ".xmodel_export";
|
||||
}
|
||||
|
||||
imstring CoDXAssetExport::AnimationExtension()
|
||||
{
|
||||
return ".xanim_export";
|
||||
}
|
||||
|
||||
ExporterScale CoDXAssetExport::ExportScale()
|
||||
{
|
||||
// Call of Duty uses inches as the primary scale constant.
|
||||
return ExporterScale::Inch;
|
||||
}
|
||||
|
||||
bool CoDXAssetExport::SupportsAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoDXAssetExport::SupportsModels()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
33
r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.h
vendored
Normal file
33
r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Exporter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
// The Call of Duty XAsset Export exporter
|
||||
class CoDXAssetExport : public Exporter
|
||||
{
|
||||
public:
|
||||
CoDXAssetExport() = default;
|
||||
~CoDXAssetExport() = default;
|
||||
|
||||
// Exports the given animation to the provided path.
|
||||
virtual bool ExportAnimation(const Animation& Animation, const String& Path);
|
||||
// Exports the given model to the provided path.
|
||||
virtual bool ExportModel(const Model& Model, const String& Path);
|
||||
|
||||
// Gets the file extension for this exporters model format.
|
||||
virtual imstring ModelExtension();
|
||||
// Gets the file extension for this exporters animation format.
|
||||
virtual imstring AnimationExtension();
|
||||
|
||||
// Gets the required scaling constant for this exporter.
|
||||
virtual ExporterScale ExportScale();
|
||||
|
||||
// Gets whether or not the exporter supports animation exporting.
|
||||
virtual bool SupportsAnimations();
|
||||
// Gets whether or not the exporter supports model exporting.
|
||||
virtual bool SupportsModels();
|
||||
};
|
||||
}
|
10
r5dev/thirdparty/cppnet/cppkore/ColumnClickEventArgs.cpp
vendored
Normal file
10
r5dev/thirdparty/cppnet/cppkore/ColumnClickEventArgs.cpp
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "ColumnClickEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ColumnClickEventArgs::ColumnClickEventArgs(int32_t Column)
|
||||
: Column(Column)
|
||||
{
|
||||
}
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/ColumnClickEventArgs.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/ColumnClickEventArgs.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides data for the OnColumnClick event.
|
||||
class ColumnClickEventArgs
|
||||
{
|
||||
public:
|
||||
ColumnClickEventArgs(int32_t Column);
|
||||
~ColumnClickEventArgs() = default;
|
||||
|
||||
// The index of the column that was clicked.
|
||||
const int32_t Column;
|
||||
};
|
||||
}
|
158
r5dev/thirdparty/cppnet/cppkore/ColumnHeader.cpp
vendored
Normal file
158
r5dev/thirdparty/cppnet/cppkore/ColumnHeader.cpp
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
#include "stdafx.h"
|
||||
#include "ColumnHeader.h"
|
||||
#include "ListView.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ColumnHeader::ColumnHeader()
|
||||
: ColumnHeader("")
|
||||
{
|
||||
}
|
||||
|
||||
ColumnHeader::ColumnHeader(const String& Text)
|
||||
: ColumnHeader(Text, 60)
|
||||
{
|
||||
}
|
||||
|
||||
ColumnHeader::ColumnHeader(const String& Text, int32_t Width)
|
||||
: ColumnHeader(Text, Width, HorizontalAlignment::Left)
|
||||
{
|
||||
}
|
||||
|
||||
ColumnHeader::ColumnHeader(const String& Text, int32_t Width, HorizontalAlignment Alignment)
|
||||
: _Text(Text), _Width(Width), _TextAlign(Alignment), _OwnerListView(nullptr), _IndexInternal(-1)
|
||||
{
|
||||
}
|
||||
|
||||
int32_t ColumnHeader::Index() const
|
||||
{
|
||||
if (_OwnerListView != nullptr)
|
||||
return _OwnerListView->Columns.IndexOf(*this);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t ColumnHeader::DisplayIndex()
|
||||
{
|
||||
return this->_IndexInternal;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetDisplayIndex(int32_t Value)
|
||||
{
|
||||
if (this->_OwnerListView == nullptr)
|
||||
{
|
||||
this->_IndexInternal = Value;
|
||||
return;
|
||||
}
|
||||
|
||||
auto LowDI = min(this->_IndexInternal, Value);
|
||||
auto HiDI = max(this->_IndexInternal, Value);
|
||||
auto ColsOrder = std::make_unique<int32_t[]>(_OwnerListView->Columns.Count());
|
||||
|
||||
bool HdrMovedForward = Value > this->_IndexInternal;
|
||||
ColumnHeader* MovedHdr = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < _OwnerListView->Columns.Count(); i++)
|
||||
{
|
||||
auto& Hdr = _OwnerListView->Columns[i];
|
||||
if (Hdr.DisplayIndex() == _IndexInternal)
|
||||
MovedHdr = &Hdr;
|
||||
else if (Hdr.DisplayIndex() >= LowDI && Hdr.DisplayIndex() <= HiDI)
|
||||
Hdr._IndexInternal -= HdrMovedForward ? 1 : -1;
|
||||
|
||||
if (i != this->Index())
|
||||
ColsOrder[Hdr._IndexInternal] = i;
|
||||
}
|
||||
|
||||
if (MovedHdr != nullptr)
|
||||
{
|
||||
MovedHdr->_IndexInternal = Value;
|
||||
ColsOrder[MovedHdr->_IndexInternal] = MovedHdr->Index();
|
||||
}
|
||||
|
||||
SetDisplayIndices(ColsOrder, _OwnerListView->Columns.Count());
|
||||
}
|
||||
|
||||
void ColumnHeader::SetDisplayIndexInternal(int32_t Value)
|
||||
{
|
||||
this->_IndexInternal = Value;
|
||||
}
|
||||
|
||||
const String& ColumnHeader::Text() const
|
||||
{
|
||||
return this->_Text;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetText(const String& Value)
|
||||
{
|
||||
_Text = Value;
|
||||
|
||||
if (_OwnerListView)
|
||||
_OwnerListView->SetColumnInfo(LVCF_TEXT, *this);
|
||||
}
|
||||
|
||||
int32_t ColumnHeader::Width() const
|
||||
{
|
||||
if (_OwnerListView != nullptr && _OwnerListView->GetState(Forms::ControlStates::StateCreated) && _OwnerListView->GetState(ControlStates::StateCreated))
|
||||
{
|
||||
auto HwndHdr = (HWND)SendMessageA(_OwnerListView->GetHandle(), LVM_GETHEADER, NULL, NULL);
|
||||
if (HwndHdr != NULL)
|
||||
{
|
||||
auto NativeItemCount = (int32_t)SendMessageA(HwndHdr, HDM_GETITEMCOUNT, NULL, NULL);
|
||||
auto Idx = Index();
|
||||
if (Idx < NativeItemCount)
|
||||
return (int32_t)SendMessageA(_OwnerListView->GetHandle(), LVM_GETCOLUMNWIDTH, (WPARAM)Idx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return this->_Width;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetWidth(int32_t Value)
|
||||
{
|
||||
_Width = Value;
|
||||
|
||||
if (_OwnerListView)
|
||||
_OwnerListView->SetColumnWidth(this->Index(), _Width);
|
||||
}
|
||||
|
||||
HorizontalAlignment ColumnHeader::TextAlign() const
|
||||
{
|
||||
return this->_TextAlign;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetTextAlign(HorizontalAlignment Value)
|
||||
{
|
||||
if (_TextAlign != Value)
|
||||
{
|
||||
_TextAlign = Value;
|
||||
|
||||
if (_OwnerListView)
|
||||
{
|
||||
_OwnerListView->SetColumnInfo(LVCF_FMT, *this);
|
||||
_OwnerListView->Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView* ColumnHeader::GetListView()
|
||||
{
|
||||
return this->_OwnerListView;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetListView(ListView* Owner)
|
||||
{
|
||||
this->_OwnerListView = Owner;
|
||||
}
|
||||
|
||||
bool ColumnHeader::operator==(const ColumnHeader& Rhs)
|
||||
{
|
||||
return (this->_IndexInternal == Rhs._IndexInternal && this->_Text == Rhs._Text && this->_TextAlign == Rhs._TextAlign);
|
||||
}
|
||||
|
||||
void ColumnHeader::SetDisplayIndices(const std::unique_ptr<int32_t[]>& Cols, int32_t Count)
|
||||
{
|
||||
if (this->_OwnerListView != nullptr && this->_OwnerListView->GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_OwnerListView->GetHandle(), LVM_SETCOLUMNORDERARRAY, (WPARAM)Count, (LPARAM)Cols.get());
|
||||
}
|
||||
}
|
71
r5dev/thirdparty/cppnet/cppkore/ColumnHeader.h
vendored
Normal file
71
r5dev/thirdparty/cppnet/cppkore/ColumnHeader.h
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "StringBase.h"
|
||||
#include "HorizontalAlignment.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Externally defined so we don't conflict
|
||||
class ListView;
|
||||
|
||||
// Displays a single column header in a ListView control.
|
||||
class ColumnHeader
|
||||
{
|
||||
public:
|
||||
ColumnHeader();
|
||||
ColumnHeader(const String& Text);
|
||||
ColumnHeader(const String& Text, int32_t Width);
|
||||
ColumnHeader(const String& Text, int32_t Width, HorizontalAlignment Alignment);
|
||||
~ColumnHeader() = default;
|
||||
|
||||
// The index of this column.
|
||||
int32_t Index() const;
|
||||
|
||||
// The index of this column as it is displayed.
|
||||
int32_t DisplayIndex();
|
||||
// The index of this column as it is displayed.
|
||||
void SetDisplayIndex(int32_t Value);
|
||||
|
||||
// Sets the display index without reflowing others.
|
||||
void SetDisplayIndexInternal(int32_t Value);
|
||||
|
||||
// The text displayed in the column header.
|
||||
const String& Text() const;
|
||||
// The text displayed in the column header.
|
||||
void SetText(const String& Value);
|
||||
|
||||
// The width of the column in pixels.
|
||||
int32_t Width() const;
|
||||
// The width of the column in pixels.
|
||||
void SetWidth(int32_t Value);
|
||||
|
||||
// The horizontal alignment of the text contained in this column.
|
||||
HorizontalAlignment TextAlign() const;
|
||||
// The horizontal alignment of the text contained in this column.
|
||||
void SetTextAlign(HorizontalAlignment Value);
|
||||
|
||||
// Returns the ListView control that this column is displayed in. May be null.
|
||||
ListView* GetListView();
|
||||
// Sets the ListView control that this column is displayed in.
|
||||
void SetListView(ListView* Owner);
|
||||
|
||||
// Custom equality operator
|
||||
bool operator==(const ColumnHeader& Rhs);
|
||||
|
||||
private:
|
||||
// Internal cached properties
|
||||
ListView* _OwnerListView;
|
||||
|
||||
// Width and index
|
||||
int32_t _Width;
|
||||
int32_t _IndexInternal;
|
||||
|
||||
// Text to display
|
||||
String _Text;
|
||||
HorizontalAlignment _TextAlign;
|
||||
|
||||
// Set the display indices of the ListView columns.
|
||||
void SetDisplayIndices(const std::unique_ptr<int32_t[]>& Cols, int32_t Count);
|
||||
};
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/ColumnHeaderStyle.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/ColumnHeaderStyle.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies how ListView column headers behave.
|
||||
enum class ColumnHeaderStyle
|
||||
{
|
||||
// No visible column header.
|
||||
None = 0,
|
||||
// Visible column header that does not respond to clicking.
|
||||
NonClickable = 1,
|
||||
// Visible column header that responds to clicking.
|
||||
Clickable = 2
|
||||
};
|
||||
}
|
496
r5dev/thirdparty/cppnet/cppkore/ComboBox.cpp
vendored
Normal file
496
r5dev/thirdparty/cppnet/cppkore/ComboBox.cpp
vendored
Normal file
@ -0,0 +1,496 @@
|
||||
#include "stdafx.h"
|
||||
#include "ComboBox.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ComboBox::ComboBox()
|
||||
: Control(), Items(this), _DrawMode(DrawMode::Normal), _FlatStyle(FlatStyle::Standard), _DropDownStyle(ComboBoxStyle::DropDown), _IntegralHeight(true), _DropDownWidth(-1), _DropDownHeight(-1), _MaxDropDownItems(8), _MaximumLength(SHRT_MAX), _SelectedIndex(-1), _ChildEdit(nullptr), _ChildListBox(nullptr)
|
||||
{
|
||||
SetStyle(ControlStyles::UserPaint |
|
||||
ControlStyles::UseTextForAccessibility |
|
||||
ControlStyles::StandardClick, false);
|
||||
|
||||
// Default back color is different...
|
||||
this->_BackColor = Drawing::GetSystemColor(Drawing::SystemColors::Window);
|
||||
// We are a ComboBox control.
|
||||
this->_RTTI = ControlTypes::ComboBox;
|
||||
}
|
||||
|
||||
DrawMode ComboBox::GetDrawMode()
|
||||
{
|
||||
return this->_DrawMode;
|
||||
}
|
||||
|
||||
void ComboBox::SetDrawMode(DrawMode Value)
|
||||
{
|
||||
if (_DrawMode != Value)
|
||||
{
|
||||
_DrawMode = Value;
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ComboBox::DropDownWidth()
|
||||
{
|
||||
if (_DropDownWidth > -1)
|
||||
return _DropDownWidth;
|
||||
|
||||
return _Width;
|
||||
}
|
||||
|
||||
void ComboBox::SetDropDownWidth(uint32_t Value)
|
||||
{
|
||||
_DropDownWidth = (int32_t)Value;
|
||||
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, CB_SETDROPPEDWIDTH, (WPARAM)Value, NULL);
|
||||
}
|
||||
|
||||
uint32_t ComboBox::DropDownHeight()
|
||||
{
|
||||
if (_DropDownHeight > -1)
|
||||
return _DropDownHeight;
|
||||
|
||||
return 106; // Default drop down height...
|
||||
}
|
||||
|
||||
void ComboBox::SetDropDownHeight(uint32_t Value)
|
||||
{
|
||||
_DropDownHeight = (int32_t)Value;
|
||||
SetIntegralHeight(false);
|
||||
}
|
||||
|
||||
bool ComboBox::DroppedDown()
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
return (SendMessageA(this->_Handle, CB_GETDROPPEDSTATE, NULL, NULL) != 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ComboBox::SetDroppedDown(bool Value)
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, CB_SHOWDROPDOWN, Value ? -1 : 0, NULL);
|
||||
}
|
||||
|
||||
FlatStyle ComboBox::GetFlatStyle()
|
||||
{
|
||||
return this->_FlatStyle;
|
||||
}
|
||||
|
||||
void ComboBox::SetFlatStyle(FlatStyle Value)
|
||||
{
|
||||
if (_FlatStyle != Value)
|
||||
{
|
||||
_FlatStyle = Value;
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
bool ComboBox::IntegralHeight()
|
||||
{
|
||||
return this->_IntegralHeight;
|
||||
}
|
||||
|
||||
void ComboBox::SetIntegralHeight(bool Value)
|
||||
{
|
||||
if (_IntegralHeight != Value)
|
||||
{
|
||||
_IntegralHeight = Value;
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ComboBox::ItemHeight()
|
||||
{
|
||||
return (int32_t)SendMessageA(this->_Handle, CB_GETITEMHEIGHT, NULL, NULL);
|
||||
}
|
||||
|
||||
void ComboBox::SetItemHeight(int32_t Value)
|
||||
{
|
||||
if (_DrawMode == DrawMode::OwnerDrawFixed)
|
||||
{
|
||||
SendMessageA(this->_Handle, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)Value);
|
||||
SendMessageA(this->_Handle, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)Value);
|
||||
}
|
||||
else if (_DrawMode == DrawMode::OwnerDrawVariable)
|
||||
{
|
||||
SendMessageA(this->_Handle, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)Value);
|
||||
|
||||
for (uint32_t i = 0; i < Items.Count(); i++)
|
||||
SendMessageA(this->_Handle, CB_SETITEMHEIGHT, (WPARAM)i, (LPARAM)Value);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ComboBox::MaxDropDownItems()
|
||||
{
|
||||
return this->_MaxDropDownItems;
|
||||
}
|
||||
|
||||
void ComboBox::SetMaxDropDownItems(uint8_t Value)
|
||||
{
|
||||
this->_MaxDropDownItems = Value;
|
||||
}
|
||||
|
||||
uint32_t ComboBox::MaxLength()
|
||||
{
|
||||
return this->_MaximumLength;
|
||||
}
|
||||
|
||||
void ComboBox::SetMaxLength(uint32_t Value)
|
||||
{
|
||||
if (_MaximumLength != Value)
|
||||
{
|
||||
_MaximumLength = Value;
|
||||
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, CB_LIMITTEXT, (WPARAM)Value, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ComboBox::SelectedIndex()
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
return (int32_t)SendMessageA(this->_Handle, CB_GETCURSEL, NULL, NULL);
|
||||
|
||||
return this->_SelectedIndex;
|
||||
}
|
||||
|
||||
void ComboBox::SetSelectedIndex(int32_t Value)
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, CB_SETCURSEL, (WPARAM)Value, NULL);
|
||||
else
|
||||
_SelectedIndex = Value;
|
||||
|
||||
OnTextChanged();
|
||||
|
||||
OnSelectedIndexChanged();
|
||||
OnSelectedItemChanged();
|
||||
}
|
||||
|
||||
String ComboBox::SelectedText()
|
||||
{
|
||||
if (_DropDownStyle == ComboBoxStyle::DropDownList)
|
||||
return "";
|
||||
|
||||
return Text().SubString(SelectionStart(), SelectionLength());
|
||||
}
|
||||
|
||||
void ComboBox::SetSelectedText(const String& Value)
|
||||
{
|
||||
if (_DropDownStyle != ComboBoxStyle::DropDownList)
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_ChildEdit, EM_REPLACESEL, (WPARAM)-1, (LPARAM)(const char*)Value);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ComboBox::SelectionLength()
|
||||
{
|
||||
int32_t End = 0;
|
||||
int32_t Start = 0;
|
||||
SendMessageA(this->_Handle, CB_GETEDITSEL, (WPARAM)&Start, (WPARAM)&End);
|
||||
|
||||
return End - Start;
|
||||
}
|
||||
|
||||
void ComboBox::SetSelectionLength(int32_t Value)
|
||||
{
|
||||
Select(SelectionStart(), Value);
|
||||
}
|
||||
|
||||
int32_t ComboBox::SelectionStart()
|
||||
{
|
||||
int32_t Value = 0;
|
||||
SendMessageA(this->_Handle, CB_GETEDITSEL, (WPARAM)&Value, NULL);
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
void ComboBox::SetSelectionStart(int32_t Value)
|
||||
{
|
||||
Select(Value, SelectionLength());
|
||||
}
|
||||
|
||||
ComboBoxStyle ComboBox::DropDownStyle()
|
||||
{
|
||||
return this->_DropDownStyle;
|
||||
}
|
||||
|
||||
void ComboBox::SetDropDownStyle(ComboBoxStyle Value)
|
||||
{
|
||||
if (_DropDownStyle != Value)
|
||||
{
|
||||
_DropDownStyle = Value;
|
||||
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
void ComboBox::Select(int32_t Start, int32_t Length)
|
||||
{
|
||||
int32_t End = Start + Length;
|
||||
SendMessageA(this->_Handle, CB_SETEDITSEL, NULL, MAKELPARAM(Start, End));
|
||||
}
|
||||
|
||||
void ComboBox::OnHandleCreated()
|
||||
{
|
||||
if (_MaximumLength > 0)
|
||||
SendMessageA(this->_Handle, CB_LIMITTEXT, (WPARAM)_MaximumLength, NULL);
|
||||
|
||||
if (_DropDownStyle != ComboBoxStyle::DropDownList)
|
||||
{
|
||||
auto Hwnd = GetWindow(this->_Handle, GW_CHILD);
|
||||
if (Hwnd != NULL)
|
||||
{
|
||||
if (_DropDownStyle == ComboBoxStyle::Simple)
|
||||
{
|
||||
_ChildListBox = Hwnd;
|
||||
Hwnd = GetWindow(Hwnd, GW_HWNDNEXT);
|
||||
}
|
||||
|
||||
_ChildEdit = Hwnd;
|
||||
}
|
||||
}
|
||||
|
||||
if (_DropDownWidth > -1)
|
||||
SendMessageA(this->_Handle, CB_SETDROPPEDWIDTH, (WPARAM)_DropDownWidth, NULL);
|
||||
|
||||
// If we have items, add them now
|
||||
for (auto& Item : Items)
|
||||
this->NativeAdd((const char*)Item);
|
||||
|
||||
if (_SelectedIndex > -1)
|
||||
{
|
||||
SendMessageA(this->_Handle, CB_SETCURSEL, (WPARAM)_SelectedIndex, NULL);
|
||||
_SelectedIndex = -1;
|
||||
}
|
||||
|
||||
// We must call the base event last
|
||||
Control::OnHandleCreated();
|
||||
}
|
||||
|
||||
void ComboBox::OnSelectedItemChanged()
|
||||
{
|
||||
SelectedItemChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void ComboBox::OnSelectedIndexChanged()
|
||||
{
|
||||
SelectedIndexChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void ComboBox::OnDropDownClosed()
|
||||
{
|
||||
DropDownClosed.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void ComboBox::WndProc(Message& Msg)
|
||||
{
|
||||
switch (Msg.Msg)
|
||||
{
|
||||
case WM_CTLCOLOREDIT:
|
||||
case WM_CTLCOLORLISTBOX:
|
||||
Msg.Result = InitializeDCForWmCtlColor((HDC)Msg.WParam, Msg.Msg);
|
||||
break;
|
||||
case WM_REFLECT + WM_COMMAND:
|
||||
WmReflectCommand(Msg);
|
||||
break;
|
||||
default:
|
||||
Control::WndProc(Msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CreateParams ComboBox::GetCreateParams()
|
||||
{
|
||||
auto Cp = Control::GetCreateParams();
|
||||
|
||||
Cp.ClassName = "COMBOBOX";
|
||||
Cp.Style |= WS_VSCROLL | CBS_HASSTRINGS | CBS_AUTOHSCROLL;
|
||||
|
||||
if (!_IntegralHeight)
|
||||
Cp.Style |= CBS_NOINTEGRALHEIGHT;
|
||||
|
||||
switch (_FlatStyle)
|
||||
{
|
||||
case FlatStyle::Popup:
|
||||
case FlatStyle::Flat:
|
||||
Cp.ExStyle |= WS_EX_STATICEDGE;
|
||||
default:
|
||||
Cp.ExStyle |= WS_EX_CLIENTEDGE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_DropDownStyle)
|
||||
{
|
||||
case ComboBoxStyle::Simple:
|
||||
Cp.Style |= CBS_SIMPLE;
|
||||
break;
|
||||
case ComboBoxStyle::DropDown:
|
||||
Cp.Style |= CBS_DROPDOWN;
|
||||
break;
|
||||
case ComboBoxStyle::DropDownList:
|
||||
Cp.Style |= CBS_DROPDOWNLIST;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_DrawMode)
|
||||
{
|
||||
case DrawMode::OwnerDrawFixed:
|
||||
Cp.Style |= CBS_OWNERDRAWFIXED;
|
||||
break;
|
||||
case DrawMode::OwnerDrawVariable:
|
||||
Cp.Style |= CBS_OWNERDRAWVARIABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
return Cp;
|
||||
}
|
||||
|
||||
uintptr_t ComboBox::InitializeDCForWmCtlColor(HDC Dc, int32_t Message)
|
||||
{
|
||||
if ((Message == WM_CTLCOLORSTATIC))
|
||||
{
|
||||
return (uintptr_t)0;
|
||||
}
|
||||
else if ((Message == WM_CTLCOLORLISTBOX) && GetStyle(ControlStyles::UserPaint))
|
||||
{
|
||||
SetTextColor(Dc, this->ForeColor().ToCOLORREF());
|
||||
SetBkColor(Dc, this->BackColor().ToCOLORREF());
|
||||
|
||||
return BackColorBrush();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Control::InitializeDCForWmCtlColor(Dc, Message);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ComboBox::NativeAdd(const char* Value)
|
||||
{
|
||||
return (int32_t)SendMessageA(this->_Handle, CB_ADDSTRING, NULL, (LPARAM)Value);
|
||||
}
|
||||
|
||||
void ComboBox::NativeClear()
|
||||
{
|
||||
String Saved;
|
||||
|
||||
if (_DropDownStyle != ComboBoxStyle::DropDownList)
|
||||
Saved = this->WindowText();
|
||||
|
||||
SendMessageA(this->_Handle, CB_RESETCONTENT, NULL, NULL);
|
||||
|
||||
if (!String::IsNullOrEmpty(Saved))
|
||||
this->SetWindowText(Saved);
|
||||
}
|
||||
|
||||
int32_t ComboBox::NativeInsert(int32_t Index, const char* Value)
|
||||
{
|
||||
return (int32_t)SendMessageA(this->_Handle, CB_INSERTSTRING, (WPARAM)Index, (LPARAM)Value);
|
||||
}
|
||||
|
||||
void ComboBox::NativeRemoveAt(int32_t Index)
|
||||
{
|
||||
if (_DropDownStyle == ComboBoxStyle::DropDownList && SelectedIndex() == Index)
|
||||
Invalidate();
|
||||
|
||||
SendMessageA(this->_Handle, CB_DELETESTRING, (WPARAM)Index, NULL);
|
||||
}
|
||||
|
||||
void ComboBox::WmReflectCommand(Message& Msg)
|
||||
{
|
||||
switch ((int16_t)HIWORD(Msg.WParam))
|
||||
{
|
||||
case CBN_EDITCHANGE:
|
||||
OnTextChanged();
|
||||
break;
|
||||
case CBN_SELCHANGE:
|
||||
OnSelectedIndexChanged();
|
||||
OnSelectedItemChanged();
|
||||
break;
|
||||
case CBN_CLOSEUP:
|
||||
OnDropDownClosed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox::ComboBoxItemCollection::ComboBoxItemCollection(ComboBox* Owner)
|
||||
: _Owner(Owner), _Items()
|
||||
{
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::Add(const imstring& Value)
|
||||
{
|
||||
_Items.EmplaceBack(Value);
|
||||
|
||||
if (_Owner->GetState(ControlStates::StateCreated))
|
||||
_Owner->NativeAdd(Value);
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::Insert(int32_t Index, const imstring& Value)
|
||||
{
|
||||
_Items.Insert(Index, Value);
|
||||
|
||||
if (_Owner->GetState(ControlStates::StateCreated))
|
||||
_Owner->NativeInsert(Index, Value);
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::Clear()
|
||||
{
|
||||
_Items.Clear();
|
||||
|
||||
if (_Owner->GetState(ControlStates::StateCreated))
|
||||
_Owner->NativeClear();
|
||||
}
|
||||
|
||||
bool ComboBox::ComboBoxItemCollection::Contains(const imstring & Value)
|
||||
{
|
||||
return (IndexOf(Value) > -1);
|
||||
}
|
||||
|
||||
int32_t ComboBox::ComboBoxItemCollection::IndexOf(const imstring& Value)
|
||||
{
|
||||
auto Str = String(Value);
|
||||
auto Res = _Items.IndexOf(Str);
|
||||
|
||||
if (Res == List<String>::InvalidPosition)
|
||||
return -1;
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::RemoveAt(int32_t Index)
|
||||
{
|
||||
if (_Owner->GetState(ControlStates::StateCreated))
|
||||
_Owner->NativeRemoveAt(Index);
|
||||
|
||||
_Items.RemoveAt(Index);
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::Remove(const imstring& Value)
|
||||
{
|
||||
auto Index = IndexOf(Value);
|
||||
|
||||
if (Index > -1)
|
||||
RemoveAt(Index);
|
||||
}
|
||||
|
||||
uint32_t ComboBox::ComboBoxItemCollection::Count()
|
||||
{
|
||||
return _Items.Count();
|
||||
}
|
||||
|
||||
String* ComboBox::ComboBoxItemCollection::begin() const
|
||||
{
|
||||
return _Items.begin();
|
||||
}
|
||||
|
||||
String* ComboBox::ComboBoxItemCollection::end() const
|
||||
{
|
||||
return _Items.end();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user