diff --git a/UnleashedRecomp/.gitignore b/UnleashedRecomp/.gitignore new file mode 100644 index 0000000..65295cb --- /dev/null +++ b/UnleashedRecomp/.gitignore @@ -0,0 +1,2 @@ +version.h +version.cpp \ No newline at end of file diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index b5b0c53..61f94b0 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -243,7 +243,8 @@ set(SWA_CXX_SOURCES "exports.cpp" "main.cpp" "misc_impl.cpp" - "stdafx.cpp" + "stdafx.cpp" + "version.cpp" ${SWA_KERNEL_CXX_SOURCES} ${SWA_LOCALE_CXX_SOURCES} @@ -263,13 +264,13 @@ set(SWA_CXX_SOURCES if (WIN32) # Set up Win32 resources for application icon. set(ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico") - configure_file("res/win32/res.rc" "${CMAKE_BINARY_DIR}/res.rc" @ONLY) + configure_file("res/win32/res.rc.template" "${CMAKE_BINARY_DIR}/res.rc" @ONLY) add_executable(UnleashedRecomp ${SWA_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") else() add_executable(UnleashedRecomp ${SWA_CXX_SOURCES}) endif() -set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) +set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) if (SWA_FLATPAK) target_compile_definitions(UnleashedRecomp PRIVATE "GAME_INSTALL_DIRECTORY=\"/var/data\"") @@ -418,6 +419,23 @@ generate_aggregate_header( "${CMAKE_CURRENT_SOURCE_DIR}/api" "${CMAKE_CURRENT_SOURCE_DIR}/api/SWA.h" ) + +# Only show build type if not Release. +set(IS_BUILD_TYPE_IN_VER_STRING 0) +if (NOT ${CMAKE_BUILD_TYPE} MATCHES "Release") + set(IS_BUILD_TYPE_IN_VER_STRING 1) +endif() + +include("version.cmake") +GenerateVersionSources( + OUTPUT_DIR "${PROJECT_SOURCE_DIR}" + VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt" + H_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.h.template" + CXX_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.cpp.template" + BUILD_TYPE ${CMAKE_BUILD_TYPE} + IS_BUILD_TYPE_IN_VER_STRING ${IS_BUILD_TYPE_IN_VER_STRING} + IS_GIT_REPO 1 +) set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") diff --git a/UnleashedRecomp/res/version.cpp.template b/UnleashedRecomp/res/version.cpp.template new file mode 100644 index 0000000..bf51f04 --- /dev/null +++ b/UnleashedRecomp/res/version.cpp.template @@ -0,0 +1,15 @@ +#include "version.h" + +// This file is auto-generated, do not modify! + +const char* g_buildType = "@BUILD_TYPE@"; + +const char* g_branchName = "@BRANCH_NAME@"; +const char* g_commitHash = "@COMMIT_HASH@"; +const char* g_commitHashShort = "@COMMIT_HASH_SHORT@"; + +const char* g_versionMilestone = "@VERSION_MILESTONE@"; +size_t g_versionMajor = @VERSION_MAJOR@; +size_t g_versionMinor = @VERSION_MINOR@; +size_t g_versionRevision = @VERSION_REVISION@; +const char* g_versionString = "@VERSION_STRING@"; diff --git a/UnleashedRecomp/res/version.h.template b/UnleashedRecomp/res/version.h.template new file mode 100644 index 0000000..074ad8b --- /dev/null +++ b/UnleashedRecomp/res/version.h.template @@ -0,0 +1,15 @@ +#pragma once + +// This file is auto-generated, do not modify! + +extern const char* g_buildType; + +extern const char* g_branchName; +extern const char* g_commitHash; +extern const char* g_commitHashShort; + +extern const char* g_versionMilestone; +extern size_t g_versionMajor; +extern size_t g_versionMinor; +extern size_t g_versionRevision; +extern const char* g_versionString; diff --git a/UnleashedRecomp/res/version.txt b/UnleashedRecomp/res/version.txt new file mode 100644 index 0000000..3e55e93 --- /dev/null +++ b/UnleashedRecomp/res/version.txt @@ -0,0 +1,4 @@ +VERSION_MILESTONE="Alpha" +VERSION_MAJOR=0 +VERSION_MINOR=0 +VERSION_REVISION=0 diff --git a/UnleashedRecomp/res/win32/res.rc b/UnleashedRecomp/res/win32/res.rc.template similarity index 100% rename from UnleashedRecomp/res/win32/res.rc rename to UnleashedRecomp/res/win32/res.rc.template diff --git a/UnleashedRecomp/ui/imgui_utils.h b/UnleashedRecomp/ui/imgui_utils.h index e576729..f7e6359 100644 --- a/UnleashedRecomp/ui/imgui_utils.h +++ b/UnleashedRecomp/ui/imgui_utils.h @@ -3,6 +3,7 @@ #include #include #include +#include #define PIXELS_TO_UV_COORDS(textureWidth, textureHeight, x, y, width, height) \ std::make_tuple(ImVec2((float)x / (float)textureWidth, (float)y / (float)textureHeight), \ @@ -437,3 +438,14 @@ inline ImU32 ColourLerp(ImU32 c0, ImU32 c1, float t) return ImGui::ColorConvertFloat4ToU32(result); } + +inline void DrawVersionString(const ImFont* font, const ImU32 col = IM_COL32(255, 255, 255, 70)) +{ + auto drawList = ImGui::GetForegroundDrawList(); + auto& res = ImGui::GetIO().DisplaySize; + auto fontSize = Scale(12); + auto textMargin = Scale(2); + auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, g_versionString); + + drawList->AddText(font, fontSize, { res.x - textSize.x - textMargin, res.y - textSize.y - textMargin }, col, g_versionString); +} diff --git a/UnleashedRecomp/ui/installer_wizard.cpp b/UnleashedRecomp/ui/installer_wizard.cpp index 2a88d71..c7e10cf 100644 --- a/UnleashedRecomp/ui/installer_wizard.cpp +++ b/UnleashedRecomp/ui/installer_wizard.cpp @@ -574,8 +574,8 @@ static void DrawScanlineBars() // Installer text const std::string &headerText = Localise(g_currentPage == WizardPage::Installing ? "Installer_Header_Installing" : "Installer_Header_Installer"); - int textAlpha = std::lround(255.0f * ComputeMotionInstaller(g_appearTime, g_disappearTime, TITLE_ANIMATION_TIME, TITLE_ANIMATION_DURATION)); - DrawTextWithOutline(g_dfsogeistdFont, Scale(42.0f), { Scale(285.0f), Scale(57.0f) }, IM_COL32(255, 195, 0, textAlpha), headerText.c_str(), 4, IM_COL32(0, 0, 0, textAlpha), IMGUI_SHADER_MODIFIER_TITLE_BEVEL); + auto alphaMotion = ComputeMotionInstaller(g_appearTime, g_disappearTime, TITLE_ANIMATION_TIME, TITLE_ANIMATION_DURATION); + DrawTextWithOutline(g_dfsogeistdFont, Scale(42.0f), { Scale(285.0f), Scale(57.0f) }, IM_COL32(255, 195, 0, 255 * alphaMotion), headerText.c_str(), 4, IM_COL32(0, 0, 0, 255 * alphaMotion), IMGUI_SHADER_MODIFIER_TITLE_BEVEL); // Top bar line drawList->AddLine @@ -596,6 +596,7 @@ static void DrawScanlineBars() ); DrawHeaderIcons(); + DrawVersionString(g_newRodinFont, IM_COL32(255, 255, 255, 70 * alphaMotion)); } static float AlignToNextGrid(float value) diff --git a/UnleashedRecomp/ui/options_menu.cpp b/UnleashedRecomp/ui/options_menu.cpp index 4a14a9c..9456901 100644 --- a/UnleashedRecomp/ui/options_menu.cpp +++ b/UnleashedRecomp/ui/options_menu.cpp @@ -180,6 +180,8 @@ static void DrawScanlineBars() OUTLINE_COLOR, Scale(1) ); + + DrawVersionString(g_newRodinFont); } static float AlignToNextGrid(float value) diff --git a/UnleashedRecomp/version.cmake b/UnleashedRecomp/version.cmake new file mode 100644 index 0000000..7c9e86a --- /dev/null +++ b/UnleashedRecomp/version.cmake @@ -0,0 +1,136 @@ +# version.cmake - written by hyperbx +# Generates a compilation unit from template files for version information. + +# OUTPUT_FILE : the original output file from a previous generation. +# TEMPLATE_FILE : the corresponding template file that was used to generate the output file. +function(CheckOutputFile OUTPUT_FILE TEMPLATE_FILE) + if (NOT OUTPUT_FILE) + message(FATAL_ERROR "OUTPUT_FILE not specified.") + endif() + + if (NOT TEMPLATE_FILE) + message(FATAL_ERROR "TEMPLATE_FILE not specified.") + endif() + + if (EXISTS "${OUTPUT_FILE}") + # Read original output file. + file(READ "${OUTPUT_FILE}" ORIGINAL_CONTENT) + + # Read template file and configure. + file(READ "${TEMPLATE_FILE}" TEMPLATE_CONTENT) + string(CONFIGURE "${TEMPLATE_CONTENT}" TEMPLATE_FILE_FINAL_CONTENT @ONLY) + + # Check if configured template matches the original output file and replace it if not. + if (NOT ORIGINAL_CONTENT STREQUAL TEMPLATE_FILE_FINAL_CONTENT) + message("-- Creating ${OUTPUT_FILE}") + file(WRITE "${OUTPUT_FILE}" "${TEMPLATE_FILE_FINAL_CONTENT}") + endif() + else() + message("-- Creating ${OUTPUT_FILE}") + configure_file("${TEMPLATE_FILE}" "${OUTPUT_FILE}" @ONLY) + endif() +endfunction() + +# OUTPUT_DIR : the output directory of the resulting *.h/*.cpp files. +# VERSION_TXT : the input text file containing the milestone, major, minor and revision variables. +# H_TEMPLATE : the input template for the header. +# CXX_TEMPLATE : the input template for the source file. +# BUILD_TYPE : the current build configuration (e.g. "Release", "RelWithDebInfo", "Debug") (optional). +# IS_BUILD_TYPE_IN_VER_STRING : the build type should be appended to the version string (optional). +# IS_GIT_REPO : the project is part of a Git repository (optional). +function(GenerateVersionSources) + cmake_parse_arguments(ARGS "" "OUTPUT_DIR;VERSION_TXT;H_TEMPLATE;CXX_TEMPLATE;BUILD_TYPE;IS_BUILD_TYPE_IN_VER_STRING;IS_GIT_REPO" "" ${ARGN}) + + message("-- Generating version information...") + + if (NOT ARGS_OUTPUT_DIR) + message(FATAL_ERROR "OUTPUT_DIR not specified.") + endif() + + if (NOT ARGS_VERSION_TXT) + message(FATAL_ERROR "VERSION_TXT not specified.") + endif() + + if (NOT ARGS_H_TEMPLATE) + message(FATAL_ERROR "H_TEMPLATE not specified.") + endif() + + if (NOT ARGS_CXX_TEMPLATE) + message(FATAL_ERROR "CXX_TEMPLATE not specified.") + endif() + + set(BUILD_TYPE ${ARGS_BUILD_TYPE}) + + if (ARGS_IS_GIT_REPO) + find_package(Git REQUIRED) + + # Get Git branch name. + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + OUTPUT_VARIABLE BRANCH_NAME + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Get Git commit hash. + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + OUTPUT_VARIABLE COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Get short Git commit hash. + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD + OUTPUT_VARIABLE COMMIT_HASH_SHORT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + + file(READ "${ARGS_VERSION_TXT}" FILE_CONTENT) + string(REGEX REPLACE "\r?\n" ";" FILE_LINES "${FILE_CONTENT}") + + foreach(LINE ${FILE_LINES}) + if (LINE STREQUAL "") + continue() + endif() + + # Find key/value pair match. + string(REGEX MATCH "([A-Za-z_]+)=\\\"?([^\"]+)\\\"?" MATCH "${LINE}") + + if (MATCH) + # Extract key/value pairs. + string(REGEX REPLACE "([A-Za-z_]+)=.*" "\\1" KEY "${MATCH}") + string(REGEX REPLACE "[A-Za-z_]+=\\\"?([^\"]+)\\\"?" "\\1" VALUE "${MATCH}") + + # Set environment variable. + set("${KEY}" "${VALUE}") + endif() + endforeach() + + set(VERSION_STRING "v${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}") + + # Prepend version milestone. + if (VERSION_MILESTONE) + string(PREPEND VERSION_STRING "${VERSION_MILESTONE} ") + endif() + + # Append commit hash and branch. + if (COMMIT_HASH_SHORT) + string(APPEND VERSION_STRING ".${COMMIT_HASH_SHORT}-${BRANCH_NAME}") + endif() + + # Append build configuration. + if (ARGS_BUILD_TYPE AND ARGS_IS_BUILD_TYPE_IN_VER_STRING) + string(APPEND VERSION_STRING " (${ARGS_BUILD_TYPE})") + endif() + + message("-- Build: ${VERSION_STRING}") + + get_filename_component(H_TEMPLATE_NAME_WE "${ARGS_H_TEMPLATE}" NAME_WE) + get_filename_component(CXX_TEMPLATE_NAME_WE "${ARGS_CXX_TEMPLATE}" NAME_WE) + set(H_OUTPUT_FILE "${ARGS_OUTPUT_DIR}/${H_TEMPLATE_NAME_WE}.h") + set(CXX_OUTPUT_FILE "${ARGS_OUTPUT_DIR}/${CXX_TEMPLATE_NAME_WE}.cpp") + + CheckOutputFile("${H_OUTPUT_FILE}" "${ARGS_H_TEMPLATE}") + CheckOutputFile("${CXX_OUTPUT_FILE}" "${ARGS_CXX_TEMPLATE}") +endfunction()