Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 106 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ project(FEBasicApplication)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(MSVC)
# Disable C4251 warning
add_compile_options(/wd4251)
endif()

option(BUILD_SHARED_LIBS "Build FEBasicApplication as a shared library" OFF)
option(USE_STATIC_RUNTIME "Use static runtime (/MT) instead of dynamic (/MD)" ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if(MSVC)
# Disable C4251 warning
add_compile_options(/wd4251)

if(USE_STATIC_RUNTIME)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
else()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
endif()

# Turn on the ability to create folders to organize projects (.vcproj)
# It creates "CMakePredefinedTargets" folder by default and adds CMake
# defined projects like INSTALL.vcproj and ZERO_CHECK.vcproj
Expand Down Expand Up @@ -65,6 +89,16 @@ file(GLOB BasicApplicationSubSystem_SRC
"FETime.h"
"FEUniqueID.cpp"
"FEUniqueID.h"
"FEBasicApplicationAPI.h"
)

set(ALL_SOURCE_FILES "")
list(APPEND ALL_SOURCE_FILES
${BasicApplicationSubSystem_SRC}
${BasicApplicationNetworkSubSystem_SRC}
${BasicApplicationProfilingSubSystem_SRC}
# *************** THIRD_PARTY ***************
${imgui_SRC}
)

set(GLEW_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/glew2/lib/$(PlatformTarget))
Expand All @@ -76,20 +110,53 @@ set(GLFW_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/GLFW/lib/$(PlatformTarge
link_directories(${GLEW_LIB_DIR})
link_directories(${GLFW_LIB_DIR})

add_library(FEBasicApplication
${BasicApplicationSubSystem_SRC}
${BasicApplicationNetworkSubSystem_SRC}
${BasicApplicationProfilingSubSystem_SRC}
# *************** THIRD_PARTY ***************
${imgui_SRC}
if(BUILD_SHARED_LIBS)
add_library(FEBasicApplication SHARED ${ALL_SOURCE_FILES})
target_compile_definitions(FEBasicApplication PRIVATE FEBASICAPPLICATION_EXPORTS)
target_compile_definitions(FEBasicApplication PUBLIC FEBASICAPPLICATION_SHARED)

# Some times /GL conflicts with WINDOWS_EXPORT_ALL_SYMBOLS
set_target_properties(FEBasicApplication PROPERTIES COMPILE_OPTIONS "/GL-")
set_target_properties(FEBasicApplication PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)

# Disable C4251 warning
target_compile_options(FEBasicApplication PRIVATE /wd4251)
else()
add_library(FEBasicApplication STATIC ${ALL_SOURCE_FILES})
endif()

# Adjust GLFW and GLEW linking based on BUILD_SHARED_LIBS and USE_STATIC_RUNTIME
if(BUILD_SHARED_LIBS)
if(USE_STATIC_RUNTIME)
message(WARNING "Building a shared library with static runtime is uncommon and may lead to issues.")
set(GLFW_LIBRARY "glfw3_mt.lib")
set(GLEW_LIBRARY "glew32s.lib")
else()
set(GLFW_LIBRARY "glfw3dll.lib")
set(GLEW_LIBRARY "glew32.lib")
endif()
else()
if(USE_STATIC_RUNTIME)
set(GLFW_LIBRARY "glfw3_mt.lib")
set(GLEW_LIBRARY "glew32s.lib")
else()
set(GLFW_LIBRARY "glfw3.lib")
set(GLEW_LIBRARY "glew32.lib")
endif()
endif()

# Define GLEW_STATIC for static builds
if(USE_STATIC_RUNTIME)
add_definitions(-DGLEW_STATIC)
endif()

target_link_libraries(FEBasicApplication
PRIVATE
${GLEW_LIBRARY}
${GLFW_LIBRARY}
opengl32.lib
)

target_link_libraries(FEBasicApplication glew32s.lib)
target_link_libraries(FEBasicApplication glfw3.lib)
target_link_libraries(FEBasicApplication glfw3_mt.lib)
target_link_libraries(FEBasicApplication glfw3dll.lib)
target_link_libraries(FEBasicApplication opengl32.lib)

source_group("Source Files" FILES ${BasicApplicationSubSystem_SRC})
source_group("Source Files/SubSystems/Networking" FILES ${BasicApplicationNetworkSubSystem_SRC})
source_group("Source Files/SubSystems/Profiling" FILES ${BasicApplicationProfilingSubSystem_SRC})
Expand All @@ -106,8 +173,33 @@ set(GLEW_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/glew2/include PARENT
set(BASICAPP_THIRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty PARENT_SCOPE)
set(BASICAPP_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)


include_directories(
${GLEW_INCLUDE_DIR}
${BASICAPP_THIRDPARTY_DIR}
)
)

# Export the BUILD_SHARED_LIBS and USE_STATIC_RUNTIME variables
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS} PARENT_SCOPE)
set(USE_STATIC_RUNTIME ${USE_STATIC_RUNTIME} PARENT_SCOPE)

# Export the GLEW_LIBRARY and GLFW_LIBRARY variables
set(GLEW_LIBRARY ${GLEW_LIBRARY} PARENT_SCOPE)
set(GLFW_LIBRARY ${GLFW_LIBRARY} PARENT_SCOPE)

# If building as DLL, copy necessary DLLs to output directory
if(BUILD_SHARED_LIBS)
add_custom_command(TARGET FEBasicApplication POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${GLFW_LIB_DIR}/glfw3.dll"
"$<TARGET_FILE_DIR:FEBasicApplication>"
)
endif()

# If using dynamic runtime, copy necessary DLLs to output directory
if(NOT USE_STATIC_RUNTIME)
add_custom_command(TARGET FEBasicApplication POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${GLEW_LIB_DIR}/glew32.dll"
"$<TARGET_FILE_DIR:FEBasicApplication>"
)
endif()
56 changes: 34 additions & 22 deletions FEBasicApplication.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#include "FEBasicApplication.h"
using namespace FocalEngine;

FEBasicApplication* FEBasicApplication::Instance = nullptr;
#ifdef FEBASICAPPLICATION_SHARED
extern "C" __declspec(dllexport) void* GetBasicApplication()
{
return FEBasicApplication::GetInstancePointer();
}
#endif

FEBasicApplication::FEBasicApplication()
{
Expand Down Expand Up @@ -304,11 +309,18 @@ bool FEBasicApplication::SetClipboardText(const std::string Text)
{
EmptyClipboard();

const HGLOBAL HMem = GlobalAlloc(GMEM_MOVEABLE, Text.size() + 1);
memcpy(GlobalLock(HMem), Text.c_str(), Text.size() + 1);
GlobalUnlock(HMem);
const HGLOBAL MemoryHandle = GlobalAlloc(GMEM_MOVEABLE, Text.size() + 1);
if (MemoryHandle == nullptr)
{
LOG.Add("Failed to allocate memory for clipboard", "FE_BASIC_APPLICATION", FE_LOG_ERROR);
CloseClipboard();
return false;
}

memcpy(GlobalLock(MemoryHandle), Text.c_str(), Text.size() + 1);
GlobalUnlock(MemoryHandle);

SetClipboardData(CF_TEXT, HMem);
SetClipboardData(CF_TEXT, MemoryHandle);

CloseClipboard();
return true;
Expand All @@ -319,23 +331,23 @@ bool FEBasicApplication::SetClipboardText(const std::string Text)

std::string FEBasicApplication::GetClipboardText()
{
std::string text;
std::string Result;

if (OpenClipboard(nullptr))
{
HANDLE data = nullptr;
data = GetClipboardData(CF_TEXT);
if (data != nullptr)
HANDLE ClipboardData = nullptr;
ClipboardData = GetClipboardData(CF_TEXT);
if (ClipboardData != nullptr)
{
const char* PszText = static_cast<char*>(GlobalLock(data));
if (PszText != nullptr)
text = PszText;
const char* ClipboardText = static_cast<char*>(GlobalLock(ClipboardData));
if (ClipboardText != nullptr)
Result = ClipboardText;
}

CloseClipboard();
}

return text;
return Result;
}

BOOL WINAPI FEBasicApplication::ConsoleHandler(DWORD dwType)
Expand Down Expand Up @@ -419,7 +431,7 @@ void FEBasicApplication::Close()
void FEBasicApplication::TryToClose()
{
// Call the user callbacks
// In these callbacks, the user can set the flag to false to prevent the application from closing
// In these callbacks, the user can set the flag to false in order to prevent the application from closing
for (auto& Func : UserOnCloseCallbackFuncs)
Func();
}
Expand Down Expand Up @@ -456,7 +468,7 @@ void FEBasicApplication::CloseWindow(FEWindow* WindowToClose)
// It could happen that ImGui_ImplGlfw_WndProc would be called in glfwPollEvents() for example;
// And if old window is destroyed, then it will cause crash.
// So, I will set ImGui context to the first window.
// It coudl be not the best solution, but it is the easiest one for now.
// It could be not the best solution, but it is the easiest one for now.
void FEBasicApplication::SwitchToImGuiContextOfWindow(size_t WindowIndex)
{
if (!Windows.empty())
Expand Down Expand Up @@ -580,16 +592,16 @@ std::vector<CommandLineAction> FEBasicApplication::ParseCommandLine(std::string
std::vector<std::string> Tokens;
std::string Token;
std::istringstream TokenStream(S);
bool insideQuotes = false;
char currentChar;
bool InsideQuotes = false;
char CurrentChar;

while (TokenStream.get(currentChar))
while (TokenStream.get(CurrentChar))
{
if (currentChar == '\"')
if (CurrentChar == '\"')
{
insideQuotes = !insideQuotes; // Toggle the state
InsideQuotes = !InsideQuotes; // Toggle the state
}
else if (currentChar == Delimiter && !insideQuotes)
else if (CurrentChar == Delimiter && !InsideQuotes)
{
if (!Token.empty())
{
Expand All @@ -599,7 +611,7 @@ std::vector<CommandLineAction> FEBasicApplication::ParseCommandLine(std::string
}
else
{
Token += currentChar;
Token += CurrentChar;
}
}

Expand Down
9 changes: 7 additions & 2 deletions FEBasicApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace FocalEngine
std::map<std::string, std::string> Settings;
};

class FEBasicApplication
class FEBASICAPPLICATION_API FEBasicApplication
{
SINGLETON_PRIVATE_PART(FEBasicApplication)

Expand Down Expand Up @@ -100,5 +100,10 @@ namespace FocalEngine
std::vector<CommandLineAction> ParseCommandLine(std::string CommandLine, const std::string ActionPrefix = "-", const std::string SettingEqualizer = "=");
};

#define APPLICATION FEBasicApplication::getInstance()
#ifdef FEBASICAPPLICATION_SHARED
extern "C" __declspec(dllexport) void* GetBasicApplication();
#define APPLICATION (*static_cast<FEBasicApplication*>(GetBasicApplication()))
#else
#define APPLICATION FEBasicApplication::GetInstance()
#endif
}
11 changes: 11 additions & 0 deletions FEBasicApplicationAPI.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#ifdef FEBASICAPPLICATION_SHARED
#ifdef FEBASICAPPLICATION_EXPORTS
#define FEBASICAPPLICATION_API __declspec(dllexport)
#else
#define FEBASICAPPLICATION_API __declspec(dllimport)
#endif
#else
#define FEBASICAPPLICATION_API
#endif
34 changes: 17 additions & 17 deletions FEConsoleWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ void FEConsoleWindow::ConsoleMainFunc()
bConsoleInitializationStarted = false;

// Redirect standard I/O to the console
FILE* pCout;
freopen_s(&pCout, "CONOUT$", "w", stdout);
FILE* pCin;
freopen_s(&pCin, "CONIN$", "r", stdin);
FILE* ConsoleOutputHandle;
freopen_s(&ConsoleOutputHandle, "CONOUT$", "w", stdout);
FILE* ConsoleInputHandle;
freopen_s(&ConsoleInputHandle, "CONIN$", "r", stdin);

UserConsoleMainFunc(UserConsoleMainFuncData);

fclose(pCout);
fclose(pCin);
fclose(ConsoleOutputHandle);
fclose(ConsoleInputHandle);
FreeConsole();

bConsoleActive = false;
Expand Down Expand Up @@ -116,7 +116,7 @@ bool FEConsoleWindow::SetTitle(const std::string Title) const
WORD FEConsoleWindow::RGBToConsoleColor(int R, int G, int B) const
{
// Define the basic console colors with their RGB values
static const std::tuple<int, int, int, WORD> consoleColors[] = {
static const std::tuple<int, int, int, WORD> CONSOLE_COLORS[] = {
{0, 0, 0, 0}, // Black
{0, 0, 128, FOREGROUND_BLUE}, // Dark Blue
{0, 128, 0, FOREGROUND_GREEN}, // Dark Green
Expand All @@ -135,24 +135,24 @@ WORD FEConsoleWindow::RGBToConsoleColor(int R, int G, int B) const
{255, 255, 255, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY} // White
};

WORD nearestColor = 0; // Default to black if no match is found
double minDistance = DBL_MAX;
WORD NearestColor = 0; // Default to black if no match is found
double MinDistance = DBL_MAX;

for (const auto& color : consoleColors)
for (const auto& color : CONSOLE_COLORS)
{
// Calculate the Euclidean distance between the two colors
double distance = std::sqrt(std::pow(std::get<0>(color) - R, 2) +
std::pow(std::get<1>(color) - G, 2) +
std::pow(std::get<2>(color) - B, 2));
const double Distance = std::sqrt(std::pow(std::get<0>(color) - R, 2) +
std::pow(std::get<1>(color) - G, 2) +
std::pow(std::get<2>(color) - B, 2));

if (distance < minDistance)
if (Distance < MinDistance)
{
minDistance = distance;
nearestColor = std::get<3>(color);
MinDistance = Distance;
NearestColor = std::get<3>(color);
}
}

return nearestColor;
return NearestColor;
}

std::vector<char> FEConsoleWindow::GetConsoleTextColor() const
Expand Down
Loading