From d9bd8322b224dfb78cff26a18d776e601c4715a4 Mon Sep 17 00:00:00 2001 From: Arsenii es3n1n Date: Wed, 14 Jun 2023 19:00:28 +0200 Subject: [PATCH] v1.0.3 (#14) * fix: color_t values are now uint8_t (#11) * chore: add `GNU GPLv3` license * #12: refactor(color_t): color_t struct refactoring * refactor(color_t): remove some leftovers * #12: refactor(vec_t): remove stupid intrins * #12: refactor(client_class): change callback types decl * refactor(cfg): remove some leftovers * feat: removed asm math in place of std:: (#15) * feat: removed asm math in place of std:: * refactor: use the standard library for constant definitions * #18: refactor(util): remove unused `MATH_PI` macro * #13: feat: added a safe_cast implementation (#16) * feat: added a safe_cast implementation * fix: typo in safe_cast * fix(util): forward template arg in is_safe_castable concept * style(util): reformat * perf: replaces static_cast with safe_cast * chore: remove wrong todo comment * build: add cmake build system (#19) * feat(build): add cmake build system * build(cmake): add `/MP` * docs(readme): minor `Building` section reformat * build: move sln to a separate `msvc` dir * docs(readme): update `Special thanks` section * docs(readme): update msvc building section * fix(math): fix math compilation error * fix(safe_cast): fix safe_cast template parameters, limits * fix(color_t): fix from_hsb casting * fix(color_t): from_hsb f/p/q/t are not constexpr * refactor(cfg): add `push_packed_vars` method * refactor(portals): add `e_identifier` enum * refactor(clamp_cast): rename from `safe_cast` to `clamp_cast` --------- Co-authored-by: Igor <100174039+kehrazy@users.noreply.github.com> Co-authored-by: Igor Fedenko --- .clang-format | 9 +- .gitattributes | 3 + .gitignore | 7 + CMakeLists.txt | 219 ++++++ LICENSE | 674 ++++++++++++++++++ cmake.toml | 62 ++ cmake/cmkr.cmake | 253 +++++++ .../portal2-internal.sln | 4 +- portal2-internal/hack/cfg/cfg.cpp | 113 +-- portal2-internal/hack/cfg/cfg.hpp | 20 +- portal2-internal/hack/cfg/opts.hpp | 17 +- .../features/visuals/change_portal_colors.cpp | 20 +- portal2-internal/hack/menu/menu.cpp | 5 +- portal2-internal/portal2-internal.vcxproj | 6 +- .../portal2-internal.vcxproj.filters | 4 + portal2-internal/sdk/misc/client_class.hpp | 8 +- portal2-internal/sdk/misc/color_t.hpp | 192 +++-- portal2-internal/sdk/misc/flt_range_t.hpp | 48 ++ portal2-internal/sdk/misc/vec_t.hpp | 6 +- portal2-internal/util/cast/cast.hpp | 101 +++ portal2-internal/util/game/game.cpp | 7 +- portal2-internal/util/math/base.hpp | 428 +---------- portal2-internal/util/math/math.cpp | 13 +- portal2-internal/util/math/math.hpp | 6 +- portal2-internal/util/util.hpp | 5 +- readme.md | 23 +- 26 files changed, 1699 insertions(+), 554 deletions(-) create mode 100644 .gitattributes create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 cmake.toml create mode 100644 cmake/cmkr.cmake rename portal2-internal.sln => msvc/portal2-internal.sln (89%) create mode 100644 portal2-internal/sdk/misc/flt_range_t.hpp create mode 100644 portal2-internal/util/cast/cast.hpp diff --git a/.clang-format b/.clang-format index a46fca1..c17f570 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,4 @@ -# es3n1n's clang-format, last upd 13 aug 2022 23:07:09 +# es3n1n's clang-format, last upd 13 may 2023 17:45:37 --- AlignAfterOpenBracket: Align AlignEscapedNewlines: Left @@ -20,7 +20,7 @@ BasedOnStyle: WebKit BinPackArguments: true BinPackParameters: true BitFieldColonSpacing: None -BraceWrapping: +BraceWrapping: AfterCaseLabel: false AfterClass: false AfterControlStatement: false @@ -57,7 +57,7 @@ ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DeriveLineEnding: true DerivePointerAlignment: false -EmptyLineBeforeAccessModifier: Never +EmptyLineBeforeAccessModifier: Always ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true IncludeBlocks: Preserve @@ -107,5 +107,4 @@ SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Latest TabWidth: 8 -UseCRLF: false -... +UseCRLF: false \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1a139ac --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# cmkr +/**/CMakeLists.txt linguist-generated +/**/cmkr.cmake linguist-vendored diff --git a/.gitignore b/.gitignore index 42007fd..e1cd9be 100644 --- a/.gitignore +++ b/.gitignore @@ -349,3 +349,10 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ /enc_temp_folder + +# cmkr +build/ +cmake-build-debug/ +build/ + + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..460b6be --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,219 @@ +# This file is automatically generated from cmake.toml - DO NOT EDIT +# See https://github.com/build-cpp/cmkr for more information + +cmake_minimum_required(VERSION 3.15) + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build") +endif() + +set(CMKR_ROOT_PROJECT OFF) +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(CMKR_ROOT_PROJECT ON) + + # Bootstrap cmkr and automatically regenerate CMakeLists.txt + include("cmake/cmkr.cmake" OPTIONAL RESULT_VARIABLE CMKR_INCLUDE_RESULT) + if(CMKR_INCLUDE_RESULT) + cmkr() + endif() + + # Enable folder support + set_property(GLOBAL PROPERTY USE_FOLDERS ON) + + # Create a configure-time dependency on cmake.toml to improve IDE support + configure_file(cmake.toml cmake.toml COPYONLY) +endif() + +# Options +option(P2_BUILD_INJECTOR "" OFF) + +project(portal2-internal + LANGUAGES + C + CXX + DESCRIPTION + "Portal 2\\MEL\\Reloaded internal modification" +) + +# Target: minhook +set(minhook_SOURCES + "portal2-internal/util/hooking/detours/mh/buffer.c" + "portal2-internal/util/hooking/detours/mh/hde/hde32.c" + "portal2-internal/util/hooking/detours/mh/hde/hde64.c" + "portal2-internal/util/hooking/detours/mh/hook.c" + "portal2-internal/util/hooking/detours/mh/trampoline.c" + "portal2-internal/util/hooking/detours/mh/buffer.h" + "portal2-internal/util/hooking/detours/mh/hde/hde32.h" + "portal2-internal/util/hooking/detours/mh/hde/hde64.h" + "portal2-internal/util/hooking/detours/mh/hde/pstdint.h" + "portal2-internal/util/hooking/detours/mh/hde/table32.h" + "portal2-internal/util/hooking/detours/mh/hde/table64.h" + "portal2-internal/util/hooking/detours/mh/minhook.h" + "portal2-internal/util/hooking/detours/mh/trampoline.h" + cmake.toml +) + +add_library(minhook STATIC) + +target_sources(minhook PRIVATE ${minhook_SOURCES}) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${minhook_SOURCES}) + +add_library(TsudaKageyu::minhook ALIAS minhook) +# Target: portal2-internal +if(WIN32) # windows + set(portal2-internal_SOURCES + "portal2-internal/dllmain.cpp" + "portal2-internal/hack/bootstrap.cpp" + "portal2-internal/hack/cfg/cfg.cpp" + "portal2-internal/hack/features/misc/airacceleration.cpp" + "portal2-internal/hack/features/misc/airacceleration_fix.cpp" + "portal2-internal/hack/features/misc/autostrafer.cpp" + "portal2-internal/hack/features/misc/bhop.cpp" + "portal2-internal/hack/features/visuals/chams.cpp" + "portal2-internal/hack/features/visuals/change_portal_colors.cpp" + "portal2-internal/hack/features/visuals/mat_ambient_light.cpp" + "portal2-internal/hack/features/visuals/trails.cpp" + "portal2-internal/hack/hooks/hooked/create_move.cpp" + "portal2-internal/hack/hooks/hooked/draw_model_execute.cpp" + "portal2-internal/hack/hooks/hooked/override_view.cpp" + "portal2-internal/hack/hooks/hooked/present.cpp" + "portal2-internal/hack/hooks/hooked/reset.cpp" + "portal2-internal/hack/hooks/hooks.cpp" + "portal2-internal/hack/menu/imgui/imgui.cpp" + "portal2-internal/hack/menu/imgui/imgui_draw.cpp" + "portal2-internal/hack/menu/imgui/imgui_tables.cpp" + "portal2-internal/hack/menu/imgui/imgui_widgets.cpp" + "portal2-internal/hack/menu/imgui/impls/imgui_impl_dx9.cpp" + "portal2-internal/hack/menu/imgui/impls/imgui_impl_win32.cpp" + "portal2-internal/hack/menu/menu.cpp" + "portal2-internal/hack/menu/ui/imgui_custom.cpp" + "portal2-internal/sdk/portal.cpp" + "portal2-internal/util/game/game.cpp" + "portal2-internal/util/hooking/detours/detours.cpp" + "portal2-internal/util/hooking/vmt/vmt.cpp" + "portal2-internal/util/input/input.cpp" + "portal2-internal/util/logger/logger.cpp" + "portal2-internal/util/math/math.cpp" + "portal2-internal/util/mem/mem.cpp" + "portal2-internal/hack/cfg/cfg.hpp" + "portal2-internal/hack/cfg/detail/json.hpp" + "portal2-internal/hack/cfg/opts.hpp" + "portal2-internal/hack/features/features.hpp" + "portal2-internal/hack/features/misc/misc.hpp" + "portal2-internal/hack/features/visuals/visuals.hpp" + "portal2-internal/hack/hack.hpp" + "portal2-internal/hack/hooks/hooks.hpp" + "portal2-internal/hack/menu/menu.hpp" + "portal2-internal/hack/menu/ui/imgui_custom.hpp" + "portal2-internal/sdk/enums/e_cmd_buttons.hpp" + "portal2-internal/sdk/enums/e_ent_flags.hpp" + "portal2-internal/sdk/enums/enums.hpp" + "portal2-internal/sdk/interfaces/c_clientmode.hpp" + "portal2-internal/sdk/interfaces/c_cvar.hpp" + "portal2-internal/sdk/interfaces/c_engine_client.hpp" + "portal2-internal/sdk/interfaces/c_entitylist.hpp" + "portal2-internal/sdk/interfaces/c_global_vars.hpp" + "portal2-internal/sdk/interfaces/c_hl_client.hpp" + "portal2-internal/sdk/interfaces/c_input.hpp" + "portal2-internal/sdk/interfaces/c_input_stacksystem.hpp" + "portal2-internal/sdk/interfaces/c_input_system.hpp" + "portal2-internal/sdk/interfaces/c_mat_system.hpp" + "portal2-internal/sdk/interfaces/c_model_render.hpp" + "portal2-internal/sdk/interfaces/c_prop_portal.hpp" + "portal2-internal/sdk/interfaces/c_studio_renderer.hpp" + "portal2-internal/sdk/interfaces/i_model_info_client.hpp" + "portal2-internal/sdk/interfaces/i_render_beams.hpp" + "portal2-internal/sdk/interfaces/i_surface.hpp" + "portal2-internal/sdk/interfaces/interfaces.hpp" + "portal2-internal/sdk/misc/ang_t.hpp" + "portal2-internal/sdk/misc/client_class.hpp" + "portal2-internal/sdk/misc/color_t.hpp" + "portal2-internal/sdk/misc/recv.hpp" + "portal2-internal/sdk/misc/vec_t.hpp" + "portal2-internal/sdk/portal.hpp" + "portal2-internal/sdk/structs/c_base_entity.hpp" + "portal2-internal/sdk/structs/c_base_player.hpp" + "portal2-internal/sdk/structs/c_usercmd.hpp" + "portal2-internal/util/game/game.hpp" + "portal2-internal/util/hash/fnv.hpp" + "portal2-internal/util/hooking/detours/detours.hpp" + "portal2-internal/util/hooking/hooking.hpp" + "portal2-internal/util/hooking/vmt/vmt.hpp" + "portal2-internal/util/input/input.hpp" + "portal2-internal/util/logger/logger.hpp" + "portal2-internal/util/math/base.hpp" + "portal2-internal/util/math/math.hpp" + "portal2-internal/util/mem/addr/addr.hpp" + "portal2-internal/util/mem/mem.hpp" + "portal2-internal/util/mem/module/module.hpp" + "portal2-internal/util/util.hpp" + cmake.toml + ) + + add_library(portal2-internal SHARED) + + target_sources(portal2-internal PRIVATE ${portal2-internal_SOURCES}) + source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${portal2-internal_SOURCES}) + + target_compile_features(portal2-internal PUBLIC + cxx_std_23 + ) + + if(MSVC) # msvc + target_compile_options(portal2-internal PRIVATE + "/MP" + ) + endif() + + if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC$") OR (CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC$")) # clang + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "GNU") # gcc + endif() + + target_include_directories(portal2-internal PUBLIC + "portal2-internal/" + "portal2-internal/hack/menu/imgui" + "portal2-internal/hack/menu/imgui/impls" + ) + + target_link_libraries(portal2-internal PUBLIC + TsudaKageyu::minhook + ) + +endif() +# Target: portal2-injector +if(P2_BUILD_INJECTOR) # build-injector + set(portal2-injector_SOURCES + "portal2-injector/injector/injector.cpp" + "portal2-injector/main.cpp" + cmake.toml + ) + + add_executable(portal2-injector) + + target_sources(portal2-injector PRIVATE ${portal2-injector_SOURCES}) + source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${portal2-injector_SOURCES}) + + target_compile_features(portal2-injector PRIVATE + cxx_std_23 + ) + + if(MSVC) # msvc + target_compile_options(portal2-injector PRIVATE + "/MP" + ) + endif() + + if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC$") OR (CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC$")) # clang + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "GNU") # gcc + endif() + + get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT) + if(NOT CMKR_VS_STARTUP_PROJECT) + set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT portal2-injector) + endif() + +endif() diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/cmake.toml b/cmake.toml new file mode 100644 index 0000000..c5d2aeb --- /dev/null +++ b/cmake.toml @@ -0,0 +1,62 @@ +[cmake] +version = "3.15" +cmkr-include = "cmake/cmkr.cmake" + +[project] +name = "portal2-internal" +languages = ["C", "CXX"] +description = "Portal 2\\MEL\\Reloaded internal modification" + +[options] +P2_BUILD_INJECTOR = false + +[conditions] +build-injector = "P2_BUILD_INJECTOR" + +# +# Dependencies +# + +[target.minhook] +type = "static" +alias = "TsudaKageyu::minhook" +sources = [ + "portal2-internal/util/hooking/detours/mh/**.c" +] +headers = [ + "portal2-internal/util/hooking/detours/mh/**.h" +] + +# +# portal2-internal dll +# +[target.portal2-internal] +type = "shared" +condition = "windows" +include-directories = [ + "portal2-internal/", + "portal2-internal/hack/menu/imgui", + "portal2-internal/hack/menu/imgui/impls", +] +sources = [ + "portal2-internal/**.cpp", "portal2-internal/**.hpp" +] +compile-features = ["cxx_std_23"] +link-libraries = ["TsudaKageyu::minhook"] + +msvc.private-compile-options = ["/MP"] +clang.private-compile-options = [] +gcc.private-compile-options = [] + +# +# injector +# +[target.portal2-injector] +condition = "build-injector" +type = "executable" +sources = ["portal2-injector/**.cpp", "portal2-injector/**.hpp"] +compile-features = ["cxx_std_23"] + +msvc.private-compile-options = ["/MP"] +clang.private-compile-options = [] +gcc.private-compile-options = [] \ No newline at end of file diff --git a/cmake/cmkr.cmake b/cmake/cmkr.cmake new file mode 100644 index 0000000..67aa64e --- /dev/null +++ b/cmake/cmkr.cmake @@ -0,0 +1,253 @@ +include_guard() + +# Change these defaults to point to your infrastructure if desired +set(CMKR_REPO "https://github.com/build-cpp/cmkr" CACHE STRING "cmkr git repository" FORCE) +set(CMKR_TAG "v0.2.24" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE) +set(CMKR_COMMIT_HASH "" CACHE STRING "cmkr git commit hash (optional)" FORCE) + +# To bootstrap/generate a cmkr project: cmake -P cmkr.cmake +if(CMAKE_SCRIPT_MODE_FILE) + set(CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}/build") + set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_BINARY_DIR}") + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}") +endif() + +# Set these from the command line to customize for development/debugging purposes +set(CMKR_EXECUTABLE "" CACHE FILEPATH "cmkr executable") +set(CMKR_SKIP_GENERATION OFF CACHE BOOL "skip automatic cmkr generation") +set(CMKR_BUILD_TYPE "Debug" CACHE STRING "cmkr build configuration") +mark_as_advanced(CMKR_REPO CMKR_TAG CMKR_COMMIT_HASH CMKR_EXECUTABLE CMKR_SKIP_GENERATION CMKR_BUILD_TYPE) + +# Disable cmkr if generation is disabled +if(DEFINED ENV{CI} OR CMKR_SKIP_GENERATION OR CMKR_BUILD_SKIP_GENERATION) + message(STATUS "[cmkr] Skipping automatic cmkr generation") + unset(CMKR_BUILD_SKIP_GENERATION CACHE) + macro(cmkr) + endmacro() + return() +endif() + +# Disable cmkr if no cmake.toml file is found +if(NOT CMAKE_SCRIPT_MODE_FILE AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") + message(AUTHOR_WARNING "[cmkr] Not found: ${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") + macro(cmkr) + endmacro() + return() +endif() + +# Convert a Windows native path to CMake path +if(CMKR_EXECUTABLE MATCHES "\\\\") + string(REPLACE "\\" "/" CMKR_EXECUTABLE_CMAKE "${CMKR_EXECUTABLE}") + set(CMKR_EXECUTABLE "${CMKR_EXECUTABLE_CMAKE}" CACHE FILEPATH "" FORCE) + unset(CMKR_EXECUTABLE_CMAKE) +endif() + +# Helper macro to execute a process (COMMAND_ERROR_IS_FATAL ANY is 3.19 and higher) +function(cmkr_exec) + execute_process(COMMAND ${ARGV} RESULT_VARIABLE CMKR_EXEC_RESULT) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "cmkr_exec(${ARGV}) failed (exit code ${CMKR_EXEC_RESULT})") + endif() +endfunction() + +# Windows-specific hack (CMAKE_EXECUTABLE_PREFIX is not set at the moment) +if(WIN32) + set(CMKR_EXECUTABLE_NAME "cmkr.exe") +else() + set(CMKR_EXECUTABLE_NAME "cmkr") +endif() + +# Use cached cmkr if found +if(DEFINED ENV{CMKR_CACHE}) + set(CMKR_DIRECTORY_PREFIX "$ENV{CMKR_CACHE}") + string(REPLACE "\\" "/" CMKR_DIRECTORY_PREFIX "${CMKR_DIRECTORY_PREFIX}") + if(NOT CMKR_DIRECTORY_PREFIX MATCHES "\\/$") + set(CMKR_DIRECTORY_PREFIX "${CMKR_DIRECTORY_PREFIX}/") + endif() + # Build in release mode for the cache + set(CMKR_BUILD_TYPE "Release") +else() + set(CMKR_DIRECTORY_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/_cmkr_") +endif() +set(CMKR_DIRECTORY "${CMKR_DIRECTORY_PREFIX}${CMKR_TAG}") +set(CMKR_CACHED_EXECUTABLE "${CMKR_DIRECTORY}/bin/${CMKR_EXECUTABLE_NAME}") + +# Helper function to check if a string starts with a prefix +# Cannot use MATCHES, see: https://github.com/build-cpp/cmkr/issues/61 +function(cmkr_startswith str prefix result) + string(LENGTH "${prefix}" prefix_length) + string(LENGTH "${str}" str_length) + if(prefix_length LESS_EQUAL str_length) + string(SUBSTRING "${str}" 0 ${prefix_length} str_prefix) + if(prefix STREQUAL str_prefix) + set("${result}" ON PARENT_SCOPE) + return() + endif() + endif() + set("${result}" OFF PARENT_SCOPE) +endfunction() + +# Handle upgrading logic +if(CMKR_EXECUTABLE AND NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE) + cmkr_startswith("${CMKR_EXECUTABLE}" "${CMAKE_CURRENT_BINARY_DIR}/_cmkr" CMKR_STARTSWITH_BUILD) + cmkr_startswith("${CMKR_EXECUTABLE}" "${CMKR_DIRECTORY_PREFIX}" CMKR_STARTSWITH_CACHE) + if(CMKR_STARTSWITH_BUILD) + if(DEFINED ENV{CMKR_CACHE}) + message(AUTHOR_WARNING "[cmkr] Switching to cached cmkr: '${CMKR_CACHED_EXECUTABLE}'") + if(EXISTS "${CMKR_CACHED_EXECUTABLE}") + set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE) + else() + unset(CMKR_EXECUTABLE CACHE) + endif() + else() + message(AUTHOR_WARNING "[cmkr] Upgrading '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'") + unset(CMKR_EXECUTABLE CACHE) + endif() + elseif(DEFINED ENV{CMKR_CACHE} AND CMKR_STARTSWITH_CACHE) + message(AUTHOR_WARNING "[cmkr] Upgrading cached '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'") + unset(CMKR_EXECUTABLE CACHE) + endif() +endif() + +if(CMKR_EXECUTABLE AND EXISTS "${CMKR_EXECUTABLE}") + message(VERBOSE "[cmkr] Found cmkr: '${CMKR_EXECUTABLE}'") +elseif(CMKR_EXECUTABLE AND NOT CMKR_EXECUTABLE STREQUAL CMKR_CACHED_EXECUTABLE) + message(FATAL_ERROR "[cmkr] '${CMKR_EXECUTABLE}' not found") +elseif(NOT CMKR_EXECUTABLE AND EXISTS "${CMKR_CACHED_EXECUTABLE}") + set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE) + message(STATUS "[cmkr] Found cached cmkr: '${CMKR_EXECUTABLE}'") +else() + set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE) + message(VERBOSE "[cmkr] Bootstrapping '${CMKR_EXECUTABLE}'") + + message(STATUS "[cmkr] Fetching cmkr...") + if(EXISTS "${CMKR_DIRECTORY}") + cmkr_exec("${CMAKE_COMMAND}" -E rm -rf "${CMKR_DIRECTORY}") + endif() + find_package(Git QUIET REQUIRED) + cmkr_exec("${GIT_EXECUTABLE}" + clone + --config advice.detachedHead=false + --branch ${CMKR_TAG} + --depth 1 + ${CMKR_REPO} + "${CMKR_DIRECTORY}" + ) + if(CMKR_COMMIT_HASH) + execute_process( + COMMAND "${GIT_EXECUTABLE}" checkout -q "${CMKR_COMMIT_HASH}" + RESULT_VARIABLE CMKR_EXEC_RESULT + WORKING_DIRECTORY "${CMKR_DIRECTORY}" + ) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "Tag '${CMKR_TAG}' hash is not '${CMKR_COMMIT_HASH}'") + endif() + endif() + message(STATUS "[cmkr] Building cmkr (using system compiler)...") + cmkr_exec("${CMAKE_COMMAND}" + --no-warn-unused-cli + "${CMKR_DIRECTORY}" + "-B${CMKR_DIRECTORY}/build" + "-DCMAKE_BUILD_TYPE=${CMKR_BUILD_TYPE}" + "-DCMAKE_UNITY_BUILD=ON" + "-DCMAKE_INSTALL_PREFIX=${CMKR_DIRECTORY}" + "-DCMKR_GENERATE_DOCUMENTATION=OFF" + ) + cmkr_exec("${CMAKE_COMMAND}" + --build "${CMKR_DIRECTORY}/build" + --config "${CMKR_BUILD_TYPE}" + --parallel + ) + cmkr_exec("${CMAKE_COMMAND}" + --install "${CMKR_DIRECTORY}/build" + --config "${CMKR_BUILD_TYPE}" + --prefix "${CMKR_DIRECTORY}" + --component cmkr + ) + if(NOT EXISTS ${CMKR_EXECUTABLE}) + message(FATAL_ERROR "[cmkr] Failed to bootstrap '${CMKR_EXECUTABLE}'") + endif() + cmkr_exec("${CMKR_EXECUTABLE}" version) + message(STATUS "[cmkr] Bootstrapped ${CMKR_EXECUTABLE}") +endif() +execute_process(COMMAND "${CMKR_EXECUTABLE}" version + RESULT_VARIABLE CMKR_EXEC_RESULT +) +if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to get version, try clearing the cache and rebuilding") +endif() + +# Use cmkr.cmake as a script +if(CMAKE_SCRIPT_MODE_FILE) + if(NOT EXISTS "${CMAKE_SOURCE_DIR}/cmake.toml") + execute_process(COMMAND "${CMKR_EXECUTABLE}" init + RESULT_VARIABLE CMKR_EXEC_RESULT + ) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to bootstrap cmkr project. Please report an issue: https://github.com/build-cpp/cmkr/issues/new") + else() + message(STATUS "[cmkr] Modify cmake.toml and then configure using: cmake -B build") + endif() + else() + execute_process(COMMAND "${CMKR_EXECUTABLE}" gen + RESULT_VARIABLE CMKR_EXEC_RESULT + ) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to generate project.") + else() + message(STATUS "[cmkr] Configure using: cmake -B build") + endif() + endif() +endif() + +# This is the macro that contains black magic +macro(cmkr) + # When this macro is called from the generated file, fake some internal CMake variables + get_source_file_property(CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}" CMKR_CURRENT_LIST_FILE) + if(CMKR_CURRENT_LIST_FILE) + set(CMAKE_CURRENT_LIST_FILE "${CMKR_CURRENT_LIST_FILE}") + get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) + endif() + + # File-based include guard (include_guard is not documented to work) + get_source_file_property(CMKR_INCLUDE_GUARD "${CMAKE_CURRENT_LIST_FILE}" CMKR_INCLUDE_GUARD) + if(NOT CMKR_INCLUDE_GUARD) + set_source_files_properties("${CMAKE_CURRENT_LIST_FILE}" PROPERTIES CMKR_INCLUDE_GUARD TRUE) + + file(SHA256 "${CMAKE_CURRENT_LIST_FILE}" CMKR_LIST_FILE_SHA256_PRE) + + # Generate CMakeLists.txt + cmkr_exec("${CMKR_EXECUTABLE}" gen + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + + file(SHA256 "${CMAKE_CURRENT_LIST_FILE}" CMKR_LIST_FILE_SHA256_POST) + + # Delete the temporary file if it was left for some reason + set(CMKR_TEMP_FILE "${CMAKE_CURRENT_SOURCE_DIR}/CMakerLists.txt") + if(EXISTS "${CMKR_TEMP_FILE}") + file(REMOVE "${CMKR_TEMP_FILE}") + endif() + + if(NOT CMKR_LIST_FILE_SHA256_PRE STREQUAL CMKR_LIST_FILE_SHA256_POST) + # Copy the now-generated CMakeLists.txt to CMakerLists.txt + # This is done because you cannot include() a file you are currently in + configure_file(CMakeLists.txt "${CMKR_TEMP_FILE}" COPYONLY) + + # Add the macro required for the hack at the start of the cmkr macro + set_source_files_properties("${CMKR_TEMP_FILE}" PROPERTIES + CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}" + ) + + # 'Execute' the newly-generated CMakeLists.txt + include("${CMKR_TEMP_FILE}") + + # Delete the generated file + file(REMOVE "${CMKR_TEMP_FILE}") + + # Do not execute the rest of the original CMakeLists.txt + return() + endif() + # Resume executing the unmodified CMakeLists.txt + endif() +endmacro() diff --git a/portal2-internal.sln b/msvc/portal2-internal.sln similarity index 89% rename from portal2-internal.sln rename to msvc/portal2-internal.sln index bf6cc64..60910bf 100644 --- a/portal2-internal.sln +++ b/msvc/portal2-internal.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.3.32901.215 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "portal2-internal", "portal2-internal\portal2-internal.vcxproj", "{2407CD2B-DA0F-4117-8FDB-5A08068E8E89}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "portal2-internal", "..\portal2-internal\portal2-internal.vcxproj", "{2407CD2B-DA0F-4117-8FDB-5A08068E8E89}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "portal2-injector", "portal2-injector\portal2-injector.vcxproj", "{5B776901-130B-4A1A-BAF4-BA9854B6EF46}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "portal2-injector", "..\portal2-injector\portal2-injector.vcxproj", "{5B776901-130B-4A1A-BAF4-BA9854B6EF46}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E4C9A89D-5A38-457C-A16B-919B56848595}" ProjectSection(SolutionItems) = preProject diff --git a/portal2-internal/hack/cfg/cfg.cpp b/portal2-internal/hack/cfg/cfg.cpp index fb3ba42..e48664b 100644 --- a/portal2-internal/hack/cfg/cfg.cpp +++ b/portal2-internal/hack/cfg/cfg.cpp @@ -1,35 +1,63 @@ -#include "cfg.hpp" -#include "detail/json.hpp" #include #include #include #include #include +#include "hack/cfg/cfg.hpp" +#include "hack/cfg/detail/json.hpp" +#include "util/cast/cast.hpp" + namespace hack::cfg { - // @fixme: - - __forceinline void push_color(color_t* col, const std::string_view prefix) { - push(&col->r, std::format("{}_r", prefix)); - push(&col->g, std::format("{}_g", prefix)); - push(&col->b, std::format("{}_b", prefix)); - push(&col->a, std::format("{}_a", prefix)); - push(&col->rainbow, std::format("{}_rainbow", prefix)); - - _cols.emplace_back(col); - } + namespace { + template + struct packed_var_t { + public: + T* ptr; + std::string_view fmt; + }; + + template + inline void push_packed_vars(const std::string_view prefix, packed_var_t var, Variadic... variadic) { + push(var.ptr, std::vformat(var.fmt, std::make_format_args(prefix))); + + if constexpr (sizeof...(Variadic)) + push_packed_vars(prefix, variadic...); + } - // @fixme: - - __forceinline void push_chams(opts::chams_opts_t* opts, const std::string_view prefix) { - push(&opts->m_enabled, std::format("{}_enabled", prefix)); - push(&opts->m_material, std::format("{}_material", prefix)); - push_color(&opts->m_color, prefix); - } + // @fixme: - + void push_color(color_t* col, const std::string_view prefix) { + // clang-format off + push_packed_vars(prefix, + packed_var_t{&col->r, "{}_r"}, + packed_var_t{&col->g, "{}_g"}, + packed_var_t{&col->b, "{}_b"}, + packed_var_t{&col->a, "{}_a"}, + packed_var_t{&col->rainbow.enabled, "{}_rainbow"} + ); + // clang-format on + + _cols.emplace_back(col); + } - // @fixme: - - __forceinline void push_portals(opts::portal_colors_t* opts, const std::string_view prefix) { - push_color(&opts->m_portal_1, std::format("{}_1", prefix)); - push_color(&opts->m_portal_2, std::format("{}_2", prefix)); - } + // @fixme: - + void push_chams(opts::chams_opts_t* opts, const std::string_view prefix) { + // clang-format off + push_packed_vars(prefix, + packed_var_t{&opts->m_enabled, "{}_enabled"}, + packed_var_t{&opts->m_material, "{}_material"} + ); + // clang-format on + + push_color(&opts->m_color, prefix); + } + + // @fixme: - + void push_portals(opts::portal_colors_t* opts, const std::string_view prefix) { + for (std::size_t i = opts::portal_colors_t::PORTAL_1; i < opts::portal_colors_t::PORTAL_MAX; ++i) + push_color(&opts->at(i), std::vformat("{}_{}", std::make_format_args(prefix, i))); + } + } // namespace void init() { push(&opts::bhop, "misc_bhop"); @@ -49,8 +77,8 @@ namespace hack::cfg { push(&opts::trails_life_time, "misc_trails_life_time"); push_color(&opts::trails_color, "misc_trails"); - push_portals(&opts::portal_colors[0], "misc_portal_1"); - push_portals(&opts::portal_colors[1], "misc_portal_2"); + for (std::size_t i = opts::portal_colors_t::PORTAL_1; i < opts::portal_colors_t::PORTAL_MAX; ++i) + push_portals(&opts::portal_colors[i], "misc_portal_1"); read("config"); // load default cfg @@ -59,21 +87,17 @@ namespace hack::cfg { void apply_rainbow() { for (auto* col : _cols) { - if (!col->rainbow) + if (!col->rainbow.enabled) continue; - col->rainbow_value += 0.1f * ImGui::GetIO().DeltaTime; - if (col->rainbow_value > 1.f) - col->rainbow_value = 0.f; - - auto new_col = color_t::from_hsb(col->rainbow_value, 0.99f, 1.f); - col->apply(new_col.r, new_col.g, new_col.b, col->a); + col->rainbow.increment(); + col->apply(color_t::from_hsb(col->rainbow.value, .99f, 1.f).replace_a(col->a)); } } void sync_rainbow() { for (auto* col : _cols) - col->rainbow_value = 0.f; + col->rainbow.reset(); } void randomize_rainbow() { @@ -82,7 +106,7 @@ namespace hack::cfg { static std::mt19937 _rnd(static_cast(time(nullptr))); for (auto* col : _cols) - col->rainbow_value = (_rnd() % 100) / 100.f; + col->rainbow.value = (_rnd() % 100) / 100.f; } std::string& get_path(std::string& path) { @@ -93,7 +117,7 @@ namespace hack::cfg { namespace { template - __forceinline void deserialize(const nlohmann::json& json, std::vector> vec) { + inline void deserialize(const nlohmann::json& json, std::vector> vec) { std::for_each(vec.begin(), vec.end(), [json](const auto& it) -> void { if (json.find(it.m_name) == json.end()) return; @@ -115,23 +139,28 @@ namespace hack::cfg { deserialize(data, _bools); deserialize(data, _floats); deserialize(data, _ints); + deserialize(data, _bytes); } +#define SERIALIZE_TYPE(name) \ + for (auto& x : name) \ + data[x.m_name] = *x.m_ptr; + void save(std::string path) { path = get_path(path); nlohmann::json data; - for (auto& b : _bools) - data[b.m_name] = *b.m_ptr; - for (auto& f : _floats) - data[f.m_name] = *f.m_ptr; - for (auto& i : _ints) - data[i.m_name] = *i.m_ptr; + SERIALIZE_TYPE(_bools); + SERIALIZE_TYPE(_floats); + SERIALIZE_TYPE(_ints); + SERIALIZE_TYPE(_bytes); std::ofstream reader(path); reader.clear(); reader << std::setw(4) << data << std::endl; reader.close(); } -} // namespace hack::cfg + +#undef SERIALIZE_TYPE +} // namespace hack::cfg \ No newline at end of file diff --git a/portal2-internal/hack/cfg/cfg.hpp b/portal2-internal/hack/cfg/cfg.hpp index 1c01850..9cc210d 100644 --- a/portal2-internal/hack/cfg/cfg.hpp +++ b/portal2-internal/hack/cfg/cfg.hpp @@ -10,6 +10,7 @@ namespace hack::cfg { public: t* m_ptr{}; std::string m_name{}; + public: cfg_item_t(t* ptr, std::string_view name): m_ptr(ptr), m_name(name) { } ~cfg_item_t() = default; @@ -29,19 +30,22 @@ namespace hack::cfg { inline std::vector> _bools = {}; inline std::vector> _floats = {}; inline std::vector> _ints = {}; + inline std::vector> _bytes = {}; inline std::vector _cols = {}; // template - inline cfg_item_t& push(t* ptr, std::string_view name) { - if constexpr (std::is_same_v) { - return _bools.emplace_back(cfg_item_t(ptr, name)); - } else if constexpr (std::is_same_v) { - return _floats.emplace_back(cfg_item_t(ptr, name)); - } else if constexpr (std::is_same_v || std::is_same_v) { - return _ints.emplace_back(cfg_item_t(ptr, name)); + inline void push(t* ptr, std::string_view name) { + if constexpr (std::is_same_v, bool>) { + _bools.emplace_back(cfg_item_t(ptr, name)); + } else if constexpr (std::is_same_v, float>) { + _floats.emplace_back(cfg_item_t(ptr, name)); + } else if constexpr (std::is_same_v, std::uint8_t>) { + _bytes.emplace_back(cfg_item_t(ptr, name)); + } else if constexpr (std::is_integral_v> && sizeof(t) <= sizeof(int)) { + _ints.emplace_back(cfg_item_t(ptr, name)); } else { - return _ints.emplace_back(cfg_item_t(ptr, name)); // oh no + _ints.emplace_back(cfg_item_t(ptr, name)); // oh no } } diff --git a/portal2-internal/hack/cfg/opts.hpp b/portal2-internal/hack/cfg/opts.hpp index 51c6578..3c24570 100644 --- a/portal2-internal/hack/cfg/opts.hpp +++ b/portal2-internal/hack/cfg/opts.hpp @@ -15,9 +15,24 @@ namespace opts { color_t m_portal_1 = {255, 255, 100, 255}; color_t m_portal_2 = {100, 255, 255, 255}; + public: + enum e_identifier : std::size_t { + PORTAL_1 = 0, + PORTAL_2, + PORTAL_MAX, + + PLAYER_1 = 0, + PLAYER_2, + PLAYER_MAX + }; + color_t& operator[](size_t index) { + return at(index); + } + + color_t& at(size_t index) { switch (index) { - case 0: + case PORTAL_1: return m_portal_1; default: return m_portal_2; diff --git a/portal2-internal/hack/features/visuals/change_portal_colors.cpp b/portal2-internal/hack/features/visuals/change_portal_colors.cpp index 432bf41..079311f 100644 --- a/portal2-internal/hack/features/visuals/change_portal_colors.cpp +++ b/portal2-internal/hack/features/visuals/change_portal_colors.cpp @@ -20,23 +20,23 @@ namespace hack::features::visuals { // and replace colours there, before applying the tinted material on the // portal textures. // we only have one tinted material for both portals, smh - color_t dark_col = {0.f, 0.f, 0.f}; + color_t dark_col = color_t::black(); for (auto* name : {"$PortalColorGradientLight", "$PortalColorGradientDark"}) { if (var = mat->find_var(name, &found); var && found) apply_color(&var->vec3, dark_col); } if (var = mat->find_var("$PortalCoopColorPlayerOnePortalOne", &found); var && found) - apply_color(&var->vec3, opts::portal_colors[0][0]); + apply_color(&var->vec3, opts::portal_colors[opts::portal_colors_t::PLAYER_1][opts::portal_colors_t::PORTAL_1]); if (var = mat->find_var("$PortalCoopColorPlayerOnePortalTwo", &found); var && found) - apply_color(&var->vec3, opts::portal_colors[0][1]); + apply_color(&var->vec3, opts::portal_colors[opts::portal_colors_t::PLAYER_1][opts::portal_colors_t::PORTAL_2]); if (var = mat->find_var("$PortalCoopColorPlayerTwoPortalOne", &found); var && found) - apply_color(&var->vec3, opts::portal_colors[1][0]); + apply_color(&var->vec3, opts::portal_colors[opts::portal_colors_t::PLAYER_2][opts::portal_colors_t::PORTAL_1]); if (var = mat->find_var("$PortalCoopColorPlayerTwoPortalTwo", &found); var && found) - apply_color(&var->vec3, opts::portal_colors[1][1]); + apply_color(&var->vec3, opts::portal_colors[opts::portal_colors_t::PLAYER_2][opts::portal_colors_t::PORTAL_2]); } __forceinline void patch_single_player_branch() { @@ -63,16 +63,16 @@ namespace hack::features::visuals { apply_color(portal::prop_portal->m_materials.m_portal_static_overlay_tinted); - for (std::size_t i = 0; i < 2; i++) - apply_color(portal::prop_portal->m_materials.m_portal_static_overlay[i]); + for (auto* material : portal::prop_portal->m_materials.m_portal_static_overlay) + apply_color(material); apply_color(portal::prop_portal->m_materials.m_portal_depth_doubler); - for (std::size_t i = 0; i < 2; i++) + for (std::size_t i = opts::portal_colors_t::PORTAL_1; i < opts::portal_colors_t::PORTAL_MAX; i++) apply_color(&portal::prop_portal->m_materials.m_single_player_portal_colors[i], opts::portal_colors[0][i]); - for (std::size_t i = 0; i < 2; i++) { - for (std::size_t j = 0; j < 2; j++) + for (std::size_t i = opts::portal_colors_t::PLAYER_1; i < opts::portal_colors_t::PLAYER_MAX; ++i) { + for (std::size_t j = opts::portal_colors_t::PORTAL_1; j < opts::portal_colors_t::PORTAL_MAX; ++j) apply_color(&portal::prop_portal->m_materials.m_coop_player_portal_colors[i][j], opts::portal_colors[i][j]); } diff --git a/portal2-internal/hack/menu/menu.cpp b/portal2-internal/hack/menu/menu.cpp index 0fb1044..f188705 100644 --- a/portal2-internal/hack/menu/menu.cpp +++ b/portal2-internal/hack/menu/menu.cpp @@ -32,7 +32,8 @@ namespace hack::menu { color_picker_flags |= ImGuiColorEditFlags_AlphaBar; if (ImGui::ColorPicker4("##picker", &clr.x, color_picker_flags)) - col->apply(clr.x, clr.y, clr.z, clr.w); + col->apply(static_cast(clr.x), static_cast(clr.y), + static_cast(clr.z), static_cast(clr.w)); ImGui::Separator(); ImGui::BeginColumns("##colsinpopup", 4, ImGuiOldColumnFlags_NoBorder); @@ -46,7 +47,7 @@ namespace hack::menu { ImGui::EndColumns(); ImGui::Separator(); - ImGui::Checkbox("Rainbow", &col->rainbow); + ImGui::Checkbox("Rainbow", &col->rainbow.enabled); ImGui::EndPopup(); } diff --git a/portal2-internal/portal2-internal.vcxproj b/portal2-internal/portal2-internal.vcxproj index 9dcb416..ab8c732 100644 --- a/portal2-internal/portal2-internal.vcxproj +++ b/portal2-internal/portal2-internal.vcxproj @@ -92,6 +92,7 @@ + @@ -119,6 +120,7 @@ + 16.0 @@ -171,7 +173,7 @@ Level3 true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + NOMINMAX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpplatest NotUsing @@ -191,7 +193,7 @@ true true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + NOMINMAX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpplatest true diff --git a/portal2-internal/portal2-internal.vcxproj.filters b/portal2-internal/portal2-internal.vcxproj.filters index c01f368..6cf110d 100644 --- a/portal2-internal/portal2-internal.vcxproj.filters +++ b/portal2-internal/portal2-internal.vcxproj.filters @@ -335,5 +335,9 @@ Header Files + + + Header Files + \ No newline at end of file diff --git a/portal2-internal/sdk/misc/client_class.hpp b/portal2-internal/sdk/misc/client_class.hpp index b6d3c10..b21b84c 100644 --- a/portal2-internal/sdk/misc/client_class.hpp +++ b/portal2-internal/sdk/misc/client_class.hpp @@ -3,12 +3,12 @@ class i_client_networkable; -typedef i_client_networkable* (*create_client_class_fn)(int entnum, int serialNum); -typedef i_client_networkable* (*create_event_fn)(); - class c_clientclass { + using create_class_fn = i_client_networkable*(int ent_num, int serial_num); + using create_event_fn = i_client_networkable*(); + public: - create_client_class_fn m_create; + create_class_fn m_create; create_event_fn m_create_event; char* m_network_name; c_recv_table* m_recv_table; diff --git a/portal2-internal/sdk/misc/color_t.hpp b/portal2-internal/sdk/misc/color_t.hpp index d6ebf7a..2f8134e 100644 --- a/portal2-internal/sdk/misc/color_t.hpp +++ b/portal2-internal/sdk/misc/color_t.hpp @@ -2,62 +2,172 @@ #include #include +#include "hack/menu/imgui/imgui.h" +#include "sdk/misc/flt_range_t.hpp" +#include "util/cast/cast.hpp" + struct color_t { - std::int32_t r = 0, g = 0, b = 0, a = 255; + using channel_t = std::uint8_t; + using channel_flt_t = flt_range_t; + + using channel_limit_t = std::numeric_limits; + using channel_flt_limit_t = std::numeric_limits; - bool rainbow = false; - float rainbow_value = 0.f; +public: + constexpr color_t() = default; + constexpr ~color_t() = default; - color_t() = default; - ~color_t() = default; +public: + constexpr color_t(channel_t r, channel_t g, channel_t b, channel_t a = channel_limit_t::max()) noexcept: r(r), g(g), b(b), a(a) { } - constexpr color_t(std::int32_t r, std::int32_t g, std::int32_t b, std::int32_t a = 255) noexcept: r(r), g(g), b(b), a(a) { } - constexpr color_t(float r, float g, float b, float a = 1.f) noexcept - : r(std::int32_t(r * 255.f)), g(std::int32_t(g * 255.f)), b(std::int32_t(b * 255.f)), a(std::int32_t(a * 255.f)) { } + // clang-format off + constexpr color_t(channel_flt_t r, channel_flt_t g, channel_flt_t b, channel_flt_t a = channel_flt_limit_t::max()) noexcept : + r(channel_t(r * channel_limit_t::max())), + g(channel_t(g * channel_limit_t::max())), + b(channel_t(b * channel_limit_t::max())), + a(channel_t(a * channel_limit_t::max())) { } + // clang-format on - color_t blend(std::int32_t r_, std::int32_t g_, std::int32_t b_, float progress) { - return color_t(static_cast((r_ * progress) + (r * (1.f - progress))), - static_cast((g_ * progress) + (g * (1.f - progress))), - static_cast((b_ * progress) + (b * (1.f - progress)))); +public: + [[nodiscard]] color_t blend(channel_t r_, channel_t g_, channel_t b_, flt_range_t progress) { + return color_t(channel_t((r_ * progress) + (r * (channel_flt_limit_t::max() - progress))), + channel_t((g_ * progress) + (g * (channel_flt_limit_t::max() - progress))), + channel_t((b_ * progress) + (b * (channel_flt_limit_t::max() - progress)))); } - unsigned long get_hex() { - return (unsigned long)((((int)this->a & 0xff) << 0x18) | (((int)this->r & 0xff) << 0x10) | (((int)this->g & 0xff) << 0x8) | ((int)this->b & 0xff)); + [[nodiscard]] std::int32_t get_hex() { + union { + struct { +#if IS_BIG_ENDIAN + channel_t a, r, g, b; +#else + channel_t b, g, r, a; +#endif + }; + + std::int32_t raw; + } converter; + + // + // @todo: @es3n1n: find more convinient way to forward all colors + // + // @note: @kehrazy: there is no way to iterate thru structs in c++23 + // + converter.r = r; + converter.g = g; + converter.b = b; + converter.a = a; + + return converter.raw; } - void apply(std::int32_t r, std::int32_t g, std::int32_t b, std::int32_t a) { +public: + inline color_t& apply(channel_t r = channel_limit_t::max(), channel_t g = channel_limit_t::max(), channel_t b = channel_limit_t::max(), + channel_t a = channel_limit_t::max()) { this->r = r; this->g = g; this->b = b; this->a = a; + + return *this; + } + + inline color_t& apply(channel_flt_t r = channel_flt_limit_t::max(), channel_flt_t g = channel_flt_limit_t::max(), + channel_flt_t b = channel_flt_limit_t::max(), channel_flt_t a = channel_flt_limit_t::max()) { + return apply(static_cast(r * channel_limit_t::max()), static_cast(g * channel_limit_t::max()), + static_cast(b * channel_limit_t::max()), static_cast(a * channel_limit_t::max())); } - void apply(float r, float g, float b, float a) { - this->r = static_cast(r * 255.f); - this->g = static_cast(g * 255.f); - this->b = static_cast(b * 255.f); - this->a = static_cast(a * 255.f); - } - - static color_t from_hsb(float hue, float saturation, float brightness) { - float h = std::fabsf(hue - 1.0f) <= 0.001f ? 0.f : hue * 6.0f; - float f = h - (int)h; - float p = brightness * (1.0f - saturation); - float q = brightness * (1.0f - saturation * f); - float t = brightness * (1.0f - (saturation * (1.0f - f))); - - if (h < 1) { - return color_t((unsigned char)(brightness * 255), (unsigned char)(t * 255), (unsigned char)(p * 255)); - } else if (h < 2) { - return color_t((unsigned char)(q * 255), (unsigned char)(brightness * 255), (unsigned char)(p * 255)); - } else if (h < 3) { - return color_t((unsigned char)(p * 255), (unsigned char)(brightness * 255), (unsigned char)(t * 255)); - } else if (h < 4) { - return color_t((unsigned char)(p * 255), (unsigned char)(q * 255), (unsigned char)(brightness * 255)); - } else if (h < 5) { - return color_t((unsigned char)(t * 255), (unsigned char)(p * 255), (unsigned char)(brightness * 255)); - } else { - return color_t((unsigned char)(brightness * 255), (unsigned char)(p * 255), (unsigned char)(q * 255)); + inline color_t& apply(color_t src) { + return apply(src.r, src.g, src.b, src.a); + } + + inline color_t& replace_a(channel_t a) { + this->a = a; + return *this; + } + + inline color_t& replace_a(channel_flt_t a) { + this->a = static_cast(a * channel_limit_t::max()); + return *this; + } + +public: + // @credits: https://github.com/znsoftm/xtd/blob/master/src/xtd.drawing/src/xtd/drawing/color.cpp#L186 + [[nodiscard]] static color_t from_hsb(flt_range_t hue, flt_range_t saturation, flt_range_t brightness) { + if (!saturation) + return color_t(brightness, brightness, brightness, channel_flt_t(1.f)); + + hue = std::fabsf(hue - 1.0f) <= 0.001f ? 0.f : hue * 6.0f; + + const float f = hue - std::trunc(hue); + const float p = brightness * (1.f - saturation); + const float q = brightness * (1.f - (saturation * f)); + const float t = brightness * (1.f - (saturation * (1.f - f))); + + constexpr channel_t chan_max = channel_limit_t::max(); + + switch (util::clamp_cast(std::trunc(hue))) { + case 0: + return color_t(util::clamp_cast(brightness * chan_max), util::clamp_cast(t * chan_max), + util::clamp_cast(p * chan_max)); + case 1: + return color_t(util::clamp_cast(q * chan_max), util::clamp_cast(brightness * chan_max), + util::clamp_cast(p * chan_max)); + case 2: + return color_t(util::clamp_cast(p * chan_max), util::clamp_cast(brightness * chan_max), + util::clamp_cast(t * chan_max)); + case 3: + return color_t(util::clamp_cast(p * chan_max), util::clamp_cast(q * chan_max), + util::clamp_cast(brightness * chan_max)); + case 4: + return color_t(util::clamp_cast(t * chan_max), util::clamp_cast(p * chan_max), + util::clamp_cast(brightness * chan_max)); + default: + return color_t(util::clamp_cast(brightness * chan_max), util::clamp_cast(p * chan_max), + util::clamp_cast(q * chan_max)); } } + +public: + channel_t r = 0; + channel_t g = 0; + channel_t b = 0; + channel_t a = 255; + + struct { + void set(flt_range_t val) { + value = val; + } + + void reset() { + value = limits_t::min(); + } + + void increment() { + constexpr float coef = 0.1f; + + value = xstd::clamp((value >= limits_t::max() ? limits_t::min() : value) + (coef * ImGui::GetIO().DeltaTime)); + } + + public: + bool enabled = false; + flt_range_t value = 0.f; + + public: + using limits_t = std::numeric_limits; + } rainbow; + +public: +#define DECL_COLOR(name, r, g, b, a) \ + static constexpr color_t name() { return color_t(r, g, b, a); } + + DECL_COLOR(black, 0, 0, 0, 255); + DECL_COLOR(white, 0, 0, 0, 255); + +#undef DECL_COLOR }; + +static_assert(!std::is_same_v && xstd::is_floating_point_v && + !xstd::is_floating_point_v, + "please adjust color channel types"); diff --git a/portal2-internal/sdk/misc/flt_range_t.hpp b/portal2-internal/sdk/misc/flt_range_t.hpp new file mode 100644 index 0000000..76a28ae --- /dev/null +++ b/portal2-internal/sdk/misc/flt_range_t.hpp @@ -0,0 +1,48 @@ +#pragma once +#include +#include +#include + +struct flt_range_t { +public: + constexpr flt_range_t() = default; + constexpr ~flt_range_t() = default; + +public: + constexpr flt_range_t(float value): value(value) { } + +public: + constexpr operator float() { + return value; + } + +public: + float value = 0.f; +}; + +// +// @todo: @es3n1n: implement other functions, not that i care about em anyway +// +template <> +class std::numeric_limits : public _Num_float_base { +public: + _NODISCARD static constexpr flt_range_t(min)() noexcept { + return 0.f; + } + + _NODISCARD static constexpr flt_range_t(max)() noexcept { + return 1.f; + } +}; + +namespace xstd { + template + _INLINE_VAR constexpr bool is_floating_point_v = std::_Is_any_of_v, float, double, long double, flt_range_t>; + + template + inline constexpr _Ty clamp(_Ty value) { + return value < std::numeric_limits<_Ty>::min() ? std::numeric_limits<_Ty>::min() : + value > std::numeric_limits<_Ty>::max() ? std::numeric_limits<_Ty>::max() : + value; + } +} // namespace xstd diff --git a/portal2-internal/sdk/misc/vec_t.hpp b/portal2-internal/sdk/misc/vec_t.hpp index d284b5a..a6863b9 100644 --- a/portal2-internal/sdk/misc/vec_t.hpp +++ b/portal2-internal/sdk/misc/vec_t.hpp @@ -8,7 +8,7 @@ struct vec2_t { float y; float length() const { - return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(x * x + y * y))); + return std::sqrt(x * x + y * y); } }; @@ -19,11 +19,11 @@ struct vec3_t { float z; float length() const { - return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(x * x + y * y + z * z))); + return std::sqrt(x * x + y * y + z * z); } float length_2d() const { - return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(x * x + y * y))); + return std::sqrt(x * x + y * y); } bool operator==(vec3_t& rhs) { diff --git a/portal2-internal/util/cast/cast.hpp b/portal2-internal/util/cast/cast.hpp new file mode 100644 index 0000000..3423f42 --- /dev/null +++ b/portal2-internal/util/cast/cast.hpp @@ -0,0 +1,101 @@ +#pragma once + +#include +#include + +namespace util { + namespace detail { + template + constexpr bool binary_radix = std::numeric_limits::radix == 2; + + template concept is_binary_radix = binary_radix; + template concept ieee754_compliant = std::numeric_limits::is_iec559; + + template concept is_clamp_castable = is_binary_radix && ieee754_compliant; + + template + requires is_clamp_castable + constexpr T exp2(const int& exp) noexcept { + T result{1.0}; + + // look into std::bit_cast + for (int i{0}; i < exp; i++) { + result *= 2.f; + } + + return result; + } + + template + requires is_clamp_castable + constexpr std::uint16_t exp_bits() noexcept { + return std::numeric_limits::max_exponent - 1; + } + } // namespace detail + + // @note: kehrazy: apparently we have to do this shit, + // std::is_nan is non constexpr + template + requires detail::is_clamp_castable + [[nodiscard]] constexpr bool is_nan(const T& val) noexcept { + static_assert(std::numeric_limits::is_iec559, "can't determine is_nan() for a non IEEE-754 compliant type"); + + // https://en.cppreference.com/w/cpp/numeric/math/isnan + return val != val; + } + + template + constexpr from_t lower_bound() noexcept { + using to_limits = std::numeric_limits; + using from_limits = std::numeric_limits; + + static_assert(to_limits::is_integer); + static_assert(detail::is_binary_radix); + + if constexpr (to_limits::is_signed) { + constexpr int to_bits = to_limits::digits; + if constexpr (detail::exp_bits() >= to_bits) { + return -detail::exp2(to_bits); + } else { + return from_limits::lowest(); + } + } + + return 0.f; + } + + template + constexpr from_t upper_bound() noexcept { + using to_limits = std::numeric_limits; + using from_limits = std::numeric_limits; + + static_assert(to_limits::is_integer); + static_assert(detail::is_binary_radix); + + constexpr int to_bits = to_limits::digits; + + if constexpr (detail::exp_bits() >= to_bits) { + return detail::exp2(to_bits); + } else { + return from_limits::infinity; + } + } + + // @credits: https://github.com/e00E/cpp-clamp-cast/blob/master/clamp-cast.hpp + template + constexpr to_t clamp_cast(const from_t from) { + if (util::is_nan(from)) { + return 0; + } + + if (from < lower_bound()) { + return std::numeric_limits::min(); + } + + if (from >= upper_bound()) { + return std::numeric_limits::max(); + } + + return static_cast(from); + } +} // namespace util \ No newline at end of file diff --git a/portal2-internal/util/game/game.cpp b/portal2-internal/util/game/game.cpp index c270a62..ccd90f1 100644 --- a/portal2-internal/util/game/game.cpp +++ b/portal2-internal/util/game/game.cpp @@ -1,6 +1,7 @@ #include "game.hpp" #include "hack/menu/imgui/imgui.h" #include "sdk/portal.hpp" +#include "util/cast/cast.hpp" namespace util::game { namespace { @@ -17,8 +18,8 @@ namespace util::game { } void unlock_cursor() { - int width = static_cast(ImGui::GetIO().DisplaySize.x / 2); - int height = static_cast(ImGui::GetIO().DisplaySize.y / 2); + int width = util::clamp_cast(ImGui::GetIO().DisplaySize.x / 2); + int height = util::clamp_cast(ImGui::GetIO().DisplaySize.y / 2); if (context) { if (portal::input_stacksys->is_topmost_enabled_context(context)) @@ -29,4 +30,4 @@ namespace util::game { portal::input_sys->get_raw_mouse_accumulators(&width, &height); } -} // namespace util::valve +} // namespace util::game \ No newline at end of file diff --git a/portal2-internal/util/math/base.hpp b/portal2-internal/util/math/base.hpp index 24baea6..87955c4 100644 --- a/portal2-internal/util/math/base.hpp +++ b/portal2-internal/util/math/base.hpp @@ -1,429 +1,21 @@ #pragma once +#include "util/cast/cast.hpp" + +#include +#include -// https://gist.github.com/es3n1n/1601c7b74d03abe36ee2cc5790409ccc namespace util::math { - constexpr auto e = 2.71828182845904523536f; - constexpr auto pi = 3.14159265358979323846f; + constexpr auto e = std::numbers::e; + constexpr auto pi = std::numbers::pi; constexpr auto radpi = 180.f / pi; constexpr auto sqrpi = pi * pi; - constexpr auto round_error = 0.5; + constexpr auto round_error = std::numeric_limits::round_error(); - double __forceinline deg2rad(double x) { + [[nodiscard]] inline double deg2rad(const double& x) { return x * (static_cast(pi) / 180.0); } - double __forceinline rad2deg(double x) { + [[nodiscard]] inline double rad2deg(const double& x) { return x * (180.0 / static_cast(pi)); } - - double __forceinline __declspec(naked) __fastcall sin(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fsin - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall asin(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld st - fabs - fcom dword ptr[ round_error ] - fstsw ax - sahf - jbe asin_cont - fld1 - fsubrp st( 1 ), st( 0 ) - fld st - fadd st( 0 ), st( 0 ) - fxch st( 1 ) - fmul st( 0 ), st( 0 ) - fsubp st( 1 ), st( 0 ) - jmp asin_exit - - asin_cont : - - fstp st( 0 ) - fld st( 0 ) - fmul st( 0 ), st( 0 ) - fld1 - fsubrp st( 1 ), st( 0 ) - - asin_exit: - - fsqrt - fpatan - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall sinh(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fldl2e - fmulp st( 1 ), st - fld1 - fld st( 1 ) - fprem - f2xm1 - faddp st( 1 ), st - fscale - fxch - fstp st - fld1 - fdiv st, st( 1 ) - fsubp st( 1 ), st - mov eax, 0x3F000000 - push eax - fld dword ptr[ esp ] - fmulp st( 1 ), st - pop eax - ret 8 - } - } - - // warn: comparing to math.h: (1.) (util::math)0.88137358701954294 vs (math.h)0.88137358701954305 - double __forceinline __declspec(naked) __fastcall asinh(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld st - fmul st, st - fld1 - faddp st( 1 ), st - fsqrt - faddp st( 1 ), st - fldln2 - fxch - fyl2x - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall cos(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fcos - ret 8 - } - } - - // warn: comparing to math.h: (.5) (util::math)1.0471975511965976 vs (math.h)1.0471975511965979 - double __forceinline __declspec(naked) __fastcall acos(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld1 - fchs - fcomp st( 1 ) - fstsw ax - je skip - - fld st( 0 ) - fld1 - fsubrp st( 1 ), st( 0 ) - fxch st( 1 ) - fld1 - faddp st( 1 ), st( 0 ) - fdivp st( 1 ), st( 0 ) - fsqrt - fld1 - jmp end - - skip : - - fld1 - fldz - - end : - - fpatan - fadd st( 0 ), st( 0 ) - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall cosh(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fldl2e - fmulp st( 1 ), st - fld1 - fld st( 1 ) - fprem - f2xm1 - faddp st( 1 ), st - fscale - fxch - fstp st - fld1 - fdiv st, st( 1 ) - faddp st( 1 ), st - mov eax, 0x3F000000 - push eax - fld dword ptr[ esp ] - fmulp st( 1 ), st - pop eax - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall acosh(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld st - fmul st, st - fld1 - fsubp st( 1 ), st - fsqrt - faddp st( 1 ), st - fldln2 - fxch - fyl2x - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall tan(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fptan - fstp st( 0 ) - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall atan(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld1 - fpatan - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall atan2(double x, double y) { - __asm { - fld qword ptr[ esp + 4 ] - fld qword ptr[ esp + 12 ] - fpatan - ret 16 - } - } - - double __forceinline __declspec(naked) __fastcall tanh(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld st - mov eax, 0x40000000 - push eax - fld dword ptr[ esp ] - fmul st, st( 1 ) - fldl2e - fmulp st( 1 ), st - fld1 - fld st( 1 ) - fprem - f2xm1 - faddp st( 1 ), st - fscale - fxch - fstp st - fld1 - fsub st, st( 1 ) - fchs - fld1 - faddp st( 2 ), st - fdivrp st( 1 ), st - pop eax - ret 8 - } - } - - // warn: comparing to math.h: (.4) (util::math)0.42364893019360178 vs (math.h)0.42364893019360184 - double __forceinline __declspec(naked) __fastcall atanh(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld1 - fsub st, st( 1 ) - fld1 - faddp st( 2 ), st - fdivrp st( 1 ), st - fldln2 - fxch - fyl2x - mov eax, 0xBF000000 - push eax - fld dword ptr[ esp ] - fmulp st( 1 ), st - pop eax - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall exp(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fldl2e - fmulp st( 1 ), st - fld1 - fld st( 1 ) - fprem - f2xm1 - faddp st( 1 ), st - fscale - fxch - fstp st - ret 8 - } - } - - // warn: comparing to math.h: (.8) (util::math)1.7411011265922482 vs (math.h)1.7411011265922485 - double __forceinline __declspec(naked) __fastcall exp2(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld1 - fld st( 1 ) - fprem - f2xm1 - faddp st( 1 ), st - fscale - fxch - fstp st - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall log(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fldln2 - fxch - fyl2x - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall log2(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld1 - fxch - fyl2x - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall fabs(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fabs - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall pow(double x, double y) { - __asm { - fld qword ptr[ esp + 12 ] - fld qword ptr[ esp + 4 ] - ftst - fstsw ax - sahf - jz skip - - fyl2x - fld1 - fld st( 1 ) - fprem - f2xm1 - faddp st( 1 ), st( 0 ) - fscale - - skip : - - fstp st( 1 ) - ret 16 - } - } - - double __forceinline __declspec(naked) __fastcall ceil(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fchs - fld1 - fld st( 1 ) - fprem - sub esp, 4 - fst dword ptr[ esp ] - fxch st( 2 ) - mov eax, [ esp ] - cmp eax, 0x80000000 - jbe skip - fsub st, st( 1 ) - - skip: - - fsub st, st( 2 ) - fstp st( 1 ) - fstp st( 1 ) - fchs - pop eax - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall floor(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fld1 - fld st( 1 ) - fprem - sub esp, 4 - fst dword ptr[ esp ] - fxch st( 2 ) - mov eax, [ esp ] - cmp eax, 0x80000000 - jbe floor_exit - fsub st, st( 1 ) - - floor_exit: - - fsub st, st( 2 ) - fstp st( 1 ) - fstp st( 1 ) - pop eax - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall fmod(double x, double y) { - __asm { - fld qword ptr[ esp + 12 ] - fld qword ptr[ esp + 4 ] - fprem - fxch - fstp st - ret 16 - } - } - - double __forceinline __declspec(naked) __fastcall sqrt(double x) { - __asm { - fld qword ptr[ esp + 4 ] - fsqrt - ret 8 - } - } - - double __forceinline __declspec(naked) __fastcall hypot(double x, double y) { - __asm { - fld qword ptr[ esp + 12 ] - fld qword ptr[ esp + 4 ] - fmul st, st - fxch - fmul st, st - faddp st( 1 ), st - fsqrt - ret 16 - } - } -} // namespace util::math +} // namespace util::math \ No newline at end of file diff --git a/portal2-internal/util/math/math.cpp b/portal2-internal/util/math/math.cpp index a36c0ff..4ab9405 100644 --- a/portal2-internal/util/math/math.cpp +++ b/portal2-internal/util/math/math.cpp @@ -20,15 +20,16 @@ namespace util::math { return x; } - void movement_fix(float& forwardmove, float& sidemove, ang_t& angles, ang_t wish_angles) { - auto delta = angles.y - wish_angles.y; + // @note: kehrazy: use std::move damn it + void movement_fix(float& forward_move, float& side_move, const ang_t& angles, const ang_t& wish_angles) { + const auto delta = angles.y - wish_angles.y; if (delta < 0.001f) return; - auto speed = math::sqrt(sidemove * sidemove + forwardmove * forwardmove); - auto yaw = math::atan2(sidemove, forwardmove) + delta; + const auto speed = std::sqrt(side_move * side_move + forward_move * forward_move); + const auto yaw = std::atan2(side_move, forward_move) + delta; - forwardmove = static_cast(math::cos(yaw) * speed); - sidemove = static_cast(math::sin(yaw) * speed); + forward_move = static_cast(std::cos(yaw) * speed); // @note: kehrazy: float to float - should be safe + side_move = static_cast(std::sin(yaw) * speed); } } // namespace util::math \ No newline at end of file diff --git a/portal2-internal/util/math/math.hpp b/portal2-internal/util/math/math.hpp index d4c6ca8..df1f53c 100644 --- a/portal2-internal/util/math/math.hpp +++ b/portal2-internal/util/math/math.hpp @@ -1,10 +1,10 @@ #pragma once +#include "base.hpp" #include "sdk/misc/ang_t.hpp" #include "sdk/misc/vec_t.hpp" -#include "base.hpp" namespace util::math { float normalize_pitch(float x); float normalize_yaw(float x); - void movement_fix(float& forwardmove, float& sidemove, ang_t& angles, ang_t wish_angles); -} // namespace util::math + void movement_fix(float& forward_move, float& side_move, ang_t& angles, ang_t wish_angles); +} // namespace util::math \ No newline at end of file diff --git a/portal2-internal/util/util.hpp b/portal2-internal/util/util.hpp index bca619e..8459747 100644 --- a/portal2-internal/util/util.hpp +++ b/portal2-internal/util/util.hpp @@ -1,9 +1,10 @@ #pragma once -#define MATH_PI 3.14159265358979323846f - +#include "cast/cast.hpp" #include "game/game.hpp" #include "hooking/hooking.hpp" #include "input/input.hpp" #include "logger/logger.hpp" #include "math/math.hpp" #include "mem/mem.hpp" +#include "mem/mem.hpp" +#include "util/util.hpp" diff --git a/readme.md b/readme.md index 7bca348..e7a88c1 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,6 @@ A simple Portal 2/Portal Reloaded internal cheat base with imgui-based menu code - mat ambient light modifications - trails -## Menu: ![menu-preview](https://i.imgur.com/RqOjrqH.png) ## Contributing @@ -26,5 +25,25 @@ Any contributions you make are **greatly appreciated**. 4. Push to the Branch (`git push origin feature/AmazingFeature`) 5. Open a Pull Request +## Building + +- CMake + ```commandline + cmake -B build -A Win32 + cmake --build build --config Release + ``` +- Visual Studio + - Building from command line + ```commandline + msbuild portal2-internal.sln /p:Configuration=Release + ``` + - Building from Visual Studio Interface using `msvc\portal2-internal.sln` + - Creating sln file using cmake and building from it `build\portal2-internal.sln` + ```commandline + cmake -B build -A Win32 + ``` + ## Special thanks: -- [spirthack](https://github.com/spirthack) / [CSGOSimple](https://github.com/spirthack/csgosimple) +- [nlohmann/json](https://github.com/nlohmann/json) +- [ocornut/imgui](https://github.com/ocornut/imgui) +- [spirthack/CSGOSimple](https://github.com/spirthack/CSGOSimple)