docs: add plugin setup guide

This commit is contained in:
2026-05-30 18:33:24 +12:00
parent f3db41c402
commit b61043a3fe
1776 changed files with 122386 additions and 2 deletions
@@ -0,0 +1,101 @@
---
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: 'false'
AlignConsecutiveBitFields: 'false'
AlignConsecutiveDeclarations: 'true'
AlignConsecutiveMacros: 'false'
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: 'true'
AllowAllArgumentsOnNextLine: 'false'
AllowAllConstructorInitializersOnNextLine: 'false'
AllowAllParametersOfDeclarationOnNextLine: 'false'
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortEnumsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: 'true'
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'true'
AlwaysBreakTemplateDeclarations: 'Yes'
BinPackArguments: 'true'
BinPackParameters: 'true'
BitFieldColonSpacing: After
BraceWrapping:
AfterCaseLabel: 'false'
AfterClass: 'true'
AfterControlStatement: 'false'
AfterEnum: 'true'
AfterFunction: 'true'
AfterNamespace: 'true'
AfterStruct: 'true'
AfterUnion: 'true'
AfterExternBlock: 'true'
BeforeCatch: 'false'
BeforeElse: 'false'
BeforeLambdaBody: 'false'
BeforeWhile: 'false'
IndentBraces: 'false'
SplitEmptyFunction: 'false'
SplitEmptyRecord: 'false'
SplitEmptyNamespace: 'false'
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: 'false'
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
BreakStringLiterals: 'true'
ColumnLimit: 0
CompactNamespaces: 'false'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'false'
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: 'false'
DeriveLineEnding: 'true'
DerivePointerAlignment: 'false'
DisableFormat: 'false'
FixNamespaceComments: 'false'
IncludeBlocks: Preserve
IndentCaseBlocks: 'false'
IndentCaseLabels: 'true'
IndentExternBlock: Indent
IndentGotoLabels: 'false'
IndentPPDirectives: AfterHash
IndentWidth: 4
IndentWrappedFunctionNames: 'true'
KeepEmptyLinesAtTheStartOfBlocks: 'false'
Language: Cpp
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PointerAlignment: Left
ReflowComments : 'false'
SortIncludes: 'true'
SortUsingDeclarations: 'true'
SpaceAfterCStyleCast: 'false'
SpaceAfterLogicalNot: 'false'
SpaceAfterTemplateKeyword: 'true'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeCpp11BracedList: 'false'
SpaceBeforeCtorInitializerColon: 'true'
SpaceBeforeInheritanceColon: 'true'
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: 'true'
SpaceBeforeSquareBrackets: 'false'
SpaceInEmptyBlock: 'false'
SpaceInEmptyParentheses: 'false'
SpacesBeforeTrailingComments: 2
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInConditionalStatement: 'false'
SpacesInContainerLiterals: 'true'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: Latest
TabWidth: 4
UseCRLF: 'true'
UseTab: AlignWithSpaces
...
@@ -0,0 +1,42 @@
---
Checks: >
-*,
bugprone-*,
-bugprone-branch-clone,
-bugprone-macro-parentheses,
-bugprone-narrowing-conversions,
-bugprone-unhandled-self-assignment,
clang-analyzer-*,
google-*,
-google-build-using-namespace,
-google-default-arguments,
-google-readability-namespace-comments,
-google-readability-todo,
misc-*,
-misc-non-private-member-variables-in-classes,
-misc-unused-alias-decls,
-misc-unused-parameters,
modernize-*,
-modernize-avoid-c-arrays,
-modernize-use-nodiscard,
-modernize-use-trailing-return-type,
performance-*,
-performance-unnecessary-value-param,
portability-*,
readability-*,
-readability-convert-member-functions-to-static,
-readability-else-after-return,
-readability-implicit-bool-conversion,
-readability-magic-numbers,
-readability-named-parameter,
-readability-qualified-auto,
-readability-redundant-control-flow,
---
@@ -0,0 +1,42 @@
name: build
on:
push:
branches: [ main ]
paths:
- ".github/workflows/build.yml"
- "include/**"
- "src/**"
- "xmake.lua"
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
xmake:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
mode:
- debug
- release
toolchain:
- msvc
- clang-cl
steps:
- name: checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: setup
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: "latest"
- name: config
run: xmake config -y --mode=${{ matrix.mode }} --toolchain=${{ matrix.toolchain }}
- name: build
run: xmake build -y -vD
@@ -0,0 +1,21 @@
name: maintenance
on: push
jobs:
maintenance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Run clang-format
run: find -type f \( -name *.h -o -name *.cpp \) | xargs clang-format -style=file -i
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: maintenance
@@ -0,0 +1,14 @@
# dot folders
.cache/
.idea/
.vs/
.vscode/
.xmake/
# folders
build*/
vs*/
# files
*.zip
compile_commands.json
@@ -0,0 +1,36 @@
This Program is intended to be used with and to modify existing code
(the "Modded Code"). The purpose of this exception is to address issues
when an open source modding community interacts with potentially
proprietary code. In addition, the modding community often uses libraries
(the "Modding Libraries") under licenses that may be incompatible with
the GPL ("Modding Library Licenses").
Modding Exception
As an exception, the author gives You the additional right to link the
code of this Program with the existing code that this Program is
intended to be used with or modify and to distribute linked combinations
including the two, subject to the limitations in this paragraph. Modded
Code permitted under this exception may link to the code of this Program
without causing the Modded Code and portion of the combined work
corresponding to the Modded Code to be covered by the GNU General Public
License. You must obey the GNU General Public License in all respects for
all of the Program code and other code used in conjunction with the
Program except the Modded Code covered by this exception. If you modify
this file, you may extend this exception to your version of the file, but
you are not obligated to do so. If you do not wish to provide this
exception without modification, you must delete this exception statement
from your version and license this file solely under the GPL without
exception.
GPL-3.0 Linking Exception (with Corresponding Source)
Additional permission under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or combining
it with Modding Libraries (or a modified version thereof), containing
parts covered by the terms of Modding Library Licenses, the licensors of
this Program grant you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination shall
include the source code for the parts of Modding Libraries used as well as
that of the covered work.
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
@@ -0,0 +1,103 @@
#pragma once
#include "REX/BASE.h"
#pragma pack(push, 1)
namespace REL::ASM
{
template <std::uint8_t OP>
struct BRANCH5
{
explicit constexpr BRANCH5(const std::int32_t a_disp) :
disp(a_disp)
{}
explicit constexpr BRANCH5(const std::uintptr_t a_address, const std::uintptr_t a_fn) :
disp(static_cast<std::int32_t>(a_fn - (a_address + sizeof(BRANCH5))))
{}
static std::uintptr_t TARGET(const std::uintptr_t a_address)
{
const auto branch = reinterpret_cast<BRANCH5*>(a_address);
const auto begin = reinterpret_cast<std::uint8_t*>(a_address);
const auto address = (begin + sizeof(BRANCH5)) + branch->disp;
return reinterpret_cast<std::uintptr_t>(address);
}
std::uint8_t op{ OP }; // 0
std::int32_t disp; // 1
};
using CALL5 = BRANCH5<0xE8>;
static_assert(sizeof(CALL5) == 0x5);
using JMP5 = BRANCH5<0xE9>;
static_assert(sizeof(JMP5) == 0x5);
template <std::uint8_t RM>
struct BRANCH6
{
explicit constexpr BRANCH6(const std::int32_t a_disp) :
disp(a_disp)
{}
explicit constexpr BRANCH6(const std::uintptr_t a_address, const std::uintptr_t a_fn) :
disp(static_cast<std::int32_t>(a_fn - (a_address + sizeof(BRANCH6))))
{}
static std::uintptr_t TARGET(const std::uintptr_t a_address)
{
const auto branch = reinterpret_cast<BRANCH6*>(a_address);
const auto begin = reinterpret_cast<std::uint8_t*>(a_address);
const auto address = (begin + sizeof(BRANCH6)) + branch->disp;
return reinterpret_cast<std::uintptr_t>(address);
}
std::uint8_t op{ 0xFF }; // 0
std::uint8_t rm{ RM }; // 1
std::int32_t disp; // 2
};
using CALL6 = BRANCH6<0x15>;
static_assert(sizeof(CALL6) == 0x6);
using JMP6 = BRANCH6<0x25>;
static_assert(sizeof(JMP6) == 0x6);
struct CALL16
{
explicit constexpr CALL16(const std::uintptr_t a_addr) :
addr(a_addr)
{}
template <class T>
explicit constexpr CALL16(const T* a_fn) :
CALL16(reinterpret_cast<std::uintptr_t>(a_fn))
{}
CALL6 call{ 0x2 }; // 0 - 0x2
std::uint8_t op{ 0xEB }; // 6 - 0xEB
std::int8_t disp{ 0x8 }; // 7 - 0x8
std::uint64_t addr; // 8
};
static_assert(sizeof(CALL16) == 0x10);
struct JMP14
{
explicit constexpr JMP14(const std::uintptr_t a_addr) :
addr(a_addr)
{}
template <class T>
explicit constexpr JMP14(const T* a_fn) :
JMP14(reinterpret_cast<std::uintptr_t>(a_fn))
{}
JMP6 jmp{ 0x0 }; // 0 - 0x0
std::uint64_t addr; // 6 - [rip]
};
static_assert(sizeof(JMP14) == 0xE);
}
#pragma pack(pop)
@@ -0,0 +1,43 @@
#pragma once
#include "REX/BASE.h"
#include "REL/IHook.h"
namespace REL
{
class FHook :
public IHook
{
public:
FHook(const std::uintptr_t a_address);
FHook(const std::uintptr_t a_address, const char* a_name);
FHook(const std::uintptr_t a_address, const EHookType a_type);
FHook(const std::uintptr_t a_address, const EHookType a_type, const EHookStep a_step);
FHook(const std::uintptr_t a_address, const EHookStep a_step);
FHook(const std::uintptr_t a_address, const char* a_name, const EHookStep a_step);
FHook(const std::uintptr_t a_address, const char* a_name, const EHookType a_type);
FHook(const std::uintptr_t a_address, const char* a_name, const EHookType a_type, const EHookStep a_step);
~FHook();
virtual bool Init() override;
virtual FHookHandle GetHandle() const override;
virtual const char* GetName() const override;
virtual EHookType GetType() const override;
virtual EHookStep GetStep() const override;
virtual std::size_t GetSize() const override;
virtual std::size_t GetSizeTrampoline() const override;
virtual bool GetEnabled() const override;
protected:
std::uintptr_t m_address{ 0 };
std::string m_name;
FHookHandle m_handle;
EHookType m_type{ EHookType::None };
EHookStep m_step{ EHookStep::Load };
std::size_t m_size{ 8 };
std::size_t m_sizeTrampoline{ 0 };
bool m_enabled{ false };
};
}
@@ -0,0 +1,34 @@
#pragma once
#include "REL/IHook.h"
#include "REX/BASE.h"
#include "REX/TSingleton.h"
namespace REL
{
class FHookStore :
public REX::TSingleton<FHookStore>
{
public:
FHookHandle Add(IHook* a_hook);
void Remove(const FHookHandle a_handle);
void Init();
void Enable();
void Enable(const FHookHandle a_handle);
void Enable(const EHookType a_type);
void Enable(const EHookStep a_step);
void Disable();
void Disable(const FHookHandle a_handle);
void Disable(const EHookType a_type);
std::size_t GetSizeTrampoline();
private:
std::map<FHookHandle, IHook*> m_hooks;
std::queue<FHookHandle> m_hookQueue;
std::uint32_t m_handleCount{ 0 };
};
}
@@ -0,0 +1,36 @@
#pragma once
#include "REX/BASE.h"
#include "REX/CAST.h"
#include "REX/W32/BASE.h"
namespace REL
{
[[nodiscard, deprecated("Use 'REX::FModule' instead")]] std::uintptr_t GetIATAddr(std::string_view a_dll, std::string_view a_function);
[[nodiscard, deprecated("Use 'REX::FModule' instead")]] std::uintptr_t GetIATAddr(REX::W32::HMODULE a_module, std::string_view a_dll, std::string_view a_function);
[[nodiscard, deprecated("Use 'REX::FModule' instead")]] void* GetIATPtr(std::string_view a_dll, std::string_view a_function);
template <class T>
[[nodiscard, deprecated("Use 'REX::FModule' instead")]] T* GetIATPtr(std::string_view a_dll, std::string_view a_function)
{
return static_cast<T*>(GetIATPtr(std::move(a_dll), std::move(a_function)));
}
[[nodiscard, deprecated("Use 'REX::FModule' instead")]] void* GetIATPtr(REX::W32::HMODULE a_module, std::string_view a_dll, std::string_view a_function);
template <class T>
[[nodiscard, deprecated("Use 'REX::FModule' instead")]] T* GetIATPtr(REX::W32::HMODULE a_module, std::string_view a_dll, std::string_view a_function)
{
return static_cast<T*>(GetIATPtr(a_module, std::move(a_dll), std::move(a_function)));
}
[[deprecated("Use 'REX::FModule' instead")]] std::uintptr_t PatchIAT(std::uintptr_t a_newFunc, std::string_view a_dll, std::string_view a_function);
template <class F>
[[deprecated("Use 'REX::FModule' instead")]] std::uintptr_t PatchIAT(F a_newFunc, std::string_view a_dll, std::string_view a_function)
{
return PatchIAT(REX::UNRESTRICTED_CAST<std::uintptr_t>(a_newFunc), a_dll, a_function);
}
}
@@ -0,0 +1,44 @@
#pragma once
#include "REX/FModule.h"
#include "REL/IDDB.h"
namespace REL
{
class ID
{
public:
constexpr ID() noexcept = default;
explicit constexpr ID(std::uint64_t a_id) noexcept :
m_id(a_id)
{}
constexpr ID& operator=(std::uint64_t a_id) noexcept
{
m_id = a_id;
return *this;
}
[[nodiscard]] std::uintptr_t address() const
{
const auto mod = REX::FModule::GetExecutingModule();
return mod.GetBaseAddress() + offset();
}
[[nodiscard]] constexpr std::uint64_t id() const noexcept
{
return m_id;
}
[[nodiscard]] std::size_t offset() const
{
const auto iddb = IDDB::GetSingleton();
return iddb->offset(m_id);
}
private:
std::uint64_t m_id{ 0 };
};
}
@@ -0,0 +1,70 @@
#pragma once
#include "REX/BASE.h"
#include "REX/FMemoryMap.h"
#include "REX/TSingleton.h"
namespace REL
{
class IDDB :
public REX::TSingleton<IDDB>
{
public:
enum class Loader : std::uint32_t
{
None,
SKSE,
F4SE,
SFSE,
OBSE,
};
enum class Format : std::int32_t
{
None = std::numeric_limits<std::int32_t>::max(),
V0 = 0,
V1 = 1,
V2 = 2,
V5 = 5
};
struct MAPPING
{
std::uint64_t id;
std::uint64_t offset;
};
IDDB();
std::uint64_t offset(std::uint64_t a_id) const;
private:
class STREAM;
class HEADER_V2;
class HEADER_V5;
void load_v0();
void load_v2(STREAM& a_stream);
void load_v5(STREAM& a_stream);
void unpack_file(STREAM& a_stream, const HEADER_V2& a_header);
void validate_file();
protected:
friend class Offset2ID;
// clang-format off
template <class T> std::span<T> get_id2offset() const noexcept;
template <> std::span<MAPPING> get_id2offset() const noexcept { return m_v0; }
template <> std::span<std::uint32_t> get_id2offset() const noexcept { return m_v5; }
// clang-format on
private:
std::filesystem::path m_path;
Loader m_loader{ Loader::None };
Format m_format{ Format::None };
REX::FMemoryMap m_mmap;
std::span<MAPPING> m_v0;
std::span<std::uint32_t> m_v5;
};
}
@@ -0,0 +1,110 @@
#pragma once
namespace REL
{
using FHookHandle = std::uint32_t;
enum class EHookType : std::uint32_t
{
None = 0,
CALL5 = 2,
CALL6 = 3,
JMP5 = 4,
JMP6 = 5,
VFT = 6,
};
enum class EHookStep : std::uint32_t
{
None = 0,
PreLoad = 1,
Load = 2,
};
struct IHook
{
virtual bool Init() = 0;
virtual FHookHandle GetHandle() const = 0;
virtual const char* GetName() const = 0;
virtual EHookType GetType() const = 0;
virtual EHookStep GetStep() const = 0;
virtual std::size_t GetSize() const = 0;
virtual std::size_t GetSizeTrampoline() const = 0;
virtual bool GetEnabled() const = 0;
virtual bool Enable() = 0;
virtual bool Disable() = 0;
};
}
template <class T>
requires(std::is_base_of_v<REL::IHook, T>)
struct std::formatter<T>
{
template <class ParseContext>
constexpr auto parse(ParseContext& a_ctx)
{
return a_ctx.begin();
}
template <class FormatContext>
constexpr auto format(const T& a_hook, FormatContext& a_ctx) const
{
return format_to(a_ctx.out(), "Hook [{}]", a_hook.GetName());
}
};
template <>
struct std::formatter<REL::EHookType>
{
template <class ParseContext>
constexpr auto parse(ParseContext& a_ctx)
{
return a_ctx.begin();
}
template <class FormatContext>
constexpr auto format(const REL::EHookType& a_type, FormatContext& a_ctx) const
{
switch (a_type) {
case REL::EHookType::None:
return format_to(a_ctx.out(), "None");
case REL::EHookType::CALL5:
return format_to(a_ctx.out(), "CALL5");
case REL::EHookType::CALL6:
return format_to(a_ctx.out(), "CALL6");
case REL::EHookType::JMP5:
return format_to(a_ctx.out(), "JMP5");
case REL::EHookType::JMP6:
return format_to(a_ctx.out(), "JMP6");
case REL::EHookType::VFT:
return format_to(a_ctx.out(), "VFT");
}
return format_to(a_ctx.out(), "<Unknown>");
}
};
template <>
struct std::formatter<REL::EHookStep>
{
template <class ParseContext>
constexpr auto parse(ParseContext& a_ctx)
{
return a_ctx.begin();
}
template <class FormatContext>
constexpr auto format(const REL::EHookStep& a_step, FormatContext& a_ctx) const
{
switch (a_step) {
case REL::EHookStep::None:
return format_to(a_ctx.out(), "None");
case REL::EHookStep::PreLoad:
return format_to(a_ctx.out(), "PreLoad");
case REL::EHookStep::Load:
return format_to(a_ctx.out(), "Load");
}
return format_to(a_ctx.out(), "<Unknown>");
}
};
@@ -0,0 +1,36 @@
#pragma once
#include "REX/FModule.h"
namespace REL
{
class Offset
{
public:
constexpr Offset() noexcept = default;
explicit constexpr Offset(std::size_t a_offset) noexcept :
m_offset(a_offset)
{}
constexpr Offset& operator=(std::size_t a_offset) noexcept
{
m_offset = a_offset;
return *this;
}
[[nodiscard]] std::uintptr_t address() const
{
const auto mod = REX::FModule::GetExecutingModule();
return mod.GetBaseAddress() + offset();
}
[[nodiscard]] constexpr std::size_t offset() const noexcept
{
return m_offset;
}
private:
std::size_t m_offset{ 0 };
};
}
@@ -0,0 +1,40 @@
#pragma once
#include "REL/IDDB.h"
#include "REX/BASE.h"
namespace REL
{
class Offset2ID :
public REX::TSingleton<Offset2ID>
{
public:
using value_type = IDDB::MAPPING;
using container_type = std::vector<value_type>;
using size_type = typename container_type::size_type;
using const_iterator = typename container_type::const_iterator;
using const_reverse_iterator = typename container_type::const_reverse_iterator;
void load_v2();
void load_v5();
[[nodiscard]] std::uint64_t get_id(std::size_t a_offset) const;
[[nodiscard]] const_iterator begin() const noexcept { return _offset2id.begin(); }
[[nodiscard]] const_iterator cbegin() const noexcept { return _offset2id.cbegin(); }
[[nodiscard]] const_iterator end() const noexcept { return _offset2id.end(); }
[[nodiscard]] const_iterator cend() const noexcept { return _offset2id.cend(); }
[[nodiscard]] const_reverse_iterator rbegin() const noexcept { return _offset2id.rbegin(); }
[[nodiscard]] const_reverse_iterator crbegin() const noexcept { return _offset2id.crbegin(); }
[[nodiscard]] const_reverse_iterator rend() const noexcept { return _offset2id.rend(); }
[[nodiscard]] const_reverse_iterator crend() const noexcept { return _offset2id.crend(); }
[[nodiscard]] size_type size() const noexcept { return _offset2id.size(); }
private:
container_type _offset2id;
};
}
@@ -0,0 +1,220 @@
#pragma once
#include "REX/BASE.h"
#include "REX/FModule.h"
#include "REX/LOG.h"
#include "REX/TStaticString.h"
namespace REL
{
namespace detail
{
namespace characters
{
[[nodiscard]] constexpr bool hexadecimal(const char a_ch) noexcept
{
return ('0' <= a_ch && a_ch <= '9') || ('A' <= a_ch && a_ch <= 'F') ||
('a' <= a_ch && a_ch <= 'f');
}
[[nodiscard]] constexpr bool space(const char a_ch) noexcept
{
return a_ch == ' ';
}
[[nodiscard]] constexpr bool wildcard(const char a_ch) noexcept
{
return a_ch == '?';
}
}
namespace rules
{
namespace detail
{
[[nodiscard]] consteval std::byte hexacharacters_to_hexadecimal(
const char a_hi,
const char a_lo) noexcept
{
constexpr auto lut = []() noexcept {
std::array<
std::uint8_t,
std::numeric_limits<unsigned char>::max() + 1>
a = {};
const auto iterate =
[&](std::uint8_t a_iFirst,
unsigned char a_cFirst,
const unsigned char a_cLast) noexcept {
for (; a_cFirst <= a_cLast; ++a_cFirst, ++a_iFirst) {
a[a_cFirst] = a_iFirst;
}
};
iterate(0, '0', '9');
iterate(0xA, 'A', 'F');
iterate(0xa, 'a', 'f');
return a;
}();
return static_cast<std::byte>(
lut[static_cast<unsigned char>(a_hi)] * 0x10u +
lut[static_cast<unsigned char>(a_lo)]);
}
}
template <char HI, char LO>
class Hexadecimal
{
public:
[[nodiscard]] static constexpr bool match(const std::byte a_byte) noexcept
{
constexpr auto expected = detail::hexacharacters_to_hexadecimal(
HI,
LO);
return a_byte == expected;
}
};
static_assert(Hexadecimal<'5', '7'>::match(std::byte{ 0x57 }));
static_assert(Hexadecimal<'6', '5'>::match(std::byte{ 0x65 }));
static_assert(Hexadecimal<'B', 'D'>::match(std::byte{ 0xBD }));
static_assert(Hexadecimal<'1', 'C'>::match(std::byte{ 0x1C }));
static_assert(Hexadecimal<'F', '2'>::match(std::byte{ 0xF2 }));
static_assert(Hexadecimal<'9', 'f'>::match(std::byte{ 0x9f }));
static_assert(!Hexadecimal<'D', '4'>::match(std::byte{ 0xF8 }));
static_assert(!Hexadecimal<'6', '7'>::match(std::byte{ 0xAA }));
static_assert(!Hexadecimal<'7', '8'>::match(std::byte{ 0xE3 }));
static_assert(!Hexadecimal<'6', 'E'>::match(std::byte{ 0x61 }));
class Wildcard
{
public:
[[nodiscard]] static constexpr bool match(std::byte) noexcept
{
return true;
}
};
static_assert(Wildcard::match(std::byte{ 0xB9 }));
static_assert(Wildcard::match(std::byte{ 0x96 }));
static_assert(Wildcard::match(std::byte{ 0x35 }));
static_assert(Wildcard::match(std::byte{ 0xE4 }));
template <char, char>
void rule_for() noexcept;
template <char C1, char C2>
Hexadecimal<C1, C2> rule_for() noexcept
requires(characters::hexadecimal(C1) && characters::hexadecimal(C2));
template <char C1, char C2>
Wildcard rule_for() noexcept
requires(characters::wildcard(C1) && characters::wildcard(C2));
}
template <class... Rules>
class PatternMatcher
{
public:
static_assert(
sizeof...(Rules) >= 1,
"must provide at least 1 rule for the pattern matcher");
[[nodiscard]] constexpr bool match(
std::span<const std::byte, sizeof...(Rules)> a_bytes) const noexcept
{
std::size_t i = 0;
return (Rules::match(a_bytes[i++]) && ...);
}
[[nodiscard]] bool match(std::uintptr_t a_address) const noexcept
{
return this->match(
*reinterpret_cast<const std::byte(*)[sizeof...(Rules)]>(a_address));
}
void match_or_fail(
const std::uintptr_t a_address,
const std::source_location& a_loc = std::source_location::current())
const noexcept
{
if (!this->match(a_address)) {
const auto mod = REX::FModule::GetExecutingModule();
const auto modVersion = mod.GetFileVersion();
REX::FAIL(
a_loc,
"A pattern has failed to match.\n"
"This means the plugin is incompatible with either the "
"current version of the game ({}), or another "
"installed mod.",
modVersion.string());
}
}
};
void consteval_error(const char* a_error);
template <REX::TStaticString S, class... Rules>
[[nodiscard]] constexpr auto do_make_pattern() noexcept
{
if constexpr (S.length() == 0) {
return PatternMatcher<Rules...>();
} else if constexpr (S.length() == 1) {
constexpr char c = S[0];
if constexpr (characters::hexadecimal(c) || characters::wildcard(c)) {
consteval_error(
"the given pattern has an unpaired rule (rules are required to "
"be written in pairs of 2)");
} else {
consteval_error(
"the given pattern has trailing characters at the end (which is "
"not allowed)");
}
} else {
using rule_t = decltype(rules::rule_for<S[0], S[1]>());
if constexpr (std::same_as<rule_t, void>) {
consteval_error("the given pattern failed to match any known rules");
} else {
if constexpr (S.length() <= 3) {
return do_make_pattern<
S.template substr<2>(),
Rules...,
rule_t>();
} else if constexpr (characters::space(S[2])) {
return do_make_pattern<
S.template substr<3>(),
Rules...,
rule_t>();
} else {
consteval_error("a space character is required to split byte patterns");
}
}
}
}
template <class... Bytes>
[[nodiscard]] consteval auto make_byte_array(Bytes... a_bytes) noexcept
-> std::array<std::byte, sizeof...(Bytes)>
{
static_assert(
(std::integral<Bytes> && ...),
"all bytes must be an integral type");
return { static_cast<std::byte>(a_bytes)... };
}
}
template <REX::TStaticString S>
[[nodiscard]] constexpr auto Pattern() noexcept
{
return detail::do_make_pattern<S>();
};
static_assert(Pattern<"40 10 F2 ??">().match(
detail::make_byte_array(0x40, 0x10, 0xF2, 0x41)));
static_assert(Pattern<"B8 D0 ?? ?? D4 6E">().match(
detail::make_byte_array(0xB8, 0xD0, 0x35, 0x2A, 0xD4, 0x6E)));
}
@@ -0,0 +1,17 @@
#pragma once
#include "REL/ASM.h"
#include "REL/FHook.h"
#include "REL/FHookStore.h"
#include "REL/IAT.h"
#include "REL/ID.h"
#include "REL/IDDB.h"
#include "REL/IHook.h"
#include "REL/Offset.h"
#include "REL/Offset2ID.h"
#include "REL/Pattern.h"
#include "REL/Relocation.h"
#include "REL/THook.h"
#include "REL/Trampoline.h"
#include "REL/Utility.h"
#include "REL/Version.h"
@@ -0,0 +1,394 @@
#pragma once
#include "REX/BASE.h"
#include "REL/ASM.h"
#include "REL/ID.h"
#include "REL/Offset.h"
#include "REL/Trampoline.h"
#include "REL/Utility.h"
#include "REX/CAST.h"
#include "REX/FModule.h"
#define REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER_IMPL(a_nopropQual, a_propQual, ...) \
template < \
class R, \
class Cls, \
class... Args> \
struct member_function_pod_type<R (Cls::*)(Args...) __VA_ARGS__ a_nopropQual a_propQual> \
{ \
using type = R(__VA_ARGS__ Cls*, Args...) a_propQual; \
}; \
\
template < \
class R, \
class Cls, \
class... Args> \
struct member_function_pod_type<R (Cls::*)(Args..., ...) __VA_ARGS__ a_nopropQual a_propQual> \
{ \
using type = R(__VA_ARGS__ Cls*, Args..., ...) a_propQual; \
};
#define REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER(a_qualifer, ...) \
REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER_IMPL(a_qualifer, , ##__VA_ARGS__) \
REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER_IMPL(a_qualifer, noexcept, ##__VA_ARGS__)
#define REL_MAKE_MEMBER_FUNCTION_POD_TYPE(...) \
REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER(, __VA_ARGS__) \
REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER(&, ##__VA_ARGS__) \
REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER(&&, ##__VA_ARGS__)
#define REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER_IMPL(a_nopropQual, a_propQual, ...) \
template < \
class R, \
class Cls, \
class... Args> \
struct member_function_non_pod_type<R (Cls::*)(Args...) __VA_ARGS__ a_nopropQual a_propQual> \
{ \
using type = R&(__VA_ARGS__ Cls*, void*, Args...)a_propQual; \
}; \
\
template < \
class R, \
class Cls, \
class... Args> \
struct member_function_non_pod_type<R (Cls::*)(Args..., ...) __VA_ARGS__ a_nopropQual a_propQual> \
{ \
using type = R&(__VA_ARGS__ Cls*, void*, Args..., ...)a_propQual; \
};
#define REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER(a_qualifer, ...) \
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER_IMPL(a_qualifer, , ##__VA_ARGS__) \
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER_IMPL(a_qualifer, noexcept, ##__VA_ARGS__)
#define REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE(...) \
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER(, __VA_ARGS__) \
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER(&, ##__VA_ARGS__) \
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER(&&, ##__VA_ARGS__)
namespace REL
{
template <class>
class Relocation;
namespace detail
{
template <class>
struct member_function_pod_type;
REL_MAKE_MEMBER_FUNCTION_POD_TYPE();
REL_MAKE_MEMBER_FUNCTION_POD_TYPE(const);
REL_MAKE_MEMBER_FUNCTION_POD_TYPE(volatile);
REL_MAKE_MEMBER_FUNCTION_POD_TYPE(const volatile);
template <class F>
using member_function_pod_type_t = typename member_function_pod_type<F>::type;
template <class>
struct member_function_non_pod_type;
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE();
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE(const);
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE(volatile);
REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE(const volatile);
template <class F>
using member_function_non_pod_type_t = typename member_function_non_pod_type<F>::type;
// https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
template <class T>
struct meets_length_req :
std::disjunction<
std::bool_constant<sizeof(T) == 1>,
std::bool_constant<sizeof(T) == 2>,
std::bool_constant<sizeof(T) == 4>,
std::bool_constant<sizeof(T) == 8>>
{};
template <class T>
struct meets_function_req :
std::conjunction<
std::is_trivially_constructible<T>,
std::is_trivially_destructible<T>,
std::is_trivially_copy_assignable<T>,
std::negation<
std::is_polymorphic<T>>>
{};
template <class T>
struct meets_member_req :
std::is_standard_layout<T>
{};
template <class T, class = void>
struct is_x64_pod :
std::true_type
{};
template <class T>
struct is_x64_pod<
T,
std::enable_if_t<
std::is_union_v<T>>> :
std::false_type
{};
template <class T>
struct is_x64_pod<
T,
std::enable_if_t<
std::is_class_v<T>>> :
std::conjunction<
meets_length_req<T>,
meets_function_req<T>,
meets_member_req<T>>
{};
template <class T>
inline constexpr bool is_x64_pod_v = is_x64_pod<T>::value;
template <
class F,
class First,
class... Rest>
decltype(auto) invoke_member_function_non_pod(F&& a_func, First&& a_first, Rest&&... a_rest) //
noexcept(std::is_nothrow_invocable_v<F, First, Rest...>)
{
using result_t = std::invoke_result_t<F, First, Rest...>;
alignas(result_t) std::array<std::byte, sizeof(result_t)> result;
using func_t = member_function_non_pod_type_t<F>;
auto func = REX::UNRESTRICTED_CAST<func_t*>(std::forward<F>(a_func));
return func(std::forward<First>(a_first), std::addressof(result), std::forward<Rest>(a_rest)...);
}
}
inline constexpr std::uint8_t NOP = 0x90;
inline constexpr std::uint8_t RET = 0xC3;
inline constexpr std::uint8_t INT3 = 0xCC;
template <class F, class... Args>
std::invoke_result_t<F, Args...> invoke(F&& a_func, Args&&... a_args) //
noexcept(std::is_nothrow_invocable_v<F, Args...>) //
requires(std::invocable<F, Args...>)
{
if constexpr (std::is_member_function_pointer_v<std::decay_t<F>>) {
if constexpr (detail::is_x64_pod_v<std::invoke_result_t<F, Args...>>) { // member functions == free functions in x64
using func_t = detail::member_function_pod_type_t<std::decay_t<F>>;
auto func = REX::UNRESTRICTED_CAST<func_t*>(std::forward<F>(a_func));
return func(std::forward<Args>(a_args)...);
} else { // shift args to insert result
return detail::invoke_member_function_non_pod(std::forward<F>(a_func), std::forward<Args>(a_args)...);
}
} else {
return std::forward<F>(a_func)(std::forward<Args>(a_args)...);
}
}
template <class T = std::uintptr_t>
class Relocation
{
public:
using value_type =
std::conditional_t<
std::is_member_pointer_v<T> || std::is_function_v<std::remove_pointer_t<T>>,
std::decay_t<T>,
T>;
constexpr Relocation() noexcept = default;
explicit constexpr Relocation(std::uintptr_t a_address) noexcept :
_impl{ a_address }
{}
explicit Relocation(Offset a_offset) :
_impl{ a_offset.address() }
{}
explicit Relocation(ID a_id) :
_impl{ a_id.address() }
{}
explicit Relocation(ID a_id, std::ptrdiff_t a_offset) :
_impl{ a_id.address() + a_offset }
{}
explicit Relocation(ID a_id, Offset a_offset) :
_impl{ a_id.address() + a_offset.offset() }
{}
constexpr Relocation& operator=(std::uintptr_t a_address) noexcept
{
_impl = a_address;
return *this;
}
Relocation& operator=(Offset a_offset)
{
_impl = a_offset.address();
return *this;
}
Relocation& operator=(ID a_id)
{
_impl = a_id.address();
return *this;
}
template <class U = value_type>
[[nodiscard]] decltype(auto) operator*() const noexcept
requires(std::is_pointer_v<U>)
{
return *get();
}
template <class U = value_type>
[[nodiscard]] auto operator->() const noexcept
requires(std::is_pointer_v<U>)
{
return get();
}
[[nodiscard]] operator bool() const noexcept
{
return _impl != 0;
}
template <class... Args>
std::invoke_result_t<const value_type&, Args...> operator()(Args&&... a_args) const
noexcept(std::is_nothrow_invocable_v<const value_type&, Args...>)
requires(std::invocable<const value_type&, Args...>)
{
return REL::invoke(get(), std::forward<Args>(a_args)...);
}
[[nodiscard]] constexpr std::uintptr_t address() const noexcept { return _impl; }
[[nodiscard]] std::size_t offset() const { return _impl - base(); }
[[nodiscard]] value_type get() const
noexcept(std::is_nothrow_copy_constructible_v<value_type>)
{
assert(_impl != 0);
return REX::UNRESTRICTED_CAST<value_type>(_impl);
}
template <std::ptrdiff_t O = 0>
void replace_func(const std::size_t a_count, const std::uintptr_t a_dst)
requires(std::same_as<value_type, std::uintptr_t>)
{
ASM::JMP14 assembly(a_dst);
write_fill<O>(INT3, a_count);
write<O>(&assembly, sizeof(assembly));
}
template <std::ptrdiff_t O = 0, class F>
void replace_func(const std::size_t a_count, const F a_dst)
requires(std::same_as<value_type, std::uintptr_t>)
{
replace_func<O>(a_count, REX::UNRESTRICTED_CAST<std::uintptr_t>(a_dst));
}
template <std::ptrdiff_t O = 0>
void write(const void* a_src, std::size_t a_count)
requires(std::same_as<value_type, std::uintptr_t>)
{
WriteSafe(address() + O, a_src, a_count);
}
template <std::ptrdiff_t O = 0, std::integral U>
void write(const U& a_data)
requires(std::same_as<value_type, std::uintptr_t>)
{
WriteSafe(address() + O, std::addressof(a_data), sizeof(U));
}
template <std::ptrdiff_t O = 0>
void write(const std::initializer_list<std::uint8_t> a_data)
requires(std::same_as<value_type, std::uintptr_t>)
{
WriteSafe(address() + O, a_data.begin(), a_data.size());
}
template <std::ptrdiff_t O = 0, class U>
void write(const std::span<U> a_data)
requires(std::same_as<value_type, std::uintptr_t>)
{
WriteSafe(address() + O, a_data.data(), a_data.size_bytes());
}
template <std::size_t N, std::ptrdiff_t O = 0>
std::uintptr_t write_jmp(const std::uintptr_t a_dst)
requires(std::same_as<value_type, std::uintptr_t>)
{
return GetTrampoline().write_jmp<N>(address() + O, a_dst);
}
template <std::size_t N, std::ptrdiff_t O = 0, class F>
std::uintptr_t write_jmp(const F a_dst)
requires(std::same_as<value_type, std::uintptr_t>)
{
return GetTrampoline().write_jmp<N>(address() + O, REX::UNRESTRICTED_CAST<std::uintptr_t>(a_dst));
}
template <std::size_t N, std::ptrdiff_t O = 0>
std::uintptr_t write_call(const std::uintptr_t a_dst)
requires(std::same_as<value_type, std::uintptr_t>)
{
return GetTrampoline().write_call<N>(address() + O, a_dst);
}
template <std::size_t N, std::ptrdiff_t O = 0, class F>
std::uintptr_t write_call(const F a_dst)
requires(std::same_as<value_type, std::uintptr_t>)
{
return GetTrampoline().write_call<N>(address() + O, REX::UNRESTRICTED_CAST<std::uintptr_t>(a_dst));
}
template <std::ptrdiff_t O = 0>
void write_fill(const std::uint8_t a_value, const std::size_t a_count)
requires(std::same_as<value_type, std::uintptr_t>)
{
WriteSafeFill(address() + O, a_value, a_count);
}
template <class U = value_type>
std::uintptr_t write_vfunc(std::size_t a_idx, std::uintptr_t a_newFunc)
requires(std::same_as<U, std::uintptr_t>)
{
const auto addr = address() + (sizeof(void*) * a_idx);
const auto result = *reinterpret_cast<std::uintptr_t*>(addr);
WriteSafeData(addr, a_newFunc);
return result;
}
template <class F>
std::uintptr_t write_vfunc(std::size_t a_idx, F a_newFunc)
requires(std::same_as<value_type, std::uintptr_t>)
{
return write_vfunc(a_idx, REX::UNRESTRICTED_CAST<std::uintptr_t>(a_newFunc));
}
private:
// clang-format off
[[nodiscard]] static std::uintptr_t base()
{
const auto mod = REX::FModule::GetExecutingModule();
return mod.GetBaseAddress();
}
// clang-format on
std::uintptr_t _impl{ 0 };
};
}
#undef REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE
#undef REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER
#undef REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER_IMPL
#undef REL_MAKE_MEMBER_FUNCTION_POD_TYPE
#undef REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER
#undef REL_MAKE_MEMBER_FUNCTION_POD_TYPE_HELPER_IMPL
@@ -0,0 +1,361 @@
#pragma once
#include "REX/BASE.h"
#include "REL/ASM.h"
#include "REL/FHook.h"
#include "REL/ID.h"
#include "REL/Offset.h"
#include "REL/Trampoline.h"
#include "REL/Utility.h"
#include "REX/LOG.h"
namespace REL
{
template <class>
class THook;
template <class R, class... T>
class THook<R(T...)> :
public FHook
{
public:
explicit THook(const ID a_id, const std::ptrdiff_t a_diff, R (*a_function)(T...)) :
FHook(a_id.address() + a_diff)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
Detect();
}
explicit THook(const Offset a_offset, const std::ptrdiff_t a_diff, R (*a_function)(T...)) :
FHook(a_offset.address() + a_diff)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
Detect();
}
explicit THook(const EHookStep a_step, const ID a_id, const std::ptrdiff_t a_diff, R (*a_function)(T...)) :
FHook(a_id.address() + a_diff, a_step)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
Detect();
}
explicit THook(const EHookStep a_step, const Offset a_offset, const std::ptrdiff_t a_diff, R (*a_function)(T...)) :
FHook(a_offset.address() + a_diff, a_step)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
Detect();
}
explicit THook(const char* a_name, const ID a_id, const std::ptrdiff_t a_diff, R (*a_function)(T...)) :
FHook(a_id.address() + a_diff, a_name)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
Detect();
}
explicit THook(const char* a_name, const Offset a_offset, const std::ptrdiff_t a_diff, R (*a_function)(T...)) :
FHook(a_offset.address() + a_diff, a_name)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
Detect();
}
explicit THook(const char* a_name, const EHookStep a_step, const ID a_id, const std::ptrdiff_t a_diff, R (*a_function)(T...)) :
FHook(a_id.address() + a_diff, a_name, a_step)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
Detect();
}
explicit THook(const char* a_name, const EHookStep a_step, const Offset a_offset, const std::ptrdiff_t a_diff, R (*a_function)(T...)) :
FHook(a_offset.address() + a_diff, a_name, a_step)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
Detect();
}
virtual bool Init() override
{
if (m_type == EHookType::None) {
REX::ERROR("{}: could not determine hook type", *this);
return false;
}
REL::Write(std::span{ m_bytesOld }, m_address);
switch (m_type) {
case EHookType::CALL5: {
ASM::CALL5 assembly(m_address, GetTrampoline().allocate_branch5(m_function));
REL::WriteData(std::span{ m_bytes }, assembly);
} break;
case EHookType::CALL6: {
ASM::CALL6 assembly(m_address, GetTrampoline().allocate_branch6(m_function));
REL::WriteData(std::span{ m_bytes }, assembly);
} break;
case EHookType::JMP5: {
ASM::JMP5 assembly(m_address, GetTrampoline().allocate_branch5(m_function));
REL::WriteData(std::span{ m_bytes }, assembly);
} break;
case EHookType::JMP6: {
ASM::JMP6 assembly(m_address, GetTrampoline().allocate_branch6(m_function));
REL::WriteData(std::span{ m_bytes }, assembly);
} break;
}
REX::TRACE("{}: Init", *this);
return true;
}
virtual bool Enable() override
{
if (m_type == EHookType::None) {
REX::ERROR("{}: hook type is none", *this);
return false;
}
REL::WriteSafe(m_address, std::span{ m_bytes });
m_enabled = true;
REX::TRACE("{}: Enabled", *this);
return true;
}
virtual bool Disable() override
{
if (m_type == EHookType::None) {
REX::ERROR("{}: hook type is none", *this);
return false;
}
REL::WriteSafe(m_address, std::span{ m_bytesOld });
m_enabled = false;
REX::TRACE("{}: Disabled", *this);
return false;
}
R operator()(T... a_args) const
{
assert(m_functionOld);
return std::invoke(reinterpret_cast<std::decay_t<R(T...)>>(m_functionOld), a_args...);
}
private:
void Detect()
{
const auto op = reinterpret_cast<std::uint8_t*>(m_address);
switch (*op) {
case 0xE8: {
m_type = EHookType::CALL5;
m_size = sizeof(ASM::CALL5);
m_sizeTrampoline = sizeof(ASM::JMP14);
m_functionOld = ASM::CALL5::TARGET(m_address);
} break;
case 0xE9: {
m_type = EHookType::JMP5;
m_size = sizeof(ASM::JMP5);
m_sizeTrampoline = sizeof(ASM::JMP14);
m_functionOld = ASM::JMP5::TARGET(m_address);
} break;
case 0xFF: {
switch (*(op + 1)) {
case 0x15: {
m_type = EHookType::CALL6;
m_size = sizeof(ASM::CALL6);
m_sizeTrampoline = sizeof(std::uintptr_t);
m_functionOld = ASM::CALL6::TARGET(m_address);
} break;
case 0x25: {
m_type = EHookType::JMP6;
m_size = sizeof(ASM::JMP6);
m_sizeTrampoline = sizeof(std::uintptr_t);
m_functionOld = ASM::JMP6::TARGET(m_address);
} break;
}
} break;
}
m_bytes.resize(m_size);
m_bytesOld.resize(m_size);
}
private:
std::uintptr_t m_function;
std::uintptr_t m_functionOld;
std::vector<std::byte> m_bytes;
std::vector<std::byte> m_bytesOld;
};
template <class R, class... T>
THook(const ID, const std::uint64_t, R (*)(T...)) -> THook<R(T...)>;
template <class R, class... T>
THook(const Offset, const std::uint64_t, R (*)(T...)) -> THook<R(T...)>;
template <class R, class... T>
THook(const EHookStep, const ID, const std::uint64_t, R (*)(T...)) -> THook<R(T...)>;
template <class R, class... T>
THook(const EHookStep, const Offset, const std::uint64_t, R (*)(T...)) -> THook<R(T...)>;
template <class R, class... T>
THook(const char*, const ID, const std::uint64_t, R (*)(T...)) -> THook<R(T...)>;
template <class R, class... T>
THook(const char*, const Offset, const std::uint64_t, R (*)(T...)) -> THook<R(T...)>;
template <class R, class... T>
THook(const char*, const EHookStep, const ID, const std::uint64_t, R (*)(T...)) -> THook<R(T...)>;
template <class R, class... T>
THook(const char*, const EHookStep, const Offset, const std::uint64_t, R (*)(T...)) -> THook<R(T...)>;
template <class T>
using Hook [[deprecated("Renamed to 'REL::THook'")]] = THook<T>;
}
namespace REL
{
template <class>
class THookVFT;
template <class R, class... T>
class THookVFT<R(T...)> :
public FHook
{
public:
explicit THookVFT(const ID a_id, const std::size_t a_idx, R (*a_function)(T...)) :
FHook(a_id.address() + (sizeof(void*) * a_idx), EHookType::VFT)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
m_functionOld = *reinterpret_cast<std::uintptr_t*>(m_address);
}
explicit THookVFT(const Offset a_offset, const std::size_t a_idx, R (*a_function)(T...)) :
FHook(a_offset.address() + (sizeof(void*) * a_idx), EHookType::VFT)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
m_functionOld = *reinterpret_cast<std::uintptr_t*>(m_address);
}
explicit THookVFT(const EHookStep a_step, const ID a_id, const std::size_t a_idx, R (*a_function)(T...)) :
FHook(a_id.address() + (sizeof(void*) * a_idx), EHookType::VFT, a_step)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
m_functionOld = *reinterpret_cast<std::uintptr_t*>(m_address);
}
explicit THookVFT(const EHookStep a_step, const Offset a_offset, const std::size_t a_idx, R (*a_function)(T...)) :
FHook(a_offset.address() + (sizeof(void*) * a_idx), EHookType::VFT, a_step)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
m_functionOld = *reinterpret_cast<std::uintptr_t*>(m_address);
}
explicit THookVFT(const char* a_name, const ID a_id, const std::size_t a_idx, R (*a_function)(T...)) :
FHook(a_id.address() + (sizeof(void*) * a_idx), a_name, EHookType::VFT)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
m_functionOld = *reinterpret_cast<std::uintptr_t*>(m_address);
}
explicit THookVFT(const char* a_name, const Offset a_offset, const std::size_t a_idx, R (*a_function)(T...)) :
FHook(a_offset.address() + (sizeof(void*) * a_idx), a_name, EHookType::VFT)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
m_functionOld = *reinterpret_cast<std::uintptr_t*>(m_address);
}
explicit THookVFT(const char* a_name, const EHookStep a_step, const ID a_id, const std::size_t a_idx, R (*a_function)(T...)) :
FHook(a_id.address() + (sizeof(void*) * a_idx), a_name, EHookType::VFT, a_step)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
m_functionOld = *reinterpret_cast<std::uintptr_t*>(m_address);
}
explicit THookVFT(const char* a_name, const EHookStep a_step, const Offset a_offset, const std::size_t a_idx, R (*a_function)(T...)) :
FHook(a_offset.address() + (sizeof(void*) * a_idx), a_name, EHookType::VFT, a_step)
{
m_function = reinterpret_cast<std::uintptr_t>(a_function);
m_functionOld = *reinterpret_cast<std::uintptr_t*>(m_address);
}
virtual bool Enable() override
{
if (!m_address) {
REX::ERROR("{}: address is null", *this);
return false;
}
REL::WriteSafeData(m_address, m_function);
m_enabled = true;
REX::TRACE("{}: Enabled", *this);
return true;
}
virtual bool Disable() override
{
if (!m_address) {
REX::ERROR("{}: address is null", *this);
return false;
}
REL::WriteSafeData(m_address, m_functionOld);
m_enabled = false;
REX::TRACE("{}: Disabled", *this);
return true;
}
R operator()(T... a_args) const
{
assert(m_functionOld);
return std::invoke(reinterpret_cast<std::decay_t<R(T...)>>(m_functionOld), a_args...);
}
private:
std::uintptr_t m_function;
std::uintptr_t m_functionOld;
};
template <class R, class... T>
THookVFT(const ID, const std::size_t, R (*)(T...)) -> THookVFT<R(T...)>;
template <class R, class... T>
THookVFT(const Offset, const std::size_t, R (*)(T...)) -> THookVFT<R(T...)>;
template <class R, class... T>
THookVFT(const EHookStep, const ID, const std::size_t, R (*)(T...)) -> THookVFT<R(T...)>;
template <class R, class... T>
THookVFT(const EHookStep, const Offset, const std::size_t, R (*)(T...)) -> THookVFT<R(T...)>;
template <class R, class... T>
THookVFT(const char*, const ID, const std::size_t, R (*)(T...)) -> THookVFT<R(T...)>;
template <class R, class... T>
THookVFT(const char*, const Offset, const std::size_t, R (*)(T...)) -> THookVFT<R(T...)>;
template <class R, class... T>
THookVFT(const char*, const EHookStep, const ID, const std::size_t, R (*)(T...)) -> THookVFT<R(T...)>;
template <class R, class... T>
THookVFT(const char*, const EHookStep, const Offset, const std::size_t, R (*)(T...)) -> THookVFT<R(T...)>;
template <class T>
using HookVFT [[deprecated("Renamed to 'REL::THookVFT'")]] = THookVFT<T>;
}
@@ -0,0 +1,131 @@
#pragma once
#include "REX/BASE.h"
#include "REX/CAST.h"
#ifdef COMMONLIB_OPTION_XBYAK
namespace Xbyak
{
class CodeGenerator;
}
#endif
namespace REL
{
class Trampoline
{
public:
using deleter_type = std::function<void(void* a_mem, std::size_t a_size)>;
Trampoline() noexcept = default;
Trampoline(const Trampoline&) = delete;
Trampoline(Trampoline&& a_rhs) noexcept;
Trampoline(const std::string_view a_name) :
m_name(a_name)
{}
~Trampoline() noexcept
{
release();
}
Trampoline& operator=(const Trampoline&) = delete;
Trampoline& operator=(Trampoline&& a_rhs) noexcept
{
if (this != std::addressof(a_rhs)) {
m_branch5 = std::move(a_rhs.m_branch5);
m_branch6 = std::move(a_rhs.m_branch6);
m_name = std::move(a_rhs.m_name);
m_deleter = std::move(a_rhs.m_deleter);
m_data = std::exchange(a_rhs.m_data, nullptr);
m_capacity = std::exchange(a_rhs.m_capacity, 0);
m_size = std::exchange(a_rhs.m_size, 0);
}
return *this;
}
public:
void create(const std::size_t a_size, void* a_module = nullptr);
void set_trampoline(void* a_trampoline, const std::size_t a_size, deleter_type a_deleter = {});
[[nodiscard]] void* allocate(const std::size_t a_size);
#ifdef COMMONLIB_OPTION_XBYAK
[[nodiscard]] void* allocate(const Xbyak::CodeGenerator& a_code);
#endif
template <class T, class... Args>
[[nodiscard]] T* allocate(Args&&... a_args)
{
auto mem = allocate(sizeof(T));
return new (mem) T(std::forward<Args>(a_args)...);
}
[[nodiscard]] constexpr std::size_t empty() const noexcept { return m_capacity == 0; }
[[nodiscard]] constexpr std::size_t capacity() const noexcept { return m_capacity; }
[[nodiscard]] constexpr std::size_t allocated_size() const noexcept { return m_size; }
[[nodiscard]] constexpr std::size_t free_size() const noexcept { return m_capacity - m_size; }
template <std::size_t N>
std::uintptr_t write_call(const std::uintptr_t a_src, const std::uintptr_t a_dst)
{
if constexpr (N == 5)
return write_call5(a_src, a_dst);
else if constexpr (N == 6)
return write_call6(a_src, a_dst);
else
static_assert(false && N, "invalid call size");
}
template <std::size_t N, class F>
std::uintptr_t write_call(const std::uintptr_t a_src, F a_dst)
{
return write_call<N>(a_src, REX::UNRESTRICTED_CAST<std::uintptr_t>(a_dst));
}
template <std::size_t N>
std::uintptr_t write_jmp(const std::uintptr_t a_src, const std::uintptr_t a_dst)
{
if constexpr (N == 5)
return write_jmp5(a_src, a_dst);
else if constexpr (N == 6)
return write_jmp6(a_src, a_dst);
else
static_assert(false && N, "invalid jmp size");
}
template <std::size_t N, class F>
std::uintptr_t write_jmp(const std::uintptr_t a_src, F a_dst)
{
return write_jmp<N>(a_src, REX::UNRESTRICTED_CAST<std::uintptr_t>(a_dst));
}
std::uintptr_t write_call5(const std::uintptr_t a_src, const std::uintptr_t a_dst);
std::uintptr_t write_call6(const std::uintptr_t a_src, const std::uintptr_t a_dst);
std::uintptr_t write_jmp5(const std::uintptr_t a_src, const std::uintptr_t a_dst);
std::uintptr_t write_jmp6(const std::uintptr_t a_src, const std::uintptr_t a_dst);
std::uintptr_t allocate_branch5(const std::uintptr_t a_dst);
std::uintptr_t allocate_branch6(const std::uintptr_t a_dst);
private:
void release();
void stats() const;
private:
std::map<std::uintptr_t, std::byte*> m_branch5;
std::map<std::uintptr_t, std::byte*> m_branch6;
std::string m_name{ "Default"sv };
deleter_type m_deleter;
std::byte* m_data{ nullptr };
std::size_t m_capacity{ 0 };
std::size_t m_size{ 0 };
};
[[nodiscard]] Trampoline& GetTrampoline() noexcept;
}
@@ -0,0 +1,98 @@
#pragma once
#include "REX/BASE.h"
namespace REL
{
void Write(void* a_dst, const void* a_src, const std::size_t a_size);
void Write(const std::uintptr_t a_dst, const void* a_src, const std::size_t a_size);
template <class T>
void Write(void* a_dst, const std::span<T> a_src)
{
Write(a_dst, a_src.data(), a_src.size_bytes());
}
template <class T>
void Write(const std::uintptr_t a_dst, const std::span<T> a_src)
{
Write(reinterpret_cast<void*>(a_dst), a_src.data(), a_src.size_bytes());
}
template <class T>
void Write(const std::span<T> a_dst, const void* a_src)
{
Write(a_dst.data(), a_src, a_dst.size_bytes());
}
template <class T>
void Write(const std::span<T> a_dst, const std::uintptr_t a_src)
{
Write(a_dst.data(), reinterpret_cast<void*>(a_src), a_dst.size_bytes());
}
template <class T>
void WriteData(void* a_dst, const T& a_src)
{
Write(a_dst, std::addressof(a_src), sizeof(T));
}
template <class T>
void WriteData(const std::uintptr_t a_dst, const T& a_src)
{
Write(reinterpret_cast<void*>(a_dst), std::addressof(a_src), sizeof(T));
}
template <class T1, class T2>
void WriteData(const std::span<T1> a_dst, const T2& a_src)
{
Write(a_dst.data(), std::addressof(a_src), a_dst.size_bytes());
}
bool WriteSafe(void* a_dst, const void* a_src, const std::size_t a_size);
bool WriteSafe(const std::uintptr_t a_dst, const void* a_src, const std::size_t a_size);
bool WriteSafeFill(void* a_dst, const std::uint8_t a_value, const std::size_t a_size);
bool WriteSafeFill(const std::uintptr_t a_dst, const std::uint8_t a_value, const std::size_t a_size);
template <class T>
bool WriteSafe(void* a_dst, const std::span<T> a_src)
{
return WriteSafe(a_dst, a_src.data(), a_src.size_bytes());
}
template <class T>
bool WriteSafe(const std::uintptr_t a_dst, const std::span<T> a_src)
{
return WriteSafe(reinterpret_cast<void*>(a_dst), a_src.data(), a_src.size_bytes());
}
template <class T>
bool WriteSafe(const std::span<T> a_dst, const void* a_src)
{
return WriteSafe(a_dst.data(), a_src, a_dst.size_bytes());
}
template <class T>
bool WriteSafe(const std::span<T> a_dst, const std::uintptr_t a_src)
{
return WriteSafe(a_dst.data(), reinterpret_cast<void*>(a_src), a_dst.size_bytes());
}
template <class T>
bool WriteSafeData(void* a_dst, const T& a_src)
{
return WriteSafe(a_dst, std::addressof(a_src), sizeof(T));
}
template <class T>
bool WriteSafeData(const std::uintptr_t a_dst, const T& a_src)
{
return WriteSafe(reinterpret_cast<void*>(a_dst), std::addressof(a_src), sizeof(T));
}
template <class T1, class T2>
bool WriteSafeData(const std::span<T1> a_dst, const T2& a_src)
{
return WriteSafe(a_dst.data(), std::addressof(a_src), a_dst.size_bytes());
}
}
@@ -0,0 +1,129 @@
#pragma once
#include "REX/BASE.h"
namespace REL
{
template <typename T>
class VersionBase
{
public:
using value_type = std::uint16_t;
using reference = value_type&;
using const_reference = const value_type&;
constexpr VersionBase() noexcept = default;
explicit constexpr VersionBase(std::array<value_type, 4> a_version) noexcept :
_impl(a_version)
{}
constexpr VersionBase(value_type a_v1, value_type a_v2 = 0, value_type a_v3 = 0, value_type a_v4 = 0) noexcept :
_impl{ a_v1, a_v2, a_v3, a_v4 }
{}
[[nodiscard]] constexpr reference operator[](std::size_t a_idx) noexcept { return _impl[a_idx]; }
[[nodiscard]] constexpr const_reference operator[](std::size_t a_idx) const noexcept { return _impl[a_idx]; }
[[nodiscard]] constexpr decltype(auto) begin() const noexcept { return _impl.begin(); }
[[nodiscard]] constexpr decltype(auto) cbegin() const noexcept { return _impl.cbegin(); }
[[nodiscard]] constexpr decltype(auto) end() const noexcept { return _impl.end(); }
[[nodiscard]] constexpr decltype(auto) cend() const noexcept { return _impl.cend(); }
[[nodiscard]] std::strong_ordering constexpr compare(const VersionBase& a_rhs) const noexcept
{
for (std::size_t i = 0; i < _impl.size(); ++i) {
if ((*this)[i] != a_rhs[i]) {
return (*this)[i] < a_rhs[i] ? std::strong_ordering::less : std::strong_ordering::greater;
}
}
return std::strong_ordering::equal;
}
[[nodiscard]] constexpr std::uint32_t pack() const noexcept
{
return static_cast<std::uint32_t>(
(_impl[0] & T::AND_MAJOR) << T::SHL_MAJOR |
(_impl[1] & T::AND_MINOR) << T::SHL_MINOR |
(_impl[2] & T::AND_PATCH) << T::SHL_PATCH |
(_impl[3] & T::AND_BUILD) << T::SHL_BUILD);
}
[[nodiscard]] constexpr value_type major() const noexcept { return _impl[0]; }
[[nodiscard]] constexpr value_type minor() const noexcept { return _impl[1]; }
[[nodiscard]] constexpr value_type patch() const noexcept { return _impl[2]; }
[[nodiscard]] constexpr value_type build() const noexcept { return _impl[3]; }
[[nodiscard]] constexpr std::string string(const std::string_view a_separator = "."sv) const
{
std::string result;
for (auto&& ver : _impl) {
result += std::to_string(ver);
result.append(a_separator.data(), a_separator.size());
}
result.erase(result.size() - a_separator.size(), a_separator.size());
return result;
}
[[nodiscard]] constexpr std::wstring wstring(const std::wstring_view a_separator = L"."sv) const
{
std::wstring result;
for (auto&& ver : _impl) {
result += std::to_wstring(ver);
result.append(a_separator.data(), a_separator.size());
}
result.erase(result.size() - a_separator.size(), a_separator.size());
return result;
}
[[nodiscard]] static constexpr VersionBase unpack(const std::uint32_t a_packedVersion) noexcept
{
return VersionBase{
static_cast<value_type>((a_packedVersion >> T::SHL_MAJOR) & T::AND_MAJOR),
static_cast<value_type>((a_packedVersion >> T::SHL_MINOR) & T::AND_MINOR),
static_cast<value_type>((a_packedVersion >> T::SHL_PATCH) & T::AND_PATCH),
static_cast<value_type>((a_packedVersion >> T::SHL_BUILD) & T::AND_BUILD)
};
}
[[nodiscard]] friend constexpr bool operator==(const VersionBase& a_lhs, const VersionBase& a_rhs) noexcept
{
return a_lhs.compare(a_rhs) == 0;
}
[[nodiscard]] friend constexpr std::strong_ordering operator<=>(const VersionBase& a_lhs, const VersionBase& a_rhs) noexcept
{
return a_lhs.compare(a_rhs);
}
private:
std::array<value_type, 4> _impl{ 0, 0, 0, 0 };
};
struct VersionPackInfo
{
static constexpr auto AND_MAJOR{ 0x0FF };
static constexpr auto AND_MINOR{ 0x0FF };
static constexpr auto AND_PATCH{ 0xFFF };
static constexpr auto AND_BUILD{ 0x00F };
static constexpr auto SHL_MAJOR{ 8 * 3 };
static constexpr auto SHL_MINOR{ 8 * 2 };
static constexpr auto SHL_PATCH{ 8 / 2 };
static constexpr auto SHL_BUILD{ 8 * 0 };
};
using Version = VersionBase<VersionPackInfo>;
[[nodiscard]] std::optional<Version> GetFileVersion(std::string_view a_filename);
[[nodiscard]] std::optional<Version> GetFileVersion(std::wstring_view a_filename);
}
template <typename T, class CharT>
struct std::formatter<REL::VersionBase<T>, CharT> : formatter<std::string, CharT>
{
template <class FormatContext>
constexpr auto format(const REL::VersionBase<T>& a_version, FormatContext& a_ctx) const
{
return formatter<std::string, CharT>::format(a_version.string(), a_ctx);
}
};
@@ -0,0 +1,74 @@
#pragma once
#include <algorithm>
#include <array>
#include <atomic>
#include <bit>
#include <bitset>
#include <cassert>
#include <cmath>
#include <compare>
#include <concepts>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <execution>
#include <filesystem>
#include <format>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <intrin.h>
#include <iomanip>
#include <ios>
#include <istream>
#include <iterator>
#include <limits>
#include <locale>
#include <map>
#include <memory>
#include <mutex>
#include <new>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <ranges>
#include <regex>
#include <set>
#include <source_location>
#include <span>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <string>
#include <string_view>
#include <system_error>
#include <thread>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>
static_assert(std::is_integral_v<std::time_t> && sizeof(std::time_t) == sizeof(std::size_t), "wrap std::time_t instead");
namespace REX
{
using namespace std::literals;
}
namespace REL
{
using namespace std::literals;
}
@@ -0,0 +1,72 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
template <class T, class U>
[[nodiscard]] auto ADJUST_POINTER(U* a_ptr, std::ptrdiff_t a_adjust) noexcept
{
auto addr = a_ptr ? reinterpret_cast<std::uintptr_t>(a_ptr) + a_adjust : 0;
if constexpr (std::is_const_v<U> && std::is_volatile_v<U>) {
return reinterpret_cast<std::add_cv_t<T>*>(addr);
} else if constexpr (std::is_const_v<U>) {
return reinterpret_cast<std::add_const_t<T>*>(addr);
} else if constexpr (std::is_volatile_v<U>) {
return reinterpret_cast<std::add_volatile_t<T>*>(addr);
} else {
return reinterpret_cast<T*>(addr);
}
}
template <class T>
void EMPLACE_VTABLE(T* a_ptr)
{
reinterpret_cast<std::uintptr_t*>(a_ptr)[0] = T::VTABLE[0].address();
}
template <class T>
void MEM_WRITE_ZERO(volatile T* a_ptr, std::size_t a_size = sizeof(T))
{
std::fill_n(reinterpret_cast<volatile char*>(a_ptr), a_size, '\0');
}
template <class T1, class T2>
[[nodiscard]] T1 UNRESTRICTED_CAST(T2 a_from)
{
if constexpr (std::is_same_v<
std::remove_cv_t<T2>,
std::remove_cv_t<T1>>) {
return T1{ a_from };
// From != To
} else if constexpr (std::is_reference_v<T2>) {
return unrestricted_cast<T1>(std::addressof(a_from));
// From: NOT reference
} else if constexpr (std::is_reference_v<T1>) {
return *unrestricted_cast<
std::add_pointer_t<
std::remove_reference_t<T1>>>(a_from);
// To: NOT reference
} else if constexpr (std::is_pointer_v<T2> &&
std::is_pointer_v<T1>) {
return static_cast<T1>(
const_cast<void*>(
static_cast<const volatile void*>(a_from)));
} else if constexpr ((std::is_pointer_v<T2> && std::is_integral_v<T1>) ||
(std::is_integral_v<T2> && std::is_pointer_v<T1>)) {
return reinterpret_cast<T1>(a_from);
} else {
union
{
std::remove_cv_t<std::remove_reference_t<T2>> from;
std::remove_cv_t<std::remove_reference_t<T1>> to;
};
from = std::forward<T2>(a_from);
return to;
}
}
}
@@ -0,0 +1,80 @@
#pragma once
#include "REX/BASE.h"
#include "REX/W32/KERNEL32.h"
namespace REX
{
template <class U, class... T>
U BITS_TO_VALUE(T... a_args)
requires(std::same_as<std::remove_cv_t<T>, bool> && ...)
{
constexpr auto ARGC = sizeof...(T);
std::bitset<ARGC> bits;
std::size_t i = 0;
((bits[i++] = a_args), ...);
if constexpr (ARGC <= std::numeric_limits<std::uint32_t>::digits) {
return static_cast<U>(bits.to_ulong());
} else if constexpr (ARGC <= std::numeric_limits<std::uint64_t>::digits) {
return static_cast<U>(bits.to_ullong());
} else {
static_assert(false && sizeof...(T));
}
}
inline bool UTF8_TO_UTF16(const std::string_view a_in, std::wstring& a_out) noexcept
{
const auto cvt = [&](wchar_t* a_dst, std::size_t a_length) {
return REX::W32::MultiByteToWideChar(
REX::W32::CP_UTF8,
0,
a_in.data(),
static_cast<int>(a_in.length()),
a_dst,
static_cast<int>(a_length));
};
const auto len = cvt(nullptr, 0);
if (len == 0) {
return false;
}
std::wstring out(len, '\0');
if (cvt(out.data(), out.length()) == 0) {
return false;
}
a_out = out;
return true;
}
inline bool UTF16_TO_UTF8(const std::wstring_view a_in, std::string& a_out) noexcept
{
const auto cvt = [&](char* a_dst, std::size_t a_length) {
return REX::W32::WideCharToMultiByte(
REX::W32::CP_UTF8,
0,
a_in.data(),
static_cast<int>(a_in.length()),
a_dst,
static_cast<int>(a_length),
nullptr,
nullptr);
};
const auto len = cvt(nullptr, 0);
if (len == 0) {
return false;
}
std::string out(len, '\0');
if (cvt(out.data(), out.length()) == 0) {
return false;
}
a_out = out;
return true;
}
}
@@ -0,0 +1,25 @@
#pragma once
#ifdef COMMONLIB_OPTION_INI
# include "REX/FSettingStore.h"
# include "REX/TSingleton.h"
namespace REX
{
class FIniSettingStore :
public FSettingStore,
public TSingleton<FIniSettingStore>
{
public:
virtual void Load() override;
virtual void Save() override;
};
}
namespace REX::INI
{
using SettingStore [[deprecated("Renamed to 'REX::FIniSettingStore'")]] = FIniSettingStore;
}
#endif
@@ -0,0 +1,25 @@
#pragma once
#ifdef COMMONLIB_OPTION_JSON
# include "REX/FSettingStore.h"
# include "REX/TSingleton.h"
namespace REX
{
class FJsonSettingStore :
public FSettingStore,
public TSingleton<FJsonSettingStore>
{
public:
virtual void Load() override;
virtual void Save() override;
};
}
namespace REX::JSON
{
using SettingStore [[deprecated("Renamed to 'REX::FJsonSettingStore")]] = FJsonSettingStore;
}
#endif
@@ -0,0 +1,134 @@
#pragma once
#include "REX/W32/KERNEL32.h"
namespace REX
{
class FMemoryMap
{
static constexpr auto DYNAMIC_SIZE{ static_cast<std::size_t>(-1) };
public:
FMemoryMap() = default;
~FMemoryMap() { close(); }
public:
void close()
{
if (m_mapView) {
REX::W32::UnmapViewOfFile(m_mapView);
m_mapView = nullptr;
}
if (m_map) {
REX::W32::CloseHandle(m_map);
m_map = nullptr;
}
if (m_file != REX::W32::INVALID_HANDLE_VALUE) {
REX::W32::CloseHandle(m_file);
m_file = nullptr;
}
m_size = 0;
m_owner = false;
}
std::byte* data() const noexcept
{
return static_cast<std::byte*>(m_mapView);
}
std::size_t size() const noexcept
{
return m_size;
}
bool is_open() const
{
return m_mapView;
}
bool is_owner() const
{
return m_owner;
}
bool is_file() const
{
return m_file != REX::W32::INVALID_HANDLE_VALUE;
}
bool create(bool a_write, const std::string_view a_name, std::size_t a_size)
{
close();
if (create_impl(a_write, a_name, a_size))
return true;
close();
return false;
}
bool create(bool a_write, std::filesystem::path a_path, const std::string_view a_name, std::size_t a_size = DYNAMIC_SIZE)
{
close();
const auto access = a_write ? REX::W32::GENERIC_READ | REX::W32::GENERIC_WRITE : REX::W32::GENERIC_READ;
const auto share = a_write ? REX::W32::FILE_SHARE_READ | REX::W32::FILE_SHARE_WRITE : REX::W32::FILE_SHARE_READ;
m_file = REX::W32::CreateFileW(a_path.c_str(), access, share, nullptr, REX::W32::OPEN_EXISTING, REX::W32::FILE_ATTRIBUTE_READONLY, nullptr);
if (m_file == REX::W32::INVALID_HANDLE_VALUE)
return false;
if (create_impl(a_write, a_name, a_size))
return true;
close();
return false;
}
private:
bool create_impl(bool a_write, const std::string_view a_name, std::size_t a_size)
{
REX::W32::LARGE_INTEGER size;
if (a_size == DYNAMIC_SIZE) {
if (m_file == REX::W32::INVALID_HANDLE_VALUE)
return false;
if (REX::W32::GetFileSizeEx(m_file, &size) == 0)
return false;
} else {
size.value = a_size;
}
const auto access = a_write ? REX::W32::FILE_MAP_READ | REX::W32::FILE_MAP_WRITE : REX::W32::FILE_MAP_READ;
m_map = REX::W32::OpenFileMappingA(access, false, a_name.data());
if (!m_map) {
const auto protect = a_write ? REX::W32::PAGE_READWRITE : REX::W32::PAGE_READONLY;
m_map = REX::W32::CreateFileMappingA(m_file, nullptr, protect, size.hi, size.lo, a_name.data());
if (!m_map)
return false;
m_owner = true;
}
m_mapView = REX::W32::MapViewOfFile(m_map, access, 0, 0, size.value);
if (!m_mapView)
return false;
m_size = static_cast<std::size_t>(size.value);
return true;
}
private:
void* m_file{ REX::W32::INVALID_HANDLE_VALUE };
void* m_map{ nullptr };
void* m_mapView{ nullptr };
std::size_t m_size{ 0 };
bool m_owner{ false };
};
using MemoryMap [[deprecated("Renamed to 'REX::FMemoryMap'")]] = FMemoryMap;
}
@@ -0,0 +1,59 @@
#pragma once
#include "REX/BASE.h"
#include "REL/Version.h"
#include "REX/FModuleSection.h"
#include "REX/W32/BASE.h"
namespace REX
{
class FModule
{
public:
constexpr FModule() = default;
explicit FModule(W32::HMODULE a_module) :
m_base(reinterpret_cast<std::uintptr_t>(a_module))
{}
static FModule GetCurrentModule();
static FModule GetExecutingModule();
static FModule GetLoadedModule(std::string_view a_name);
[[nodiscard]] std::string GetFileName() const noexcept;
[[nodiscard]] REL::Version GetFileVersion() const noexcept;
[[nodiscard]] void* GetExportFunctionPointer(std::string_view a_function) const;
[[nodiscard]] std::uintptr_t GetExportFunctionAddress(std::string_view a_function) const
{
return reinterpret_cast<std::uintptr_t>(GetExportFunctionPointer(a_function));
}
[[nodiscard]] void* GetImportFunctionPointer(std::string_view a_function, std::string_view a_library) const;
[[nodiscard]] std::uintptr_t GetImportFunctionAddress(std::string_view a_function, std::string_view a_library) const
{
return reinterpret_cast<std::uintptr_t>(GetImportFunctionPointer(a_function, a_library));
}
void* SetImportFunctionPointer(std::string_view a_function, std::string_view a_library, void* a_pointer) const;
std::uintptr_t SetImportFunctionAddress(std::string_view a_function, std::string_view a_library, std::uintptr_t a_address) const
{
return reinterpret_cast<std::uintptr_t>(SetImportFunctionPointer(a_function, a_library, reinterpret_cast<void*>(a_address)));
}
[[nodiscard]] FModuleSection GetSection(std::string_view a_section) const;
[[nodiscard]] constexpr std::uintptr_t GetBaseAddress() const noexcept
{
return m_base;
}
private:
std::uintptr_t m_base{ 0 };
};
}
@@ -0,0 +1,44 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
class FModuleSection
{
public:
constexpr FModuleSection() noexcept = default;
constexpr FModuleSection(std::uintptr_t a_base, std::uintptr_t a_address, std::uintptr_t a_size) noexcept :
m_base(a_base),
m_address(a_address),
m_size(a_size)
{}
[[nodiscard]] constexpr std::uintptr_t GetAddress() const noexcept
{
return m_address;
}
[[nodiscard]] constexpr std::ptrdiff_t GetOffset() const noexcept
{
return GetAddress() - m_base;
}
[[nodiscard]] constexpr std::size_t GetSize() const noexcept
{
return m_size;
}
template <class T = void>
[[nodiscard]] T* GetPointer() const noexcept
{
return reinterpret_cast<T*>(GetAddress());
}
private:
std::uintptr_t m_base{ 0 };
std::uintptr_t m_address{ 0 };
std::size_t m_size{ 0 };
};
}
@@ -0,0 +1,27 @@
#pragma once
#include "REX/ISettingStore.h"
namespace REX
{
class FSettingStore :
public ISettingStore
{
public:
virtual void Init(const char* a_fileBase, const char* a_fileUser) override
{
m_fileBase = a_fileBase;
m_fileUser = a_fileUser;
}
virtual void Add(ISetting* a_setting) override
{
m_settings.emplace_back(a_setting);
}
protected:
std::string_view m_fileBase;
std::string_view m_fileUser;
std::vector<ISetting*> m_settings;
};
}
@@ -0,0 +1,25 @@
#pragma once
#ifdef COMMONLIB_OPTION_TOML
# include "REX/FSettingStore.h"
# include "REX/TSingleton.h"
namespace REX
{
class FTomlSettingStore :
public FSettingStore,
public TSingleton<FTomlSettingStore>
{
public:
virtual void Load() override;
virtual void Save() override;
};
}
namespace REX::TOML
{
using SettingStore [[deprecated("Renamed to 'REX::FTomlSettingStore")]] = FTomlSettingStore;
}
#endif
@@ -0,0 +1,95 @@
#pragma once
namespace REX
{
class FUUID
{
public:
inline constexpr FUUID() noexcept = default;
inline constexpr FUUID(FUUID&&) noexcept = default;
inline constexpr FUUID(const FUUID&) noexcept = default;
inline constexpr FUUID(std::uint8_t a_b1, std::uint8_t a_b2, std::uint8_t a_b3, std::uint8_t a_b4, std::uint8_t a_b5, std::uint8_t a_b6, std::uint8_t a_b7, std::uint8_t a_b8, std::uint8_t a_b9, std::uint8_t a_b10, std::uint8_t a_b11, std::uint8_t a_b12, std::uint8_t a_b13, std::uint8_t a_b14, std::uint8_t a_b15, std::uint8_t a_b16) noexcept :
m_data{ a_b1, a_b2, a_b3, a_b4, a_b5, a_b6, a_b7, a_b8, a_b9, a_b10, a_b11, a_b12, a_b13, a_b14, a_b15, a_b16 }
{}
template <std::size_t N>
requires(N == 37)
inline constexpr FUUID(const char (&a_string)[N]) noexcept
{
ParseString(a_string);
}
inline constexpr FUUID& operator=(FUUID&&) noexcept = default;
inline constexpr FUUID& operator=(const FUUID&) noexcept = default;
inline constexpr std::uint8_t& operator[](std::size_t a_pos) noexcept
{
return m_data[a_pos];
}
inline constexpr const std::uint8_t operator[](std::size_t a_pos) const noexcept
{
return m_data[a_pos];
}
inline constexpr bool operator==(const FUUID& a_rhs) const noexcept
{
for (auto i = 0u; i < sizeof(m_data); i++) {
if (m_data[i] != a_rhs.m_data[i]) {
return false;
}
}
return true;
}
inline constexpr explicit operator bool() const noexcept
{
for (auto i = 0u; i < sizeof(m_data); i++) {
if (m_data[i]) {
return true;
}
}
return false;
}
private:
inline static constexpr std::uint8_t ParseStringHexChar(const char a_char)
{
const char c = a_char | 0x20;
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else
throw "invalid hexadecimal character in FUUID";
}
inline static constexpr std::uint8_t ParseStringHex(const char* a_str, const std::size_t a_pos)
{
return (ParseStringHexChar(a_str[a_pos]) << 4) + ParseStringHexChar(a_str[a_pos + 1]);
}
inline constexpr void ParseString(const char* a_str)
{
//constexpr std::size_t parse_string_table_le[16]{
// 6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 24, 26, 28, 30, 32, 34
//};
constexpr std::size_t parse_string_table_be[16]{
0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34
};
for (auto i = 0u; i < sizeof(m_data); i++) {
m_data[i] = ParseStringHex(a_str, parse_string_table_be[i]);
}
}
private:
std::uint8_t m_data[16];
};
static_assert(sizeof(FUUID) == 16);
static_assert(FUUID{ "62470f2d-f92b-4189-8af6-157310dadc8b" } == FUUID{ 0x62, 0x47, 0x0f, 0x2d, 0xf9, 0x2b, 0x41, 0x89, 0x8a, 0xf6, 0x15, 0x73, 0x10, 0xda, 0xdc, 0x8b });
}
@@ -0,0 +1,49 @@
#pragma once
#include "REX/BASE.h"
#include "REX/TScopeExit.h"
#include "REX/W32/BCRYPT.h"
namespace REX
{
inline std::optional<std::string> SHA512(std::span<const std::byte> a_data)
{
REX::W32::BCRYPT_ALG_HANDLE algorithm;
if (!REX::W32::NT_SUCCESS(REX::W32::BCryptOpenAlgorithmProvider(&algorithm, REX::W32::BCRYPT_SHA512_ALGORITHM)))
return std::nullopt;
const TScopeExit cleanup_algo([&]() {
[[maybe_unused]] const auto success = REX::W32::NT_SUCCESS(REX::W32::BCryptCloseAlgorithmProvider(algorithm));
assert(success);
});
REX::W32::BCRYPT_HASH_HANDLE hash;
if (!REX::W32::NT_SUCCESS(REX::W32::BCryptCreateHash(algorithm, &hash)))
return std::nullopt;
const TScopeExit cleanup_hash([&]() {
[[maybe_unused]] const auto success = REX::W32::NT_SUCCESS(REX::W32::BCryptDestroyHash(hash));
assert(success);
});
if (!REX::W32::NT_SUCCESS(REX::W32::BCryptHashData(hash, reinterpret_cast<std::uint8_t*>(const_cast<std::byte*>(a_data.data())), static_cast<std::uint32_t>(a_data.size()))))
return std::nullopt;
std::uint32_t length{ 0 };
std::uint32_t output{ 0 };
if (!REX::W32::NT_SUCCESS(REX::W32::BCryptGetProperty(hash, REX::W32::BCRYPT_HASH_LENGTH, reinterpret_cast<std::uint8_t*>(&length), sizeof(length), &output)))
return std::nullopt;
std::vector<std::uint8_t> buffer(static_cast<std::size_t>(length));
if (!REX::W32::NT_SUCCESS(REX::W32::BCryptFinishHash(hash, buffer.data(), static_cast<std::uint32_t>(buffer.size()))))
return std::nullopt;
std::string result;
result.reserve(buffer.size() * 2);
for (const auto byte : buffer) {
result += std::format("{:02X}", byte);
}
return { std::move(result) };
}
}
@@ -0,0 +1,10 @@
#pragma once
namespace REX
{
struct ISetting
{
virtual void Load(void* a_data, bool a_isBase) = 0;
virtual void Save(void* a_data) = 0;
};
}
@@ -0,0 +1,14 @@
#pragma once
namespace REX
{
struct ISetting;
struct ISettingStore
{
virtual void Init(const char* a_file, const char* a_fileCustom) = 0;
virtual void Add(ISetting* a_setting) = 0;
virtual void Load() = 0;
virtual void Save() = 0;
};
}
@@ -0,0 +1,352 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
enum class ELogLevel
{
Trace = 0,
Debug = 1,
Info = 2,
Warning = 3,
Error = 4,
Critical = 5,
};
}
namespace REX::Impl
{
void Log(const std::source_location a_loc, const ELogLevel a_level, const std::string_view a_fmt);
void Log(const std::source_location a_loc, const ELogLevel a_level, const std::wstring_view a_fmt);
template <class... T>
void Log(const std::source_location a_loc, const ELogLevel a_level, const std::format_string<T...> a_fmt, T&&... a_args)
{
Log(a_loc, a_level, std::vformat(a_fmt.get(), std::make_format_args(a_args...)));
}
template <class... T>
void Log(const std::source_location a_loc, const ELogLevel a_level, const std::wformat_string<T...> a_fmt, T&&... a_args)
{
Log(a_loc, a_level, std::vformat(a_fmt.get(), std::make_wformat_args(a_args...)));
}
}
namespace REX
{
template <class... T>
struct TRACE
{
TRACE() = delete;
explicit TRACE(const std::format_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Trace, a_fmt, std::forward<T>(a_args)...);
}
explicit TRACE(const std::wformat_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Trace, a_fmt, std::forward<T>(a_args)...);
}
};
template <>
struct TRACE<void>
{
TRACE() = delete;
explicit TRACE(const std::string_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Trace, a_fmt);
}
explicit TRACE(const std::wstring_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Trace, a_fmt);
}
};
template <class... T>
struct DEBUG
{
DEBUG() = delete;
explicit DEBUG(const std::format_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Debug, a_fmt, std::forward<T>(a_args)...);
}
explicit DEBUG(const std::wformat_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Debug, a_fmt, std::forward<T>(a_args)...);
}
};
template <>
struct DEBUG<void>
{
DEBUG() = delete;
explicit DEBUG(const std::string_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Debug, a_fmt);
}
explicit DEBUG(const std::wstring_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Debug, a_fmt);
}
};
template <class... T>
struct INFO
{
INFO() = delete;
explicit INFO(const std::format_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Info, a_fmt, std::forward<T>(a_args)...);
}
explicit INFO(const std::wformat_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Info, a_fmt, std::forward<T>(a_args)...);
}
};
template <>
struct INFO<void>
{
INFO() = delete;
explicit INFO(const std::string_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Info, a_fmt);
}
explicit INFO(const std::wstring_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Info, a_fmt);
}
};
template <class... T>
struct WARN
{
WARN() = delete;
explicit WARN(const std::format_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Warning, a_fmt, std::forward<T>(a_args)...);
}
explicit WARN(const std::wformat_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Warning, a_fmt, std::forward<T>(a_args)...);
}
};
template <>
struct WARN<void>
{
WARN() = delete;
explicit WARN(const std::string_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Warning, a_fmt);
}
explicit WARN(const std::wstring_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Warning, a_fmt);
}
};
template <class... T>
struct ERROR
{
ERROR() = delete;
explicit ERROR(const std::format_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Error, a_fmt, std::forward<T>(a_args)...);
}
explicit ERROR(const std::wformat_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Error, a_fmt, std::forward<T>(a_args)...);
}
};
template <>
struct ERROR<void>
{
ERROR() = delete;
explicit ERROR(const std::string_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Error, a_fmt);
}
explicit ERROR(const std::wstring_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Error, a_fmt);
}
};
template <class... T>
struct CRITICAL
{
CRITICAL() = delete;
explicit CRITICAL(const std::format_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Critical, a_fmt, std::forward<T>(a_args)...);
}
explicit CRITICAL(const std::wformat_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Critical, a_fmt, std::forward<T>(a_args)...);
}
};
template <>
struct CRITICAL<void>
{
CRITICAL() = delete;
explicit CRITICAL(const std::string_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Critical, a_fmt);
}
explicit CRITICAL(const std::wstring_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Log(a_loc, ELogLevel::Critical, a_fmt);
}
};
template <class... T>
TRACE(const std::format_string<T...>, T&&...) -> TRACE<T...>;
template <class... T>
TRACE(const std::wformat_string<T...>, T&&...) -> TRACE<T...>;
TRACE(const std::string_view) -> TRACE<void>;
TRACE(const std::wstring_view) -> TRACE<void>;
template <class... T>
DEBUG(const std::format_string<T...>, T&&...) -> DEBUG<T...>;
template <class... T>
DEBUG(const std::wformat_string<T...>, T&&...) -> DEBUG<T...>;
DEBUG(const std::string_view) -> DEBUG<void>;
DEBUG(const std::wstring_view) -> DEBUG<void>;
template <class... T>
INFO(const std::format_string<T...>, T&&...) -> INFO<T...>;
template <class... T>
INFO(const std::wformat_string<T...>, T&&...) -> INFO<T...>;
INFO(const std::string_view) -> INFO<void>;
INFO(const std::wstring_view) -> INFO<void>;
template <class... T>
WARN(const std::format_string<T...>, T&&...) -> WARN<T...>;
template <class... T>
WARN(const std::wformat_string<T...>, T&&...) -> WARN<T...>;
WARN(const std::string_view) -> WARN<void>;
WARN(const std::wstring_view) -> WARN<void>;
template <class... T>
ERROR(const std::format_string<T...>, T&&...) -> ERROR<T...>;
template <class... T>
ERROR(const std::wformat_string<T...>, T&&...) -> ERROR<T...>;
ERROR(const std::string_view) -> ERROR<void>;
ERROR(const std::wstring_view) -> ERROR<void>;
template <class... T>
CRITICAL(const std::format_string<T...>, T&&...) -> CRITICAL<T...>;
template <class... T>
CRITICAL(const std::wformat_string<T...>, T&&...) -> CRITICAL<T...>;
CRITICAL(const std::string_view) -> CRITICAL<void>;
CRITICAL(const std::wstring_view) -> CRITICAL<void>;
}
namespace REX
{
namespace Impl
{
void Fail(const std::source_location a_loc, const std::string_view a_fmt);
void Fail(const std::source_location a_loc, const std::wstring_view a_fmt);
template <class... T>
void Fail(const std::source_location a_loc, const std::format_string<T...> a_fmt, T&&... a_args)
{
Fail(a_loc, std::vformat(a_fmt.get(), std::make_format_args(a_args...)));
}
template <class... T>
void Fail(const std::source_location a_loc, const std::wformat_string<T...> a_fmt, T&&... a_args)
{
Fail(a_loc, std::vformat(a_fmt.get(), std::make_wformat_args(a_args...)));
}
}
template <class... T>
struct FAIL
{
FAIL() = delete;
explicit FAIL(const std::format_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Fail(a_loc, a_fmt, std::forward<T>(a_args)...);
}
explicit FAIL(const std::wformat_string<T...> a_fmt, T&&... a_args, const std::source_location a_loc = std::source_location::current())
{
Impl::Fail(a_loc, a_fmt, std::forward<T>(a_args)...);
}
explicit FAIL(const std::source_location a_loc, const std::format_string<T...> a_fmt, T&&... a_args)
{
Impl::Fail(a_loc, a_fmt, std::forward<T>(a_args)...);
}
explicit FAIL(const std::source_location a_loc, const std::wformat_string<T...> a_fmt, T&&... a_args)
{
Impl::Fail(a_loc, a_fmt, std::forward<T>(a_args)...);
}
};
template <>
struct FAIL<void>
{
FAIL() = delete;
explicit FAIL(const std::string_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Fail(a_loc, a_fmt);
}
explicit FAIL(const std::wstring_view a_fmt, const std::source_location a_loc = std::source_location::current())
{
Impl::Fail(a_loc, a_fmt);
}
explicit FAIL(const std::source_location a_loc, const std::string_view a_fmt)
{
Impl::Fail(a_loc, a_fmt);
}
explicit FAIL(const std::source_location a_loc, const std::wstring_view a_fmt)
{
Impl::Fail(a_loc, a_fmt);
}
};
template <class... T>
FAIL(const std::format_string<T...>, T&&...) -> FAIL<T...>;
template <class... T>
FAIL(const std::wformat_string<T...>, T&&...) -> FAIL<T...>;
FAIL(const std::string_view) -> FAIL<void>;
FAIL(const std::wstring_view) -> FAIL<void>;
}
@@ -0,0 +1,3 @@
#pragma once
#include "REX/PS4/SCEPAD.h"
@@ -0,0 +1,29 @@
#pragma once
#include "REX/BASE.h"
namespace REX::PS4
{
enum SCE_PAD_BUTTON : std::uint32_t
{
SCE_PAD_BUTTON_SHARE = 0x00000001,
SCE_PAD_BUTTON_L3 = 0x00000002,
SCE_PAD_BUTTON_R3 = 0x00000004,
SCE_PAD_BUTTON_OPTIONS = 0x00000008,
SCE_PAD_BUTTON_UP = 0x00000010,
SCE_PAD_BUTTON_RIGHT = 0x00000020,
SCE_PAD_BUTTON_DOWN = 0x00000040,
SCE_PAD_BUTTON_LEFT = 0x00000080,
SCE_PAD_BUTTON_L2 = 0x00000100,
SCE_PAD_BUTTON_R2 = 0x00000200,
SCE_PAD_BUTTON_L1 = 0x00000400,
SCE_PAD_BUTTON_R1 = 0x00000800,
SCE_PAD_BUTTON_TRIANGLE = 0x00001000,
SCE_PAD_BUTTON_CIRCLE = 0x00002000,
SCE_PAD_BUTTON_CROSS = 0x00004000,
SCE_PAD_BUTTON_SQUARE = 0x00008000,
SCE_PAD_BUTTON_PLAYSTATION = 0x00010000,
SCE_PAD_BUTTON_TOUCH_PAD = 0x00100000,
SCE_PAD_BUTTON_INTERCEPTED = 0x80000000,
};
}
@@ -0,0 +1,26 @@
#pragma once
#include "CAST.h"
#include "CONVERT.h"
#include "FIniSettingStore.h"
#include "FJsonSettingStore.h"
#include "FMemoryMap.h"
#include "FModule.h"
#include "FModuleSection.h"
#include "FSettingStore.h"
#include "FTomlSettingStore.h"
#include "FUUID.h"
#include "HASH.h"
#include "ISetting.h"
#include "ISettingStore.h"
#include "LOG.h"
#include "TAtomicRef.h"
#include "TEnum.h"
#include "TEnumSet.h"
#include "TIniSetting.h"
#include "TJsonSetting.h"
#include "TScopeExit.h"
#include "TSetting.h"
#include "TSingleton.h"
#include "TStaticString.h"
#include "TTomlSetting.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/AtomicRef.h' is deprecated, please include 'REX/REX.h'"
#include "REX/TAtomicRef.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/CAST.h' is deprecated, please include 'REX/REX.h'"
#include "REX/CAST.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/CONVERT.h' is deprecated, please include 'REX/REX.h'"
#include "REX/CONVERT.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/Enum.h' is deprecated, please include 'REX/REX.h'"
#include "REX/TEnum.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/EnumSet.h' is deprecated, please include 'REX/REX.h'"
#include "REX/TEnumSet.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/HASH.h' is deprecated, please include 'REX/REX.h'"
#include "REX/HASH.h"
@@ -0,0 +1,6 @@
#pragma once
#warning "The header 'REX/REX/INI.h' is deprecated, please include 'REX/REX.h'"
#include "REX/FIniSettingStore.h"
#include "REX/TIniSetting.h"
@@ -0,0 +1,6 @@
#pragma once
#warning "The header 'REX/REX/JSON.h' is deprecated, please include 'REX/REX.h'"
#include "REX/FJsonSettingStore.h"
#include "REX/TJsonSetting.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/LOG.h' is deprecated, please include 'REX/REX.h'"
#include "REX/LOG.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/MemoryMap.h' is deprecated, please include 'REX/REX.h'"
#include "REX/FMemoryMap.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/ScopeExit.h' is deprecated, please include 'REX/REX.h'"
#include "REX/TScopeExit.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/Singleton.h' is deprecated, please include 'REX/REX.h'"
#include "REX/TSingleton.h"
@@ -0,0 +1,5 @@
#pragma once
#warning "The header 'REX/REX/StaticString.h' is deprecated, please include 'REX/REX.h'"
#include "REX/TStaticString.h"
@@ -0,0 +1,6 @@
#pragma once
#warning "The header 'REX/REX/TOML.h' is deprecated, please include 'REX/REX.h'"
#include "REX/FTomlSettingStore.h"
#include "REX/TTomlSetting.h"
@@ -0,0 +1,45 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
template <class T>
class TAtomicRef :
public std::atomic_ref<T>
{
private:
using super = std::atomic_ref<T>;
public:
using value_type = typename super::value_type;
explicit TAtomicRef(volatile T& a_obj) noexcept(std::is_nothrow_constructible_v<super, value_type&>) :
super(const_cast<value_type&>(a_obj))
{}
using super::super;
using super::operator=;
};
template <class T>
TAtomicRef(volatile T&) -> TAtomicRef<T>;
template class TAtomicRef<std::int8_t>;
template class TAtomicRef<std::uint8_t>;
template class TAtomicRef<std::int16_t>;
template class TAtomicRef<std::uint16_t>;
template class TAtomicRef<std::int32_t>;
template class TAtomicRef<std::uint32_t>;
template class TAtomicRef<std::int64_t>;
template class TAtomicRef<std::uint64_t>;
static_assert(TAtomicRef<std::int8_t>::is_always_lock_free);
static_assert(TAtomicRef<std::uint8_t>::is_always_lock_free);
static_assert(TAtomicRef<std::int16_t>::is_always_lock_free);
static_assert(TAtomicRef<std::uint16_t>::is_always_lock_free);
static_assert(TAtomicRef<std::int32_t>::is_always_lock_free);
static_assert(TAtomicRef<std::uint32_t>::is_always_lock_free);
static_assert(TAtomicRef<std::int64_t>::is_always_lock_free);
static_assert(TAtomicRef<std::uint64_t>::is_always_lock_free);
}
@@ -0,0 +1,101 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
template <
class E,
class U = std::underlying_type_t<E>>
class TEnum
{
public:
using enum_type = E;
using underlying_type = U;
static_assert(std::is_enum_v<E>, "TEnum<E, ...> must be an enum");
static_assert(std::is_integral_v<U>, "TEnum<..., U> must be an integral");
constexpr TEnum() noexcept = default;
constexpr TEnum(const TEnum&) noexcept = default;
constexpr TEnum(TEnum&&) noexcept = default;
template <class U2> // NOLINTNEXTLINE(google-explicit-constructor)
constexpr TEnum(TEnum<E, U2> a_rhs) noexcept :
_impl(static_cast<U>(a_rhs.get()))
{}
constexpr TEnum(E a_value) noexcept :
_impl(static_cast<U>(a_value))
{}
~TEnum() noexcept = default;
constexpr TEnum& operator=(const TEnum&) noexcept = default;
constexpr TEnum& operator=(TEnum&&) noexcept = default;
template <class U2>
constexpr TEnum& operator=(TEnum<E, U2> a_rhs) noexcept
{
_impl = static_cast<U>(a_rhs.get());
}
constexpr TEnum& operator=(E a_value) noexcept
{
_impl = static_cast<U>(a_value);
return *this;
}
public:
[[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); }
[[nodiscard]] constexpr E operator*() const noexcept { return get(); }
[[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); }
[[nodiscard]] constexpr U underlying() const noexcept { return _impl; }
public:
friend constexpr bool operator==(TEnum a_lhs, TEnum a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); }
friend constexpr bool operator==(TEnum a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); }
friend constexpr bool operator==(E a_lhs, TEnum a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); }
private:
U _impl{ 0 };
};
template <class... Args>
TEnum(Args...) -> TEnum<
std::common_type_t<Args...>,
std::underlying_type_t<
std::common_type_t<Args...>>>;
}
namespace REX
{
template <
class E,
class U = std::underlying_type_t<E>>
class [[deprecated("Renamed to 'REX::TEnum'")]] Enum :
public TEnum<E, U>
{
using super = TEnum<E, U>;
public:
using enum_type = E;
using underlying_type = U;
using super::super;
using super::operator=;
using super::operator*;
};
#pragma warning(push)
#pragma warning(disable: 4996)
template <class... Args>
Enum(Args...) -> Enum<
std::common_type_t<Args...>,
std::underlying_type_t<
std::common_type_t<Args...>>>;
#pragma warning(pop)
}
@@ -0,0 +1,226 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
template <
class E,
class U = std::underlying_type_t<E>>
class TEnumSet
{
public:
using enum_type = E;
using underlying_type = U;
static_assert(std::is_enum_v<E>, "TEnumSet<E, ...> must be an enum");
static_assert(std::is_integral_v<U>, "TEnumSet<..., U> must be an integral");
constexpr TEnumSet() noexcept = default;
constexpr TEnumSet(const TEnumSet&) noexcept = default;
constexpr TEnumSet(TEnumSet&&) noexcept = default;
template <class U2> // NOLINTNEXTLINE(google-explicit-constructor)
constexpr TEnumSet(TEnumSet<E, U2> a_rhs) noexcept :
_impl(static_cast<U>(a_rhs.get()))
{}
template <class... Args>
constexpr TEnumSet(Args... a_values) noexcept
requires(std::same_as<Args, E> && ...)
:
_impl((static_cast<U>(a_values) | ...))
{}
~TEnumSet() noexcept = default;
constexpr TEnumSet& operator=(const TEnumSet&) noexcept = default;
constexpr TEnumSet& operator=(TEnumSet&&) noexcept = default;
template <class U2>
constexpr TEnumSet& operator=(TEnumSet<E, U2> a_rhs) noexcept
{
_impl = static_cast<U>(a_rhs.get());
return *this;
}
constexpr TEnumSet& operator=(E a_value) noexcept
{
_impl = static_cast<U>(a_value);
return *this;
}
public:
[[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); }
[[nodiscard]] constexpr E operator*() const noexcept { return get(); }
[[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); }
[[nodiscard]] constexpr U underlying() const noexcept { return _impl; }
public:
template <class... Args>
constexpr TEnumSet& set(Args... a_args) noexcept
requires(std::same_as<Args, E> && ...)
{
_impl |= (static_cast<U>(a_args) | ...);
return *this;
}
template <class... Args>
constexpr TEnumSet& set(bool a_set, Args... a_args) noexcept
requires(std::same_as<Args, E> && ...)
{
if (a_set)
_impl |= (static_cast<U>(a_args) | ...);
else
_impl &= ~(static_cast<U>(a_args) | ...);
return *this;
}
template <class... Args>
constexpr TEnumSet& reset(Args... a_args) noexcept
requires(std::same_as<Args, E> && ...)
{
_impl &= ~(static_cast<U>(a_args) | ...);
return *this;
}
constexpr TEnumSet& reset() noexcept
{
_impl = 0;
return *this;
}
template <class... Args>
[[nodiscard]] constexpr bool any(Args... a_args) const noexcept
requires(std::same_as<Args, E> && ...)
{
return (_impl & (static_cast<U>(a_args) | ...)) != static_cast<U>(0);
}
template <class... Args>
[[nodiscard]] constexpr bool all(Args... a_args) const noexcept
requires(std::same_as<Args, E> && ...)
{
return (_impl & (static_cast<U>(a_args) | ...)) == (static_cast<U>(a_args) | ...);
}
template <class... Args>
[[nodiscard]] constexpr bool none(Args... a_args) const noexcept
requires(std::same_as<Args, E> && ...)
{
return (_impl & (static_cast<U>(a_args) | ...)) == static_cast<U>(0);
}
public:
friend constexpr bool operator==(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); }
friend constexpr bool operator==(TEnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); }
friend constexpr bool operator==(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); }
friend constexpr std::strong_ordering operator<=>(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return a_lhs.underlying() <=> a_rhs.underlying(); }
friend constexpr std::strong_ordering operator<=>(TEnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() <=> static_cast<U>(a_rhs); }
friend constexpr std::strong_ordering operator<=>(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) <=> a_rhs.underlying(); }
friend constexpr TEnumSet operator&(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & a_rhs.underlying()); }
friend constexpr TEnumSet operator&(TEnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & static_cast<U>(a_rhs)); }
friend constexpr TEnumSet operator&(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) & a_rhs.underlying()); }
friend constexpr TEnumSet& operator&=(TEnumSet& a_lhs, TEnumSet a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; }
friend constexpr TEnumSet& operator&=(TEnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; }
friend constexpr TEnumSet operator|(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | a_rhs.underlying()); }
friend constexpr TEnumSet operator|(TEnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | static_cast<U>(a_rhs)); }
friend constexpr TEnumSet operator|(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) | a_rhs.underlying()); }
friend constexpr TEnumSet& operator|=(TEnumSet& a_lhs, TEnumSet a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; }
friend constexpr TEnumSet& operator|=(TEnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; }
friend constexpr TEnumSet operator^(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ a_rhs.underlying()); }
friend constexpr TEnumSet operator^(TEnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ static_cast<U>(a_rhs)); }
friend constexpr TEnumSet operator^(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) ^ a_rhs.underlying()); }
friend constexpr TEnumSet& operator^=(TEnumSet& a_lhs, TEnumSet a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; }
friend constexpr TEnumSet& operator^=(TEnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; }
friend constexpr TEnumSet operator+(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + a_rhs.underlying()); }
friend constexpr TEnumSet operator+(TEnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + static_cast<U>(a_rhs)); }
friend constexpr TEnumSet operator+(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) + a_rhs.underlying()); }
friend constexpr TEnumSet& operator+=(TEnumSet& a_lhs, TEnumSet a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; }
friend constexpr TEnumSet& operator+=(TEnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; }
friend constexpr TEnumSet operator-(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - a_rhs.underlying()); }
friend constexpr TEnumSet operator-(TEnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - static_cast<U>(a_rhs)); }
friend constexpr TEnumSet operator-(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) - a_rhs.underlying()); }
friend constexpr TEnumSet& operator-=(TEnumSet& a_lhs, TEnumSet a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; }
friend constexpr TEnumSet& operator-=(TEnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; }
friend constexpr TEnumSet operator<<(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << a_rhs.underlying()); }
friend constexpr TEnumSet operator<<(TEnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << static_cast<U>(a_rhs)); }
friend constexpr TEnumSet operator<<(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) << a_rhs.underlying()); }
friend constexpr TEnumSet& operator<<=(TEnumSet& a_lhs, TEnumSet a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; }
friend constexpr TEnumSet& operator<<=(TEnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; }
friend constexpr TEnumSet operator>>(TEnumSet a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> a_rhs.underlying()); }
friend constexpr TEnumSet operator>>(TEnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> static_cast<U>(a_rhs)); }
friend constexpr TEnumSet operator>>(E a_lhs, TEnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) >> a_rhs.underlying()); }
friend constexpr TEnumSet& operator>>=(TEnumSet& a_lhs, TEnumSet a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; }
friend constexpr TEnumSet& operator>>=(TEnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; }
friend constexpr TEnumSet& operator~(TEnumSet& a_lhs) noexcept { return a_lhs = ~a_lhs.underlying(); }
private:
U _impl{ 0 };
};
template <class... Args>
TEnumSet(Args...) -> TEnumSet<
std::common_type_t<Args...>,
std::underlying_type_t<
std::common_type_t<Args...>>>;
}
namespace REX
{
template <
class E,
class U = std::underlying_type_t<E>>
class [[deprecated("Renamed to 'REX::TEnumSet'")]] EnumSet :
public TEnumSet<E, U>
{
using super = TEnumSet<E, U>;
public:
using enum_type = E;
using underlying_type = U;
using super::super;
using super::operator=;
using super::operator*;
};
#pragma warning(push)
#pragma warning(disable: 4996)
template <class... Args>
EnumSet(Args...) -> EnumSet<
std::common_type_t<Args...>,
std::underlying_type_t<
std::common_type_t<Args...>>>;
#pragma warning(pop)
}
#define REX_DEFINE_ENUM_CLASS_FLAGS(E) \
inline constexpr E& operator|=(E& a_lhs, E a_rhs) { return a_lhs = (E)((__underlying_type(E))a_lhs | (__underlying_type(E))a_rhs); } \
inline constexpr E& operator&=(E& a_lhs, E a_rhs) { return a_lhs = (E)((__underlying_type(E))a_lhs & (__underlying_type(E))a_rhs); } \
inline constexpr E& operator^=(E& a_lhs, E a_rhs) { return a_lhs = (E)((__underlying_type(E))a_lhs ^ (__underlying_type(E))a_rhs); } \
inline constexpr E operator|(E a_lhs, E a_rhs) { return (E)((__underlying_type(E))a_lhs | (__underlying_type(E))a_rhs); } \
inline constexpr E operator&(E a_lhs, E a_rhs) { return (E)((__underlying_type(E))a_lhs & (__underlying_type(E))a_rhs); } \
inline constexpr E operator^(E a_lhs, E a_rhs) { return (E)((__underlying_type(E))a_lhs ^ (__underlying_type(E))a_rhs); } \
inline constexpr bool operator!(E a_lhs) { return !(__underlying_type(E))a_lhs; } \
inline constexpr E operator~(E a_lhs) { return (E) ~(__underlying_type(E))a_lhs; }
@@ -0,0 +1,99 @@
#pragma once
#ifdef COMMONLIB_OPTION_INI
# include "REX/FIniSettingStore.h"
# include "REX/TSetting.h"
namespace REX::Impl
{
template <class T>
void IniSettingLoad(void* a_data, std::string_view a_section, std::string_view a_key, T& a_value, T& a_valueDefault);
template <class T>
void IniSettingSave(void* a_data, std::string_view a_section, std::string_view a_key, T& a_value);
}
namespace REX
{
template <class T, class S = FIniSettingStore>
class TIniSetting :
public TSetting<T>
{
public:
TIniSetting(std::string_view a_section, std::string_view a_key, T a_default) :
TSetting<T>(a_default),
m_section(a_section),
m_key(a_key)
{
S::GetSingleton()->Add(this);
}
TIniSetting(std::string_view a_key, T a_default) :
TSetting<T>(a_default),
m_section(),
m_key(a_key)
{
S::GetSingleton()->Add(this);
}
public:
virtual void Load(void* a_data, bool a_isBase) override
{
if (a_isBase) {
Impl::IniSettingLoad<T>(a_data, m_section, m_key, this->m_valueDefault, this->m_valueDefault);
this->SetValue(this->m_valueDefault);
} else {
Impl::IniSettingLoad<T>(a_data, m_section, m_key, this->m_value, this->m_valueDefault);
}
}
virtual void Save(void* a_data) override
{
Impl::IniSettingSave<T>(a_data, m_section, m_key, this->m_value);
}
private:
std::string_view m_section;
std::string_view m_key;
};
}
// DEPRECATED
namespace REX::INI
{
template <class T, class S = FIniSettingStore>
using Setting [[deprecated("Renamed to 'REX::TIniSetting'")]] = TIniSetting<T, S>;
template <class S = FIniSettingStore>
using Bool = TIniSetting<bool, S>;
template <class S = FIniSettingStore>
using F32 = TIniSetting<float, S>;
template <class S = FIniSettingStore>
using F64 = TIniSetting<double, S>;
template <class S = FIniSettingStore>
using I8 = TIniSetting<std::int8_t, S>;
template <class S = FIniSettingStore>
using I16 = TIniSetting<std::int16_t, S>;
template <class S = FIniSettingStore>
using I32 = TIniSetting<std::int32_t, S>;
template <class S = FIniSettingStore>
using U8 = TIniSetting<std::uint8_t, S>;
template <class S = FIniSettingStore>
using U16 = TIniSetting<std::uint16_t, S>;
template <class S = FIniSettingStore>
using U32 = TIniSetting<std::uint32_t, S>;
template <class S = FIniSettingStore>
using Str = TIniSetting<std::string, S>;
}
#endif
@@ -0,0 +1,122 @@
#pragma once
#ifdef COMMONLIB_OPTION_JSON
# include "REX/FJsonSettingStore.h"
# include "REX/TSetting.h"
namespace REX::Impl
{
template <class T>
void JsonSettingLoad(void* a_data, std::string_view a_path, T& a_value, T& a_valueDefault);
template <class T>
void JsonSettingSave(void* a_data, std::string_view a_path, T& a_value);
}
namespace REX
{
template <class T, class S = FJsonSettingStore>
class TJsonSetting :
public TSetting<T>
{
public:
TJsonSetting(std::string_view a_path, T a_default) :
TSetting<T>(a_default),
m_path(a_path)
{
S::GetSingleton()->Add(this);
}
public:
virtual void Load(void* a_data, bool a_isBase) override
{
if (a_isBase) {
Impl::JsonSettingLoad<T>(a_data, m_path, this->m_valueDefault, this->m_valueDefault);
this->SetValue(this->m_valueDefault);
} else {
Impl::JsonSettingLoad<T>(a_data, m_path, this->m_value, this->m_valueDefault);
}
}
virtual void Save(void* a_data) override
{
Impl::JsonSettingSave<T>(a_data, m_path, this->m_value);
}
private:
std::string_view m_path;
};
}
// DEPRECATED
namespace REX::JSON
{
template <class T, class S = FJsonSettingStore>
using Setting [[deprecated("Renamed to 'REX::TJsonSetting")]] = TJsonSetting<T, S>;
template <class S = FJsonSettingStore>
using Bool = TJsonSetting<bool, S>;
//template <class S = FJsonSettingStore>
//using F32 = TJsonSetting<float, S>;
template <class S = FJsonSettingStore>
using F64 = TJsonSetting<double, S>;
template <class S = FJsonSettingStore>
using I8 = TJsonSetting<std::int8_t, S>;
template <class S = FJsonSettingStore>
using I16 = TJsonSetting<std::int16_t, S>;
template <class S = FJsonSettingStore>
using I32 = TJsonSetting<std::int32_t, S>;
template <class S = FJsonSettingStore>
using U8 = TJsonSetting<std::uint8_t, S>;
template <class S = FJsonSettingStore>
using U16 = TJsonSetting<std::uint16_t, S>;
template <class S = FJsonSettingStore>
using U32 = TJsonSetting<std::uint32_t, S>;
template <class S = FJsonSettingStore>
using Str = TJsonSetting<std::string, S>;
template <class T, class S = FJsonSettingStore>
using SettingA = TJsonSetting<std::vector<T>, S>;
template <class S = FJsonSettingStore>
using BoolA = SettingA<bool, S>;
//template <class S = FJsonSettingStore>
//using F32A = SettingA<float, S>;
template <class S = FJsonSettingStore>
using F64A = SettingA<double, S>;
template <class S = FJsonSettingStore>
using I8A = SettingA<std::int8_t, S>;
template <class S = FJsonSettingStore>
using I16A = SettingA<std::int16_t, S>;
template <class S = FJsonSettingStore>
using I32A = SettingA<std::int32_t, S>;
template <class S = FJsonSettingStore>
using U8A = SettingA<std::uint8_t, S>;
template <class S = FJsonSettingStore>
using U16A = SettingA<std::uint16_t, S>;
template <class S = FJsonSettingStore>
using U32A = SettingA<std::uint32_t, S>;
template <class S = FJsonSettingStore>
using StrA = SettingA<std::string, S>;
}
#endif
@@ -0,0 +1,65 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
template <class EF>
requires(std::invocable<std::remove_reference_t<EF>>)
class TScopeExit
{
public:
template <class Fn>
explicit TScopeExit(Fn&& a_fn) noexcept(std::is_nothrow_constructible_v<EF, Fn> ||
std::is_nothrow_constructible_v<EF, Fn&>)
requires(!std::is_same_v<std::remove_cvref_t<Fn>, TScopeExit> &&
std::is_constructible_v<EF, Fn>)
{
static_assert(std::invocable<Fn>);
if constexpr (!std::is_lvalue_reference_v<Fn> &&
std::is_nothrow_constructible_v<EF, Fn>) {
_fn.emplace(std::forward<Fn>(a_fn));
} else {
_fn.emplace(a_fn);
}
}
TScopeExit(TScopeExit&& a_rhs) noexcept(std::is_nothrow_move_constructible_v<EF> ||
std::is_nothrow_copy_constructible_v<EF>)
requires(std::is_nothrow_move_constructible_v<EF> ||
std::is_copy_constructible_v<EF>)
{
static_assert(!(std::is_nothrow_move_constructible_v<EF> && !std::is_move_constructible_v<EF>));
static_assert(!(!std::is_nothrow_move_constructible_v<EF> && !std::is_copy_constructible_v<EF>));
if (a_rhs.active()) {
if constexpr (std::is_nothrow_move_constructible_v<EF>) {
_fn.emplace(std::forward<EF>(*a_rhs._fn));
} else {
_fn.emplace(a_rhs._fn);
}
a_rhs.release();
}
}
TScopeExit(const TScopeExit&) = delete;
~TScopeExit() noexcept
{
if (_fn.has_value()) {
(*_fn)();
}
}
void release() noexcept { _fn.reset(); }
private:
[[nodiscard]] bool active() const noexcept { return _fn.has_value(); }
std::optional<std::remove_reference_t<EF>> _fn;
};
template <class EF>
TScopeExit(EF) -> TScopeExit<EF>;
}
@@ -0,0 +1,43 @@
#pragma once
#include "ISetting.h"
namespace REX
{
template <class T>
class TSetting :
public ISetting
{
public:
TSetting() = delete;
TSetting(T a_default) :
m_value(a_default),
m_valueDefault(a_default)
{}
public:
T GetValue() const
{
return m_value;
}
T GetValueDefault() const
{
return m_valueDefault;
}
void SetValue(T a_value)
{
m_value = a_value;
}
public:
operator T&() { return m_value; }
operator const T&() const { return m_value; }
protected:
T m_value;
T m_valueDefault;
};
}
@@ -0,0 +1,30 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
template <class T>
class TSingleton
{
public:
static T* GetSingleton()
{
static T singleton;
return std::addressof(singleton);
}
protected:
TSingleton() = default;
~TSingleton() = default;
TSingleton(const TSingleton&) = delete;
TSingleton(TSingleton&&) = delete;
TSingleton& operator=(const TSingleton&) = delete;
TSingleton& operator=(TSingleton&&) = delete;
};
template <class T>
using Singleton [[deprecated("Renamed to 'REX::TSingleton'")]] = TSingleton<T>;
}
@@ -0,0 +1,56 @@
#pragma once
#include "REX/BASE.h"
namespace REX
{
template <class T, std::size_t N>
struct TStaticString
{
using char_type = T;
using pointer = char_type*;
using const_pointer = const char_type*;
using reference = char_type&;
using const_reference = const char_type&;
using size_type = std::size_t;
static constexpr auto NPOS = static_cast<std::size_t>(-1);
consteval TStaticString(const_pointer a_string) noexcept
{
for (size_type i = 0; i < N; ++i) {
c[i] = a_string[i];
}
}
[[nodiscard]] consteval const_reference operator[](size_type a_pos) const noexcept
{
assert(a_pos < N);
return c[a_pos];
}
[[nodiscard]] consteval char_type value_at(size_type a_pos) const noexcept
{
assert(a_pos < N);
return c[a_pos];
}
[[nodiscard]] consteval const_reference back() const noexcept { return (*this)[size() - 1]; }
[[nodiscard]] consteval const_pointer data() const noexcept { return c; }
[[nodiscard]] consteval bool empty() const noexcept { return this->size() == 0; }
[[nodiscard]] consteval const_reference front() const noexcept { return (*this)[0]; }
[[nodiscard]] consteval size_type length() const noexcept { return N; }
[[nodiscard]] consteval size_type size() const noexcept { return length(); }
template <std::size_t POS = 0, std::size_t COUNT = NPOS>
consteval auto substr() const noexcept
{
return TStaticString < T, COUNT != NPOS ? COUNT : N - POS > (this->data() + POS);
}
char_type c[N] = {};
};
template <class T, std::size_t N>
TStaticString(const T (&)[N]) -> TStaticString<T, N - 1>;
}
@@ -0,0 +1,111 @@
#pragma once
#ifdef COMMONLIB_OPTION_TOML
# include "REX/FTomlSettingStore.h"
# include "REX/TSetting.h"
namespace REX::Impl
{
template <class T>
void TomlSettingLoad(void* a_data, std::vector<std::string> a_section, std::string_view a_key, T& a_value, T& a_valueDefault);
template <class T>
void TomlSettingSave(void* a_data, std::vector<std::string> a_section, std::string_view a_key, T& a_value);
}
namespace REX
{
template <class T, class S = FTomlSettingStore>
class TTomlSetting :
public TSetting<T>
{
public:
TTomlSetting(std::string_view a_key, T a_default) :
TSetting<T>(a_default),
m_section(),
m_key(a_key)
{
S::GetSingleton()->Add(this);
}
TTomlSetting(std::string_view a_section, std::string_view a_key, T a_default) :
TSetting<T>(a_default),
m_section(),
m_key(a_key)
{
for (const auto token : std::ranges::split_view{ a_section, std::string_view{ "." } }) {
m_section.emplace_back(token.data(), token.size());
}
S::GetSingleton()->Add(this);
}
TTomlSetting(std::initializer_list<std::string> a_section, std::string_view a_key, T a_default) :
TSetting<T>(a_default),
m_section(a_section),
m_key(a_key)
{
S::GetSingleton()->Add(this);
}
public:
virtual void Load(void* a_data, bool a_isBase) override
{
if (a_isBase) {
Impl::TomlSettingLoad<T>(a_data, m_section, m_key, this->m_valueDefault, this->m_valueDefault);
this->SetValue(this->m_valueDefault);
} else {
Impl::TomlSettingLoad<T>(a_data, m_section, m_key, this->m_value, this->m_valueDefault);
}
}
virtual void Save(void* a_data) override
{
Impl::TomlSettingSave<T>(a_data, m_section, m_key, this->m_value);
}
private:
std::vector<std::string> m_section;
std::string_view m_key;
};
}
// DEPRECATED
namespace REX::TOML
{
template <class T, class S = FTomlSettingStore>
using Setting [[deprecated("Renamed to 'REX::TTomlSetting")]] = TTomlSetting<T, S>;
template <class S = FTomlSettingStore>
using Bool = TTomlSetting<bool, S>;
template <class S = FTomlSettingStore>
using F32 = TTomlSetting<float, S>;
template <class S = FTomlSettingStore>
using F64 = TTomlSetting<double, S>;
template <class S = FTomlSettingStore>
using I8 = TTomlSetting<std::int8_t, S>;
template <class S = FTomlSettingStore>
using I16 = TTomlSetting<std::int16_t, S>;
template <class S = FTomlSettingStore>
using I32 = TTomlSetting<std::int32_t, S>;
template <class S = FTomlSettingStore>
using U8 = TTomlSetting<std::uint8_t, S>;
template <class S = FTomlSettingStore>
using U16 = TTomlSetting<std::uint16_t, S>;
template <class S = FTomlSettingStore>
using U32 = TTomlSetting<std::uint32_t, S>;
template <class S = FTomlSettingStore>
using Str = TTomlSetting<std::string, S>;
}
#endif
@@ -0,0 +1,30 @@
#pragma once
#include "REX/W32/ADVAPI32.h"
#include "REX/W32/BCRYPT.h"
#include "REX/W32/COM.h"
#include "REX/W32/COMPTR.h"
#include "REX/W32/D3D.h"
#include "REX/W32/D3D11.h"
#include "REX/W32/D3D11_1.h"
#include "REX/W32/D3D11_2.h"
#include "REX/W32/D3D11_3.h"
#include "REX/W32/D3D11_4.h"
#include "REX/W32/D3DCOMPILER.h"
#include "REX/W32/DBGHELP.h"
#include "REX/W32/DINPUT.h"
#include "REX/W32/DXGI.h"
#include "REX/W32/DXGI_2.h"
#include "REX/W32/DXGI_3.h"
#include "REX/W32/DXGI_4.h"
#include "REX/W32/DXGI_5.h"
#include "REX/W32/DXGI_6.h"
#include "REX/W32/KERNEL32.h"
#include "REX/W32/NT.h"
#include "REX/W32/OLE32.h"
#include "REX/W32/RTTI.h"
#include "REX/W32/SHELL32.h"
#include "REX/W32/USER32.h"
#include "REX/W32/VERSION.h"
#include "REX/W32/WS2_32.h"
#include "REX/W32/XINPUT.h"
@@ -0,0 +1,16 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
inline auto HKEY_CLASSES_ROOT{ reinterpret_cast<HKEY>(0x80000000ull) };
inline auto HKEY_CURRENT_USER{ reinterpret_cast<HKEY>(0x80000001ull) };
inline auto HKEY_LOCAL_MACHINE{ reinterpret_cast<HKEY>(0x80000002ull) };
}
namespace REX::W32
{
std::int32_t RegGetValueA(HKEY a_key, const char* a_subKey, const char* a_value, std::uint32_t a_flags, std::uint32_t* a_type, void* a_data, std::uint32_t* a_dataLen);
std::int32_t RegGetValueW(HKEY a_key, const wchar_t* a_subKey, const wchar_t* a_value, std::uint32_t a_flags, std::uint32_t* a_type, void* a_data, std::uint32_t* a_dataLen);
}
@@ -0,0 +1,200 @@
#pragma once
#include "REX/BASE.h"
#ifdef _INC_WINAPIFAMILY
# error Windows API detected. Please move any Windows API includes after CommonLib, or remove them.
#endif
#define REX_W32_IMPORT(a_ret, a_name, ...) \
extern "C" __declspec(dllimport) a_ret __stdcall W32_IMPL_##a_name(...) noexcept; \
__pragma(comment(linker, "/alternatename:__imp_W32_IMPL_" #a_name "=__imp_" #a_name))
namespace REX::W32
{
using BOOL = std::int32_t;
using HANDLE = void*;
using HBITMAP = struct HBITMAP__*;
using HBRUSH = struct HBRUSH__*;
using HCURSOR = struct HCURSOR__*;
using HDC = struct HDC__*;
using HFONT = struct HFONT__*;
using HICON = struct HICON__*;
using HINSTANCE = struct HINSTANCE__*;
using HKEY = struct HKEY__*;
using HMENU = struct HMENU__*;
using HMODULE = HINSTANCE;
using HMONITOR = struct HMONITOR__*;
using HPALETTE = struct HPALETTE__*;
using HPEN = struct HPEN__*;
using HRESULT = std::int32_t;
using HSTRING = struct HSTRING__*;
using HWND = struct HWND__*;
using NTSTATUS = std::int32_t;
// general constants
inline const auto INVALID_HANDLE_VALUE{ reinterpret_cast<HANDLE>(static_cast<std::intptr_t>(-1)) };
inline constexpr auto MAX_PATH{ 260u };
}
namespace REX::W32
{
struct FILETIME
{
constexpr FILETIME() noexcept = default;
constexpr FILETIME(std::uint64_t a_value) noexcept
{
*this = std::bit_cast<FILETIME>(a_value);
}
constexpr operator std::uint64_t() const noexcept
{
return std::bit_cast<std::uint64_t>(*this);
}
std::uint32_t lo{}; // 00
std::uint32_t hi{}; // 04
};
static_assert(sizeof(FILETIME) == 0x8);
}
namespace REX::W32
{
struct GUID
{
constexpr GUID() noexcept = default;
constexpr GUID(const std::uint32_t a_data1, const std::uint16_t a_data2, const std::uint16_t a_data3, const std::array<std::uint8_t, 8>& a_data4) noexcept :
data1(a_data1), data2(a_data2), data3(a_data3), data4{ a_data4[0], a_data4[1], a_data4[2], a_data4[3], a_data4[4], a_data4[5], a_data4[6], a_data4[7] }
{}
friend bool operator==(const GUID& a_lhs, const GUID& a_rhs) noexcept
{
return std::memcmp(&a_lhs, &a_rhs, sizeof(a_lhs)) == 0;
}
friend bool operator!=(const GUID& a_lhs, const GUID& a_rhs) noexcept
{
return !(a_lhs == a_rhs);
}
std::uint32_t data1{}; // 00
std::uint16_t data2{}; // 04
std::uint16_t data3{}; // 08
std::uint8_t data4[8]{}; // 10
};
static_assert(sizeof(GUID) == 0x10);
using UUID = GUID;
using IID = GUID;
}
namespace REX::W32
{
struct POINT
{
constexpr POINT() noexcept = default;
constexpr POINT(std::int32_t a_x, std::int32_t a_y) noexcept :
x(a_x), y(a_y)
{}
std::int32_t x{}; // 00
std::int32_t y{}; // 04
};
static_assert(sizeof(POINT) == 0x8);
}
namespace REX::W32
{
struct RECT
{
constexpr RECT() noexcept = default;
constexpr RECT(const std::int32_t a_x1, const std::int32_t a_y1, const std::int32_t a_x2, const std::int32_t a_y2) noexcept :
x1(a_x1), y1(a_y1), x2(a_x2), y2(a_y2)
{}
std::int32_t x1{}; // 00
std::int32_t y1{}; // 04
std::int32_t x2{}; // 08
std::int32_t y2{}; // 10
};
static_assert(sizeof(RECT) == 0x10);
}
namespace REX::W32
{
struct SIZE
{
std::int32_t x; // 00
std::int32_t y; // 04
};
static_assert(sizeof(SIZE) == 0x8);
}
namespace REX::W32
{
struct CRITICAL_SECTION
{
void* debugInfo; // 00
std::int32_t lockCount; // 08
std::int32_t recursionCount; // 0C
HANDLE owningThread; // 10
HANDLE lockSemaphore; // 18
std::uintptr_t spinCount; // 20
};
static_assert(sizeof(CRITICAL_SECTION) == 0x28);
struct SECURITY_ATTRIBUTES
{
std::uint32_t length; // 00
void* securityDescriptor; // 04
BOOL inheritHandle; // 0C
};
static_assert(sizeof(SECURITY_ATTRIBUTES) == 0x18);
union LARGE_INTEGER
{
struct
{
std::uint32_t lo;
std::int32_t hi;
};
std::int64_t value;
};
static_assert(sizeof(LARGE_INTEGER) == 0x8);
union ULARGE_INTEGER
{
struct
{
std::uint32_t lo;
std::uint32_t hi;
};
std::uint64_t value;
};
static_assert(sizeof(ULARGE_INTEGER) == 0x8);
struct UNICODE_STRING
{
std::uint16_t length;
std::uint16_t maxLength;
wchar_t* buffer;
};
static_assert(sizeof(UNICODE_STRING) == 0x10);
}
namespace REX::W32
{
constexpr bool SUCCESS(const HRESULT a_result)
{
return a_result >= 0;
}
constexpr bool NT_SUCCESS(const NTSTATUS a_status)
{
return a_status >= 0;
}
}
@@ -0,0 +1,73 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
using BCRYPT_HANDLE = void*;
using BCRYPT_ALG_HANDLE = void*;
using BCRYPT_KEY_HANDLE = void*;
using BCRYPT_HASH_HANDLE = void*;
using BCRYPT_SECRET_HANDLE = void*;
// algorithms
inline constexpr auto BCRYPT_RSA_ALGORITHM{ L"RSA" };
inline constexpr auto BCRYPT_RSA_SIGN_ALGORITHM{ L"RSA_SIGN" };
inline constexpr auto BCRYPT_DH_ALGORITHM{ L"DH" };
inline constexpr auto BCRYPT_DSA_ALGORITHM{ L"DSA" };
inline constexpr auto BCRYPT_RC2_ALGORITHM{ L"RC2" };
inline constexpr auto BCRYPT_RC4_ALGORITHM{ L"RC4" };
inline constexpr auto BCRYPT_AES_ALGORITHM{ L"AES" };
inline constexpr auto BCRYPT_DES_ALGORITHM{ L"DES" };
inline constexpr auto BCRYPT_DESX_ALGORITHM{ L"DESX" };
inline constexpr auto BCRYPT_3DES_ALGORITHM{ L"3DES" };
inline constexpr auto BCRYPT_3DES_112_ALGORITHM{ L"3DES_112" };
inline constexpr auto BCRYPT_MD2_ALGORITHM{ L"MD2" };
inline constexpr auto BCRYPT_MD4_ALGORITHM{ L"MD4" };
inline constexpr auto BCRYPT_MD5_ALGORITHM{ L"MD5" };
inline constexpr auto BCRYPT_SHA1_ALGORITHM{ L"SHA1" };
inline constexpr auto BCRYPT_SHA256_ALGORITHM{ L"SHA256" };
inline constexpr auto BCRYPT_SHA384_ALGORITHM{ L"SHA384" };
inline constexpr auto BCRYPT_SHA512_ALGORITHM{ L"SHA512" };
inline constexpr auto BCRYPT_AES_GMAC_ALGORITHM{ L"AES-GMAC" };
inline constexpr auto BCRYPT_AES_CMAC_ALGORITHM{ L"AES-CMAC" };
inline constexpr auto BCRYPT_ECDSA_P256_ALGORITHM{ L"ECDSA_P256" };
inline constexpr auto BCRYPT_ECDSA_P384_ALGORITHM{ L"ECDSA_P384" };
inline constexpr auto BCRYPT_ECDSA_P521_ALGORITHM{ L"ECDSA_P521" };
inline constexpr auto BCRYPT_ECDH_P256_ALGORITHM{ L"ECDH_P256" };
inline constexpr auto BCRYPT_ECDH_P384_ALGORITHM{ L"ECDH_P384" };
inline constexpr auto BCRYPT_ECDH_P521_ALGORITHM{ L"ECDH_P521" };
inline constexpr auto BCRYPT_RNG_ALGORITHM{ L"RNG" };
inline constexpr auto BCRYPT_RNG_FIPS186_DSA_ALGORITHM{ L"FIPS186DSARNG" };
inline constexpr auto BCRYPT_RNG_DUAL_EC_ALGORITHM{ L"DUALECRNG" };
// properties
inline constexpr auto BCRYPT_OBJECT_LENGTH{ L"ObjectLength" };
inline constexpr auto BCRYPT_ALGORITHM_NAME{ L"AlgorithmName" };
inline constexpr auto BCRYPT_PROVIDER_HANDLE{ L"ProviderHandle" };
inline constexpr auto BCRYPT_CHAINING_MODE{ L"ChainingMode" };
inline constexpr auto BCRYPT_BLOCK_LENGTH{ L"BlockLength" };
inline constexpr auto BCRYPT_KEY_LENGTH{ L"KeyLength" };
inline constexpr auto BCRYPT_KEY_OBJECT_LENGTH{ L"KeyObjectLength" };
inline constexpr auto BCRYPT_KEY_STRENGTH{ L"KeyStrength" };
inline constexpr auto BCRYPT_KEY_LENGTHS{ L"KeyLengths" };
inline constexpr auto BCRYPT_BLOCK_SIZE_LIST{ L"BlockSizeList" };
inline constexpr auto BCRYPT_EFFECTIVE_KEY_LENGTH{ L"EffectiveKeyLength" };
inline constexpr auto BCRYPT_HASH_LENGTH{ L"HashDigestLength" };
inline constexpr auto BCRYPT_HASH_OID_LIST{ L"HashOIDList" };
inline constexpr auto BCRYPT_PADDING_SCHEMES{ L"PaddingSchemes" };
inline constexpr auto BCRYPT_SIGNATURE_LENGTH{ L"SignatureLength" };
inline constexpr auto BCRYPT_HASH_BLOCK_LENGTH{ L"HashBlockLength" };
inline constexpr auto BCRYPT_AUTH_TAG_LENGTH{ L"AuthTagLength" };
}
namespace REX::W32
{
NTSTATUS BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE* a_algorithm, const wchar_t* a_id, const wchar_t* a_impl = nullptr, std::uint32_t a_flags = 0);
NTSTATUS BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE a_algorithm, std::uint32_t a_flags = 0);
NTSTATUS BCryptCreateHash(BCRYPT_ALG_HANDLE a_algorithm, BCRYPT_HASH_HANDLE* a_hash, std::uint8_t* a_hashObject = nullptr, std::uint32_t a_hashObjectSize = 0, std::uint8_t* a_secret = nullptr, std::uint32_t a_secretSize = 0, std::uint32_t a_flags = 0);
NTSTATUS BCryptDestroyHash(BCRYPT_HASH_HANDLE a_hash);
NTSTATUS BCryptFinishHash(BCRYPT_HASH_HANDLE a_hash, std::uint8_t* a_output, std::uint32_t a_outputSize, std::uint32_t a_flags = 0);
NTSTATUS BCryptGetProperty(BCRYPT_HANDLE a_object, const wchar_t* a_property, std::uint8_t* a_output, std::uint32_t a_outputSize, std::uint32_t* a_result, std::uint32_t a_flags = 0);
NTSTATUS BCryptHashData(BCRYPT_HASH_HANDLE a_hash, std::uint8_t* a_input, std::uint32_t a_inputSize, std::uint32_t a_flags = 0);
}
@@ -0,0 +1,25 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
struct __declspec(novtable, uuid("00000000-0000-0000-c000-000000000046"))
IUnknown
{
virtual HRESULT QueryInterface(const IID& a_iid, void** a_object) = 0;
virtual std::uint32_t AddRef() = 0;
virtual std::uint32_t Release() = 0;
template <class T>
HRESULT QueryInterface(T** a_object)
{
return QueryInterface(*reinterpret_cast<const IID*>(&__uuidof(T)), static_cast<void**>(a_object));
}
};
}
namespace REX::W32
{
inline constexpr IID IID_IUnknown{ 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
}
@@ -0,0 +1,196 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
// based on Microsoft::WRL::ComPtr
template <class T>
struct ComPtr
{
constexpr ComPtr() noexcept = default;
constexpr ComPtr(std::nullptr_t) noexcept {}
ComPtr(const ComPtr& a_other) noexcept :
_ptr(a_other._ptr)
{
TryAddRef();
}
template <class U>
ComPtr(U* a_other) noexcept :
_ptr(a_other)
{
TryAddRef();
}
~ComPtr() noexcept
{
TryRelease();
}
ComPtr& operator=(std::nullptr_t) noexcept
{
TryRelease();
return *this;
}
ComPtr& operator=(T* a_other) noexcept
{
if (_ptr != a_other)
ComPtr(a_other).Swap(*this);
return *this;
}
template <class U>
ComPtr& operator=(U* a_other) noexcept
{
ComPtr(a_other).Swap(*this);
return *this;
}
ComPtr& operator=(const ComPtr& a_other) noexcept
{
if (_ptr != a_other._ptr)
ComPtr(a_other).Swap(*this);
return *this;
}
template <class U>
ComPtr& operator=(const ComPtr<U>& a_other) noexcept
{
ComPtr(a_other).Swap(*this);
return *this;
}
ComPtr& operator=(ComPtr&& a_other) noexcept
{
ComPtr(static_cast<ComPtr&&>(a_other)).Swap(*this);
return *this;
}
template <class U>
ComPtr& operator=(ComPtr<U>&& a_other) noexcept
{
ComPtr(static_cast<ComPtr<U>&&>(a_other)).Swap(*this);
return *this;
}
T* operator->() const noexcept
{
return _ptr;
}
void Attach(T* a_other) noexcept
{
if (_ptr != nullptr) {
[[maybe_unused]] auto ref = _ptr->Release();
assert((ref != 0) || (_ptr != a_other));
}
_ptr = a_other;
}
T* Detach() noexcept
{
T* ptr = _ptr;
_ptr = nullptr;
return ptr;
}
T* Get() const noexcept
{
return _ptr;
}
T** GetAddressOf() noexcept
{
return &_ptr;
}
T* const* GetAddressOf() const noexcept
{
return &_ptr;
}
T** ReleaseAndGetAddressOf() noexcept
{
TryRelease();
return &_ptr;
}
std::uint32_t Reset() noexcept
{
return TryRelease();
}
void Swap(ComPtr& a_other) noexcept
{
T* ptr = _ptr;
_ptr = a_other._ptr;
a_other._ptr = ptr;
}
void Swap(ComPtr&& a_other) noexcept
{
T* ptr = _ptr;
_ptr = a_other._ptr;
a_other._ptr = ptr;
}
template <class U>
HRESULT As(ComPtr<U>* a_ptr) const noexcept
{
return _ptr->QueryInterface(__uuidof(U), reinterpret_cast<void**>(a_ptr->ReleaseAndGetAddressOf()));
}
template <class U>
HRESULT AsIID(const IID& a_iid, ComPtr<U>* a_ptr) const noexcept
{
return _ptr->QueryInterface(a_iid, reinterpret_cast<void**>(a_ptr->ReleaseAndGetAddressOf()));
}
HRESULT CopyTo(const IID& a_iid, void** a_ptr) const noexcept
{
return _ptr->QueryInterface(a_iid, a_ptr);
}
HRESULT CopyTo(T** a_ptr) const noexcept
{
TryAddRef();
*a_ptr = _ptr;
return 0;
}
template <class U>
HRESULT CopyTo(U** a_ptr) const noexcept
{
return _ptr->QueryInterface(__uuidof(U), reinterpret_cast<void**>(a_ptr));
}
protected:
template <class U>
friend struct ComPtr;
void TryAddRef() const noexcept
{
if (_ptr)
_ptr->AddRef();
}
std::uint32_t TryRelease() noexcept
{
T* ptr = _ptr;
if (ptr) {
_ptr = nullptr;
return ptr->Release();
}
return 0;
}
T* _ptr{ nullptr };
};
}
@@ -0,0 +1,784 @@
#pragma once
#include "REX/W32/DXGI.h"
namespace REX::W32
{
struct ID3DBlob;
struct ID3DDestructionNotifier;
struct ID3DInclude;
}
namespace REX::W32
{
enum D3D_CBUFFER_TYPE
{
D3D_CT_CBUFFER = 0,
D3D_CT_TBUFFER = (D3D_CT_CBUFFER + 1),
D3D_CT_INTERFACE_POINTERS = (D3D_CT_TBUFFER + 1),
D3D_CT_RESOURCE_BIND_INFO = (D3D_CT_INTERFACE_POINTERS + 1),
D3D10_CT_CBUFFER = D3D_CT_CBUFFER,
D3D10_CT_TBUFFER = D3D_CT_TBUFFER,
D3D11_CT_CBUFFER = D3D_CT_CBUFFER,
D3D11_CT_TBUFFER = D3D_CT_TBUFFER,
D3D11_CT_INTERFACE_POINTERS = D3D_CT_INTERFACE_POINTERS,
D3D11_CT_RESOURCE_BIND_INFO = D3D_CT_RESOURCE_BIND_INFO,
};
enum D3D_DRIVER_TYPE
{
D3D_DRIVER_TYPE_UNKNOWN = 0,
D3D_DRIVER_TYPE_HARDWARE = (D3D_DRIVER_TYPE_UNKNOWN + 1),
D3D_DRIVER_TYPE_REFERENCE = (D3D_DRIVER_TYPE_HARDWARE + 1),
D3D_DRIVER_TYPE_NULL = (D3D_DRIVER_TYPE_REFERENCE + 1),
D3D_DRIVER_TYPE_SOFTWARE = (D3D_DRIVER_TYPE_NULL + 1),
D3D_DRIVER_TYPE_WARP = (D3D_DRIVER_TYPE_SOFTWARE + 1),
};
enum D3D_FEATURE_LEVEL
{
D3D_FEATURE_LEVEL_1_0_CORE = 0x1000,
D3D_FEATURE_LEVEL_9_1 = 0x9100,
D3D_FEATURE_LEVEL_9_2 = 0x9200,
D3D_FEATURE_LEVEL_9_3 = 0x9300,
D3D_FEATURE_LEVEL_10_0 = 0xA000,
D3D_FEATURE_LEVEL_10_1 = 0xA100,
D3D_FEATURE_LEVEL_11_0 = 0xB000,
D3D_FEATURE_LEVEL_11_1 = 0xB100,
D3D_FEATURE_LEVEL_12_0 = 0xC000,
D3D_FEATURE_LEVEL_12_1 = 0xC100,
D3D_FEATURE_LEVEL_12_2 = 0xC200,
};
enum D3D_INCLUDE_TYPE
{
D3D_INCLUDE_LOCAL = 0,
D3D_INCLUDE_SYSTEM = (D3D_INCLUDE_LOCAL + 1),
D3D10_INCLUDE_LOCAL = D3D_INCLUDE_LOCAL,
D3D10_INCLUDE_SYSTEM = D3D_INCLUDE_SYSTEM,
D3D_INCLUDE_FORCE_DWORD = 0x7FFFFFFF,
};
enum D3D_INTERPOLATION_MODE
{
D3D_INTERPOLATION_UNDEFINED = 0,
D3D_INTERPOLATION_CONSTANT = 1,
D3D_INTERPOLATION_LINEAR = 2,
D3D_INTERPOLATION_LINEAR_CENTROID = 3,
D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE = 4,
D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID = 5,
D3D_INTERPOLATION_LINEAR_SAMPLE = 6,
D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE = 7,
};
enum D3D_MIN_PRECISION
{
D3D_MIN_PRECISION_DEFAULT = 0,
D3D_MIN_PRECISION_FLOAT_16 = 1,
D3D_MIN_PRECISION_FLOAT_2_8 = 2,
D3D_MIN_PRECISION_RESERVED = 3,
D3D_MIN_PRECISION_SINT_16 = 4,
D3D_MIN_PRECISION_UINT_16 = 5,
D3D_MIN_PRECISION_ANY_16 = 0xF0,
D3D_MIN_PRECISION_ANY_10 = 0xF1,
};
enum D3D_NAME
{
D3D_NAME_UNDEFINED = 0,
D3D_NAME_POSITION = 1,
D3D_NAME_CLIP_DISTANCE = 2,
D3D_NAME_CULL_DISTANCE = 3,
D3D_NAME_RENDER_TARGET_ARRAY_INDEX = 4,
D3D_NAME_VIEWPORT_ARRAY_INDEX = 5,
D3D_NAME_VERTEX_ID = 6,
D3D_NAME_PRIMITIVE_ID = 7,
D3D_NAME_INSTANCE_ID = 8,
D3D_NAME_IS_FRONT_FACE = 9,
D3D_NAME_SAMPLE_INDEX = 10,
D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR = 11,
D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = 12,
D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR = 13,
D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR = 14,
D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR = 15,
D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR = 16,
D3D_NAME_BARYCENTRICS = 23,
D3D_NAME_SHADINGRATE = 24,
D3D_NAME_CULLPRIMITIVE = 25,
D3D_NAME_TARGET = 64,
D3D_NAME_DEPTH = 65,
D3D_NAME_COVERAGE = 66,
D3D_NAME_DEPTH_GREATER_EQUAL = 67,
D3D_NAME_DEPTH_LESS_EQUAL = 68,
D3D_NAME_STENCIL_REF = 69,
D3D_NAME_INNER_COVERAGE = 70,
D3D10_NAME_UNDEFINED = D3D_NAME_UNDEFINED,
D3D10_NAME_POSITION = D3D_NAME_POSITION,
D3D10_NAME_CLIP_DISTANCE = D3D_NAME_CLIP_DISTANCE,
D3D10_NAME_CULL_DISTANCE = D3D_NAME_CULL_DISTANCE,
D3D10_NAME_RENDER_TARGET_ARRAY_INDEX = D3D_NAME_RENDER_TARGET_ARRAY_INDEX,
D3D10_NAME_VIEWPORT_ARRAY_INDEX = D3D_NAME_VIEWPORT_ARRAY_INDEX,
D3D10_NAME_VERTEX_ID = D3D_NAME_VERTEX_ID,
D3D10_NAME_PRIMITIVE_ID = D3D_NAME_PRIMITIVE_ID,
D3D10_NAME_INSTANCE_ID = D3D_NAME_INSTANCE_ID,
D3D10_NAME_IS_FRONT_FACE = D3D_NAME_IS_FRONT_FACE,
D3D10_NAME_SAMPLE_INDEX = D3D_NAME_SAMPLE_INDEX,
D3D10_NAME_TARGET = D3D_NAME_TARGET,
D3D10_NAME_DEPTH = D3D_NAME_DEPTH,
D3D10_NAME_COVERAGE = D3D_NAME_COVERAGE,
D3D11_NAME_FINAL_QUAD_EDGE_TESSFACTOR = D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR,
D3D11_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR,
D3D11_NAME_FINAL_TRI_EDGE_TESSFACTOR = D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR,
D3D11_NAME_FINAL_TRI_INSIDE_TESSFACTOR = D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR,
D3D11_NAME_FINAL_LINE_DETAIL_TESSFACTOR = D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR,
D3D11_NAME_FINAL_LINE_DENSITY_TESSFACTOR = D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR,
D3D11_NAME_DEPTH_GREATER_EQUAL = D3D_NAME_DEPTH_GREATER_EQUAL,
D3D11_NAME_DEPTH_LESS_EQUAL = D3D_NAME_DEPTH_LESS_EQUAL,
D3D11_NAME_STENCIL_REF = D3D_NAME_STENCIL_REF,
D3D11_NAME_INNER_COVERAGE = D3D_NAME_INNER_COVERAGE,
D3D12_NAME_BARYCENTRICS = D3D_NAME_BARYCENTRICS,
D3D12_NAME_SHADINGRATE = D3D_NAME_SHADINGRATE,
D3D12_NAME_CULLPRIMITIVE = D3D_NAME_CULLPRIMITIVE,
};
enum D3D_PARAMETER_FLAGS
{
D3D_PF_NONE = 0,
D3D_PF_IN = 0x1,
D3D_PF_OUT = 0x2,
D3D_PF_FORCE_DWORD = 0x7FFFFFFF,
};
enum D3D_PRIMITIVE
{
D3D_PRIMITIVE_UNDEFINED = 0,
D3D_PRIMITIVE_POINT = 1,
D3D_PRIMITIVE_LINE = 2,
D3D_PRIMITIVE_TRIANGLE = 3,
D3D_PRIMITIVE_LINE_ADJ = 6,
D3D_PRIMITIVE_TRIANGLE_ADJ = 7,
D3D_PRIMITIVE_1_CONTROL_POINT_PATCH = 8,
D3D_PRIMITIVE_2_CONTROL_POINT_PATCH = 9,
D3D_PRIMITIVE_3_CONTROL_POINT_PATCH = 10,
D3D_PRIMITIVE_4_CONTROL_POINT_PATCH = 11,
D3D_PRIMITIVE_5_CONTROL_POINT_PATCH = 12,
D3D_PRIMITIVE_6_CONTROL_POINT_PATCH = 13,
D3D_PRIMITIVE_7_CONTROL_POINT_PATCH = 14,
D3D_PRIMITIVE_8_CONTROL_POINT_PATCH = 15,
D3D_PRIMITIVE_9_CONTROL_POINT_PATCH = 16,
D3D_PRIMITIVE_10_CONTROL_POINT_PATCH = 17,
D3D_PRIMITIVE_11_CONTROL_POINT_PATCH = 18,
D3D_PRIMITIVE_12_CONTROL_POINT_PATCH = 19,
D3D_PRIMITIVE_13_CONTROL_POINT_PATCH = 20,
D3D_PRIMITIVE_14_CONTROL_POINT_PATCH = 21,
D3D_PRIMITIVE_15_CONTROL_POINT_PATCH = 22,
D3D_PRIMITIVE_16_CONTROL_POINT_PATCH = 23,
D3D_PRIMITIVE_17_CONTROL_POINT_PATCH = 24,
D3D_PRIMITIVE_18_CONTROL_POINT_PATCH = 25,
D3D_PRIMITIVE_19_CONTROL_POINT_PATCH = 26,
D3D_PRIMITIVE_20_CONTROL_POINT_PATCH = 27,
D3D_PRIMITIVE_21_CONTROL_POINT_PATCH = 28,
D3D_PRIMITIVE_22_CONTROL_POINT_PATCH = 29,
D3D_PRIMITIVE_23_CONTROL_POINT_PATCH = 30,
D3D_PRIMITIVE_24_CONTROL_POINT_PATCH = 31,
D3D_PRIMITIVE_25_CONTROL_POINT_PATCH = 32,
D3D_PRIMITIVE_26_CONTROL_POINT_PATCH = 33,
D3D_PRIMITIVE_27_CONTROL_POINT_PATCH = 34,
D3D_PRIMITIVE_28_CONTROL_POINT_PATCH = 35,
D3D_PRIMITIVE_29_CONTROL_POINT_PATCH = 36,
D3D_PRIMITIVE_30_CONTROL_POINT_PATCH = 37,
D3D_PRIMITIVE_31_CONTROL_POINT_PATCH = 38,
D3D_PRIMITIVE_32_CONTROL_POINT_PATCH = 39,
D3D10_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED,
D3D10_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT,
D3D10_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE,
D3D10_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE,
D3D10_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ,
D3D10_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ,
D3D11_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED,
D3D11_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT,
D3D11_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE,
D3D11_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE,
D3D11_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ,
D3D11_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ,
D3D11_PRIMITIVE_1_CONTROL_POINT_PATCH = D3D_PRIMITIVE_1_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_2_CONTROL_POINT_PATCH = D3D_PRIMITIVE_2_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_3_CONTROL_POINT_PATCH = D3D_PRIMITIVE_3_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_4_CONTROL_POINT_PATCH = D3D_PRIMITIVE_4_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_5_CONTROL_POINT_PATCH = D3D_PRIMITIVE_5_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_6_CONTROL_POINT_PATCH = D3D_PRIMITIVE_6_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_7_CONTROL_POINT_PATCH = D3D_PRIMITIVE_7_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_8_CONTROL_POINT_PATCH = D3D_PRIMITIVE_8_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_9_CONTROL_POINT_PATCH = D3D_PRIMITIVE_9_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_10_CONTROL_POINT_PATCH = D3D_PRIMITIVE_10_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_11_CONTROL_POINT_PATCH = D3D_PRIMITIVE_11_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_12_CONTROL_POINT_PATCH = D3D_PRIMITIVE_12_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_13_CONTROL_POINT_PATCH = D3D_PRIMITIVE_13_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_14_CONTROL_POINT_PATCH = D3D_PRIMITIVE_14_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_15_CONTROL_POINT_PATCH = D3D_PRIMITIVE_15_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_16_CONTROL_POINT_PATCH = D3D_PRIMITIVE_16_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_17_CONTROL_POINT_PATCH = D3D_PRIMITIVE_17_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_18_CONTROL_POINT_PATCH = D3D_PRIMITIVE_18_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_19_CONTROL_POINT_PATCH = D3D_PRIMITIVE_19_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_20_CONTROL_POINT_PATCH = D3D_PRIMITIVE_20_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_21_CONTROL_POINT_PATCH = D3D_PRIMITIVE_21_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_22_CONTROL_POINT_PATCH = D3D_PRIMITIVE_22_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_23_CONTROL_POINT_PATCH = D3D_PRIMITIVE_23_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_24_CONTROL_POINT_PATCH = D3D_PRIMITIVE_24_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_25_CONTROL_POINT_PATCH = D3D_PRIMITIVE_25_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_26_CONTROL_POINT_PATCH = D3D_PRIMITIVE_26_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_27_CONTROL_POINT_PATCH = D3D_PRIMITIVE_27_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_28_CONTROL_POINT_PATCH = D3D_PRIMITIVE_28_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_29_CONTROL_POINT_PATCH = D3D_PRIMITIVE_29_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_30_CONTROL_POINT_PATCH = D3D_PRIMITIVE_30_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_31_CONTROL_POINT_PATCH = D3D_PRIMITIVE_31_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_32_CONTROL_POINT_PATCH = D3D_PRIMITIVE_32_CONTROL_POINT_PATCH,
};
enum D3D_PRIMITIVE_TOPOLOGY
{
D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0,
D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1,
D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2,
D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5,
D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10,
D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13,
D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33,
D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34,
D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = 35,
D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = 36,
D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = 37,
D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = 38,
D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = 39,
D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = 40,
D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = 41,
D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = 42,
D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = 43,
D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = 44,
D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = 45,
D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = 46,
D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = 47,
D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = 48,
D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = 49,
D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = 50,
D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = 51,
D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = 52,
D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = 53,
D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = 54,
D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = 55,
D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = 56,
D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = 57,
D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = 58,
D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = 59,
D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = 60,
D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = 61,
D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = 62,
D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = 63,
D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64,
D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED,
D3D10_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
D3D10_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST,
D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED,
D3D11_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
D3D11_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST,
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST,
};
enum D3D_REGISTER_COMPONENT_TYPE
{
D3D_REGISTER_COMPONENT_UNKNOWN = 0,
D3D_REGISTER_COMPONENT_UINT32 = 1,
D3D_REGISTER_COMPONENT_SINT32 = 2,
D3D_REGISTER_COMPONENT_FLOAT32 = 3,
D3D10_REGISTER_COMPONENT_UNKNOWN = D3D_REGISTER_COMPONENT_UNKNOWN,
D3D10_REGISTER_COMPONENT_UINT32 = D3D_REGISTER_COMPONENT_UINT32,
D3D10_REGISTER_COMPONENT_SINT32 = D3D_REGISTER_COMPONENT_SINT32,
D3D10_REGISTER_COMPONENT_FLOAT32 = D3D_REGISTER_COMPONENT_FLOAT32,
};
enum D3D_RESOURCE_RETURN_TYPE
{
D3D_RETURN_TYPE_UNORM = 1,
D3D_RETURN_TYPE_SNORM = 2,
D3D_RETURN_TYPE_SINT = 3,
D3D_RETURN_TYPE_UINT = 4,
D3D_RETURN_TYPE_FLOAT = 5,
D3D_RETURN_TYPE_MIXED = 6,
D3D_RETURN_TYPE_DOUBLE = 7,
D3D_RETURN_TYPE_CONTINUED = 8,
D3D10_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM,
D3D10_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM,
D3D10_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT,
D3D10_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT,
D3D10_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT,
D3D10_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED,
D3D11_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM,
D3D11_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM,
D3D11_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT,
D3D11_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT,
D3D11_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT,
D3D11_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED,
D3D11_RETURN_TYPE_DOUBLE = D3D_RETURN_TYPE_DOUBLE,
D3D11_RETURN_TYPE_CONTINUED = D3D_RETURN_TYPE_CONTINUED,
};
enum D3D_SHADER_CBUFFER_FLAGS
{
D3D_CBF_USERPACKED = 1,
D3D10_CBF_USERPACKED = D3D_CBF_USERPACKED,
D3D_CBF_FORCE_DWORD = 0x7FFFFFFF,
};
enum D3D_SHADER_INPUT_FLAGS
{
D3D_SIF_USERPACKED = 0x1,
D3D_SIF_COMPARISON_SAMPLER = 0x2,
D3D_SIF_TEXTURE_COMPONENT_0 = 0x4,
D3D_SIF_TEXTURE_COMPONENT_1 = 0x8,
D3D_SIF_TEXTURE_COMPONENTS = 0xc,
D3D_SIF_UNUSED = 0x10,
D3D10_SIF_USERPACKED = D3D_SIF_USERPACKED,
D3D10_SIF_COMPARISON_SAMPLER = D3D_SIF_COMPARISON_SAMPLER,
D3D10_SIF_TEXTURE_COMPONENT_0 = D3D_SIF_TEXTURE_COMPONENT_0,
D3D10_SIF_TEXTURE_COMPONENT_1 = D3D_SIF_TEXTURE_COMPONENT_1,
D3D10_SIF_TEXTURE_COMPONENTS = D3D_SIF_TEXTURE_COMPONENTS,
D3D_SIF_FORCE_DWORD = 0x7FFFFFFF,
};
enum D3D_SHADER_INPUT_TYPE
{
D3D_SIT_CBUFFER = 0,
D3D_SIT_TBUFFER = (D3D_SIT_CBUFFER + 1),
D3D_SIT_TEXTURE = (D3D_SIT_TBUFFER + 1),
D3D_SIT_SAMPLER = (D3D_SIT_TEXTURE + 1),
D3D_SIT_UAV_RWTYPED = (D3D_SIT_SAMPLER + 1),
D3D_SIT_STRUCTURED = (D3D_SIT_UAV_RWTYPED + 1),
D3D_SIT_UAV_RWSTRUCTURED = (D3D_SIT_STRUCTURED + 1),
D3D_SIT_BYTEADDRESS = (D3D_SIT_UAV_RWSTRUCTURED + 1),
D3D_SIT_UAV_RWBYTEADDRESS = (D3D_SIT_BYTEADDRESS + 1),
D3D_SIT_UAV_APPEND_STRUCTURED = (D3D_SIT_UAV_RWBYTEADDRESS + 1),
D3D_SIT_UAV_CONSUME_STRUCTURED = (D3D_SIT_UAV_APPEND_STRUCTURED + 1),
D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = (D3D_SIT_UAV_CONSUME_STRUCTURED + 1),
D3D_SIT_RTACCELERATIONSTRUCTURE = (D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER + 1),
D3D_SIT_UAV_FEEDBACKTEXTURE = (D3D_SIT_RTACCELERATIONSTRUCTURE + 1),
D3D10_SIT_CBUFFER = D3D_SIT_CBUFFER,
D3D10_SIT_TBUFFER = D3D_SIT_TBUFFER,
D3D10_SIT_TEXTURE = D3D_SIT_TEXTURE,
D3D10_SIT_SAMPLER = D3D_SIT_SAMPLER,
D3D11_SIT_UAV_RWTYPED = D3D_SIT_UAV_RWTYPED,
D3D11_SIT_STRUCTURED = D3D_SIT_STRUCTURED,
D3D11_SIT_UAV_RWSTRUCTURED = D3D_SIT_UAV_RWSTRUCTURED,
D3D11_SIT_BYTEADDRESS = D3D_SIT_BYTEADDRESS,
D3D11_SIT_UAV_RWBYTEADDRESS = D3D_SIT_UAV_RWBYTEADDRESS,
D3D11_SIT_UAV_APPEND_STRUCTURED = D3D_SIT_UAV_APPEND_STRUCTURED,
D3D11_SIT_UAV_CONSUME_STRUCTURED = D3D_SIT_UAV_CONSUME_STRUCTURED,
D3D11_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER,
};
enum D3D_SHADER_VARIABLE_CLASS
{
D3D_SVC_SCALAR = 0,
D3D_SVC_VECTOR = (D3D_SVC_SCALAR + 1),
D3D_SVC_MATRIX_ROWS = (D3D_SVC_VECTOR + 1),
D3D_SVC_MATRIX_COLUMNS = (D3D_SVC_MATRIX_ROWS + 1),
D3D_SVC_OBJECT = (D3D_SVC_MATRIX_COLUMNS + 1),
D3D_SVC_STRUCT = (D3D_SVC_OBJECT + 1),
D3D_SVC_INTERFACE_CLASS = (D3D_SVC_STRUCT + 1),
D3D_SVC_INTERFACE_POINTER = (D3D_SVC_INTERFACE_CLASS + 1),
D3D10_SVC_SCALAR = D3D_SVC_SCALAR,
D3D10_SVC_VECTOR = D3D_SVC_VECTOR,
D3D10_SVC_MATRIX_ROWS = D3D_SVC_MATRIX_ROWS,
D3D10_SVC_MATRIX_COLUMNS = D3D_SVC_MATRIX_COLUMNS,
D3D10_SVC_OBJECT = D3D_SVC_OBJECT,
D3D10_SVC_STRUCT = D3D_SVC_STRUCT,
D3D11_SVC_INTERFACE_CLASS = D3D_SVC_INTERFACE_CLASS,
D3D11_SVC_INTERFACE_POINTER = D3D_SVC_INTERFACE_POINTER,
D3D_SVC_FORCE_DWORD = 0x7FFFFFFF,
};
enum D3D_SHADER_VARIABLE_FLAGS
{
D3D_SVF_USERPACKED = 1,
D3D_SVF_USED = 2,
D3D_SVF_INTERFACE_POINTER = 4,
D3D_SVF_INTERFACE_PARAMETER = 8,
D3D10_SVF_USERPACKED = D3D_SVF_USERPACKED,
D3D10_SVF_USED = D3D_SVF_USED,
D3D11_SVF_INTERFACE_POINTER = D3D_SVF_INTERFACE_POINTER,
D3D11_SVF_INTERFACE_PARAMETER = D3D_SVF_INTERFACE_PARAMETER,
D3D_SVF_FORCE_DWORD = 0x7FFFFFFF,
};
enum D3D_SHADER_VARIABLE_TYPE
{
D3D_SVT_VOID = 0,
D3D_SVT_BOOL = 1,
D3D_SVT_INT = 2,
D3D_SVT_FLOAT = 3,
D3D_SVT_STRING = 4,
D3D_SVT_TEXTURE = 5,
D3D_SVT_TEXTURE1D = 6,
D3D_SVT_TEXTURE2D = 7,
D3D_SVT_TEXTURE3D = 8,
D3D_SVT_TEXTURECUBE = 9,
D3D_SVT_SAMPLER = 10,
D3D_SVT_SAMPLER1D = 11,
D3D_SVT_SAMPLER2D = 12,
D3D_SVT_SAMPLER3D = 13,
D3D_SVT_SAMPLERCUBE = 14,
D3D_SVT_PIXELSHADER = 15,
D3D_SVT_VERTEXSHADER = 16,
D3D_SVT_PIXELFRAGMENT = 17,
D3D_SVT_VERTEXFRAGMENT = 18,
D3D_SVT_UINT = 19,
D3D_SVT_UINT8 = 20,
D3D_SVT_GEOMETRYSHADER = 21,
D3D_SVT_RASTERIZER = 22,
D3D_SVT_DEPTHSTENCIL = 23,
D3D_SVT_BLEND = 24,
D3D_SVT_BUFFER = 25,
D3D_SVT_CBUFFER = 26,
D3D_SVT_TBUFFER = 27,
D3D_SVT_TEXTURE1DARRAY = 28,
D3D_SVT_TEXTURE2DARRAY = 29,
D3D_SVT_RENDERTARGETVIEW = 30,
D3D_SVT_DEPTHSTENCILVIEW = 31,
D3D_SVT_TEXTURE2DMS = 32,
D3D_SVT_TEXTURE2DMSARRAY = 33,
D3D_SVT_TEXTURECUBEARRAY = 34,
D3D_SVT_HULLSHADER = 35,
D3D_SVT_DOMAINSHADER = 36,
D3D_SVT_INTERFACE_POINTER = 37,
D3D_SVT_COMPUTESHADER = 38,
D3D_SVT_DOUBLE = 39,
D3D_SVT_RWTEXTURE1D = 40,
D3D_SVT_RWTEXTURE1DARRAY = 41,
D3D_SVT_RWTEXTURE2D = 42,
D3D_SVT_RWTEXTURE2DARRAY = 43,
D3D_SVT_RWTEXTURE3D = 44,
D3D_SVT_RWBUFFER = 45,
D3D_SVT_BYTEADDRESS_BUFFER = 46,
D3D_SVT_RWBYTEADDRESS_BUFFER = 47,
D3D_SVT_STRUCTURED_BUFFER = 48,
D3D_SVT_RWSTRUCTURED_BUFFER = 49,
D3D_SVT_APPEND_STRUCTURED_BUFFER = 50,
D3D_SVT_CONSUME_STRUCTURED_BUFFER = 51,
D3D_SVT_MIN8FLOAT = 52,
D3D_SVT_MIN10FLOAT = 53,
D3D_SVT_MIN16FLOAT = 54,
D3D_SVT_MIN12INT = 55,
D3D_SVT_MIN16INT = 56,
D3D_SVT_MIN16UINT = 57,
D3D_SVT_INT16 = 58,
D3D_SVT_UINT16 = 59,
D3D_SVT_FLOAT16 = 60,
D3D_SVT_INT64 = 61,
D3D_SVT_UINT64 = 62,
D3D10_SVT_VOID = D3D_SVT_VOID,
D3D10_SVT_BOOL = D3D_SVT_BOOL,
D3D10_SVT_INT = D3D_SVT_INT,
D3D10_SVT_FLOAT = D3D_SVT_FLOAT,
D3D10_SVT_STRING = D3D_SVT_STRING,
D3D10_SVT_TEXTURE = D3D_SVT_TEXTURE,
D3D10_SVT_TEXTURE1D = D3D_SVT_TEXTURE1D,
D3D10_SVT_TEXTURE2D = D3D_SVT_TEXTURE2D,
D3D10_SVT_TEXTURE3D = D3D_SVT_TEXTURE3D,
D3D10_SVT_TEXTURECUBE = D3D_SVT_TEXTURECUBE,
D3D10_SVT_SAMPLER = D3D_SVT_SAMPLER,
D3D10_SVT_SAMPLER1D = D3D_SVT_SAMPLER1D,
D3D10_SVT_SAMPLER2D = D3D_SVT_SAMPLER2D,
D3D10_SVT_SAMPLER3D = D3D_SVT_SAMPLER3D,
D3D10_SVT_SAMPLERCUBE = D3D_SVT_SAMPLERCUBE,
D3D10_SVT_PIXELSHADER = D3D_SVT_PIXELSHADER,
D3D10_SVT_VERTEXSHADER = D3D_SVT_VERTEXSHADER,
D3D10_SVT_PIXELFRAGMENT = D3D_SVT_PIXELFRAGMENT,
D3D10_SVT_VERTEXFRAGMENT = D3D_SVT_VERTEXFRAGMENT,
D3D10_SVT_UINT = D3D_SVT_UINT,
D3D10_SVT_UINT8 = D3D_SVT_UINT8,
D3D10_SVT_GEOMETRYSHADER = D3D_SVT_GEOMETRYSHADER,
D3D10_SVT_RASTERIZER = D3D_SVT_RASTERIZER,
D3D10_SVT_DEPTHSTENCIL = D3D_SVT_DEPTHSTENCIL,
D3D10_SVT_BLEND = D3D_SVT_BLEND,
D3D10_SVT_BUFFER = D3D_SVT_BUFFER,
D3D10_SVT_CBUFFER = D3D_SVT_CBUFFER,
D3D10_SVT_TBUFFER = D3D_SVT_TBUFFER,
D3D10_SVT_TEXTURE1DARRAY = D3D_SVT_TEXTURE1DARRAY,
D3D10_SVT_TEXTURE2DARRAY = D3D_SVT_TEXTURE2DARRAY,
D3D10_SVT_RENDERTARGETVIEW = D3D_SVT_RENDERTARGETVIEW,
D3D10_SVT_DEPTHSTENCILVIEW = D3D_SVT_DEPTHSTENCILVIEW,
D3D10_SVT_TEXTURE2DMS = D3D_SVT_TEXTURE2DMS,
D3D10_SVT_TEXTURE2DMSARRAY = D3D_SVT_TEXTURE2DMSARRAY,
D3D10_SVT_TEXTURECUBEARRAY = D3D_SVT_TEXTURECUBEARRAY,
D3D11_SVT_HULLSHADER = D3D_SVT_HULLSHADER,
D3D11_SVT_DOMAINSHADER = D3D_SVT_DOMAINSHADER,
D3D11_SVT_INTERFACE_POINTER = D3D_SVT_INTERFACE_POINTER,
D3D11_SVT_COMPUTESHADER = D3D_SVT_COMPUTESHADER,
D3D11_SVT_DOUBLE = D3D_SVT_DOUBLE,
D3D11_SVT_RWTEXTURE1D = D3D_SVT_RWTEXTURE1D,
D3D11_SVT_RWTEXTURE1DARRAY = D3D_SVT_RWTEXTURE1DARRAY,
D3D11_SVT_RWTEXTURE2D = D3D_SVT_RWTEXTURE2D,
D3D11_SVT_RWTEXTURE2DARRAY = D3D_SVT_RWTEXTURE2DARRAY,
D3D11_SVT_RWTEXTURE3D = D3D_SVT_RWTEXTURE3D,
D3D11_SVT_RWBUFFER = D3D_SVT_RWBUFFER,
D3D11_SVT_BYTEADDRESS_BUFFER = D3D_SVT_BYTEADDRESS_BUFFER,
D3D11_SVT_RWBYTEADDRESS_BUFFER = D3D_SVT_RWBYTEADDRESS_BUFFER,
D3D11_SVT_STRUCTURED_BUFFER = D3D_SVT_STRUCTURED_BUFFER,
D3D11_SVT_RWSTRUCTURED_BUFFER = D3D_SVT_RWSTRUCTURED_BUFFER,
D3D11_SVT_APPEND_STRUCTURED_BUFFER = D3D_SVT_APPEND_STRUCTURED_BUFFER,
D3D11_SVT_CONSUME_STRUCTURED_BUFFER = D3D_SVT_CONSUME_STRUCTURED_BUFFER,
D3D_SVT_FORCE_DWORD = 0x7FFFFFFF,
};
enum D3D_SRV_DIMENSION
{
D3D_SRV_DIMENSION_UNKNOWN = 0,
D3D_SRV_DIMENSION_BUFFER = 1,
D3D_SRV_DIMENSION_TEXTURE1D = 2,
D3D_SRV_DIMENSION_TEXTURE1DARRAY = 3,
D3D_SRV_DIMENSION_TEXTURE2D = 4,
D3D_SRV_DIMENSION_TEXTURE2DARRAY = 5,
D3D_SRV_DIMENSION_TEXTURE2DMS = 6,
D3D_SRV_DIMENSION_TEXTURE2DMSARRAY = 7,
D3D_SRV_DIMENSION_TEXTURE3D = 8,
D3D_SRV_DIMENSION_TEXTURECUBE = 9,
D3D_SRV_DIMENSION_TEXTURECUBEARRAY = 10,
D3D_SRV_DIMENSION_BUFFEREX = 11,
D3D10_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN,
D3D10_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER,
D3D10_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D,
D3D10_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY,
D3D10_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D,
D3D10_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY,
D3D10_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS,
D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY,
D3D10_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D,
D3D10_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE,
D3D10_1_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN,
D3D10_1_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER,
D3D10_1_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D,
D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY,
D3D10_1_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D,
D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY,
D3D10_1_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS,
D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY,
D3D10_1_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D,
D3D10_1_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE,
D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY,
D3D11_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN,
D3D11_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER,
D3D11_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D,
D3D11_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY,
D3D11_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D,
D3D11_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY,
D3D11_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS,
D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY,
D3D11_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D,
D3D11_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE,
D3D11_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY,
D3D11_SRV_DIMENSION_BUFFEREX = D3D_SRV_DIMENSION_BUFFEREX,
};
enum D3D_TESSELLATOR_DOMAIN
{
D3D_TESSELLATOR_DOMAIN_UNDEFINED = 0,
D3D_TESSELLATOR_DOMAIN_ISOLINE = 1,
D3D_TESSELLATOR_DOMAIN_TRI = 2,
D3D_TESSELLATOR_DOMAIN_QUAD = 3,
D3D11_TESSELLATOR_DOMAIN_UNDEFINED = D3D_TESSELLATOR_DOMAIN_UNDEFINED,
D3D11_TESSELLATOR_DOMAIN_ISOLINE = D3D_TESSELLATOR_DOMAIN_ISOLINE,
D3D11_TESSELLATOR_DOMAIN_TRI = D3D_TESSELLATOR_DOMAIN_TRI,
D3D11_TESSELLATOR_DOMAIN_QUAD = D3D_TESSELLATOR_DOMAIN_QUAD,
};
enum D3D_TESSELLATOR_OUTPUT_PRIMITIVE
{
D3D_TESSELLATOR_OUTPUT_UNDEFINED = 0,
D3D_TESSELLATOR_OUTPUT_POINT = 1,
D3D_TESSELLATOR_OUTPUT_LINE = 2,
D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW = 3,
D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4,
D3D11_TESSELLATOR_OUTPUT_UNDEFINED = D3D_TESSELLATOR_OUTPUT_UNDEFINED,
D3D11_TESSELLATOR_OUTPUT_POINT = D3D_TESSELLATOR_OUTPUT_POINT,
D3D11_TESSELLATOR_OUTPUT_LINE = D3D_TESSELLATOR_OUTPUT_LINE,
D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW,
D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW,
};
enum D3D_TESSELLATOR_PARTITIONING
{
D3D_TESSELLATOR_PARTITIONING_UNDEFINED = 0,
D3D_TESSELLATOR_PARTITIONING_INTEGER = 1,
D3D_TESSELLATOR_PARTITIONING_POW2 = 2,
D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 3,
D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4,
D3D11_TESSELLATOR_PARTITIONING_UNDEFINED = D3D_TESSELLATOR_PARTITIONING_UNDEFINED,
D3D11_TESSELLATOR_PARTITIONING_INTEGER = D3D_TESSELLATOR_PARTITIONING_INTEGER,
D3D11_TESSELLATOR_PARTITIONING_POW2 = D3D_TESSELLATOR_PARTITIONING_POW2,
D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD,
D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN,
};
}
namespace REX::W32
{
using D3DCOLOR = std::uint32_t;
struct D3DMATRIX
{
union
{
struct
{
float m11, m12, m13, m14;
float m21, m22, m23, m24;
float m31, m32, m33, m34;
float m41, m42, m43, m44;
};
float m[4][4];
};
};
struct D3DRECT
{
std::int32_t x1;
std::int32_t y1;
std::int32_t x2;
std::int32_t y2;
};
struct D3DVECTOR
{
float x;
float y;
float z;
};
struct D3D_SHADER_MACRO
{
const char* name;
const char* definition;
};
struct XMCOLOR
{
union
{
struct
{
std::uint8_t b;
std::uint8_t g;
std::uint8_t r;
std::uint8_t a;
};
std::uint32_t c;
};
};
static_assert(sizeof(XMCOLOR) == 0x4);
struct XMFLOAT3
{
float x;
float y;
float z;
};
static_assert(sizeof(XMFLOAT3) == 0xC);
struct XMFLOAT4
{
float x;
float y;
float z;
float w;
};
static_assert(sizeof(XMFLOAT4) == 0x10);
struct XMFLOAT4X4
{
float m[4][4];
};
static_assert(sizeof(XMFLOAT4X4) == 0x40);
}
namespace REX::W32
{
using PFN_DESTRUCTION_CALLBACK = void(__stdcall*)(void* a_data);
}
namespace REX::W32
{
struct __declspec(novtable, uuid("8BA5FB08-5195-40e2-AC58-0D989C3A0102"))
ID3DBlob : public IUnknown
{
virtual void* GetBufferPointer(void) = 0;
virtual std::size_t GetBufferSize(void) = 0;
};
struct __declspec(novtable, uuid("A06EB39A-50DA-425B-8C31-4EECD6C270F3"))
ID3DDestructionNotifier : public IUnknown
{
virtual HRESULT RegisterDestructionCallback(PFN_DESTRUCTION_CALLBACK a_callbackFn, void* a_data, std::uint32_t* a_callbackID) = 0;
virtual HRESULT UnregisterDestructionCallback(std::uint32_t a_callbackID) = 0;
};
struct __declspec(novtable) // uuid(?)
ID3DInclude : public IUnknown
{
virtual HRESULT Open(D3D_INCLUDE_TYPE a_includeType, const char* a_fileName, const void* a_parentData, const void** a_data, std::uint32_t* a_bytes) = 0;
virtual HRESULT Close(const void* a_data) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_ID3DBlob{ 0xA06EB39A, 0x50DA, 0x425B, { 0x8C, 0x31, 0x4E, 0xEC, 0xD6, 0xC2, 0x70, 0xF3 } };
inline constexpr IID IID_ID3DDestructionNotifier{ 0xA06EB39A, 0x50DA, 0x425B, { 0x8C, 0x31, 0x4E, 0xEC, 0xD6, 0xC2, 0x70, 0xF3 } };
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,296 @@
#pragma once
#include "REX/W32/D3D11.h"
namespace REX::W32
{
struct ID3DDeviceContextState;
struct ID3DUserDefinedAnnotation;
struct ID3D11BlendState1;
struct ID3D11Device1;
struct ID3D11DeviceContext1;
struct ID3D11RasterizerState1;
struct ID3D11VideoContext1;
struct ID3D11VideoDevice1;
struct ID3D11VideoProcessorEnumerator1;
}
namespace REX::W32
{
enum D3D11_1_CREATE_DEVICE_CONTEXT_STATE_FLAG
{
D3D11_1_CREATE_DEVICE_CONTEXT_STATE_SINGLETHREADED = 0x1,
};
enum D3D11_COPY_FLAGS
{
D3D11_COPY_NO_OVERWRITE = 0x1,
D3D11_COPY_DISCARD = 0x2,
};
enum D3D11_CRYPTO_SESSION_STATUS
{
D3D11_CRYPTO_SESSION_STATUS_OK = 0,
D3D11_CRYPTO_SESSION_STATUS_KEY_LOST = 1,
D3D11_CRYPTO_SESSION_STATUS_KEY_AND_CONTENT_LOST = 2,
};
enum D3D11_LOGIC_OP
{
D3D11_LOGIC_OP_CLEAR = 0,
D3D11_LOGIC_OP_SET = (D3D11_LOGIC_OP_CLEAR + 1),
D3D11_LOGIC_OP_COPY = (D3D11_LOGIC_OP_SET + 1),
D3D11_LOGIC_OP_COPY_INVERTED = (D3D11_LOGIC_OP_COPY + 1),
D3D11_LOGIC_OP_NOOP = (D3D11_LOGIC_OP_COPY_INVERTED + 1),
D3D11_LOGIC_OP_INVERT = (D3D11_LOGIC_OP_NOOP + 1),
D3D11_LOGIC_OP_AND = (D3D11_LOGIC_OP_INVERT + 1),
D3D11_LOGIC_OP_NAND = (D3D11_LOGIC_OP_AND + 1),
D3D11_LOGIC_OP_OR = (D3D11_LOGIC_OP_NAND + 1),
D3D11_LOGIC_OP_NOR = (D3D11_LOGIC_OP_OR + 1),
D3D11_LOGIC_OP_XOR = (D3D11_LOGIC_OP_NOR + 1),
D3D11_LOGIC_OP_EQUIV = (D3D11_LOGIC_OP_XOR + 1),
D3D11_LOGIC_OP_AND_REVERSE = (D3D11_LOGIC_OP_EQUIV + 1),
D3D11_LOGIC_OP_AND_INVERTED = (D3D11_LOGIC_OP_AND_REVERSE + 1),
D3D11_LOGIC_OP_OR_REVERSE = (D3D11_LOGIC_OP_AND_INVERTED + 1),
D3D11_LOGIC_OP_OR_INVERTED = (D3D11_LOGIC_OP_OR_REVERSE + 1),
};
enum D3D11_VIDEO_DECODER_CAPS
{
D3D11_VIDEO_DECODER_CAPS_DOWNSAMPLE = 0x1,
D3D11_VIDEO_DECODER_CAPS_NON_REAL_TIME = 0x2,
D3D11_VIDEO_DECODER_CAPS_DOWNSAMPLE_DYNAMIC = 0x4,
D3D11_VIDEO_DECODER_CAPS_DOWNSAMPLE_REQUIRED = 0x8,
D3D11_VIDEO_DECODER_CAPS_UNSUPPORTED = 0x10,
};
enum D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINTS
{
D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINT_MULTIPLANE_OVERLAY_ROTATION = 0x1,
D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINT_MULTIPLANE_OVERLAY_RESIZE = 0x2,
D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINT_MULTIPLANE_OVERLAY_COLOR_SPACE_CONVERSION = 0x4,
D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINT_TRIPLE_BUFFER_OUTPUT = 0x8,
};
}
namespace REX::W32
{
struct D3D11_KEY_EXCHANGE_HW_PROTECTION_INPUT_DATA;
struct D3D11_KEY_EXCHANGE_HW_PROTECTION_OUTPUT_DATA;
struct D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK;
struct D3D11_KEY_EXCHANGE_HW_PROTECTION_DATA
{
std::uint32_t hwProtectionFunctionID;
D3D11_KEY_EXCHANGE_HW_PROTECTION_INPUT_DATA* inputData;
D3D11_KEY_EXCHANGE_HW_PROTECTION_OUTPUT_DATA* outputData;
HRESULT status;
};
struct D3D11_KEY_EXCHANGE_HW_PROTECTION_INPUT_DATA
{
std::uint32_t privateDataSize;
std::uint32_t hwProtectionDataSize;
std::uint8_t input[4];
};
struct D3D11_KEY_EXCHANGE_HW_PROTECTION_OUTPUT_DATA
{
std::uint32_t privateDataSize;
std::uint32_t maxHWProtectionDataSize;
std::uint32_t hwProtectionDataSize;
std::uint64_t transportTime;
std::uint64_t executionTime;
std::uint8_t output[4];
};
struct D3D11_RASTERIZER_DESC1
{
D3D11_FILL_MODE fillMode;
D3D11_CULL_MODE cullMode;
BOOL frontCounterClockwise;
std::int32_t depthBias;
float depthBiasClamp;
float slopeScaledDepthBias;
BOOL depthClipEnable;
BOOL scissorEnable;
BOOL multisampleEnable;
BOOL antialiasedLineEnable;
std::uint32_t forcedSampleCount;
};
struct D3D11_RENDER_TARGET_BLEND_DESC1
{
BOOL blendEnable;
BOOL logicOpEnable;
D3D11_BLEND srcBlend;
D3D11_BLEND destBlend;
D3D11_BLEND_OP blendOp;
D3D11_BLEND srcBlendAlpha;
D3D11_BLEND destBlendAlpha;
D3D11_BLEND_OP blendOpAlpha;
D3D11_LOGIC_OP logicOp;
std::uint8_t renderTargetWriteMask;
};
struct D3D11_VIDEO_DECODER_BEGIN_FRAME_CRYPTO_SESSION
{
ID3D11CryptoSession* cryptoSession;
std::uint32_t blobSize;
void* blob;
GUID* keyInfoId;
std::uint32_t privateDataSize;
void* privateData;
};
struct D3D11_VIDEO_DECODER_BUFFER_DESC1
{
D3D11_VIDEO_DECODER_BUFFER_TYPE bufferType;
std::uint32_t dataOffset;
std::uint32_t dataSize;
void* iv;
std::uint32_t ivSize;
D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK* subSampleMappingBlock;
std::uint32_t subSampleMappingCount;
};
struct D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK
{
std::uint32_t clearSize;
std::uint32_t encryptedSize;
};
struct D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT
{
BOOL enable;
std::uint32_t width;
std::uint32_t height;
DXGI_FORMAT format;
};
struct D3D11_VIDEO_SAMPLE_DESC
{
std::uint32_t width;
std::uint32_t height;
DXGI_FORMAT format;
DXGI_COLOR_SPACE_TYPE colorSpace;
};
struct D3D11_BLEND_DESC1
{
BOOL alphaToCoverageEnable;
BOOL independentBlendEnable;
D3D11_RENDER_TARGET_BLEND_DESC1 renderTarget[8];
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("5c1e0d8a-7c23-48f9-8c59-a92958ceff11"))
ID3DDeviceContextState : public ID3D11DeviceChild
{};
struct __declspec(novtable, uuid("b2daad8b-03d4-4dbf-95eb-32ab4b63d0ab"))
ID3DUserDefinedAnnotation : public IUnknown
{
virtual std::int32_t BeginEvent(const wchar_t* a_name) = 0;
virtual std::int32_t EndEvent(void) = 0;
virtual void SetMarker(const wchar_t* a_name) = 0;
virtual BOOL GetStatus(void) = 0;
};
struct __declspec(novtable, uuid("cc86fabe-da55-401d-85e7-e3c9de2877e9"))
ID3D11BlendState1 : public ID3D11BlendState
{
virtual void GetDesc1(D3D11_BLEND_DESC1* a_desc) = 0;
};
struct __declspec(novtable, uuid("a04bfb29-08ef-43d6-a49c-a9bdbdcbe686"))
ID3D11Device1 : public ID3D11Device
{
virtual void GetImmediateContext1(ID3D11DeviceContext1** a_immediateContext) = 0;
virtual HRESULT CreateDeferredContext1(std::uint32_t a_contextFlags, ID3D11DeviceContext1** a_deferredContext) = 0;
virtual HRESULT CreateBlendState1(const D3D11_BLEND_DESC1* a_blendStateDesc, ID3D11BlendState1** a_blendState) = 0;
virtual HRESULT CreateRasterizerState1(const D3D11_RASTERIZER_DESC1* a_rasterizerDesc, ID3D11RasterizerState1** a_rasterizerState) = 0;
virtual HRESULT CreateDeviceContextState(std::uint32_t a_flags, const D3D_FEATURE_LEVEL* a_pFeatureLevels, std::uint32_t a_featureLevels, std::uint32_t a_sdkVersion, const IID& a_emulatedInterface, D3D_FEATURE_LEVEL* a_pFeatureLevel, ID3DDeviceContextState** a_contextState) = 0;
virtual HRESULT OpenSharedResource1(HANDLE a_resourceHandle, const IID& a_returnedInterface, void** a_resource) = 0;
virtual HRESULT OpenSharedResourceByName(const wchar_t* a_name, std::uint32_t a_desiredAccess, const IID& a_returnedInterface, void** a_resource) = 0;
};
struct __declspec(novtable, uuid("bb2c6faa-b5fb-4082-8e6b-388b8cfa90e1"))
ID3D11DeviceContext1 : public ID3D11DeviceContext
{
virtual void CopySubresourceRegion1(ID3D11Resource* a_dstResource, std::uint32_t a_dstSubresource, std::uint32_t a_dstX, std::uint32_t a_dstY, std::uint32_t a_dstZ, ID3D11Resource* a_srcResource, std::uint32_t a_srcSubresource, const D3D11_BOX* a_srcBox, std::uint32_t a_copyFlags) = 0;
virtual void UpdateSubresource1(ID3D11Resource* a_dstResource, std::uint32_t a_dstSubresource, const D3D11_BOX* a_dstBox, const void* a_srcData, std::uint32_t a_srcRowPitch, std::uint32_t a_srcDepthPitch, std::uint32_t a_copyFlags) = 0;
virtual void DiscardResource(ID3D11Resource* a_resource) = 0;
virtual void DiscardView(ID3D11View* a_resourceView) = 0;
virtual void VSSetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer* const* a_constantBuffers, const std::uint32_t* a_firstConstant, const std::uint32_t* a_numConstants) = 0;
virtual void HSSetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer* const* a_constantBuffers, const std::uint32_t* a_firstConstant, const std::uint32_t* a_numConstants) = 0;
virtual void DSSetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer* const* a_constantBuffers, const std::uint32_t* a_firstConstant, const std::uint32_t* a_numConstants) = 0;
virtual void GSSetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer* const* a_constantBuffers, const std::uint32_t* a_firstConstant, const std::uint32_t* a_numConstants) = 0;
virtual void PSSetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer* const* a_constantBuffers, const std::uint32_t* a_firstConstant, const std::uint32_t* a_numConstants) = 0;
virtual void CSSetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer* const* a_constantBuffers, const std::uint32_t* a_firstConstant, const std::uint32_t* a_numConstants) = 0;
virtual void VSGetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer** a_constantBuffers, std::uint32_t* a_firstConstant, std::uint32_t* a_numConstants) = 0;
virtual void HSGetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer** a_constantBuffers, std::uint32_t* a_firstConstant, std::uint32_t* a_numConstants) = 0;
virtual void DSGetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer** a_constantBuffers, std::uint32_t* a_firstConstant, std::uint32_t* a_numConstants) = 0;
virtual void GSGetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer** a_constantBuffers, std::uint32_t* a_firstConstant, std::uint32_t* a_numConstants) = 0;
virtual void PSGetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer** a_constantBuffers, std::uint32_t* a_firstConstant, std::uint32_t* a_numConstants) = 0;
virtual void CSGetConstantBuffers1(std::uint32_t a_startSlot, std::uint32_t a_numBuffers, ID3D11Buffer** a_constantBuffers, std::uint32_t* a_firstConstant, std::uint32_t* a_numConstants) = 0;
virtual void SwapDeviceContextState(ID3DDeviceContextState* a_state, ID3DDeviceContextState** a_previousState) = 0;
virtual void ClearView(ID3D11View* a_view, const float a_color[4], const D3D11_RECT* a_rect, std::uint32_t a_numRects) = 0;
virtual void DiscardView1(ID3D11View* a_resourceView, const D3D11_RECT* a_rects, std::uint32_t a_numRects) = 0;
};
struct __declspec(novtable, uuid("1217d7a6-5039-418c-b042-9cbe256afd6e"))
ID3D11RasterizerState1 : public ID3D11RasterizerState
{
virtual void GetDesc1(D3D11_RASTERIZER_DESC1* a_desc) = 0;
};
struct __declspec(novtable, uuid("A7F026DA-A5F8-4487-A564-15E34357651E"))
ID3D11VideoContext1 : public ID3D11VideoContext
{
virtual HRESULT SubmitDecoderBuffers1(ID3D11VideoDecoder* a_decoder, std::uint32_t a_numBuffers, const D3D11_VIDEO_DECODER_BUFFER_DESC1* a_bufferDesc) = 0;
virtual HRESULT GetDataForNewHardwareKey(ID3D11CryptoSession* a_cryptoSession, std::uint32_t a_privateInputSize, const void* a_privateInputData, std::uint64_t* a_privateOutputData) = 0;
virtual HRESULT CheckCryptoSessionStatus(ID3D11CryptoSession* a_cryptoSession, D3D11_CRYPTO_SESSION_STATUS* a_status) = 0;
virtual HRESULT DecoderEnableDownsampling(ID3D11VideoDecoder* a_decoder, DXGI_COLOR_SPACE_TYPE a_inputColorSpace, const D3D11_VIDEO_SAMPLE_DESC* a_outputDesc, std::uint32_t a_referenceFrameCount) = 0;
virtual HRESULT DecoderUpdateDownsampling(ID3D11VideoDecoder* a_decoder, const D3D11_VIDEO_SAMPLE_DESC* a_outputDesc) = 0;
virtual void VideoProcessorSetOutputColorSpace1(ID3D11VideoProcessor* a_videoProcessor, DXGI_COLOR_SPACE_TYPE a_colorSpace) = 0;
virtual void VideoProcessorSetOutputShaderUsage(ID3D11VideoProcessor* a_videoProcessor, BOOL a_shaderUsage) = 0;
virtual void VideoProcessorGetOutputColorSpace1(ID3D11VideoProcessor* a_videoProcessor, DXGI_COLOR_SPACE_TYPE* a_colorSpace) = 0;
virtual void VideoProcessorGetOutputShaderUsage(ID3D11VideoProcessor* a_videoProcessor, BOOL* a_shaderUsage) = 0;
virtual void VideoProcessorSetStreamColorSpace1(ID3D11VideoProcessor* a_videoProcessor, std::uint32_t a_streamIndex, DXGI_COLOR_SPACE_TYPE a_colorSpace) = 0;
virtual void VideoProcessorSetStreamMirror(ID3D11VideoProcessor* a_videoProcessor, std::uint32_t a_streamIndex, BOOL a_enable, BOOL a_flipHorizontal, BOOL a_flipVertical) = 0;
virtual void VideoProcessorGetStreamColorSpace1(ID3D11VideoProcessor* a_videoProcessor, std::uint32_t a_streamIndex, DXGI_COLOR_SPACE_TYPE* a_colorSpace) = 0;
virtual void VideoProcessorGetStreamMirror(ID3D11VideoProcessor* a_videoProcessor, std::uint32_t a_streamIndex, BOOL* a_enable, BOOL* a_flipHorizontal, BOOL* a_flipVertical) = 0;
virtual HRESULT VideoProcessorGetBehaviorHints(ID3D11VideoProcessor* a_videoProcessor, std::uint32_t a_outputWidth, std::uint32_t a_outputHeight, DXGI_FORMAT a_outputFormat, std::uint32_t a_streamCount, const D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT* a_streams, std::uint32_t* a_behaviorHints) = 0;
};
struct __declspec(novtable, uuid("29DA1D51-1321-4454-804B-F5FC9F861F0F"))
ID3D11VideoDevice1 : public ID3D11VideoDevice
{
virtual HRESULT GetCryptoSessionPrivateDataSize(const GUID* a_cryptoType, const GUID* a_decoderProfile, const GUID* a_keyExchangeType, std::uint32_t* a_privateInputSize, std::uint32_t* a_privateOutputSize) = 0;
virtual HRESULT GetVideoDecoderCaps(const GUID* a_decoderProfile, std::uint32_t a_sampleWidth, std::uint32_t a_sampleHeight, const DXGI_RATIONAL* a_frameRate, std::uint32_t a_bitRate, const GUID* a_cryptoType, std::uint32_t* a_decoderCaps) = 0;
virtual HRESULT CheckVideoDecoderDownsampling(const D3D11_VIDEO_DECODER_DESC* a_inputDesc, DXGI_COLOR_SPACE_TYPE a_inputColorSpace, const D3D11_VIDEO_DECODER_CONFIG* a_inputConfig, const DXGI_RATIONAL* a_frameRate, const D3D11_VIDEO_SAMPLE_DESC* a_outputDesc, BOOL* a_supported, BOOL* a_realTimeHint) = 0;
virtual HRESULT RecommendVideoDecoderDownsampleParameters(const D3D11_VIDEO_DECODER_DESC* a_inputDesc, DXGI_COLOR_SPACE_TYPE a_inputColorSpace, const D3D11_VIDEO_DECODER_CONFIG* a_inputConfig, const DXGI_RATIONAL* a_frameRate, D3D11_VIDEO_SAMPLE_DESC* a_recommendedOutputDesc) = 0;
};
struct __declspec(novtable, uuid("465217F2-5568-43CF-B5B9-F61D54531CA1"))
ID3D11VideoProcessorEnumerator1 : public ID3D11VideoProcessorEnumerator
{
virtual HRESULT CheckVideoProcessorFormatConversion(DXGI_FORMAT a_inputFormat, DXGI_COLOR_SPACE_TYPE a_inputColorSpace, DXGI_FORMAT a_outputFormat, DXGI_COLOR_SPACE_TYPE a_outputColorSpace, BOOL* a_supported) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_ID3DDeviceContextState{ 0x5C1E0D8A, 0x7C23, 0x48F9, { 0x8C, 0x59, 0xA9, 0x29, 0x58, 0xCE, 0xFF, 0x11 } };
inline constexpr IID IID_ID3DUserDefinedAnnotation{ 0xB2DAAD8B, 0x03D4, 0x4DBF, { 0x95, 0xEB, 0x32, 0xAB, 0x4B, 0x63, 0xD0, 0xAB } };
inline constexpr IID IID_ID3D11BlendState1{ 0xCC86FABE, 0xDA55, 0x401D, { 0x85, 0xE7, 0xE3, 0xC9, 0xDE, 0x28, 0x77, 0xE9 } };
inline constexpr IID IID_ID3D11Device1{ 0xA04BFB29, 0x08EF, 0x43D6, { 0xA4, 0x9C, 0xA9, 0xBD, 0xBD, 0xCB, 0xE6, 0x86 } };
inline constexpr IID IID_ID3D11DeviceContext1{ 0xBB2C6FAA, 0xB5FB, 0x4082, { 0x8E, 0x6B, 0x38, 0x8B, 0x8C, 0xFA, 0x90, 0xE1 } };
inline constexpr IID IID_ID3D11RasterizerState1{ 0x1217D7A6, 0x5039, 0x418C, { 0xB0, 0x42, 0x9C, 0xBE, 0x25, 0x6A, 0xFD, 0x6E } };
inline constexpr IID IID_ID3D11VideoContext1{ 0xA7F026DA, 0xA5F8, 0x4487, { 0xA5, 0x64, 0x15, 0xE3, 0x43, 0x57, 0x65, 0x1E } };
inline constexpr IID IID_ID3D11VideoDevice1{ 0x29DA1D51, 0x1321, 0x4454, { 0x80, 0x4B, 0xF5, 0xFC, 0x9F, 0x86, 0x1F, 0x0F } };
inline constexpr IID IID_ID3D11VideoProcessorEnumerator1{ 0x465217F2, 0x5568, 0x43CF, { 0xB5, 0xB9, 0xF6, 0x1D, 0x54, 0x53, 0x1C, 0xA1 } };
}
@@ -0,0 +1,112 @@
#pragma once
#include "REX/W32/D3D11_1.h"
namespace REX::W32
{
struct ID3D11Device2;
struct ID3D11DeviceContext2;
}
namespace REX::W32
{
enum D3D11_CHECK_MULTISAMPLE_QUALITY_LEVELS_FLAG
{
D3D11_CHECK_MULTISAMPLE_QUALITY_LEVELS_TILED_RESOURCE = 0x1,
};
enum D3D11_TILE_COPY_FLAG
{
D3D11_TILE_COPY_NO_OVERWRITE = 0x1,
D3D11_TILE_COPY_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2,
D3D11_TILE_COPY_SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4,
};
enum D3D11_TILE_MAPPING_FLAG
{
D3D11_TILE_MAPPING_NO_OVERWRITE = 0x1,
};
enum D3D11_TILE_RANGE_FLAG
{
D3D11_TILE_RANGE_NULL = 0x1,
D3D11_TILE_RANGE_SKIP = 0x2,
D3D11_TILE_RANGE_REUSE_SINGLE_TILE = 0x4,
};
}
namespace REX::W32
{
struct D3D11_PACKED_MIP_DESC
{
std::uint8_t numStandardMips;
std::uint8_t numPackedMips;
std::uint32_t numTilesForPackedMips;
std::uint32_t startTileIndexInOverallResource;
};
struct D3D11_SUBRESOURCE_TILING
{
std::uint32_t widthInTiles;
std::uint16_t heightInTiles;
std::uint16_t depthInTiles;
std::uint32_t startTileIndexInOverallResource;
};
struct D3D11_TILED_RESOURCE_COORDINATE
{
std::uint32_t x;
std::uint32_t y;
std::uint32_t z;
std::uint32_t subResource;
};
struct D3D11_TILE_REGION_SIZE
{
std::uint32_t numTiles;
BOOL bUseBox;
std::uint32_t width;
std::uint16_t height;
std::uint16_t depth;
};
struct D3D11_TILE_SHAPE
{
std::uint32_t widthInTexels;
std::uint32_t heightInTexels;
std::uint32_t depthInTexels;
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("9d06dffa-d1e5-4d07-83a8-1bb123f2f841"))
ID3D11Device2 : public ID3D11Device1
{
virtual void GetImmediateContext2(ID3D11DeviceContext2** a_immediateContext) = 0;
virtual HRESULT CreateDeferredContext2(std::uint32_t a_contextFlags, ID3D11DeviceContext2** a_deferredContext) = 0;
virtual void GetResourceTiling(ID3D11Resource* a_tiledResource, std::uint32_t* a_numTilesForEntireResource, D3D11_PACKED_MIP_DESC* a_packedMipDesc, D3D11_TILE_SHAPE* a_standardTileShapeForNonPackedMips, std::uint32_t* a_numSubresourceTilings, std::uint32_t a_firstSubResourceTilingToGet, D3D11_SUBRESOURCE_TILING* a_subResourceTilingsForNonPackedMips) = 0;
virtual HRESULT CheckMultisampleQualityLevels1(DXGI_FORMAT a_format, std::uint32_t a_sampleCount, std::uint32_t a_flags, std::uint32_t* a_numQualityLevels) = 0;
};
struct __declspec(novtable, uuid("420d5b32-b90c-4da4-bef0-359f6a24a83a"))
ID3D11DeviceContext2 : public ID3D11DeviceContext1
{
virtual HRESULT UpdateTileMappings(ID3D11Resource* a_tiledResource, std::uint32_t numTiledResourceRegions, const D3D11_TILED_RESOURCE_COORDINATE* a_tiledResourceRegionStartCoordinates, const D3D11_TILE_REGION_SIZE* a_tiledResourceRegionSizes, ID3D11Buffer* a_tilePool, std::uint32_t a_numRanges, const std::uint32_t* a_rangeFlags, const std::uint32_t* a_tilePoolStartOffsets, const std::uint32_t* a_rangeTileCounts, std::uint32_t a_flags) = 0;
virtual HRESULT CopyTileMappings(ID3D11Resource* a_destTiledResource, const D3D11_TILED_RESOURCE_COORDINATE* a_destRegionStartCoordinate, ID3D11Resource* a_sourceTiledResource, const D3D11_TILED_RESOURCE_COORDINATE* a_sourceRegionStartCoordinate, const D3D11_TILE_REGION_SIZE* a_tileRegionSize, std::uint32_t a_flags) = 0;
virtual void CopyTiles(ID3D11Resource* a_tiledResource, const D3D11_TILED_RESOURCE_COORDINATE* a_tileRegionStartCoordinate, const D3D11_TILE_REGION_SIZE* a_tileRegionSize, ID3D11Buffer* a_buffer, std::uint64_t a_bufferStartOffsetInBytes, std::uint32_t a_flags) = 0;
virtual void UpdateTiles(ID3D11Resource* a_destTiledResource, const D3D11_TILED_RESOURCE_COORDINATE* a_destTileRegionStartCoordinate, const D3D11_TILE_REGION_SIZE* a_destTileRegionSize, const void* a_sourceTileData, std::uint32_t a_flags) = 0;
virtual HRESULT ResizeTilePool(ID3D11Buffer* a_tilePool, std::uint64_t a_newSizeInBytes) = 0;
virtual void TiledResourceBarrier(ID3D11DeviceChild* a_tiledResourceOrViewAccessBeforeBarrier, ID3D11DeviceChild* a_tiledResourceOrViewAccessAfterBarrier) = 0;
virtual BOOL IsAnnotationEnabled(void) = 0;
virtual void SetMarkerInt(const wchar_t* a_label, std::int32_t a_data) = 0;
virtual void BeginEventInt(const wchar_t* a_label, std::int32_t a_data) = 0;
virtual void EndEvent(void) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_ID3D11Device2{ 0x9D06DFFA, 0xD1E5, 0x4D07, { 0x83, 0xA8, 0x1B, 0xB1, 0x23, 0xF2, 0xF8, 0x41 } };
inline constexpr IID IID_ID3D11DeviceContext2{ 0x420D5B32, 0xB90C, 0x4DA4, { 0xBE, 0xF0, 0x35, 0x9F, 0x6A, 0x24, 0xA8, 0x3A } };
}
@@ -0,0 +1,301 @@
#pragma once
#include "REX/W32/D3D11_2.h"
namespace REX::W32
{
struct ID3D11Device3;
struct ID3D11DeviceContext3;
struct ID3D11DeviceContext4;
struct ID3D11Fence;
struct ID3D11Query1;
struct ID3D11RasterizerState2;
struct ID3D11RenderTargetView1;
struct ID3D11ShaderResourceView1;
struct ID3D11Texture2D1;
struct ID3D11Texture3D1;
struct ID3D11UnorderedAccessView1;
}
namespace REX::W32
{
enum D3D11_CONSERVATIVE_RASTERIZATION_MODE
{
D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF = 0,
D3D11_CONSERVATIVE_RASTERIZATION_MODE_ON = 1,
};
enum D3D11_CONTEXT_TYPE
{
D3D11_CONTEXT_TYPE_ALL = 0,
D3D11_CONTEXT_TYPE_3D = 1,
D3D11_CONTEXT_TYPE_COMPUTE = 2,
D3D11_CONTEXT_TYPE_COPY = 3,
D3D11_CONTEXT_TYPE_VIDEO = 4,
};
enum D3D11_FENCE_FLAG
{
D3D11_FENCE_FLAG_NONE = 0,
D3D11_FENCE_FLAG_SHARED = 0x2,
D3D11_FENCE_FLAG_SHARED_CROSS_ADAPTER = 0x4,
D3D11_FENCE_FLAG_NON_MONITORED = 0x8,
};
enum D3D11_TEXTURE_LAYOUT
{
D3D11_TEXTURE_LAYOUT_UNDEFINED = 0,
D3D11_TEXTURE_LAYOUT_ROW_MAJOR = 1,
D3D11_TEXTURE_LAYOUT_64K_STANDARD_SWIZZLE = 2,
};
}
namespace REX::W32
{
struct D3D11_TEX2D_ARRAY_RTV1
{
std::uint32_t mipSlice;
std::uint32_t firstArraySlice;
std::uint32_t arraySize;
std::uint32_t planeSlice;
};
struct D3D11_TEX2D_ARRAY_SRV1
{
std::uint32_t mostDetailedMip;
std::uint32_t mipLevels;
std::uint32_t firstArraySlice;
std::uint32_t arraySize;
std::uint32_t planeSlice;
};
struct D3D11_TEX2D_ARRAY_UAV1
{
std::uint32_t mipSlice;
std::uint32_t firstArraySlice;
std::uint32_t arraySize;
std::uint32_t planeSlice;
};
struct D3D11_TEX2D_RTV1
{
std::uint32_t mipSlice;
std::uint32_t planeSlice;
};
struct D3D11_TEX2D_SRV1
{
std::uint32_t mostDetailedMip;
std::uint32_t mipLevels;
std::uint32_t planeSlice;
};
struct D3D11_TEX2D_UAV1
{
std::uint32_t mipSlice;
std::uint32_t planeSlice;
};
struct D3D11_QUERY_DESC1
{
D3D11_QUERY query;
std::uint32_t miscFlags;
D3D11_CONTEXT_TYPE contextType;
};
struct D3D11_RASTERIZER_DESC2
{
D3D11_FILL_MODE fillMode;
D3D11_CULL_MODE cullMode;
BOOL frontCounterClockwise;
std::int32_t depthBias;
float depthBiasClamp;
float slopeScaledDepthBias;
BOOL depthClipEnable;
BOOL scissorEnable;
BOOL multisampleEnable;
BOOL antialiasedLineEnable;
std::uint32_t forcedSampleCount;
D3D11_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster;
};
struct D3D11_RENDER_TARGET_VIEW_DESC1
{
DXGI_FORMAT format;
D3D11_RTV_DIMENSION viewDimension;
union
{
D3D11_BUFFER_RTV buffer;
D3D11_TEX1D_RTV texture1D;
D3D11_TEX1D_ARRAY_RTV texture1DArray;
D3D11_TEX2D_RTV1 texture2D;
D3D11_TEX2D_ARRAY_RTV1 texture2DArray;
D3D11_TEX2DMS_RTV texture2DMS;
D3D11_TEX2DMS_ARRAY_RTV texture2DMSArray;
D3D11_TEX3D_RTV texture3D;
};
};
struct D3D11_TEXTURE2D_DESC1
{
std::uint32_t width;
std::uint32_t height;
std::uint32_t mipLevels;
std::uint32_t arraySize;
DXGI_FORMAT format;
DXGI_SAMPLE_DESC sampleDesc;
D3D11_USAGE usage;
std::uint32_t bindFlags;
std::uint32_t cpuAccessFlags;
std::uint32_t miscFlags;
D3D11_TEXTURE_LAYOUT textureLayout;
};
struct D3D11_TEXTURE3D_DESC1
{
std::uint32_t width;
std::uint32_t height;
std::uint32_t depth;
std::uint32_t mipLevels;
DXGI_FORMAT format;
D3D11_USAGE usage;
std::uint32_t bindFlags;
std::uint32_t cpuAccessFlags;
std::uint32_t miscFlags;
D3D11_TEXTURE_LAYOUT textureLayout;
};
struct D3D11_SHADER_RESOURCE_VIEW_DESC1
{
DXGI_FORMAT format;
D3D11_SRV_DIMENSION viewDimension;
union
{
D3D11_BUFFER_SRV buffer;
D3D11_TEX1D_SRV texture1D;
D3D11_TEX1D_ARRAY_SRV texture1DArray;
D3D11_TEX2D_SRV1 texture2D;
D3D11_TEX2D_ARRAY_SRV1 texture2DArray;
D3D11_TEX2DMS_SRV texture2DMS;
D3D11_TEX2DMS_ARRAY_SRV texture2DMSArray;
D3D11_TEX3D_SRV texture3D;
D3D11_TEXCUBE_SRV textureCube;
D3D11_TEXCUBE_ARRAY_SRV textureCubeArray;
D3D11_BUFFEREX_SRV bufferEx;
};
};
struct D3D11_UNORDERED_ACCESS_VIEW_DESC1
{
DXGI_FORMAT format;
D3D11_UAV_DIMENSION viewDimension;
union
{
D3D11_BUFFER_UAV buffer;
D3D11_TEX1D_UAV texture1D;
D3D11_TEX1D_ARRAY_UAV texture1DArray;
D3D11_TEX2D_UAV1 texture2D;
D3D11_TEX2D_ARRAY_UAV1 texture2DArray;
D3D11_TEX3D_UAV texture3D;
};
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("A05C8C37-D2C6-4732-B3A0-9CE0B0DC9AE6"))
ID3D11Device3 : public ID3D11Device2
{
virtual HRESULT CreateTexture2D1(const D3D11_TEXTURE2D_DESC1* a_desc1, const D3D11_SUBRESOURCE_DATA* a_initialData, ID3D11Texture2D1** a_texture2D) = 0;
virtual HRESULT CreateTexture3D1(const D3D11_TEXTURE3D_DESC1* a_desc1, const D3D11_SUBRESOURCE_DATA* a_initialData, ID3D11Texture3D1** a_texture3D) = 0;
virtual HRESULT CreateRasterizerState2(const D3D11_RASTERIZER_DESC2* a_rasterizerDesc, ID3D11RasterizerState2** a_rasterizerState) = 0;
virtual HRESULT CreateShaderResourceView1(ID3D11Resource* a_resource, const D3D11_SHADER_RESOURCE_VIEW_DESC1* a_desc1, ID3D11ShaderResourceView1** a_srView1) = 0;
virtual HRESULT CreateUnorderedAccessView1(ID3D11Resource* a_resource, const D3D11_UNORDERED_ACCESS_VIEW_DESC1* a_desc1, ID3D11UnorderedAccessView1** a_uaView1) = 0;
virtual HRESULT CreateRenderTargetView1(ID3D11Resource* a_resource, const D3D11_RENDER_TARGET_VIEW_DESC1* a_desc1, ID3D11RenderTargetView1** a_rtView1) = 0;
virtual HRESULT CreateQuery1(const D3D11_QUERY_DESC1* a_queryDesc1, ID3D11Query1** a_query1) = 0;
virtual void GetImmediateContext3(ID3D11DeviceContext3** a_immediateContext) = 0;
virtual HRESULT CreateDeferredContext3(std::uint32_t a_contextFlags, ID3D11DeviceContext3** a_deferredContext) = 0;
virtual void WriteToSubresource(ID3D11Resource* a_dstResource, std::uint32_t a_dstSubresource, const D3D11_BOX* a_dstBox, const void* a_srcData, std::uint32_t a_srcRowPitch, std::uint32_t a_srcDepthPitch) = 0;
virtual void ReadFromSubresource(void* a_dstData, std::uint32_t a_dstRowPitch, std::uint32_t a_dstDepthPitch, ID3D11Resource* a_srcResource, std::uint32_t a_srcSubresource, const D3D11_BOX* a_srcBox) = 0;
};
struct __declspec(novtable, uuid("b4e3c01d-e79e-4637-91b2-510e9f4c9b8f"))
ID3D11DeviceContext3 : public ID3D11DeviceContext2
{
virtual void Flush1(D3D11_CONTEXT_TYPE a_contextType, HANDLE a_event) = 0;
virtual void SetHardwareProtectionState(BOOL a_hwProtectionEnable) = 0;
virtual void GetHardwareProtectionState(BOOL* a_hwProtectionEnable) = 0;
};
struct __declspec(novtable, uuid("917600da-f58c-4c33-98d8-3e15b390fa24"))
ID3D11DeviceContext4 : public ID3D11DeviceContext3
{
virtual HRESULT Signal(ID3D11Fence* a_fence, std::uint64_t a_value) = 0;
virtual HRESULT Wait(ID3D11Fence* a_fence, std::uint64_t a_value) = 0;
};
struct __declspec(novtable, uuid("affde9d1-1df7-4bb7-8a34-0f46251dab80"))
ID3D11Fence : public ID3D11DeviceChild
{
virtual HRESULT CreateSharedHandle(const SECURITY_ATTRIBUTES* a_attributes, std::uint32_t a_access, const wchar_t* a_name, HANDLE* a_handle) = 0;
virtual std::uint64_t GetCompletedValue(void) = 0;
virtual HRESULT SetEventOnCompletion(std::uint64_t a_value, HANDLE a_event) = 0;
};
struct __declspec(novtable, uuid("631b4766-36dc-461d-8db6-c47e13e60916"))
ID3D11Query1 : public ID3D11Query
{
virtual void GetDesc1(D3D11_QUERY_DESC1* a_desc) = 0;
};
struct __declspec(novtable, uuid("6fbd02fb-209f-46c4-b059-2ed15586a6ac"))
ID3D11RasterizerState2 : public ID3D11RasterizerState1
{
virtual void GetDesc2(D3D11_RASTERIZER_DESC2* a_desc) = 0;
};
struct __declspec(novtable, uuid("ffbe2e23-f011-418a-ac56-5ceed7c5b94b"))
ID3D11RenderTargetView1 : public ID3D11RenderTargetView
{
virtual void GetDesc1(D3D11_RENDER_TARGET_VIEW_DESC1* a_desc1) = 0;
};
struct __declspec(novtable, uuid("91308b87-9040-411d-8c67-c39253ce3802"))
ID3D11ShaderResourceView1 : public ID3D11ShaderResourceView
{
virtual void GetDesc1(D3D11_SHADER_RESOURCE_VIEW_DESC1* a_desc) = 0;
};
struct __declspec(novtable, uuid("51218251-1E33-4617-9CCB-4D3A4367E7BB"))
ID3D11Texture2D1 : public ID3D11Texture2D
{
virtual void GetDesc1(D3D11_TEXTURE2D_DESC1* a_desc) = 0;
};
struct __declspec(novtable, uuid("0C711683-2853-4846-9BB0-F3E60639E46A"))
ID3D11Texture3D1 : public ID3D11Texture3D
{
virtual void GetDesc1(D3D11_TEXTURE3D_DESC1* a_desc) = 0;
};
struct __declspec(novtable, uuid("7b3b6153-a886-4544-ab37-6537c8500403"))
ID3D11UnorderedAccessView1 : public ID3D11UnorderedAccessView
{
virtual void GetDesc1(D3D11_UNORDERED_ACCESS_VIEW_DESC1* a_desc) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_ID3D11Device3{ 0xA05C8C37, 0xD2C6, 0x4732, { 0xB3, 0xA0, 0x9C, 0xE0, 0xB0, 0xDC, 0x9A, 0xE6 } };
inline constexpr IID IID_ID3D11DeviceContext3{ 0xB4E3C01D, 0xE79E, 0x4637, { 0x91, 0xB2, 0x51, 0x0E, 0x9F, 0x4C, 0x9B, 0x8F } };
inline constexpr IID IID_ID3D11DeviceContext4{ 0x917600DA, 0xF58C, 0x4C33, { 0x98, 0xD8, 0x3E, 0x15, 0xB3, 0x90, 0xFA, 0x24 } };
inline constexpr IID IID_ID3D11Fence{ 0xAFFDE9D1, 0x1DF7, 0x4BB7, { 0x8A, 0x34, 0x0F, 0x46, 0x25, 0x1D, 0xAB, 0x80 } };
inline constexpr IID IID_ID3D11Query1{ 0x631B4766, 0x36DC, 0x461D, { 0x8D, 0xB6, 0xC4, 0x7E, 0x13, 0xE6, 0x09, 0x16 } };
inline constexpr IID IID_ID3D11RasterizerState2{ 0x6FBD02FB, 0x209F, 0x46C4, { 0xb0, 0x59, 0x2E, 0xD1, 0x55, 0x86, 0xA6, 0xAC } };
inline constexpr IID IID_ID3D11RenderTargetView1{ 0xFFBE2E23, 0xF011, 0x418A, { 0xAC, 0x56, 0x5C, 0xEE, 0xD7, 0xC5, 0xB9, 0x4B } };
inline constexpr IID IID_ID3D11ShaderResourceView1{ 0x91308B87, 0x9040, 0x411D, { 0x8C, 0x67, 0xC3, 0x92, 0x53, 0xCE, 0x38, 0x02 } };
inline constexpr IID IID_ID3D11Texture2D1{ 0x51218251, 0x1E33, 0x4617, { 0x9C, 0xCB, 0x4D, 0x3A, 0x43, 0x67, 0xE7, 0xBB } };
inline constexpr IID IID_ID3D11Texture3D1{ 0x0C711683, 0x2853, 0x4846, { 0x9B, 0xB0, 0xF3, 0xE6, 0x06, 0x39, 0xE4, 0x6A } };
inline constexpr IID IID_ID3D11UnorderedAccessView1{ 0x7B3B6153, 0xA886, 0x4544, { 0xAB, 0x37, 0x65, 0x37, 0xC8, 0x50, 0x04, 0x03 } };
}
@@ -0,0 +1,138 @@
#pragma once
#include "REX/W32/D3D11_3.h"
#include "REX/W32/DXGI_5.h"
namespace REX::W32
{
struct ID3D11Device4;
struct ID3D11Device5;
struct ID3D11Multithread;
struct ID3D11VideoContext2;
struct ID3D11VideoContext3;
struct ID3D11VideoDevice2;
}
namespace REX::W32
{
enum D3D11_CRYPTO_SESSION_KEY_EXCHANGE_FLAGS
{
D3D11_CRYPTO_SESSION_KEY_EXCHANGE_FLAG_NONE = 0,
};
enum D3D11_FEATURE_VIDEO
{
D3D11_FEATURE_VIDEO_DECODER_HISTOGRAM = 0,
};
enum D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT
{
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_Y = 0,
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_U = 1,
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_V = 2,
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_R = 0,
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_G = 1,
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_B = 2,
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_A = 3,
};
enum D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAGS
{
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAG_NONE = 0,
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAG_Y = (1 << D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_Y),
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAG_U = (1 << D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_U),
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAG_V = (1 << D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_V),
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAG_R = (1 << D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_R),
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAG_G = (1 << D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_G),
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAG_B = (1 << D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_B),
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAG_A = (1 << D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_A),
};
}
namespace REX::W32
{
struct D3D11_FEATURE_DATA_D3D11_OPTIONS4
{
BOOL extendedNV12SharedTextureSupported;
};
struct D3D11_FEATURE_DATA_VIDEO_DECODER_HISTOGRAM
{
D3D11_VIDEO_DECODER_DESC decoderDesc;
D3D11_VIDEO_DECODER_HISTOGRAM_COMPONENT_FLAGS components;
std::uint32_t binCount;
std::uint32_t counterBitDepth;
};
struct D3D11_VIDEO_DECODER_BUFFER_DESC2
{
D3D11_VIDEO_DECODER_BUFFER_TYPE bufferType;
std::uint32_t dataOffset;
std::uint32_t dataSize;
void* iv;
std::uint32_t ivSize;
D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK* subSampleMappingBlock;
std::uint32_t subSampleMappingCount;
std::uint32_t cBlocksStripeEncrypted;
std::uint32_t cBlocksStripeClear;
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("8992ab71-02e6-4b8d-ba48-b056dcda42c4"))
ID3D11Device4 : public ID3D11Device3
{
virtual HRESULT RegisterDeviceRemovedEvent(HANDLE a_event, std::uint32_t* a_cookie) = 0;
virtual void UnregisterDeviceRemoved(std::uint32_t a_cookie) = 0;
};
struct __declspec(novtable, uuid("8ffde202-a0e7-45df-9e01-e837801b5ea0"))
ID3D11Device5 : public ID3D11Device4
{
virtual HRESULT OpenSharedFence(HANDLE a_fenceHandle, const IID& a_returnedInterface, void** a_fence) = 0;
virtual HRESULT CreateFence(std::uint64_t a_initialValue, D3D11_FENCE_FLAG a_flags, const IID& a_returnedInterface, void** a_fence) = 0;
};
struct __declspec(novtable, uuid("9B7E4E00-342C-4106-A19F-4F2704F689F0"))
ID3D11Multithread : public IUnknown
{
virtual void Enter(void) = 0;
virtual void Leave(void) = 0;
virtual BOOL SetMultithreadProtected(BOOL a_mtProtect) = 0;
virtual BOOL GetMultithreadProtected(void) = 0;
};
struct __declspec(novtable, uuid("C4E7374C-6243-4D1B-AE87-52B4F740E261"))
ID3D11VideoContext2 : public ID3D11VideoContext1
{
virtual void VideoProcessorSetOutputHDRMetaData(ID3D11VideoProcessor* a_videoProcessor, DXGI_HDR_METADATA_TYPE a_type, std::uint32_t a_size, const void* a_hdrMetaData) = 0;
virtual void VideoProcessorGetOutputHDRMetaData(ID3D11VideoProcessor* a_videoProcessor, DXGI_HDR_METADATA_TYPE* a_type, std::uint32_t a_size, void* a_hdrMetaData) = 0;
virtual void VideoProcessorSetStreamHDRMetaData(ID3D11VideoProcessor* a_videoProcessor, std::uint32_t a_streamIndex, DXGI_HDR_METADATA_TYPE a_type, std::uint32_t a_size, const void* a_hdrMetaData) = 0;
virtual void VideoProcessorGetStreamHDRMetaData(ID3D11VideoProcessor* a_videoProcessor, std::uint32_t a_streamIndex, DXGI_HDR_METADATA_TYPE* a_type, std::uint32_t a_size, void* a_hdrMetaData) = 0;
};
struct __declspec(novtable, uuid("A9E2FAA0-CB39-418F-A0B7-D8AAD4DE672E"))
ID3D11VideoContext3 : public ID3D11VideoContext2
{
virtual HRESULT DecoderBeginFrame1(ID3D11VideoDecoder* a_decoder, ID3D11VideoDecoderOutputView* a_view, std::uint32_t a_contentKeySize, const void* a_contentKey, std::uint32_t a_numComponentHistograms, const std::uint32_t* a_histogramOffsets, ID3D11Buffer* const* a_histogramBuffers) = 0;
virtual HRESULT SubmitDecoderBuffers2(ID3D11VideoDecoder* a_decoder, std::uint32_t a_numBuffers, const D3D11_VIDEO_DECODER_BUFFER_DESC2* a_bufferDesc) = 0;
};
struct __declspec(novtable, uuid("59C0CB01-35F0-4A70-8F67-87905C906A53"))
ID3D11VideoDevice2 : public ID3D11VideoDevice1
{
virtual HRESULT CheckFeatureSupport(D3D11_FEATURE_VIDEO a_feature, void* a_featureSupportData, std::uint32_t a_featureSupportDataSize) = 0;
virtual HRESULT NegotiateCryptoSessionKeyExchangeMT(ID3D11CryptoSession* a_cryptoSession, D3D11_CRYPTO_SESSION_KEY_EXCHANGE_FLAGS a_flags, std::uint32_t a_dataSize, void* a_data) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_ID3D11Device4{ 0x8992AB71, 0x02E6, 0x4B8D, { 0xBA, 0x48, 0xB0, 0x56, 0xDC, 0xDA, 0x42, 0xC4 } };
inline constexpr IID IID_ID3D11Device5{ 0x8FFDE202, 0xA0E7, 0x45DF, { 0x9E, 0x01, 0xE8, 0x37, 0x80, 0x1B, 0x5E, 0xA0 } };
inline constexpr IID IID_ID3D11Multithread{ 0x9B7E4E00, 0x342C, 0x4106, { 0xA1, 0x9F, 0x4F, 0x27, 0x04, 0xF6, 0x89, 0xF0 } };
inline constexpr IID IID_ID3D11VideoContext2{ 0xC4E7374C, 0x6243, 0x4D1B, { 0xAE, 0x87, 0x52, 0xB4, 0xF7, 0x40, 0xE2, 0x61 } };
inline constexpr IID IID_ID3D11VideoContext3{ 0xA9E2FAA0, 0xCB39, 0x418F, { 0xA0, 0xB7, 0xD8, 0xAA, 0xD4, 0xDE, 0x67, 0x2E } };
inline constexpr IID IID_ID3D11VideoDevice2{ 0x59C0CB01, 0x35F0, 0x4A70, { 0x8F, 0x67, 0x87, 0x90, 0x5C, 0x90, 0x6A, 0x53 } };
}
@@ -0,0 +1,154 @@
#pragma once
#include "REX/W32/D3D.h"
namespace REX::W32
{
struct ID3DBlob;
struct ID3DInclude;
struct ID3D10Effect;
struct ID3D11FunctionLinkingGraph;
struct ID3D11Linker;
struct ID3D11Module;
}
namespace REX::W32
{
enum D3D_BLOB_PART
{
D3D_BLOB_INPUT_SIGNATURE_BLOB,
D3D_BLOB_OUTPUT_SIGNATURE_BLOB,
D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB,
D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB,
D3D_BLOB_ALL_SIGNATURE_BLOB,
D3D_BLOB_DEBUG_INFO,
D3D_BLOB_LEGACY_SHADER,
D3D_BLOB_XNA_PREPASS_SHADER,
D3D_BLOB_XNA_SHADER,
D3D_BLOB_PDB,
D3D_BLOB_PRIVATE_DATA,
D3D_BLOB_ROOT_SIGNATURE,
D3D_BLOB_DEBUG_NAME,
D3D_BLOB_TEST_ALTERNATE_SHADER = 0x8000,
D3D_BLOB_TEST_COMPILE_DETAILS,
D3D_BLOB_TEST_COMPILE_PERF,
D3D_BLOB_TEST_COMPILE_REPORT,
};
enum D3D_DISASM_FLAGS
{
D3D_DISASM_ENABLE_COLOR_CODE = 0x00000001,
D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS = 0x00000002,
D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING = 0x00000004,
D3D_DISASM_ENABLE_INSTRUCTION_CYCLE = 0x00000008,
D3D_DISASM_DISABLE_DEBUG_INFO = 0x00000010,
D3D_DISASM_ENABLE_INSTRUCTION_OFFSET = 0x00000020,
D3D_DISASM_INSTRUCTION_ONLY = 0x00000040,
D3D_DISASM_PRINT_HEX_LITERALS = 0x00000080,
};
enum D3DCOMPILE_EFFECT
{
D3DCOMPILE_EFFECT_CHILD_EFFECT = (1 << 0),
D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS = (1 << 1),
};
enum D3DCOMPILE_FLAGS
{
D3DCOMPILE_DEBUG = (1 << 0),
D3DCOMPILE_SKIP_VALIDATION = (1 << 1),
D3DCOMPILE_SKIP_OPTIMIZATION = (1 << 2),
D3DCOMPILE_PACK_MATRIX_ROW_MAJOR = (1 << 3),
D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR = (1 << 4),
D3DCOMPILE_PARTIAL_PRECISION = (1 << 5),
D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT = (1 << 6),
D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT = (1 << 7),
D3DCOMPILE_NO_PRESHADER = (1 << 8),
D3DCOMPILE_AVOID_FLOW_CONTROL = (1 << 9),
D3DCOMPILE_PREFER_FLOW_CONTROL = (1 << 10),
D3DCOMPILE_ENABLE_STRICTNESS = (1 << 11),
D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY = (1 << 12),
D3DCOMPILE_IEEE_STRICTNESS = (1 << 13),
D3DCOMPILE_OPTIMIZATION_LEVEL0 = (1 << 14),
D3DCOMPILE_OPTIMIZATION_LEVEL1 = 0,
D3DCOMPILE_OPTIMIZATION_LEVEL2 = ((1 << 14) | (1 << 15)),
D3DCOMPILE_OPTIMIZATION_LEVEL3 = (1 << 15),
D3DCOMPILE_RESERVED16 = (1 << 16),
D3DCOMPILE_RESERVED17 = (1 << 17),
D3DCOMPILE_WARNINGS_ARE_ERRORS = (1 << 18),
D3DCOMPILE_RESOURCES_MAY_ALIAS = (1 << 19),
D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES = (1 << 20),
D3DCOMPILE_ALL_RESOURCES_BOUND = (1 << 21),
D3DCOMPILE_DEBUG_NAME_FOR_SOURCE = (1 << 22),
D3DCOMPILE_DEBUG_NAME_FOR_BINARY = (1 << 23),
};
enum D3DCOMPILE_FLAGS2
{
D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_LATEST = 0,
D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_0 = (1 << 4),
D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_1 = (1 << 5),
};
enum D3DCOMPILE_SECDATA_FLAGS
{
D3DCOMPILE_SECDATA_MERGE_UAV_SLOTS = 0x00000001,
D3DCOMPILE_SECDATA_PRESERVE_TEMPLATE_SLOTS = 0x00000002,
D3DCOMPILE_SECDATA_REQUIRE_TEMPLATE_MATCH = 0x00000004,
};
enum D3DCOMPILER_STRIP_FLAGS
{
D3DCOMPILER_STRIP_REFLECTION_DATA = 0x00000001,
D3DCOMPILER_STRIP_DEBUG_INFO = 0x00000002,
D3DCOMPILER_STRIP_TEST_BLOBS = 0x00000004,
D3DCOMPILER_STRIP_PRIVATE_DATA = 0x00000008,
D3DCOMPILER_STRIP_ROOT_SIGNATURE = 0x00000010,
D3DCOMPILER_STRIP_FORCE_DWORD = 0x7FFFFFFF,
};
}
namespace REX::W32
{
struct D3D_SHADER_DATA
{
const void* bytecode;
std::size_t bytecodeLength;
};
}
namespace REX::W32
{
inline const auto D3D_COMPILE_STANDARD_FILE_INCLUDE{ reinterpret_cast<ID3DInclude*>(static_cast<std::uintptr_t>(1)) };
inline constexpr auto D3D_COMPRESS_SHADER_KEEP_ALL_PARTS{ 0x00000001u };
inline constexpr auto D3D_GET_INST_OFFSETS_INCLUDE_NON_EXECUTABLE{ 0x00000001u };
}
namespace REX::W32
{
HRESULT D3DCompile(const void* a_srcData, std::size_t a_srcDataSize, const char* a_sourceName, const D3D_SHADER_MACRO* a_defines, ID3DInclude* a_include, const char* a_entrypoint, const char* a_target, std::uint32_t a_flags1, std::uint32_t a_flags2, ID3DBlob** a_code, ID3DBlob** a_errorMsgs);
HRESULT D3DCompile2(const void* a_srcData, std::size_t a_srcDataSize, const char* a_sourceName, const D3D_SHADER_MACRO* a_defines, ID3DInclude* a_include, const char* a_entrypoint, const char* a_target, std::uint32_t a_flags1, std::uint32_t a_flags2, std::uint32_t a_secondaryDataFlags, const void* a_secondaryData, std::size_t a_secondaryDataSize, ID3DBlob** a_code, ID3DBlob** a_errorMsgs);
HRESULT D3DCompileFromFile(const wchar_t* a_fileName, const D3D_SHADER_MACRO* a_defines, ID3DInclude* a_include, const char* a_entrypoint, const char* a_target, std::uint32_t a_flags1, std::uint32_t a_flags2, ID3DBlob** a_code, ID3DBlob** a_errorMsgs);
HRESULT D3DCompressShaders(std::uint32_t a_numShaders, D3D_SHADER_DATA* a_shaderData, std::uint32_t a_flags, ID3DBlob** a_compressedData);
HRESULT D3DCreateBlob(std::size_t a_size, ID3DBlob** a_blob);
HRESULT D3DCreateFunctionLinkingGraph(std::uint32_t a_flags, ID3D11FunctionLinkingGraph** a_functionLinkingGraph);
HRESULT D3DCreateLinker(ID3D11Linker** a_linker);
HRESULT D3DDecompressShaders(const void* a_srcData, std::size_t a_srcDataSize, std::uint32_t a_numShaders, std::uint32_t a_startIndex, std::uint32_t* a_indices, std::uint32_t a_flags, ID3DBlob** a_shaders, std::uint32_t* a_totalShaders);
HRESULT D3DDisassemble(const void* a_srcData, std::size_t a_srcDataSize, std::uint32_t a_flags, const char* a_comments, ID3DBlob** a_disassembly);
HRESULT D3DDisassemble10Effect(ID3D10Effect* a_effect, std::uint32_t a_flags, ID3DBlob** a_disassembly);
HRESULT D3DDisassembleRegion(const void* a_srcData, std::size_t a_srcDataSize, std::uint32_t a_flags, const char* a_comments, std::size_t a_startByteOffset, std::size_t a_numInsts, std::size_t* a_finishByteOffset, ID3DBlob** a_disassembly);
HRESULT D3DGetBlobPart(const void* a_srcData, std::size_t a_srcDataSize, D3D_BLOB_PART a_partType, std::uint32_t a_flags, ID3DBlob** a_part);
HRESULT D3DGetDebugInfo(const void* a_srcData, std::size_t a_srcDataSize, ID3DBlob** a_debugInfo);
HRESULT D3DGetInputSignatureBlob(const void* a_srcData, std::size_t a_srcDataSize, ID3DBlob** a_signatureBlob);
HRESULT D3DGetInputAndOutputSignatureBlob(const void* a_srcData, std::size_t a_srcDataSize, ID3DBlob** a_signatureBlob);
HRESULT D3DGetOutputSignatureBlob(const void* a_srcData, std::size_t a_srcDataSize, ID3DBlob** a_signatureBlob);
HRESULT D3DGetTraceInstructionOffsets(const void* a_srcData, std::size_t a_srcDataSize, std::uint32_t a_flags, std::size_t a_startInstIndex, std::size_t a_numInsts, std::size_t* a_offsets, std::size_t* a_totalInsts);
HRESULT D3DLoadModule(const void* a_srcData, std::size_t a_srcDataSize, ID3D11Module** a_module);
HRESULT D3DPreprocess(const void* a_srcData, std::size_t a_srcDataSize, const char* a_sourceName, const D3D_SHADER_MACRO* a_defines, ID3DInclude* a_include, ID3DBlob** a_codeText, ID3DBlob** a_errorMsgs);
HRESULT D3DReadFileToBlob(const wchar_t* a_fileName, ID3DBlob** a_contents);
HRESULT D3DReflect(const void* a_srcData, std::size_t a_srcDataSize, const IID& a_iid, void** a_reflector);
HRESULT D3DReflectLibrary(const void* a_srcData, std::size_t a_srcDataSize, const IID& a_iid, void** a_reflector);
HRESULT D3DSetBlobPart(const void* a_srcData, std::size_t a_srcDataSize, D3D_BLOB_PART a_partType, std::uint32_t a_flags, const void* a_part, std::size_t a_partSize, ID3DBlob** a_newShader);
HRESULT D3DStripShader(const void* a_srcData, std::size_t a_srcDataSize, std::uint32_t a_stripFlags, ID3DBlob** a_strippedBlob);
HRESULT D3DWriteBlobToFile(ID3DBlob* a_blob, const wchar_t* a_fileName, bool a_overwrite);
}
@@ -0,0 +1,22 @@
#pragma once
namespace REX::W32
{
// symbol name undecoration flags
inline constexpr auto UNDNAME_NO_MS_KEYWORDS{ 0x00000002u };
inline constexpr auto UNDNAME_NO_FUNCTION_RETURNS{ 0x00000004u };
inline constexpr auto UNDNAME_NO_ALLOCATION_MODEL{ 0x00000008u };
inline constexpr auto UNDNAME_NO_ALLOCATION_LANGUAGE{ 0x00000010u };
inline constexpr auto UNDNAME_NO_THISTYPE{ 0x00000060u };
inline constexpr auto UNDNAME_NO_ACCESS_SPECIFIERS{ 0x00000080u };
inline constexpr auto UNDNAME_NO_THROW_SIGNATURES{ 0x00000100u };
inline constexpr auto UNDNAME_NO_RETURN_UDT_MODEL{ 0x00000400u };
inline constexpr auto UNDNAME_NAME_ONLY{ 0x00001000u };
inline constexpr auto UNDNAME_NO_ARGUMENTS{ 0x00002000u };
}
namespace REX::W32
{
std::uint32_t UnDecorateSymbolName(const char* a_name, char* a_buf, std::uint32_t a_bufLen, std::uint32_t a_flags) noexcept;
std::uint32_t UnDecorateSymbolNameW(const wchar_t* a_name, wchar_t* a_buf, std::uint32_t a_bufLen, std::uint32_t a_flags) noexcept;
}
@@ -0,0 +1,499 @@
#pragma once
#include "REX/W32/COM.h"
#include "REX/W32/D3D.h"
namespace REX::W32
{
struct IDirectInput8A;
struct IDirectInputDevice8A;
struct IDirectInputEffect;
}
namespace REX::W32
{
enum DIK : std::uint32_t
{
DIK_ESCAPE = 0x1,
DIK_1 = 0x2,
DIK_2 = 0x3,
DIK_3 = 0x4,
DIK_4 = 0x5,
DIK_5 = 0x6,
DIK_6 = 0x7,
DIK_7 = 0x8,
DIK_8 = 0x9,
DIK_9 = 0xA,
DIK_0 = 0xB,
DIK_MINUS = 0xC,
DIK_EQUALS = 0xD,
DIK_BACK = 0xE,
DIK_TAB = 0xF,
DIK_Q = 0x10,
DIK_W = 0x11,
DIK_E = 0x12,
DIK_R = 0x13,
DIK_T = 0x14,
DIK_Y = 0x15,
DIK_U = 0x16,
DIK_I = 0x17,
DIK_O = 0x18,
DIK_P = 0x19,
DIK_LBRACKET = 0x1A,
DIK_RBRACKET = 0x1B,
DIK_RETURN = 0x1C,
DIK_LCONTROL = 0x1D,
DIK_A = 0x1E,
DIK_S = 0x1F,
DIK_D = 0x20,
DIK_F = 0x21,
DIK_G = 0x22,
DIK_H = 0x23,
DIK_J = 0x24,
DIK_K = 0x25,
DIK_L = 0x26,
DIK_SEMICOLON = 0x27,
DIK_APOSTROPHE = 0x28,
DIK_GRAVE = 0x29,
DIK_LSHIFT = 0x2A,
DIK_BACKSLASH = 0x2B,
DIK_Z = 0x2C,
DIK_X = 0x2D,
DIK_C = 0x2E,
DIK_V = 0x2F,
DIK_B = 0x30,
DIK_N = 0x31,
DIK_M = 0x32,
DIK_COMMA = 0x33,
DIK_PERIOD = 0x34,
DIK_SLASH = 0x35,
DIK_RSHIFT = 0x36,
DIK_MULTIPLY = 0x37,
DIK_LMENU = 0x38,
DIK_SPACE = 0x39,
DIK_CAPITAL = 0x3A,
DIK_F1 = 0x3B,
DIK_F2 = 0x3C,
DIK_F3 = 0x3D,
DIK_F4 = 0x3E,
DIK_F5 = 0x3F,
DIK_F6 = 0x40,
DIK_F7 = 0x41,
DIK_F8 = 0x42,
DIK_F9 = 0x43,
DIK_F10 = 0x44,
DIK_NUMLOCK = 0x45,
DIK_SCROLL = 0x46,
DIK_NUMPAD7 = 0x47,
DIK_NUMPAD8 = 0x48,
DIK_NUMPAD9 = 0x49,
DIK_SUBTRACT = 0x4A,
DIK_NUMPAD4 = 0x4B,
DIK_NUMPAD5 = 0x4C,
DIK_NUMPAD6 = 0x4D,
DIK_ADD = 0x4E,
DIK_NUMPAD1 = 0x4F,
DIK_NUMPAD2 = 0x50,
DIK_NUMPAD3 = 0x51,
DIK_NUMPAD0 = 0x52,
DIK_DECIMAL = 0x53,
DIK_OEM_102 = 0x56,
DIK_F11 = 0x57,
DIK_F12 = 0x58,
DIK_F13 = 0x64,
DIK_F14 = 0x65,
DIK_F15 = 0x66,
DIK_KANA = 0x70,
DIK_ABNT_C1 = 0x73,
DIK_CONVERT = 0x79,
DIK_NOCONVERT = 0x7B,
DIK_YEN = 0x7D,
DIK_ABNT_C2 = 0x7E,
DIK_NUMPADEQUALS = 0x8D,
DIK_PREVTRACK = 0x90,
DIK_AT = 0x91,
DIK_COLON = 0x92,
DIK_UNDERLINE = 0x93,
DIK_KANJI = 0x94,
DIK_STOP = 0x95,
DIK_AX = 0x96,
DIK_UNLABELED = 0x97,
DIK_NEXTTRACK = 0x99,
DIK_NUMPADENTER = 0x9C,
DIK_RCONTROL = 0x9D,
DIK_MUTE = 0xA0,
DIK_CALCULATOR = 0xA1,
DIK_PLAYPAUSE = 0xA2,
DIK_MEDIASTOP = 0xA4,
DIK_VOLUMEDOWN = 0xAE,
DIK_VOLUMEUP = 0xB0,
DIK_WEBHOME = 0xB2,
DIK_NUMPADCOMMA = 0xB3,
DIK_DIVIDE = 0xB5,
DIK_SYSRQ = 0xB7,
DIK_RMENU = 0xB8,
DIK_PAUSE = 0xC5,
DIK_HOME = 0xC7,
DIK_UP = 0xC8,
DIK_PRIOR = 0xC9,
DIK_LEFT = 0xCB,
DIK_RIGHT = 0xCD,
DIK_END = 0xCF,
DIK_DOWN = 0xD0,
DIK_NEXT = 0xD1,
DIK_INSERT = 0xD2,
DIK_DELETE = 0xD3,
DIK_LWIN = 0xDB,
DIK_RWIN = 0xDC,
DIK_APPS = 0xDD,
DIK_POWER = 0xDE,
DIK_SLEEP = 0xDF,
DIK_WAKE = 0xE3,
DIK_WEBSEARCH = 0xE5,
DIK_WEBFAVORITES = 0xE6,
DIK_WEBREFRESH = 0xE7,
DIK_WEBSTOP = 0xE8,
DIK_WEBFORWARD = 0xE9,
DIK_WEBBACK = 0xEA,
DIK_MYCOMPUTER = 0xEB,
DIK_MAIL = 0xEC,
DIK_MEDIASELECT = 0xED,
DIK_BACKSPACE = DIK_BACK,
DIK_NUMPADSTAR = DIK_MULTIPLY,
DIK_LALT = DIK_LMENU,
DIK_CAPSLOCK = DIK_CAPITAL,
DIK_NUMPADMINUS = DIK_SUBTRACT,
DIK_NUMPADPLUS = DIK_ADD,
DIK_NUMPADPERIOD = DIK_DECIMAL,
DIK_NUMPADSLASH = DIK_DIVIDE,
DIK_RALT = DIK_RMENU,
DIK_UPARROW = DIK_UP,
DIK_PGUP = DIK_PRIOR,
DIK_LEFTARROW = DIK_LEFT,
DIK_RIGHTARROW = DIK_RIGHT,
DIK_DOWNARROW = DIK_DOWN,
DIK_PGDN = DIK_NEXT
};
}
namespace REX::W32
{
struct DIENVELOPE;
struct DIOBJECTDATAFORMAT;
struct DIACTIONA
{
std::uintptr_t appData;
std::uint32_t semantic;
std::uint32_t flags;
union
{
const char* actionName;
std::uint32_t resIdString;
};
GUID guidInstance;
std::uint32_t objID;
std::uint32_t how;
};
struct DIACTIONFORMATA
{
std::uint32_t size;
std::uint32_t actionSize;
std::uint32_t dataSize;
std::uint32_t numActions;
DIACTIONA* action;
GUID guidActionMap;
std::uint32_t genre;
std::uint32_t bufferSize;
std::int32_t axisMin;
std::int32_t axisMax;
HINSTANCE instString;
FILETIME timeStamp;
std::uint32_t crc;
char actionMap[MAX_PATH];
};
struct DICOLORSET
{
std::uint32_t size;
D3DCOLOR textFore;
D3DCOLOR textHighlight;
D3DCOLOR calloutLine;
D3DCOLOR calloutHighlight;
D3DCOLOR border;
D3DCOLOR controlFill;
D3DCOLOR highlightFill;
D3DCOLOR areaFill;
};
struct DICONFIGUREDEVICESPARAMSA
{
std::uint32_t size;
std::uint32_t users;
char* userNames;
std::uint32_t formatsSize;
DIACTIONFORMATA* formats;
HWND hwnd;
DICOLORSET dics;
IUnknown* unkDDSTarget;
};
struct DIDATAFORMAT
{
std::uint32_t size;
std::uint32_t objSize;
std::uint32_t flags;
std::uint32_t dataSize;
std::uint32_t numObjs;
DIOBJECTDATAFORMAT* odf;
};
struct DIDEVCAPS
{
std::uint32_t size;
std::uint32_t flags;
std::uint32_t devType;
std::uint32_t axes;
std::uint32_t buttons;
std::uint32_t povs;
std::uint32_t ffSamplePeriod;
std::uint32_t ffMinTimeResolution;
std::uint32_t firmwareRevision;
std::uint32_t hardwareRevision;
std::uint32_t ffDriverVersion;
};
struct DIDEVICEIMAGEINFOA
{
char imagePath[MAX_PATH];
std::uint32_t flags;
std::uint32_t viewID;
RECT overlay;
std::uint32_t objID;
std::uint32_t validPts;
POINT calloutLine[5];
RECT calloutRect;
std::uint32_t textAlign;
};
struct DIDEVICEIMAGEINFOHEADERA
{
std::uint32_t size;
std::uint32_t sizeImageInfo;
std::uint32_t views;
std::uint32_t buttons;
std::uint32_t axes;
std::uint32_t povs;
std::uint32_t bufferSize;
std::uint32_t bufferUsed;
DIDEVICEIMAGEINFOA* imageInfoArray;
};
struct DIDEVICEINSTANCEA
{
std::uint32_t size;
GUID guidInstance;
GUID guidProduct;
std::uint32_t devType;
char instanceName[MAX_PATH];
char productName[MAX_PATH];
GUID guidFFDriver;
// DIRECTINPUT_VERSION >= 0x0500
std::uint16_t usagePage;
std::uint16_t usage;
};
struct DIDEVICEOBJECTDATA
{
std::uint32_t ofs;
std::uint32_t data;
std::uint32_t timeStamp;
std::uint32_t sequence;
std::uintptr_t appData;
};
struct DIDEVICEOBJECTINSTANCEA
{
std::uint32_t size;
GUID guidType;
std::uint32_t ofs;
std::uint32_t type;
std::uint32_t flags;
char name[MAX_PATH];
// DIRECTINPUT_VERSION >= 0x0500
std::uint32_t ffMaxForce;
std::uint32_t ffForceResolution;
std::uint16_t collectionNumber;
std::uint16_t designatorIndex;
std::uint16_t usagePage;
std::uint16_t usage;
std::uint32_t dimension;
std::uint16_t exponent;
std::uint16_t reportId;
};
struct DIEFFECT
{
std::uint32_t size;
std::uint32_t flags;
std::uint32_t duration;
std::uint32_t samplePeriod;
std::uint32_t gain;
std::uint32_t triggerButton;
std::uint32_t triggerRepeatInterval;
std::uint32_t axesSize;
std::uint32_t* axes;
std::int32_t* direction;
DIENVELOPE* envelope;
std::uint32_t typeSpecificParamsSize;
void* typeSpecificParams;
std::uint32_t startDelay;
};
struct DIENVELOPE
{
std::uint32_t size;
std::uint32_t attackLevel;
std::uint32_t attackTime;
std::uint32_t fadeLevel;
std::uint32_t fadeTime;
};
struct DIEFFECTINFOA
{
std::uint32_t size;
GUID guid;
std::uint32_t effectType;
std::uint32_t staticParams;
std::uint32_t dynamicParams;
char name[MAX_PATH];
};
struct DIEFFESCAPE
{
std::uint32_t size;
std::uint32_t command;
void* inBuffer;
std::uint32_t inBufferSize;
void* outBuffer;
std::uint32_t outBufferSize;
};
struct DIFILEEFFECT
{
std::uint32_t size;
GUID guidEffect;
const DIEFFECT* effect;
char friendlyName[MAX_PATH];
};
struct DIMOUSESTATE2
{
std::int32_t x;
std::int32_t y;
std::int32_t z;
std::uint8_t rgbButtons[8];
};
struct DIOBJECTDATAFORMAT
{
const GUID* guid;
std::uint32_t ofs;
std::uint32_t type;
std::uint32_t flags;
};
struct DIPROPHEADER
{
std::uint32_t size;
std::uint32_t headerSize;
std::uint32_t obj;
std::uint32_t how;
};
}
namespace REX::W32
{
using LPDICONFIGUREDEVICESCALLBACK = BOOL(__stdcall*)(IUnknown*, void*);
using LPDIENUMCREATEDEFFECTOBJECTSCALLBACK = BOOL(__stdcall*)(IDirectInputEffect*, void*);
using LPDIENUMDEVICESBYSEMANTICSCBA = BOOL(__stdcall*)(const DIDEVICEINSTANCEA*, IDirectInputDevice8A*, std::uint32_t, std::uint32_t, void*);
using LPDIENUMDEVICESCALLBACKA = BOOL(__stdcall*)(const DIDEVICEINSTANCEA*, void*);
using LPDIENUMDEVICEOBJECTSCALLBACKA = BOOL(__stdcall*)(const DIDEVICEOBJECTINSTANCEA*, void*);
using LPDIENUMEFFECTSCALLBACKA = BOOL(__stdcall*)(const DIEFFECTINFOA*, void*);
using LPDIENUMEFFECTSINFILECALLBACK = BOOL(__stdcall*)(const DIFILEEFFECT*, void*);
}
namespace REX::W32
{
struct __declspec(novtable, uuid("BF798030-483A-4DA2-AA99-5D64ED369700"))
IDirectInput8A : public IUnknown
{
virtual HRESULT CreateDevice(const GUID&, IDirectInputDevice8A**, IUnknown*) noexcept = 0;
virtual HRESULT EnumDevices(std::uint32_t, LPDIENUMDEVICESCALLBACKA, void*, std::uint32_t) noexcept = 0;
virtual HRESULT GetDeviceStatus(const GUID&) noexcept = 0;
virtual HRESULT RunControlPanel(HWND, std::uint32_t) noexcept = 0;
virtual HRESULT Initialize(HINSTANCE, std::uint32_t) noexcept = 0;
virtual HRESULT FindDevice(const GUID&, const char*, GUID*) noexcept = 0;
virtual HRESULT EnumDevicesBySemantics(const char*, DIACTIONFORMATA*, LPDIENUMDEVICESBYSEMANTICSCBA, void*, std::uint32_t) noexcept = 0;
virtual HRESULT ConfigureDevices(LPDICONFIGUREDEVICESCALLBACK, DICONFIGUREDEVICESPARAMSA*, std::uint32_t, void*) noexcept = 0;
};
struct __declspec(novtable, uuid("54D41080-DC15-4833-A41B-748F73A38179"))
IDirectInputDevice8A : public IUnknown
{
virtual HRESULT GetCapabilities(DIDEVCAPS*) noexcept = 0;
virtual HRESULT EnumObjects(LPDIENUMDEVICEOBJECTSCALLBACKA, void*, std::uint32_t) noexcept = 0;
virtual HRESULT GetProperty(const GUID&, DIPROPHEADER*) noexcept = 0;
virtual HRESULT SetProperty(const GUID&, const DIPROPHEADER*) noexcept = 0;
virtual HRESULT Acquire() noexcept = 0;
virtual HRESULT Unacquire() noexcept = 0;
virtual HRESULT GetDeviceState(std::uint32_t, void*) noexcept = 0;
virtual HRESULT GetDeviceData(std::uint32_t, DIDEVICEOBJECTDATA*, std::uint32_t*, std::uint32_t) noexcept = 0;
virtual HRESULT SetDataFormat(const DIDATAFORMAT*) noexcept = 0;
virtual HRESULT SetEventNotification(HANDLE) noexcept = 0;
virtual HRESULT SetCooperativeLevel(HWND, std::uint32_t) noexcept = 0;
virtual HRESULT GetObjectInfo(DIDEVICEOBJECTINSTANCEA*, std::uint32_t, std::uint32_t) noexcept = 0;
virtual HRESULT GetDeviceInfo(DIDEVICEINSTANCEA*) noexcept = 0;
virtual HRESULT RunControlPanel(HWND, std::uint32_t) noexcept = 0;
virtual HRESULT Initialize(HINSTANCE, std::uint32_t, const GUID&) noexcept = 0;
virtual HRESULT CreateEffect(const GUID&, const DIEFFECT*, IDirectInputEffect*, IUnknown*) noexcept = 0;
virtual HRESULT EnumEffects(LPDIENUMEFFECTSCALLBACKA, void*, std::uint32_t) noexcept = 0;
virtual HRESULT GetEffectInfo(DIEFFECTINFOA*, const GUID&) noexcept = 0;
virtual HRESULT GetForceFeedbackState(std::uint32_t*) noexcept = 0;
virtual HRESULT SendForceFeedbackCommand(std::uint32_t) noexcept = 0;
virtual HRESULT EnumCreatedEffectObjects(LPDIENUMCREATEDEFFECTOBJECTSCALLBACK, void*, std::uint32_t) noexcept = 0;
virtual HRESULT Escape(DIEFFESCAPE*) noexcept = 0;
virtual HRESULT Poll() noexcept = 0;
virtual HRESULT SendDeviceData(std::uint32_t, const DIDEVICEOBJECTDATA*, std::uint32_t*, std::uint32_t) noexcept = 0;
virtual HRESULT EnumEffectsInFile(const char*, LPDIENUMEFFECTSINFILECALLBACK, void*, std::uint32_t) noexcept = 0;
virtual HRESULT WriteEffectToFile(const char*, std::uint32_t, DIFILEEFFECT*, std::uint32_t) noexcept = 0;
virtual HRESULT BuildActionMap(DIACTIONFORMATA*, const char*, std::uint32_t) noexcept = 0;
virtual HRESULT SetActionMap(DIACTIONFORMATA*, const char*, std::uint32_t) noexcept = 0;
virtual HRESULT GetImageInfo(DIDEVICEIMAGEINFOHEADERA*) noexcept = 0;
};
struct __declspec(novtable, uuid("E7E1F7C0-88D2-11D0-9AD0-00A0C9A06E35"))
IDirectInputEffect : public IUnknown
{
virtual HRESULT Initialize(HINSTANCE, std::uint32_t, const GUID&) noexcept = 0;
virtual HRESULT GetEffectGuid(GUID*) noexcept = 0;
virtual HRESULT GetParameters(DIEFFECT*, std::uint32_t) noexcept = 0;
virtual HRESULT SetParameters(const DIEFFECT*, std::uint32_t) noexcept = 0;
virtual HRESULT Start(std::uint32_t, std::uint32_t) noexcept = 0;
virtual HRESULT Stop() noexcept = 0;
virtual HRESULT GetEffectStatus(std::uint32_t*) noexcept = 0;
virtual HRESULT Download() noexcept = 0;
virtual HRESULT Unload() noexcept = 0;
virtual HRESULT Escape(DIEFFESCAPE*) noexcept = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_IDirectInput8A{ 0xBF798030, 0x483A, 0x4DA2, { 0xAA, 0x99, 0x5D, 0x64, 0xED, 0x36, 0x97, 0x00 } };
inline constexpr IID IID_IDirectInputDevice8A{ 0x54D41080, 0xDC15, 0x4833, { 0xA4, 0x1B, 0x74, 0x8F, 0x73, 0xA3, 0x81, 0x79 } };
inline constexpr IID IID_IDirectInputEffect{ 0xE7E1F7C0, 0x88D2, 0x11D0, { 0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35 } };
}
@@ -0,0 +1,549 @@
#pragma once
#include "REX/W32/COM.h"
namespace REX::W32
{
struct IDXGIAdapter;
struct IDXGIAdapter1;
struct IDXGIDevice;
struct IDXGIDevice1;
struct IDXGIDeviceSubObject;
struct IDXGIFactory1;
struct IDXGIKeyedMutex;
struct IDXGIObject;
struct IDXGIOutput;
struct IDXGIResource;
struct IDXGISurface;
struct IDXGISurface1;
struct IDXGISwapChain;
}
namespace REX::W32
{
enum DXGI_ADAPTER_FLAG
{
DXGI_ADAPTER_FLAG_NONE = 0,
DXGI_ADAPTER_FLAG_REMOTE = 1,
DXGI_ADAPTER_FLAG_SOFTWARE = 2,
DXGI_ADAPTER_FLAG_FORCE_DWORD = 0xFFFFFFFF,
};
enum DXGI_COLOR_SPACE_TYPE
{
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 = 0,
DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 = 1,
DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 = 2,
DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020 = 3,
DXGI_COLOR_SPACE_RESERVED = 4,
DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601 = 5,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601 = 6,
DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601 = 7,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 = 8,
DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709 = 9,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020 = 10,
DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020 = 11,
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 = 12,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020 = 13,
DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 = 14,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020 = 15,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020 = 16,
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020 = 17,
DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020 = 18,
DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020 = 19,
DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709 = 20,
DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020 = 21,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P709 = 22,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020 = 23,
DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020 = 24,
DXGI_COLOR_SPACE_CUSTOM = 0xFFFFFFFF,
};
enum DXGI_FORMAT
{
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
DXGI_FORMAT_AYUV = 100,
DXGI_FORMAT_Y410 = 101,
DXGI_FORMAT_Y416 = 102,
DXGI_FORMAT_NV12 = 103,
DXGI_FORMAT_P010 = 104,
DXGI_FORMAT_P016 = 105,
DXGI_FORMAT_420_OPAQUE = 106,
DXGI_FORMAT_YUY2 = 107,
DXGI_FORMAT_Y210 = 108,
DXGI_FORMAT_Y216 = 109,
DXGI_FORMAT_NV11 = 110,
DXGI_FORMAT_AI44 = 111,
DXGI_FORMAT_IA44 = 112,
DXGI_FORMAT_P8 = 113,
DXGI_FORMAT_A8P8 = 114,
DXGI_FORMAT_B4G4R4A4_UNORM = 115,
DXGI_FORMAT_P208 = 130,
DXGI_FORMAT_V208 = 131,
DXGI_FORMAT_V408 = 132,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190,
DXGI_FORMAT_FORCE_UINT = 0xFFFFFFFF,
};
enum DXGI_MODE_ROTATION
{
DXGI_MODE_ROTATION_UNSPECIFIED = 0,
DXGI_MODE_ROTATION_IDENTITY = 1,
DXGI_MODE_ROTATION_ROTATE90 = 2,
DXGI_MODE_ROTATION_ROTATE180 = 3,
DXGI_MODE_ROTATION_ROTATE270 = 4,
};
enum DXGI_MODE_SCALING
{
DXGI_MODE_SCALING_UNSPECIFIED = 0,
DXGI_MODE_SCALING_CENTERED = 1,
DXGI_MODE_SCALING_STRETCHED = 2,
};
enum DXGI_MODE_SCANLINE_ORDER
{
DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED = 0,
DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE = 1,
DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST = 2,
DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST = 3,
};
enum DXGI_RESIDENCY
{
DXGI_RESIDENCY_FULLY_RESIDENT = 1,
DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY = 2,
DXGI_RESIDENCY_EVICTED_TO_DISK = 3,
};
enum DXGI_SWAP_EFFECT
{
DXGI_SWAP_EFFECT_DISCARD = 0,
DXGI_SWAP_EFFECT_SEQUENTIAL = 1,
DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3,
DXGI_SWAP_EFFECT_FLIP_DISCARD = 4,
};
enum DXGI_SWAP_CHAIN_FLAG
{
DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1,
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2,
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4,
DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT = 8,
DXGI_SWAP_CHAIN_FLAG_RESTRICT_SHARED_RESOURCE_DRIVER = 16,
DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY = 32,
DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT = 64,
DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER = 128,
DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO = 256,
DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO = 512,
DXGI_SWAP_CHAIN_FLAG_HW_PROTECTED = 1024,
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING = 2048,
DXGI_SWAP_CHAIN_FLAG_RESTRICTED_TO_ALL_HOLOGRAPHIC_DISPLAYS = 4096,
};
}
namespace REX::W32
{
struct D3DCOLORVALUE
{
float r;
float g;
float b;
float a;
};
using DXGI_RGBA = D3DCOLORVALUE;
using DXGI_USAGE = std::uint32_t;
struct LUID
{
std::uint32_t lo;
std::int32_t hi;
};
}
namespace REX::W32
{
struct DXGI_ADAPTER_DESC
{
wchar_t description[128];
std::uint32_t vendorId;
std::uint32_t deviceId;
std::uint32_t subSysId;
std::uint32_t revision;
std::size_t dedicatedVideoMemory;
std::size_t dedicatedSystemMemory;
std::size_t sharedSystemMemory;
LUID adapterLuid;
};
struct DXGI_ADAPTER_DESC1
{
wchar_t description[128];
std::uint32_t vendorId;
std::uint32_t deviceId;
std::uint32_t subSysId;
std::uint32_t revision;
std::size_t dedicatedVideoMemory;
std::size_t dedicatedSystemMemory;
std::size_t sharedSystemMemory;
LUID adapterLuid;
std::uint32_t flags;
};
struct DXGI_DISPLAY_COLOR_SPACE
{
float primaryCoordinates[8][2];
float whitePoints[16][2];
};
struct DXGI_FRAME_STATISTICS
{
std::uint32_t presentCount;
std::uint32_t presentRefreshCount;
std::uint32_t syncRefreshCount;
std::int64_t syncQPCTime;
std::int64_t syncGPUTime;
};
struct DXGI_RGB
{
float red;
float green;
float blue;
};
struct DXGI_GAMMA_CONTROL
{
DXGI_RGB scale;
DXGI_RGB offset;
DXGI_RGB gammaCurve[1025];
};
struct DXGI_GAMMA_CONTROL_CAPABILITIES
{
BOOL scaleAndOffsetSupported;
float maxConvertedValue;
float minConvertedValue;
std::uint32_t numGammaControlPoints;
float controlPointPositions[1025];
};
struct DXGI_MAPPED_RECT
{
std::int32_t pitch;
std::uint8_t* bits;
};
struct DXGI_RATIONAL
{
std::uint32_t numerator;
std::uint32_t denominator;
};
struct DXGI_MODE_DESC
{
std::uint32_t width;
std::uint32_t height;
DXGI_RATIONAL refreshRate;
DXGI_FORMAT format;
DXGI_MODE_SCANLINE_ORDER scanlineOrdering;
DXGI_MODE_SCALING scaling;
};
struct DXGI_OUTPUT_DESC
{
wchar_t deviceName[32];
RECT desktopCoordinates;
BOOL attachedToDesktop;
DXGI_MODE_ROTATION rotation;
HMONITOR monitor;
};
struct DXGI_SAMPLE_DESC
{
std::uint32_t count;
std::uint32_t quality;
};
struct DXGI_SHARED_RESOURCE
{
HANDLE handle;
};
struct DXGI_SURFACE_DESC
{
std::uint32_t width;
std::uint32_t height;
DXGI_FORMAT format;
DXGI_SAMPLE_DESC sampleDesc;
};
struct DXGI_SWAP_CHAIN_DESC
{
DXGI_MODE_DESC bufferDesc;
DXGI_SAMPLE_DESC sampleDesc;
DXGI_USAGE bufferUsage;
std::uint32_t bufferCount;
HWND outputWindow;
BOOL windowed;
DXGI_SWAP_EFFECT swapEffect;
std::uint32_t flags;
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("aec22fb8-76f3-4639-9be0-28eb43a67a2e"))
IDXGIObject : public IUnknown
{
virtual HRESULT SetPrivateData(const GUID& a_iid, std::uint32_t a_dataSize, const void* a_data) = 0;
virtual HRESULT SetPrivateDataInterface(const GUID& a_iid, const IUnknown* a_unknown) = 0;
virtual HRESULT GetPrivateData(const GUID& a_iid, std::uint32_t* a_dataSize, void* a_data) = 0;
virtual HRESULT GetParent(const GUID& a_iid, void** a_parent) = 0;
};
struct __declspec(novtable, uuid("3d3e0379-f9de-4d58-bb6c-18d62992f1a6"))
IDXGIDeviceSubObject : public IDXGIObject
{
virtual HRESULT GetDevice(const GUID& a_iid, void** a_device) = 0;
};
struct __declspec(novtable, uuid("035f3ab4-482e-4e50-b41f-8a7f8bd8960b"))
IDXGIResource : public IDXGIDeviceSubObject
{
virtual HRESULT GetSharedHandle(HANDLE* a_sharedHandle) = 0;
virtual HRESULT GetUsage(DXGI_USAGE* a_usage) = 0;
virtual HRESULT SetEvictionPriority(std::uint32_t a_evictionPriority) = 0;
virtual HRESULT GetEvictionPriority(std::uint32_t* a_evictionPriority) = 0;
};
struct __declspec(novtable, uuid("9d8e1289-d7b3-465f-8126-250e349af85d"))
IDXGIKeyedMutex : public IDXGIDeviceSubObject
{
virtual HRESULT AcquireSync(std::uint64_t a_key, std::uint32_t a_milliseconds) = 0;
virtual HRESULT ReleaseSync(std::uint64_t a_key) = 0;
};
struct __declspec(novtable, uuid("cafcb56c-6ac3-4889-bf47-9e23bbd260ec"))
IDXGISurface : public IDXGIDeviceSubObject
{
virtual HRESULT GetDesc(DXGI_SURFACE_DESC* a_desc) = 0;
virtual HRESULT Map(DXGI_MAPPED_RECT* a_lockedRect, std::uint32_t a_mapFlags) = 0;
virtual HRESULT Unmap(void) = 0;
};
struct __declspec(novtable, uuid("4AE63092-6327-4c1b-80AE-BFE12EA32B86"))
IDXGISurface1 : public IDXGISurface
{
virtual HRESULT GetDC(BOOL a_discard, HDC* a_hdc) = 0;
virtual HRESULT ReleaseDC(RECT* a_dirtyRect) = 0;
};
struct __declspec(novtable, uuid("2411e7e1-12ac-4ccf-bd14-9798e8534dc0"))
IDXGIAdapter : public IDXGIObject
{
virtual HRESULT EnumOutputs(std::uint32_t a_outputSize, IDXGIOutput** a_output) = 0;
virtual HRESULT GetDesc(DXGI_ADAPTER_DESC* a_desc) = 0;
virtual HRESULT CheckInterfaceSupport(const GUID& a_iid, std::int64_t* a_umdVersion) = 0;
};
struct __declspec(novtable, uuid("29038f61-3839-4626-91fd-086879011a05"))
IDXGIAdapter1 : public IDXGIAdapter
{
virtual HRESULT GetDesc1(DXGI_ADAPTER_DESC1* a_desc) = 0;
};
struct __declspec(novtable, uuid("ae02eedb-c735-4690-8d52-5a8dc20213aa"))
IDXGIOutput : public IDXGIObject
{
virtual HRESULT GetDesc(DXGI_OUTPUT_DESC* a_desc) = 0;
virtual HRESULT GetDisplayModeList(DXGI_FORMAT a_enumFormat, std::uint32_t a_flags, std::uint32_t* a_numModes, DXGI_MODE_DESC* a_desc) = 0;
virtual HRESULT FindClosestMatchingMode(const DXGI_MODE_DESC* a_modeToMatch, DXGI_MODE_DESC* a_closestMatch, IUnknown* a_concernedDevice) = 0;
virtual HRESULT WaitForVBlank(void) = 0;
virtual HRESULT TakeOwnership(IUnknown* a_device, BOOL a_exclusive) = 0;
virtual void ReleaseOwnership(void) = 0;
virtual HRESULT GetGammaControlCapabilities(DXGI_GAMMA_CONTROL_CAPABILITIES* a_gammaCaps) = 0;
virtual HRESULT SetGammaControl(const DXGI_GAMMA_CONTROL* a_array) = 0;
virtual HRESULT GetGammaControl(DXGI_GAMMA_CONTROL* a_array) = 0;
virtual HRESULT SetDisplaySurface(IDXGISurface* a_scanoutSurface) = 0;
virtual HRESULT GetDisplaySurfaceData(IDXGISurface* a_destination) = 0;
virtual HRESULT GetFrameStatistics(DXGI_FRAME_STATISTICS* a_stats) = 0;
};
struct __declspec(novtable, uuid("310d36a0-d2e7-4c0a-aa04-6a9d23b8886a"))
IDXGISwapChain : public IDXGIDeviceSubObject
{
virtual HRESULT Present(std::uint32_t a_syncInterval, std::uint32_t a_flags) = 0;
virtual HRESULT GetBuffer(std::uint32_t a_buffer, const GUID& a_iid, void** a_surface) = 0;
virtual HRESULT SetFullscreenState(BOOL a_fullscreen, IDXGIOutput* a_target) = 0;
virtual HRESULT GetFullscreenState(BOOL* a_fullscreen, IDXGIOutput** a_target) = 0;
virtual HRESULT GetDesc(DXGI_SWAP_CHAIN_DESC* a_desc) = 0;
virtual HRESULT ResizeBuffers(std::uint32_t a_bufferCount, std::uint32_t a_width, std::uint32_t a_height, DXGI_FORMAT a_newFormat, std::uint32_t a_swapChainFlags) = 0;
virtual HRESULT ResizeTarget(const DXGI_MODE_DESC* a_newTargetParameters) = 0;
virtual HRESULT GetContainingOutput(IDXGIOutput** a_output) = 0;
virtual HRESULT GetFrameStatistics(DXGI_FRAME_STATISTICS* a_stats) = 0;
virtual HRESULT GetLastPresentCount(std::uint32_t* a_lastPresentCount) = 0;
};
struct __declspec(novtable, uuid("7b7166ec-21c7-44ae-b21a-c9ae321ae369"))
IDXGIFactory : public IDXGIObject
{
virtual HRESULT EnumAdapters(std::uint32_t a_adapterSize, IDXGIAdapter** a_adapter) = 0;
virtual HRESULT MakeWindowAssociation(HWND a_windowHandle, std::uint32_t a_flags) = 0;
virtual HRESULT GetWindowAssociation(HWND* a_windowHandle) = 0;
virtual HRESULT CreateSwapChain(IUnknown* a_device, DXGI_SWAP_CHAIN_DESC* a_desc, IDXGISwapChain** a_swapChain) = 0;
virtual HRESULT CreateSoftwareAdapter(HMODULE a_module, IDXGIAdapter** a_adapter) = 0;
};
struct __declspec(novtable, uuid("770aae78-f26f-4dba-a829-253c83d1b387"))
IDXGIFactory1 : public IDXGIFactory
{
virtual HRESULT EnumAdapters1(std::uint32_t a_adapterSize, IDXGIAdapter1** a_adapter) = 0;
virtual BOOL IsCurrent(void) = 0;
};
struct __declspec(novtable, uuid("54ec77fa-1377-44e6-8c32-88fd5f44c84c"))
IDXGIDevice : public IDXGIObject
{
virtual HRESULT GetAdapter(IDXGIAdapter** a_adapter) = 0;
virtual HRESULT CreateSurface(const DXGI_SURFACE_DESC* a_desc, std::uint32_t a_numSurfaces, DXGI_USAGE a_usage, const DXGI_SHARED_RESOURCE* a_sharedResource, IDXGISurface** a_surface) = 0;
virtual HRESULT QueryResourceResidency(IUnknown* const* a_resources, DXGI_RESIDENCY* a_residencyStatus, std::uint32_t a_numResources) = 0;
virtual HRESULT SetGPUThreadPriority(std::int32_t a_priority) = 0;
virtual HRESULT GetGPUThreadPriority(std::int32_t* a_priority) = 0;
};
struct __declspec(novtable, uuid("77db970f-6276-48ba-ba28-070143b4392c"))
IDXGIDevice1 : public IDXGIDevice
{
virtual HRESULT SetMaximumFrameLatency(std::uint32_t a_maxLatency) = 0;
virtual HRESULT GetMaximumFrameLatency(std::uint32_t* a_maxLatency) = 0;
};
}
namespace REX::W32
{
HRESULT CreateDXGIFactory(const IID& a_iid, void** a_factory) noexcept;
HRESULT CreateDXGIFactory1(const IID& a_iid, void** a_factory) noexcept;
}
namespace REX::W32
{
inline constexpr IID IID_IDXGIAdapter{ 0x2411E7E1, 0x12AC, 0x4CCF, { 0xBD, 0x14, 0x97, 0x98, 0xE8, 0x53, 0x4D, 0xC0 } };
inline constexpr IID IID_IDXGIAdapter1{ 0x29038F61, 0x3839, 0x4626, { 0x91, 0xFD, 0x08, 0x68, 0x79, 0x01, 0x1A, 0x05 } };
inline constexpr IID IID_IDXGIObject{ 0xAEC22Fb8, 0x76F3, 0x4639, { 0x9B, 0xE0, 0x28, 0xEB, 0x43, 0xA6, 0x7A, 0x2E } };
inline constexpr IID IID_IDXGIDevice{ 0x54EC77FA, 0x1377, 0x44E6, { 0x8C, 0x32, 0x88, 0xFD, 0x5F, 0x44, 0xC8, 0x4C } };
inline constexpr IID IID_IDXGIDevice1{ 0x77DB970F, 0x6276, 0x48BA, { 0xBA, 0x28, 0x07, 0x01, 0x43, 0xB4, 0x39, 0x2C } };
inline constexpr IID IID_IDXGIDeviceSubObject{ 0x3D3E0379, 0xF9DE, 0x4D58, { 0xBB, 0x6C, 0x18, 0xD6, 0x29, 0x92, 0xF1, 0xA6 } };
inline constexpr IID IID_IDXGIFactory{ 0x7B7166EC, 0x21C7, 0x44AE, { 0xB2, 0x1A, 0xC9, 0xAE, 0x32, 0x1A, 0xE3, 0x69 } };
inline constexpr IID IID_IDXGIFactory1{ 0x770AAE78, 0xF26F, 0x4DBA, { 0xA8, 0x29, 0x25, 0x3C, 0x83, 0xD1, 0xB3, 0x87 } };
inline constexpr IID IID_IDXGIKeyedMutex{ 0x9D8E1289, 0xD7B3, 0x465F, { 0x81, 0x26, 0x25, 0x0E, 0x34, 0x9A, 0xF8, 0x5D } };
inline constexpr IID IID_IDXGIOutput{ 0xAE02EEDB, 0xC735, 0x4690, { 0x8D, 0x52, 0x5A, 0x8D, 0xC2, 0x02, 0x13, 0xAA } };
inline constexpr IID IID_IDXGIResource{ 0x035F3AB4, 0x482E, 0x4E50, { 0xB4, 0x1F, 0x8A, 0x7F, 0x8B, 0xD8, 0x96, 0x0B } };
inline constexpr IID IID_IDXGISurface{ 0xCAFCB56C, 0x6AC3, 0x4889, { 0xBF, 0x47, 0x9E, 0x23, 0xBB, 0xD2, 0x60, 0xEC } };
inline constexpr IID IID_IDXGISurface1{ 0x4AE63092, 0x6327, 0x4C1B, { 0x80, 0xAE, 0xBF, 0xE1, 0x2E, 0xA3, 0x2B, 0x86 } };
inline constexpr IID IID_IDXGISwapChain{ 0x310D36A0, 0xD2E7, 0x4C0A, { 0xAA, 0x04, 0x6A, 0x9D, 0x23, 0xB8, 0x88, 0x6A } };
}
@@ -0,0 +1,272 @@
#pragma once
#include "REX/W32/DXGI.h"
namespace REX::W32
{
struct IDXGIAdapter2;
struct IDXGIDevice2;
struct IDXGIDisplayControl;
struct IDXGIFactory2;
struct IDXGIOutput1;
struct IDXGIOutputDuplication;
struct IDXGIResource1;
struct IDXGISurface2;
struct IDXGISwapChain1;
}
namespace REX::W32
{
enum DXGI_ALPHA_MODE
{
DXGI_ALPHA_MODE_UNSPECIFIED = 0,
DXGI_ALPHA_MODE_PREMULTIPLIED = 1,
DXGI_ALPHA_MODE_STRAIGHT = 2,
DXGI_ALPHA_MODE_IGNORE = 3,
DXGI_ALPHA_MODE_FORCE_DWORD = 0xFFFFFFFF,
};
enum DXGI_COMPUTE_PREEMPTION_GRANULARITY
{
DXGI_COMPUTE_PREEMPTION_DMA_BUFFER_BOUNDARY = 0,
DXGI_COMPUTE_PREEMPTION_DISPATCH_BOUNDARY = 1,
DXGI_COMPUTE_PREEMPTION_THREAD_GROUP_BOUNDARY = 2,
DXGI_COMPUTE_PREEMPTION_THREAD_BOUNDARY = 3,
DXGI_COMPUTE_PREEMPTION_INSTRUCTION_BOUNDARY = 4,
};
enum DXGI_GRAPHICS_PREEMPTION_GRANULARITY
{
DXGI_GRAPHICS_PREEMPTION_DMA_BUFFER_BOUNDARY = 0,
DXGI_GRAPHICS_PREEMPTION_PRIMITIVE_BOUNDARY = 1,
DXGI_GRAPHICS_PREEMPTION_TRIANGLE_BOUNDARY = 2,
DXGI_GRAPHICS_PREEMPTION_PIXEL_BOUNDARY = 3,
DXGI_GRAPHICS_PREEMPTION_INSTRUCTION_BOUNDARY = 4,
};
enum DXGI_OFFER_RESOURCE_PRIORITY
{
DXGI_OFFER_RESOURCE_PRIORITY_LOW = 1,
DXGI_OFFER_RESOURCE_PRIORITY_NORMAL = (DXGI_OFFER_RESOURCE_PRIORITY_LOW + 1),
DXGI_OFFER_RESOURCE_PRIORITY_HIGH = (DXGI_OFFER_RESOURCE_PRIORITY_NORMAL + 1)
};
enum DXGI_OUTDUPL_POINTER_SHAPE_TYPE
{
DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME = 0x1,
DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR = 0x2,
DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR = 0x4,
};
enum DXGI_SCALING
{
DXGI_SCALING_STRETCH = 0,
DXGI_SCALING_NONE = 1,
DXGI_SCALING_ASPECT_RATIO_STRETCH = 2,
};
}
namespace REX::W32
{
struct DXGI_ADAPTER_DESC2
{
wchar_t description[128];
std::uint32_t vendorID;
std::uint32_t deviceID;
std::uint32_t subSysID;
std::uint32_t revision;
std::size_t dedicatedVideoMemory;
std::size_t dedicatedSystemMemory;
std::size_t sharedSystemMemory;
LUID adapterLUID;
std::uint32_t flags;
DXGI_GRAPHICS_PREEMPTION_GRANULARITY graphicsPreemptionGranularity;
DXGI_COMPUTE_PREEMPTION_GRANULARITY computePreemptionGranularity;
};
struct DXGI_MODE_DESC1
{
std::uint32_t width;
std::uint32_t height;
DXGI_RATIONAL refreshRate;
DXGI_FORMAT format;
DXGI_MODE_SCANLINE_ORDER scanlineOrdering;
DXGI_MODE_SCALING scaling;
BOOL stereo;
};
struct DXGI_OUTDUPL_DESC
{
DXGI_MODE_DESC modeDesc;
DXGI_MODE_ROTATION rotation;
BOOL desktopImageInSystemMemory;
};
struct DXGI_OUTDUPL_POINTER_POSITION
{
POINT position;
BOOL visible;
};
struct DXGI_OUTDUPL_FRAME_INFO
{
std::int64_t lastPresentTime;
std::int64_t lastMouseUpdateTime;
std::uint32_t accumulatedFrames;
BOOL rectsCoalesced;
BOOL protectedContentMaskedOut;
DXGI_OUTDUPL_POINTER_POSITION pointerPosition;
std::uint32_t totalMetadataBufferSize;
std::uint32_t pointerShapeBufferSize;
};
struct DXGI_OUTDUPL_MOVE_RECT
{
POINT sourcePoint;
RECT destinationRect;
};
struct DXGI_OUTDUPL_POINTER_SHAPE_INFO
{
std::uint32_t type;
std::uint32_t width;
std::uint32_t height;
std::uint32_t pitch;
POINT hotSpot;
};
struct DXGI_PRESENT_PARAMETERS
{
std::uint32_t dirtyRectsCount;
RECT* dirtyRects;
RECT* scrollRect;
POINT* scrollOffset;
};
struct DXGI_SWAP_CHAIN_DESC1
{
std::uint32_t width;
std::uint32_t height;
DXGI_FORMAT format;
BOOL stereo;
DXGI_SAMPLE_DESC sampleDesc;
DXGI_USAGE bufferUsage;
std::uint32_t bufferCount;
DXGI_SCALING scaling;
DXGI_SWAP_EFFECT swapEffect;
DXGI_ALPHA_MODE alphaMode;
std::uint32_t flags;
};
struct DXGI_SWAP_CHAIN_FULLSCREEN_DESC
{
DXGI_RATIONAL refreshRate;
DXGI_MODE_SCANLINE_ORDER scanlineOrdering;
DXGI_MODE_SCALING scaling;
BOOL windowed;
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("0AA1AE0A-FA0E-4B84-8644-E05FF8E5ACB5"))
IDXGIAdapter2 : public IDXGIAdapter1
{
virtual HRESULT GetDesc2(DXGI_ADAPTER_DESC2* a_desc) = 0;
};
struct __declspec(novtable, uuid("05008617-FBFD-4051-A790-144884B4F6A9"))
IDXGIDevice2 : public IDXGIDevice1
{
virtual HRESULT OfferResources(std::uint32_t a_numResources, IDXGIResource* const* a_resources, DXGI_OFFER_RESOURCE_PRIORITY a_priority) = 0;
virtual HRESULT ReclaimResources(std::uint32_t a_numResources, IDXGIResource* const* a_resources, BOOL* a_discarded) = 0;
virtual HRESULT EnqueueSetEvent(HANDLE a_event) = 0;
};
struct __declspec(novtable, uuid("EA9DBF1A-C88E-4486-854A-98AA0138F30C"))
IDXGIDisplayControl : public IUnknown
{
virtual BOOL IsStereoEnabled(void) = 0;
virtual void SetStereoEnabled(BOOL a_enabled) = 0;
};
struct __declspec(novtable, uuid("50C83A1C-E072-4C48-87B0-3630FA36A6D0"))
IDXGIFactory2 : public IDXGIFactory1
{
virtual BOOL IsWindowedStereoEnabled(void) = 0;
virtual HRESULT CreateSwapChainForHwnd(IUnknown* a_device, HWND a_wnd, const DXGI_SWAP_CHAIN_DESC1* a_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* a_fullscreenDesc, IDXGIOutput* a_restrictToOutput, IDXGISwapChain1** a_swapChain) = 0;
virtual HRESULT CreateSwapChainForCoreWindow(IUnknown* a_device, IUnknown* a_window, const DXGI_SWAP_CHAIN_DESC1* a_desc, IDXGIOutput* a_restrictToOutput, IDXGISwapChain1** a_swapChain) = 0;
virtual HRESULT GetSharedResourceAdapterLuid(HANDLE a_resource, LUID* a_luid) = 0;
virtual HRESULT RegisterStereoStatusWindow(HWND a_wnd, std::uint32_t a_msg, std::uint32_t* a_cookie) = 0;
virtual HRESULT RegisterStereoStatusEvent(HANDLE a_event, std::uint32_t* a_cookie) = 0;
virtual void UnregisterStereoStatus(std::uint32_t a_cookie) = 0;
virtual HRESULT RegisterOcclusionStatusWindow(HWND a_wnd, std::uint32_t a_msg, std::uint32_t* a_cookie) = 0;
virtual HRESULT RegisterOcclusionStatusEvent(HANDLE a_event, std::uint32_t* a_cookie) = 0;
virtual void UnregisterOcclusionStatus(std::uint32_t dwCookie) = 0;
virtual HRESULT CreateSwapChainForComposition(IUnknown* a_device, const DXGI_SWAP_CHAIN_DESC1* a_desc, IDXGIOutput* a_restrictToOutput, IDXGISwapChain1** a_swapChain) = 0;
};
struct __declspec(novtable, uuid("00CDDEA8-939B-4B83-A340-A685226666CC"))
IDXGIOutput1 : public IDXGIOutput
{
virtual HRESULT GetDisplayModeList1(DXGI_FORMAT a_enumFormat, std::uint32_t a_flags, std::uint32_t* a_numModes, DXGI_MODE_DESC1* a_desc) = 0;
virtual HRESULT FindClosestMatchingMode1(const DXGI_MODE_DESC1* a_modeToMatch, DXGI_MODE_DESC1* a_closestMatch, IUnknown* a_concernedDevice) = 0;
virtual HRESULT GetDisplaySurfaceData1(IDXGIResource* a_destination) = 0;
virtual HRESULT DuplicateOutput(IUnknown* a_device, IDXGIOutputDuplication** a_outputDuplication) = 0;
};
struct __declspec(novtable, uuid("191CFAC3-A341-470D-B26E-A864F428319C"))
IDXGIOutputDuplication : public IDXGIObject
{
virtual void GetDesc(DXGI_OUTDUPL_DESC* a_desc) = 0;
virtual HRESULT AcquireNextFrame(std::uint32_t a_timeoutInMilliseconds, DXGI_OUTDUPL_FRAME_INFO* a_frameInfo, IDXGIResource** a_desktopResource) = 0;
virtual HRESULT GetFrameDirtyRects(std::uint32_t a_dirtyRectsBufferSize, RECT* a_dirtyRectsBuffer, std::uint32_t* a_dirtyRectsBufferSizeRequired) = 0;
virtual HRESULT GetFrameMoveRects(std::uint32_t a_moveRectsBufferSize, DXGI_OUTDUPL_MOVE_RECT* a_moveRectBuffer, std::uint32_t* a_moveRectsBufferSizeRequired) = 0;
virtual HRESULT GetFramePointerShape(std::uint32_t a_pointerShapeBufferSize, void* a_pointerShapeBuffer, std::uint32_t* a_pointerShapeBufferSizeRequired, DXGI_OUTDUPL_POINTER_SHAPE_INFO* a_pointerShapeInfo) = 0;
virtual HRESULT MapDesktopSurface(DXGI_MAPPED_RECT* a_lockedRect) = 0;
virtual HRESULT UnMapDesktopSurface(void) = 0;
virtual HRESULT ReleaseFrame(void) = 0;
};
struct __declspec(novtable, uuid("30961379-4609-4A41-998E-54FE567EE0C1"))
IDXGIResource1 : public IDXGIResource
{
virtual HRESULT CreateSubresourceSurface(std::uint32_t a_index, IDXGISurface2** a_surface) = 0;
virtual HRESULT CreateSharedHandle(const SECURITY_ATTRIBUTES* a_attributes, std::uint32_t a_access, const wchar_t* a_name, HANDLE* a_handle) = 0;
};
struct __declspec(novtable, uuid("ABA496DD-B617-4CB8-A866-BC44D7EB1FA2"))
IDXGISurface2 : public IDXGISurface1
{
virtual HRESULT GetResource(const IID& a_iid, void** a_parentResource, std::uint32_t* a_subresourceIndex) = 0;
};
struct __declspec(novtable, uuid("790A45F7-0D42-4876-983A-0A55CFE6F4AA"))
IDXGISwapChain1 : public IDXGISwapChain
{
virtual HRESULT GetDesc1(DXGI_SWAP_CHAIN_DESC1* a_desc) = 0;
virtual HRESULT GetFullscreenDesc(DXGI_SWAP_CHAIN_FULLSCREEN_DESC* a_desc) = 0;
virtual HRESULT GetHwnd(HWND* a_wnd) = 0;
virtual HRESULT GetCoreWindow(const IID& a_iid, void** a_unk) = 0;
virtual HRESULT Present1(std::uint32_t a_syncInterval, std::uint32_t a_presentFlags, const DXGI_PRESENT_PARAMETERS* a_presentParameters) = 0;
virtual BOOL IsTemporaryMonoSupported(void) = 0;
virtual HRESULT GetRestrictToOutput(IDXGIOutput** a_restrictToOutput) = 0;
virtual HRESULT SetBackgroundColor(const DXGI_RGBA* a_color) = 0;
virtual HRESULT GetBackgroundColor(DXGI_RGBA* a_color) = 0;
virtual HRESULT SetRotation(DXGI_MODE_ROTATION a_rotation) = 0;
virtual HRESULT GetRotation(DXGI_MODE_ROTATION* a_rotation) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_IDXGIAdapter2{ 0x0AA1AE0A, 0xFA0E, 0x4B84, { 0x86, 0x44, 0xE0, 0x5F, 0xF8, 0xE5, 0xAC, 0xB5 } };
inline constexpr IID IID_IDXGIDevice2{ 0x05008617, 0xFBFD, 0x4051, { 0xA7, 0x90, 0x14, 0x48, 0x84, 0xB4, 0xF6, 0xA9 } };
inline constexpr IID IID_IDXGIDisplayControl{ 0xEA9DBF1A, 0xC88E, 0x4486, { 0x85, 0x4A, 0x98, 0xAA, 0x01, 0x38, 0xF3, 0x0C } };
inline constexpr IID IID_IDXGIFactory2{ 0x50C83A1C, 0xE072, 0x4C48, { 0x87, 0xB0, 0x36, 0x30, 0xFA, 0x36, 0xA6, 0xD0 } };
inline constexpr IID IID_IDXGIOutput1{ 0x00CDDEA8, 0x939B, 0x4B83, { 0xA3, 0x40, 0xA6, 0x85, 0x22, 0x66, 0x66, 0xCC } };
inline constexpr IID IID_IDXGIOutputDuplication{ 0x191CFAC3, 0xA341, 0x470D, { 0xB2, 0x6E, 0xA8, 0x64, 0xF4, 0x28, 0x31, 0x9C } };
inline constexpr IID IID_IDXGIResource1{ 0x30961379, 0x4609, 0x4A41, { 0x99, 0x8E, 0x54, 0xFE, 0x56, 0x7E, 0xE0, 0xC1 } };
inline constexpr IID IID_IDXGISurface2{ 0xABA496DD, 0xB617, 0x4CB8, { 0xA8, 0x66, 0xBC, 0x44, 0xD7, 0xEB, 0x1F, 0xA2 } };
inline constexpr IID IID_IDXGISwapChain1{ 0x790A45F7, 0x0D42, 0x4876, { 0x98, 0x3A, 0x0A, 0x55, 0xCF, 0xE6, 0xF4, 0xAA } };
}
@@ -0,0 +1,148 @@
#pragma once
#include "REX/W32/DXGI_2.h"
namespace REX::W32
{
struct IDXGIDecodeSwapChain;
struct IDXGIDevice3;
struct IDXGIFactory3;
struct IDXGIFactoryMedia;
struct IDXGIOutput2;
struct IDXGIOutput3;
struct IDXGISwapChain2;
struct IDXGISwapChainMedia;
}
namespace REX::W32
{
enum DXGI_FRAME_PRESENTATION_MODE
{
DXGI_FRAME_PRESENTATION_MODE_COMPOSED = 0,
DXGI_FRAME_PRESENTATION_MODE_OVERLAY = 1,
DXGI_FRAME_PRESENTATION_MODE_NONE = 2,
DXGI_FRAME_PRESENTATION_MODE_COMPOSITION_FAILURE = 3,
};
enum DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS
{
DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_NOMINAL_RANGE = 0x1,
DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_BT709 = 0x2,
DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_xvYCC = 0x4,
};
enum DXGI_OVERLAY_SUPPORT_FLAG
{
DXGI_OVERLAY_SUPPORT_FLAG_DIRECT = 0x1,
DXGI_OVERLAY_SUPPORT_FLAG_SCALING = 0x2,
};
}
namespace REX::W32
{
struct DXGI_DECODE_SWAP_CHAIN_DESC
{
std::uint32_t flags;
};
struct DXGI_FRAME_STATISTICS_MEDIA
{
std::uint32_t presentCount;
std::uint32_t presentRefreshCount;
std::uint32_t syncRefreshCount;
std::int64_t syncQPCTime;
std::int64_t syncGPUTime;
DXGI_FRAME_PRESENTATION_MODE compositionMode;
std::uint32_t approvedPresentDuration;
};
struct DXGI_MATRIX_3X2_F
{
float _11;
float _12;
float _21;
float _22;
float _31;
float _32;
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("2633066B-4514-4C7A-8FD8-12EA98059D18"))
IDXGIDecodeSwapChain : public IUnknown
{
virtual HRESULT PresentBuffer(std::uint32_t a_bufferToPresent, std::uint32_t a_syncInterval, std::uint32_t a_flags) = 0;
virtual HRESULT SetSourceRect(const RECT* a_rect) = 0;
virtual HRESULT SetTargetRect(const RECT* a_rect) = 0;
virtual HRESULT SetDestSize(std::uint32_t a_width, std::uint32_t a_height) = 0;
virtual HRESULT GetSourceRect(RECT* a_rect) = 0;
virtual HRESULT GetTargetRect(RECT* a_rect) = 0;
virtual HRESULT GetDestSize(std::uint32_t* a_width, std::uint32_t* a_height) = 0;
virtual HRESULT SetColorSpace(DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS a_colorSpace) = 0;
virtual DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS GetColorSpace(void) = 0;
};
struct __declspec(novtable, uuid("6007896C-3244-4AFD-BF18-A6D3BEDA5023"))
IDXGIDevice3 : public IDXGIDevice2
{
virtual void Trim(void) = 0;
};
struct __declspec(novtable, uuid("25483823-CD46-4C7D-86CA-47AA95B837BD"))
IDXGIFactory3 : public IDXGIFactory2
{
virtual std::uint32_t GetCreationFlags(void) = 0;
};
struct __declspec(novtable, uuid("41E7D1F2-A591-4F7B-A2E5-FA9C843E1C12"))
IDXGIFactoryMedia : public IUnknown
{
virtual HRESULT CreateSwapChainForCompositionSurfaceHandle(IUnknown* a_device, HANDLE a_surface, const DXGI_SWAP_CHAIN_DESC1* a_desc, IDXGIOutput* a_restrictToOutput, IDXGISwapChain1** a_swapChain) = 0;
virtual HRESULT CreateDecodeSwapChainForCompositionSurfaceHandle(IUnknown* a_device, HANDLE a_surface, DXGI_DECODE_SWAP_CHAIN_DESC* a_desc, IDXGIResource* a_yuvDecodeBuffers, IDXGIOutput* a_restrictToOutput, IDXGIDecodeSwapChain** a_swapChain) = 0;
};
struct __declspec(novtable, uuid("595E39D1-2724-4663-99B1-DA969DE28364"))
IDXGIOutput2 : public IDXGIOutput1
{
virtual BOOL SupportsOverlays(void) = 0;
};
struct __declspec(novtable, uuid("8A6BB301-7E7E-41F4-A8E0-5B32F7F99B18"))
IDXGIOutput3 : public IDXGIOutput2
{
virtual HRESULT CheckOverlaySupport(DXGI_FORMAT a_enumFormat, IUnknown* a_concernedDevice, std::uint32_t* a_flags) = 0;
};
struct __declspec(novtable, uuid("A8BE2AC4-199F-4946-B331-79599FB98DE7"))
IDXGISwapChain2 : public IDXGISwapChain1
{
virtual HRESULT SetSourceSize(std::uint32_t a_width, std::uint32_t a_height) = 0;
virtual HRESULT GetSourceSize(std::uint32_t* a_width, std::uint32_t* a_height) = 0;
virtual HRESULT SetMaximumFrameLatency(std::uint32_t a_maxLatency) = 0;
virtual HRESULT GetMaximumFrameLatency(std::uint32_t* a_maxLatency) = 0;
virtual HANDLE GetFrameLatencyWaitableObject(void) = 0;
virtual HRESULT SetMatrixTransform(const DXGI_MATRIX_3X2_F* a_matrix) = 0;
virtual HRESULT GetMatrixTransform(DXGI_MATRIX_3X2_F* a_matrix) = 0;
};
struct __declspec(novtable, uuid("DD95B90B-F05F-4F6A-BD65-25BFB264BD84"))
IDXGISwapChainMedia : public IUnknown
{
virtual HRESULT GetFrameStatisticsMedia(DXGI_FRAME_STATISTICS_MEDIA* a_stats) = 0;
virtual HRESULT SetPresentDuration(std::uint32_t a_duration) = 0;
virtual HRESULT CheckPresentDurationSupport(std::uint32_t a_desiredPresentDuration, std::uint32_t* a_closestSmallerPresentDuration, std::uint32_t* a_closestLargerPresentDuration) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_IDXGIDecodeSwapChain{ 0x2633066B, 0x4514, 0x4C7A, { 0x8F, 0xD8, 0x12, 0xEA, 0x98, 0x05, 0x9D, 0x18 } };
inline constexpr IID IID_IDXGIDevice3{ 0x6007896C, 0x3244, 0x4AFD, { 0xBF, 0x18, 0xA6, 0xD3, 0xBE, 0xDA, 0x50, 0x23 } };
inline constexpr IID IID_IDXGIFactory3{ 0x25483823, 0xCD46, 0x4C7D, { 0x86, 0xCA, 0x47, 0xAA, 0x95, 0xB8, 0x37, 0xBD } };
inline constexpr IID IID_IDXGIFactoryMedia{ 0x41E7D1F2, 0xA591, 0x4F7B, { 0xA2, 0xE5, 0xFA, 0x9C, 0x84, 0x3E, 0x1C, 0x12 } };
inline constexpr IID IID_IDXGIOutput2{ 0x595E39D1, 0x2724, 0x4663, { 0x99, 0xB1, 0xDA, 0x96, 0x9D, 0xE2, 0x83, 0x64 } };
inline constexpr IID IID_IDXGIOutput3{ 0x8A6BB301, 0x7E7E, 0x41F4, { 0xA8, 0xE0, 0x5B, 0x32, 0xF7, 0xF9, 0x9B, 0x18 } };
inline constexpr IID IID_IDXGISwapChain2{ 0xA8BE2AC4, 0x199F, 0x4946, { 0xB3, 0x31, 0x79, 0x59, 0x9F, 0xB9, 0x8D, 0xE7 } };
inline constexpr IID IID_IDXGISwapChainMedia{ 0xDD95B90B, 0xF05F, 0x4F6A, { 0xBD, 0x65, 0x25, 0xBF, 0xB2, 0x64, 0xBD, 0x84 } };
}
@@ -0,0 +1,86 @@
#pragma once
#include "REX/W32/DXGI_3.h"
namespace REX::W32
{
struct IDXGIAdapter3;
struct IDXGIFactory4;
struct IDXGIOutput4;
struct IDXGISwapChain3;
}
namespace REX::W32
{
enum DXGI_MEMORY_SEGMENT_GROUP
{
DXGI_MEMORY_SEGMENT_GROUP_LOCAL = 0,
DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL = 1,
};
enum DXGI_OVERLAY_COLOR_SPACE_SUPPORT_FLAG
{
DXGI_OVERLAY_COLOR_SPACE_SUPPORT_FLAG_PRESENT = 0x1,
};
enum DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG
{
DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT = 0x1,
DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_OVERLAY_PRESENT = 0x2,
};
}
namespace REX::W32
{
struct DXGI_QUERY_VIDEO_MEMORY_INFO
{
std::uint64_t budget;
std::uint64_t currentUsage;
std::uint64_t availableForReservation;
std::uint64_t currentReservation;
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("645967A4-1392-4310-A798-8053CE3E93FD"))
IDXGIAdapter3 : public IDXGIAdapter2
{
virtual HRESULT RegisterHardwareContentProtectionTeardownStatusEvent(HANDLE a_event, std::uint32_t* a_cookie) = 0;
virtual void UnregisterHardwareContentProtectionTeardownStatus(std::uint32_t a_cookie) = 0;
virtual HRESULT QueryVideoMemoryInfo(std::uint32_t a_nodeIndex, DXGI_MEMORY_SEGMENT_GROUP a_memorySegmentGroup, DXGI_QUERY_VIDEO_MEMORY_INFO* a_videoMemoryInfo) = 0;
virtual HRESULT SetVideoMemoryReservation(std::uint32_t a_nodeIndex, DXGI_MEMORY_SEGMENT_GROUP a_memorySegmentGroup, std::uint64_t a_reservation) = 0;
virtual HRESULT RegisterVideoMemoryBudgetChangeNotificationEvent(HANDLE a_event, std::uint32_t* a_cookie) = 0;
virtual void UnregisterVideoMemoryBudgetChangeNotification(std::uint32_t a_cookie) = 0;
};
struct __declspec(novtable, uuid("1BC6EA02-EF36-464F-BF0C-21CA39E5168A"))
IDXGIFactory4 : public IDXGIFactory3
{
virtual HRESULT EnumAdapterByLuid(LUID a_luid, const IID& a_iid, void** a_adapter) = 0;
virtual HRESULT EnumWarpAdapter(const IID& a_iid, void** a_adapter) = 0;
};
struct __declspec(novtable, uuid("DC7DCA35-2196-414D-9F53-617884032A60"))
IDXGIOutput4 : public IDXGIOutput3
{
virtual HRESULT CheckOverlayColorSpaceSupport(DXGI_FORMAT a_format, DXGI_COLOR_SPACE_TYPE a_colorSpace, IUnknown* a_concernedDevice, std::uint32_t* a_flags) = 0;
};
struct __declspec(novtable, uuid("94D99BDB-F1F8-4AB0-B236-7DA0170EDAB1"))
IDXGISwapChain3 : public IDXGISwapChain2
{
virtual std::uint32_t GetCurrentBackBufferIndex(void) = 0;
virtual HRESULT CheckColorSpaceSupport(DXGI_COLOR_SPACE_TYPE a_colorSpace, std::uint32_t* a_colorSpaceSupport) = 0;
virtual HRESULT SetColorSpace1(DXGI_COLOR_SPACE_TYPE a_colorSpace) = 0;
virtual HRESULT ResizeBuffers1(std::uint32_t a_bufferCount, std::uint32_t a_width, std::uint32_t a_height, DXGI_FORMAT a_format, std::uint32_t a_swapChainFlags, const std::uint32_t* a_creationNodeMask, IUnknown* const* a_presentQueue) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_IDXGIAdapter3{ 0x645967A4, 0x1392, 0x4310, { 0xA7, 0x98, 0x80, 0x53, 0xCE, 0x3E, 0x93, 0xFD } };
inline constexpr IID IID_IDXGIFactory4{ 0x1BC6EA02, 0xEF36, 0x464F, { 0xBF, 0x0C, 0x21, 0xCA, 0x39, 0xE5, 0x16, 0x8A } };
inline constexpr IID IID_IDXGIOutput4{ 0xDC7DCA35, 0x2196, 0x414D, { 0x9F, 0x53, 0x61, 0x78, 0x84, 0x03, 0x2A, 0x60 } };
inline constexpr IID IID_IDXGISwapChain3{ 0x94D99BDB, 0xF1F8, 0x4AB0, { 0xB2, 0x36, 0x7D, 0xA0, 0x17, 0x0E, 0xDA, 0xB1 } };
}
@@ -0,0 +1,94 @@
#pragma once
#include "REX/W32/DXGI_4.h"
namespace REX::W32
{
struct IDXGIDevice4;
struct IDXGIFactory5;
struct IDXGIOutput5;
struct IDXGISwapChain4;
}
namespace REX::W32
{
enum DXGI_FEATURE
{
DXGI_FEATURE_PRESENT_ALLOW_TEARING = 0,
};
enum DXGI_HDR_METADATA_TYPE
{
DXGI_HDR_METADATA_TYPE_NONE = 0,
DXGI_HDR_METADATA_TYPE_HDR10 = 1,
DXGI_HDR_METADATA_TYPE_HDR10PLUS = 2,
};
enum DXGI_OFFER_RESOURCE_FLAGS
{
DXGI_OFFER_RESOURCE_FLAG_ALLOW_DECOMMIT = 0x1,
};
enum DXGI_RECLAIM_RESOURCE_RESULTS
{
DXGI_RECLAIM_RESOURCE_RESULT_OK = 0,
DXGI_RECLAIM_RESOURCE_RESULT_DISCARDED = 1,
DXGI_RECLAIM_RESOURCE_RESULT_NOT_COMMITTED = 2,
};
}
namespace REX::W32
{
struct DXGI_HDR_METADATA_HDR10
{
std::uint16_t redPrimary[2];
std::uint16_t GreenPrimary[2];
std::uint16_t bluePrimary[2];
std::uint16_t whitePoint[2];
std::uint32_t maxMasteringLuminance;
std::uint32_t minMasteringLuminance;
std::uint16_t maxContentLightLevel;
std::uint16_t maxFrameAverageLightLevel;
};
struct DXGI_HDR_METADATA_HDR10PLUS
{
std::uint8_t data[72];
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("95B4F95F-D8DA-4CA4-9EE6-3B76D5968A10"))
IDXGIDevice4 : public IDXGIDevice3
{
virtual HRESULT OfferResources1(std::uint32_t a_numResources, IDXGIResource* const* a_resources, DXGI_OFFER_RESOURCE_PRIORITY a_priority, std::uint32_t a_flags) = 0;
virtual HRESULT ReclaimResources1(std::uint32_t a_numResources, IDXGIResource* const* a_resources, DXGI_RECLAIM_RESOURCE_RESULTS* a_results) = 0;
};
struct __declspec(novtable, uuid("7632E1F5-EE65-4DCA-87FD-84CD75F8838D"))
IDXGIFactory5 : public IDXGIFactory4
{
virtual HRESULT CheckFeatureSupport(DXGI_FEATURE a_feature, void* a_featureSupportData, std::uint32_t a_featureSupportDataSize) = 0;
};
struct __declspec(novtable, uuid("80A07424-AB52-42EB-833C-0C42FD282D98"))
IDXGIOutput5 : public IDXGIOutput4
{
virtual HRESULT DuplicateOutput1(IUnknown* a_device, std::uint32_t a_flags, std::uint32_t a_supportedFormatsCount, const DXGI_FORMAT* a_supportedFormats, IDXGIOutputDuplication** a_outputDuplication) = 0;
};
struct __declspec(novtable, uuid("3D585D5A-BD4A-489E-B1F4-3DBCB6452FFB"))
IDXGISwapChain4 : public IDXGISwapChain3
{
virtual HRESULT SetHDRMetaData(DXGI_HDR_METADATA_TYPE a_type, std::uint32_t a_size, void* a_metaData) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_IDXGIDevice4{ 0x95B4F95F, 0xD8DA, 0x4CA4, { 0x9E, 0xE6, 0x3B, 0x76, 0xD5, 0x96, 0x8A, 0x10 } };
inline constexpr IID IID_IDXGIFactory5{ 0x7632E1F5, 0xEE65, 0x4DCA, { 0x87, 0xFD, 0x84, 0xCD, 0x75, 0xF8, 0x83, 0x8D } };
inline constexpr IID IID_IDXGIOutput5{ 0x80A07424, 0xAB52, 0x42EB, { 0x83, 0x3C, 0x0C, 0x42, 0xFD, 0x28, 0x2D, 0x98 } };
inline constexpr IID IID_IDXGISwapChain4{ 0x3D585D5A, 0xBD4A, 0x489E, { 0xB1, 0xF4, 0x3D, 0xBC, 0xB6, 0x45, 0x2F, 0xFB } };
}
@@ -0,0 +1,114 @@
#pragma once
#include "REX/W32/DXGI_5.h"
namespace REX::W32
{
struct IDXGIAdapter4;
struct IDXGIFactory6;
struct IDXGIFactory7;
struct IDXGIOutput6;
}
namespace REX::W32
{
enum DXGI_ADAPTER_FLAG3
{
DXGI_ADAPTER_FLAG3_NONE = 0,
DXGI_ADAPTER_FLAG3_REMOTE = 1,
DXGI_ADAPTER_FLAG3_SOFTWARE = 2,
DXGI_ADAPTER_FLAG3_ACG_COMPATIBLE = 4,
DXGI_ADAPTER_FLAG3_SUPPORT_MONITORED_FENCES = 8,
DXGI_ADAPTER_FLAG3_SUPPORT_NON_MONITORED_FENCES = 0x10,
DXGI_ADAPTER_FLAG3_KEYED_MUTEX_CONFORMANCE = 0x20,
DXGI_ADAPTER_FLAG3_FORCE_DWORD = 0xFFFFFFFF,
};
enum DXGI_GPU_PREFERENCE
{
DXGI_GPU_PREFERENCE_UNSPECIFIED = 0,
DXGI_GPU_PREFERENCE_MINIMUM_POWER = (DXGI_GPU_PREFERENCE_UNSPECIFIED + 1),
DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE = (DXGI_GPU_PREFERENCE_MINIMUM_POWER + 1),
};
enum DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAGS
{
DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_FULLSCREEN = 1,
DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_WINDOWED = 2,
DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_CURSOR_STRETCHED = 4,
};
}
namespace REX::W32
{
struct DXGI_ADAPTER_DESC3
{
wchar_t description[128];
std::uint32_t vendorID;
std::uint32_t deviceID;
std::uint32_t subSysID;
std::uint32_t revision;
std::size_t dedicatedVideoMemory;
std::size_t dedicatedSystemMemory;
std::size_t sharedSystemMemory;
LUID adapterLUID;
DXGI_ADAPTER_FLAG3 flags;
DXGI_GRAPHICS_PREEMPTION_GRANULARITY graphicsPreemptionGranularity;
DXGI_COMPUTE_PREEMPTION_GRANULARITY computePreemptionGranularity;
};
struct DXGI_OUTPUT_DESC1
{
wchar_t deviceName[32];
RECT desktopCoordinates;
BOOL attachedToDesktop;
DXGI_MODE_ROTATION rotation;
HMONITOR monitor;
std::uint32_t bitsPerColor;
DXGI_COLOR_SPACE_TYPE colorSpace;
float redPrimary[2];
float greenPrimary[2];
float bluePrimary[2];
float whitePoint[2];
float minLuminance;
float maxLuminance;
float maxFullFrameLuminance;
};
}
namespace REX::W32
{
struct __declspec(novtable, uuid("3C8D99D1-4FBF-4181-A82C-AF66BF7BD24E"))
IDXGIAdapter4 : public IDXGIAdapter3
{
virtual HRESULT GetDesc3(DXGI_ADAPTER_DESC3* a_desc) = 0;
};
struct __declspec(novtable, uuid("C1B6694F-FF09-44A9-B03C-77900A0A1D17"))
IDXGIFactory6 : public IDXGIFactory5
{
virtual HRESULT EnumAdapterByGpuPreference(std::uint32_t a_adapterFlags, DXGI_GPU_PREFERENCE a_gpuPreference, const IID& a_iid, void** a_adapter) = 0;
};
struct __declspec(novtable, uuid("A4966EED-76DB-44DA-84C1-EE9A7AFB20A8"))
IDXGIFactory7 : public IDXGIFactory6
{
virtual HRESULT RegisterAdaptersChangedEvent(HANDLE a_event, std::uint32_t* a_cookie) = 0;
virtual HRESULT UnregisterAdaptersChangedEvent(std::uint32_t a_cookie) = 0;
};
struct __declspec(novtable, uuid("068346E8-AAEC-4B84-ADD7-137F513F77A1"))
IDXGIOutput6 : public IDXGIOutput5
{
virtual HRESULT GetDesc1(DXGI_OUTPUT_DESC1* a_desc) = 0;
virtual HRESULT CheckHardwareCompositionSupport(std::uint32_t* a_flags) = 0;
};
}
namespace REX::W32
{
inline constexpr IID IID_IDXGIAdapter4{ 0x3C8D99D1, 0x4FBF, 0x4181, { 0xA8, 0x2C, 0xAF, 0x66, 0xBF, 0x7B, 0xD2, 0x4E } };
inline constexpr IID IID_IDXGIFactory6{ 0xC1B6694F, 0xFF09, 0x44A9, { 0xB0, 0x3C, 0x77, 0x90, 0x0A, 0x0A, 0x1D, 0x17 } };
inline constexpr IID IID_IDXGIFactory7{ 0xA4966EED, 0x76DB, 0x44DA, { 0x84, 0xC1, 0xEE, 0x9A, 0x7A, 0xFB, 0x20, 0xA8 } };
inline constexpr IID IID_IDXGIOutput6{ 0x068346E8, 0xAAEC, 0x4B84, { 0xAD, 0xD7, 0x13, 0x7F, 0x51, 0x3F, 0x77, 0xA1 } };
}
@@ -0,0 +1,560 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
// standard access
inline constexpr auto STANDARD_RIGHTS_REQUIRED{ 0x000F0000 };
inline constexpr auto STANDARD_RIGHTS_ALL{ 0x001F0000 };
// code page identifiers
inline constexpr auto CP_UTF8{ 65001u };
// memory allocation types
inline constexpr auto MEM_COMMIT{ 0x00001000u };
inline constexpr auto MEM_RESERVE{ 0x00002000u };
inline constexpr auto MEM_DECOMMIT{ 0x00004000u };
inline constexpr auto MEM_RELEASE{ 0x00008000u };
inline constexpr auto MEM_FREE{ 0x00010000u };
inline constexpr auto MEM_RESET{ 0x00080000u };
inline constexpr auto MEM_RESET_UNDO{ 0x01000000u };
// memory page protection attributes
inline constexpr auto PAGE_NOACCESS{ 0x00000001u };
inline constexpr auto PAGE_READONLY{ 0x00000002u };
inline constexpr auto PAGE_READWRITE{ 0x00000004u };
inline constexpr auto PAGE_WRITECOPY{ 0x00000008u };
inline constexpr auto PAGE_EXECUTE{ 0x00000010u };
inline constexpr auto PAGE_EXECUTE_READ{ 0x00000020u };
inline constexpr auto PAGE_EXECUTE_READWRITE{ 0x00000040u };
// memory section
inline constexpr auto SECTION_QUERY{ 0x00000001 };
inline constexpr auto SECTION_MAP_WRITE{ 0x00000002 };
inline constexpr auto SECTION_MAP_READ{ 0x00000004 };
inline constexpr auto SECTION_MAP_EXECUTE{ 0x00000008 };
inline constexpr auto SECTION_EXTEND_SIZE{ 0x00000010 };
inline constexpr auto SECTION_MAP_EXECUTE_EXPLICIT{ 0x00000020 };
inline constexpr auto SECTION_ALL_ACCESS{
STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE
};
// file attributes
inline constexpr auto FILE_ATTRIBUTE_READONLY{ 0x00000001u };
inline constexpr auto FILE_ATTRIBUTE_HIDDEN{ 0x00000002u };
inline constexpr auto FILE_ATTRIBUTE_SYSTEM{ 0x00000004u };
inline constexpr auto FILE_ATTRIBUTE_DIRECTORY{ 0x00000010u };
inline constexpr auto FILE_ATTRIBUTE_ARCHIVE{ 0x00000020u };
inline constexpr auto FILE_ATTRIBUTE_DEVICE{ 0x00000040 };
inline constexpr auto FILE_ATTRIBUTE_NORMAL{ 0x00000080 };
inline constexpr auto FILE_ATTRIBUTE_TEMPORARY{ 0x00000100 };
inline constexpr auto FILE_ATTRIBUTE_SPARSE_FILE{ 0x00000200 };
inline constexpr auto FILE_ATTRIBUTE_REPARSE_POINT{ 0x00000400 };
inline constexpr auto FILE_ATTRIBUTE_COMPRESSED{ 0x00000800 };
inline constexpr auto FILE_ATTRIBUTE_OFFLINE{ 0x00001000 };
inline constexpr auto FILE_ATTRIBUTE_NOT_CONTENT_INDEXED{ 0x00002000 };
inline constexpr auto FILE_ATTRIBUTE_ENCRYPTED{ 0x00004000 };
inline constexpr auto FILE_ATTRIBUTE_INTEGRITY_STREAM{ 0x00008000 };
inline constexpr auto FILE_ATTRIBUTE_VIRTUAL{ 0x00010000 };
inline constexpr auto FILE_ATTRIBUTE_NO_SCRUB_DATA{ 0x00020000 };
inline constexpr auto FILE_ATTRIBUTE_EA{ 0x00040000 };
inline constexpr auto FILE_ATTRIBUTE_PINNED{ 0x00080000 };
inline constexpr auto FILE_ATTRIBUTE_UNPINNED{ 0x00100000 };
inline constexpr auto FILE_ATTRIBUTE_RECALL_ON_OPEN{ 0x00040000 };
inline constexpr auto FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS{ 0x00400000 };
// file creation diposition
inline constexpr auto CREATE_NEW{ 1 };
inline constexpr auto CREATE_ALWAYS{ 2 };
inline constexpr auto OPEN_EXISTING{ 3 };
inline constexpr auto OPEN_ALWAYS{ 4 };
inline constexpr auto TRUNCATE_EXISTING{ 5 };
// file share mode
inline constexpr auto FILE_SHARE_READ{ 0x00000001 };
inline constexpr auto FILE_SHARE_WRITE{ 0x00000002 };
inline constexpr auto FILE_SHARE_DELETE{ 0x00000004 };
// file mapping flags
inline constexpr auto FILE_MAP_ALL_ACCESS{ SECTION_ALL_ACCESS };
inline constexpr auto FILE_MAP_COPY{ 0x00000001u };
inline constexpr auto FILE_MAP_WRITE{ 0x00000002u };
inline constexpr auto FILE_MAP_READ{ 0x00000004u };
inline constexpr auto FILE_MAP_EXECUTE{ 0x00000020u };
inline constexpr auto FILE_MAP_LARGE_PAGES{ 0x20000000u };
inline constexpr auto FILE_MAP_TARGETS_INVALID{ 0x40000000u };
inline constexpr auto FILE_MAP_RESERVE{ 0x80000000u };
// file open mode flags
inline constexpr auto GENERIC_READ{ 0x80000000L };
inline constexpr auto GENERIC_WRITE{ 0x40000000L };
inline constexpr auto GENERIC_EXECUTE{ 0x20000000L };
inline constexpr auto GENERIC_ALL{ 0x10000000L };
// pe image header
inline constexpr auto IMAGE_DOS_SIGNATURE{ 0x5A4Du };
inline constexpr auto IMAGE_NT_SIGNATURE{ 0x00004550u };
inline constexpr auto IMAGE_NT_OPTIONAL_HDR32_MAGIC{ 0x10Bu };
inline constexpr auto IMAGE_NT_OPTIONAL_HDR64_MAGIC{ 0x20Bu };
// pe image directory entries
inline constexpr auto IMAGE_DIRECTORY_ENTRY_EXPORT{ 0u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_IMPORT{ 1u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_RESOURCE{ 2u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_EXCEPTION{ 3u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_SECURITY{ 4u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_BASERELOC{ 5u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_DEBUG{ 6u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_ARCHITECTURE{ 7u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_GLOBALPTR{ 8u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_TLS{ 9u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG{ 10u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT{ 11u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_IAT{ 12u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT{ 13u };
inline constexpr auto IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR{ 14u };
inline constexpr auto IMAGE_NUMBEROF_DIRECTORY_ENTRIES{ 16u };
// pe image ordinal
inline constexpr auto IMAGE_ORDINAL_FLAG32{ 0x80000000u };
inline constexpr auto IMAGE_ORDINAL_FLAG64{ 0x8000000000000000ull };
// pe image section header characteristics
inline constexpr auto IMAGE_SCN_MEM_SHARED{ 0x10000000u };
inline constexpr auto IMAGE_SCN_MEM_EXECUTE{ 0x20000000u };
inline constexpr auto IMAGE_SCN_MEM_READ{ 0x40000000u };
inline constexpr auto IMAGE_SCN_MEM_WRITE{ 0x80000000u };
inline constexpr auto IMAGE_SIZEOF_SECTION_HEADER{ 40u };
inline constexpr auto IMAGE_SIZEOF_SHORT_NAME{ 8u };
// process creation flags
inline constexpr auto DEBUG_PROCESS{ 0x00000001u };
inline constexpr auto DEBUG_ONLY_THIS_PROCESS{ 0x00000002u };
inline constexpr auto CREATE_SUSPENDED{ 0x00000004u };
inline constexpr auto DETACHED_PROCESS{ 0x00000008u };
inline constexpr auto CREATE_NEW_CONSOLE{ 0x00000010u };
inline constexpr auto NORMAL_PRIORITY_CLASS{ 0x00000020u };
inline constexpr auto IDLE_PRIORITY_CLASS{ 0x00000040u };
inline constexpr auto HIGH_PRIORITY_CLASS{ 0x00000080u };
inline constexpr auto REALTIME_PRIORITY_CLASS{ 0x00000100u };
inline constexpr auto CREATE_NEW_PROCESS_GROUP{ 0x00000200u };
inline constexpr auto CREATE_UNICODE_ENVIRONMENT{ 0x00000400u };
inline constexpr auto CREATE_FORCEDOS{ 0x00002000u };
inline constexpr auto BELOW_NORMAL_PRIORITY_CLASS{ 0x00004000u };
inline constexpr auto ABOVE_NORMAL_PRIORITY_CLASS{ 0x00008000u };
inline constexpr auto INHERIT_PARENT_AFFINITY{ 0x00010000u };
inline constexpr auto CREATE_PROTECTED_PROCESS{ 0x00040000u };
inline constexpr auto EXTENDED_STARTUPINFO_PRESENT{ 0x00080000u };
inline constexpr auto PROCESS_MODE_BACKGROUND_BEGIN{ 0x00100000u };
inline constexpr auto PROCESS_MODE_BACKGROUND_END{ 0x00200000u };
inline constexpr auto CREATE_SECURE_PROCESS{ 0x00400000 };
inline constexpr auto CREATE_BREAKAWAY_FROM_JOB{ 0x01000000u };
inline constexpr auto CREATE_PRESERVE_CODE_AUTHZ_LEVEL{ 0x02000000u };
inline constexpr auto CREATE_DEFAULT_ERROR_MODE{ 0x04000000u };
inline constexpr auto CREATE_NO_WINDOW{ 0x08000000u };
// locale map flags
inline constexpr auto LCMAP_LOWERCASE{ 0x00000100u };
inline constexpr auto LCMAP_UPPERCASE{ 0x00000200u };
inline constexpr auto LCMAP_TITLECASE{ 0x00000300u };
inline constexpr auto LCMAP_SORTKEY{ 0x00000400u };
inline constexpr auto LCMAP_BYTEREV{ 0x00000800u };
inline constexpr auto LCMAP_HIRAGANA{ 0x00100000u };
inline constexpr auto LCMAP_KATAKANA{ 0x00200000u };
inline constexpr auto LCMAP_HALFWIDTH{ 0x00400000u };
inline constexpr auto LCMAP_FULLWIDTH{ 0x00800000u };
inline constexpr auto LCMAP_LINGUISTIC_CASING{ 0x01000000u };
inline constexpr auto LCMAP_SIMPLIFIED_CHINESE{ 0x02000000u };
inline constexpr auto LCMAP_TRADITIONAL_CHINESE{ 0x04000000u };
// locale names
inline constexpr auto LOCALE_NAME_USER_DEFAULT{ nullptr };
inline constexpr auto LOCALE_NAME_INVARIANT{ L"" };
inline constexpr auto LOCALE_NAME_SYSTEM_DEFAULT{ L"!x-sys-default-locale" };
}
namespace REX::W32
{
struct IMAGE_DATA_DIRECTORY
{
std::uint32_t virtualAddress;
std::uint32_t size;
};
static_assert(sizeof(IMAGE_DATA_DIRECTORY) == 0x8);
struct IMAGE_DOS_HEADER
{
std::uint16_t magic;
std::uint16_t cblp;
std::uint16_t cp;
std::uint16_t crlc;
std::uint16_t cparhdr;
std::uint16_t minalloc;
std::uint16_t maxalloc;
std::uint16_t ss;
std::uint16_t sp;
std::uint16_t csum;
std::uint16_t ip;
std::uint16_t cs;
std::uint16_t lfarlc;
std::uint16_t ovno;
std::uint16_t res[4];
std::uint16_t oemid;
std::uint16_t oeminfo;
std::uint16_t res2[10];
std::int32_t lfanew;
};
static_assert(sizeof(IMAGE_DOS_HEADER) == 0x40);
struct IMAGE_FILE_HEADER
{
std::uint16_t machine;
std::uint16_t sectionCount;
std::uint32_t timeDateStamp;
std::uint32_t symbolTablePtr;
std::uint32_t symbolCount;
std::uint16_t optionalHeaderSize;
std::uint16_t characteristics;
};
static_assert(sizeof(IMAGE_FILE_HEADER) == 0x14);
struct IMAGE_IMPORT_BY_NAME
{
std::uint16_t hint;
char name[1];
};
static_assert(sizeof(IMAGE_IMPORT_BY_NAME) == 0x4);
struct IMAGE_IMPORT_DESCRIPTOR
{
union
{
std::uint32_t characteristics;
std::uint32_t firstThunkOriginal;
};
std::uint32_t timeDateStamp;
std::uint32_t forwarderChain;
std::uint32_t name;
std::uint32_t firstThunk;
};
static_assert(sizeof(IMAGE_IMPORT_DESCRIPTOR) == 0x14);
struct IMAGE_OPTIONAL_HEADER64
{
std::uint16_t magic;
std::uint8_t linkerVersionMajor;
std::uint8_t linkerVersionMinor;
std::uint32_t codeSize;
std::uint32_t initializedDataSize;
std::uint32_t uninitializedDataSize;
std::uint32_t entryPointAddress;
std::uint32_t codeBase;
std::uint64_t imageBase;
std::uint32_t sectionAlignment;
std::uint32_t fileAlignment;
std::uint16_t osVersionMajor;
std::uint16_t osVersionMinor;
std::uint16_t imageVersionMajor;
std::uint16_t imageVersionMinor;
std::uint16_t subsystemVersionMajor;
std::uint16_t subsystemVersionMinor;
std::uint32_t win32Version;
std::uint32_t imageSize;
std::uint32_t headersSize;
std::uint32_t checksum;
std::uint16_t subsystem;
std::uint16_t dllCharacteristics;
std::uint64_t stackReserveSize;
std::uint64_t stackCommitSize;
std::uint64_t heapReserveSize;
std::uint64_t heapCommitSize;
std::uint32_t loaderFlags;
std::uint32_t rvaAndSizesCount;
IMAGE_DATA_DIRECTORY dataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
};
static_assert(sizeof(IMAGE_OPTIONAL_HEADER64) == 0xF0);
struct IMAGE_NT_HEADERS64
{
std::uint32_t signature;
IMAGE_FILE_HEADER fileHeader;
IMAGE_OPTIONAL_HEADER64 optionalHeader;
};
static_assert(sizeof(IMAGE_NT_HEADERS64) == 0x108);
struct IMAGE_SECTION_HEADER
{
std::uint8_t name[IMAGE_SIZEOF_SHORT_NAME];
union
{
std::uint32_t physicalAddress;
std::uint32_t virtualSize;
};
std::uint32_t virtualAddress;
std::uint32_t rawDataSize;
std::uint32_t rawDataPtr;
std::uint32_t relocationsPtr;
std::uint32_t lineNumbersPtr;
std::uint16_t relocationsCount;
std::uint16_t lineNumbersCount;
std::uint32_t characteristics;
};
static_assert(sizeof(IMAGE_SECTION_HEADER) == 0x28);
struct IMAGE_THUNK_DATA64
{
union
{
std::uint64_t forwarderString;
std::uint64_t function;
std::uint64_t ordinal;
std::uint64_t address;
};
};
static_assert(sizeof(IMAGE_THUNK_DATA64) == 0x8);
struct MEMORY_BASIC_INFORMATION
{
void* baseAddress;
void* allocationBase;
std::uint32_t allocationProtect;
std::uint16_t partitionID;
std::size_t regionSize;
std::uint32_t state;
std::uint32_t protect;
std::uint32_t type;
};
static_assert(sizeof(MEMORY_BASIC_INFORMATION) == 0x30);
struct NLSVERSIONINFO
{
std::uint32_t nlsVersionInfoSize;
std::uint32_t nlsVersion;
std::uint32_t definedVersion;
std::uint32_t effectiveID;
GUID guidCustomVersion;
};
static_assert(sizeof(NLSVERSIONINFO) == 0x20);
struct PROCESS_INFORMATION
{
void* process;
void* thread;
std::uint32_t processID;
std::uint32_t threadID;
};
static_assert(sizeof(PROCESS_INFORMATION) == 0x18);
struct SRWLOCK
{
void* ptr;
};
static_assert(sizeof(SRWLOCK) == 0x08);
struct STARTUPINFOA
{
std::uint32_t size;
char* reserved0;
char* desktop;
char* title;
std::uint32_t x;
std::uint32_t y;
std::uint32_t xSize;
std::uint32_t ySize;
std::uint32_t xCountChars;
std::uint32_t yCountChars;
std::uint32_t fillAttribute;
std::uint32_t flags;
std::uint16_t showWindow;
std::uint16_t reserved1;
std::uint8_t* reserved2;
void* stdIn;
void* stdOut;
void* stdErr;
};
static_assert(sizeof(STARTUPINFOA) == 0x68);
struct STARTUPINFOW
{
std::uint32_t size;
wchar_t* reserved0;
wchar_t* desktop;
wchar_t* title;
std::uint32_t x;
std::uint32_t y;
std::uint32_t xSize;
std::uint32_t ySize;
std::uint32_t xCountChars;
std::uint32_t yCountChars;
std::uint32_t fillAttribute;
std::uint32_t flags;
std::uint16_t showWindow;
std::uint16_t reserved1;
std::uint8_t* reserved2;
void* stdIn;
void* stdOut;
void* stdErr;
};
static_assert(sizeof(STARTUPINFOW) == 0x68);
struct SYSTEM_INFO
{
union
{
std::uint32_t oemID;
struct
{
std::uint16_t processorArch;
std::uint16_t reserved;
};
};
std::uint32_t pageSize;
void* appAddressMin;
void* appAddressMax;
std::uintptr_t processorActiveMask;
std::uint32_t processorCount;
std::uint32_t processorType;
std::uint32_t allocationGranularity;
std::uint16_t processorLevel;
std::uint16_t processorRevision;
};
static_assert(sizeof(SYSTEM_INFO) == 0x30);
struct WIN32_FIND_DATAA
{
std::uint32_t fileAttributes;
FILETIME creationTime;
FILETIME lastAccessTime;
FILETIME lastWriteTime;
std::uint32_t fileSizeHi;
std::uint32_t fileSizeLo;
std::uint32_t reserved0;
std::uint32_t reserved1;
char fileName[MAX_PATH];
char fileNameAlt[14];
};
static_assert(sizeof(WIN32_FIND_DATAA) == 0x140);
struct WIN32_FIND_DATAW
{
std::uint32_t fileAttributes;
FILETIME creationTime;
FILETIME lastAccessTime;
FILETIME lastWriteTime;
std::uint32_t fileSizeHi;
std::uint32_t fileSizeLo;
std::uint32_t reserved0;
std::uint32_t reserved1;
wchar_t fileName[MAX_PATH];
wchar_t fileNameAlt[14];
};
static_assert(sizeof(WIN32_FIND_DATAW) == 0x250);
}
namespace REX::W32
{
using THREAD_START_ROUTINE = std::uint32_t(void* a_param);
}
namespace REX::W32
{
void AcquireSRWLockShared(SRWLOCK* a_lock) noexcept;
void AcquireSRWLockExclusive(SRWLOCK* a_lock) noexcept;
bool CloseHandle(HANDLE a_handle) noexcept;
HANDLE CreateFileA(const char* a_fileName, std::uint32_t a_desiredAccess, std::uint32_t a_shareMode, SECURITY_ATTRIBUTES* a_attributes, std::uint32_t a_creationDisposition, std::uint32_t a_flags, HANDLE a_templateFile);
HANDLE CreateFileW(const wchar_t* a_fileName, std::uint32_t a_desiredAccess, std::uint32_t a_shareMode, SECURITY_ATTRIBUTES* a_attributes, std::uint32_t a_creationDisposition, std::uint32_t a_flags, HANDLE a_templateFile);
HANDLE CreateFileMappingA(HANDLE a_file, SECURITY_ATTRIBUTES* a_attributes, std::uint32_t a_protect, std::uint32_t a_maxSizeHigh, std::uint32_t a_maxSizeLow, const char* a_name) noexcept;
HANDLE CreateFileMappingW(HANDLE a_file, SECURITY_ATTRIBUTES* a_attributes, std::uint32_t a_protect, std::uint32_t a_maxSizeHigh, std::uint32_t a_maxSizeLow, const wchar_t* a_name) noexcept;
bool CreateProcessA(const char* a_name, char* a_cmd, SECURITY_ATTRIBUTES* a_procAttr, SECURITY_ATTRIBUTES* a_threadAttr, bool a_inheritHandles, std::uint32_t a_flags, void* a_env, const char* a_curDir, STARTUPINFOA* a_startInfo, PROCESS_INFORMATION* a_procInfo) noexcept;
bool CreateProcessW(const wchar_t* a_name, wchar_t* a_cmd, SECURITY_ATTRIBUTES* a_procAttr, SECURITY_ATTRIBUTES* a_threadAttr, bool a_inheritHandles, std::uint32_t a_flags, void* a_env, const wchar_t* a_curDir, STARTUPINFOW* a_startInfo, PROCESS_INFORMATION* a_procInfo) noexcept;
HANDLE CreateRemoteThread(HANDLE a_process, SECURITY_ATTRIBUTES* a_threadAttr, std::size_t a_stackSize, THREAD_START_ROUTINE* a_startAddr, void* a_param, std::uint32_t a_flags, std::uint32_t* a_threadID) noexcept;
HANDLE CreateSemaphoreA(SECURITY_ATTRIBUTES* a_semaphoreAttr, std::int32_t a_initCount, std::int32_t a_maxCount, const char* a_name);
HANDLE CreateThread(SECURITY_ATTRIBUTES* a_threadAttr, std::size_t a_stackSize, THREAD_START_ROUTINE* a_startAddr, void* a_param, std::uint32_t a_flags, std::uint32_t* a_threadID) noexcept;
void DeleteCriticalSection(CRITICAL_SECTION* a_criticalSection);
void EnterCriticalSection(CRITICAL_SECTION* a_criticalSection);
std::uint32_t ExpandEnvironmentStringsA(const char* a_src, char* a_dst, std::uint32_t a_dstLen) noexcept;
std::uint32_t ExpandEnvironmentStringsW(const wchar_t* a_src, wchar_t* a_dst, std::uint32_t a_dstLen) noexcept;
bool FindClose(HANDLE a_file) noexcept;
HANDLE FindFirstFileA(const char* a_name, WIN32_FIND_DATAA* a_data) noexcept;
HANDLE FindFirstFileW(const wchar_t* a_name, WIN32_FIND_DATAW* a_data) noexcept;
bool FindNextFileA(HANDLE a_file, WIN32_FIND_DATAA* a_data) noexcept;
bool FindNextFileW(HANDLE a_file, WIN32_FIND_DATAW* a_data) noexcept;
bool FlushInstructionCache(HANDLE a_process, const void* a_baseAddr, std::size_t a_size) noexcept;
bool FreeLibrary(HMODULE a_module) noexcept;
bool GetComputerNameA(char* a_buffer, std::uint32_t* a_size) noexcept;
bool GetComputerNameW(wchar_t* a_buffer, std::uint32_t* a_size) noexcept;
std::uint32_t GetCurrentDirectoryA(std::uint32_t a_size, char* a_buffer) noexcept;
std::uint32_t GetCurrentDirectoryW(std::uint32_t a_size, wchar_t* a_buffer) noexcept;
HMODULE GetCurrentModule() noexcept;
HANDLE GetCurrentProcess() noexcept;
std::uint32_t GetCurrentThreadId() noexcept;
std::uint32_t GetEnvironmentVariableA(const char* a_name, char* a_buf, std::uint32_t a_bufLen) noexcept;
std::uint32_t GetEnvironmentVariableW(const wchar_t* a_name, wchar_t* a_buf, std::uint32_t a_bufLen) noexcept;
bool GetFileSizeEx(HANDLE a_file, LARGE_INTEGER* a_fileSize) noexcept;
std::uint32_t GetLastError() noexcept;
std::uint32_t GetModuleFileNameA(HMODULE a_module, char* a_name, std::uint32_t a_nameLen) noexcept;
std::uint32_t GetModuleFileNameW(HMODULE a_module, wchar_t* a_name, std::uint32_t a_nameLen) noexcept;
HMODULE GetModuleHandleA(const char* a_name) noexcept;
HMODULE GetModuleHandleW(const wchar_t* a_name) noexcept;
std::uint32_t GetPrivateProfileIntA(const char* a_app, const char* a_key, std::int32_t a_default, const char* a_name) noexcept;
std::uint32_t GetPrivateProfileIntW(const wchar_t* a_app, const wchar_t* a_key, std::int32_t a_default, const wchar_t* a_name) noexcept;
std::uint32_t GetPrivateProfileStringA(const char* a_app, const char* a_key, const char* a_default, char* a_buf, std::uint32_t a_bufLen, const char* a_name) noexcept;
std::uint32_t GetPrivateProfileStringW(const wchar_t* a_app, const wchar_t* a_key, const wchar_t* a_default, wchar_t* a_buf, std::uint32_t a_bufLen, const wchar_t* a_name) noexcept;
void* GetProcAddress(HMODULE a_module, const char* a_name) noexcept;
void GetSystemInfo(SYSTEM_INFO* a_info) noexcept;
bool IMAGE_SNAP_BY_ORDINAL64(std::uint64_t a_ordinal) noexcept;
IMAGE_SECTION_HEADER* IMAGE_FIRST_SECTION(const IMAGE_NT_HEADERS64* a_header) noexcept;
void InitializeCriticalSection(CRITICAL_SECTION* a_criticalSection) noexcept;
bool InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION* a_criticalSection, std::uint32_t a_spinCount) noexcept;
void InitializeSRWLock(SRWLOCK* a_lock) noexcept;
std::uint32_t InterlockedCompareExchange(volatile std::uint32_t* a_target, std::uint32_t a_value, std::uint32_t a_compare) noexcept;
std::uint64_t InterlockedCompareExchange64(volatile std::uint64_t* a_target, std::uint64_t a_value, std::uint64_t a_compare) noexcept;
std::uint32_t InterlockedDecrement(volatile std::uint32_t* a_target) noexcept;
std::uint64_t InterlockedDecrement64(volatile std::uint64_t* a_target) noexcept;
std::uint32_t InterlockedExchange(volatile std::uint32_t* a_target, std::uint32_t a_value) noexcept;
std::uint64_t InterlockedExchange64(volatile std::uint64_t* a_target, std::uint64_t a_value) noexcept;
std::uint32_t InterlockedIncrement(volatile std::uint32_t* a_target) noexcept;
std::uint64_t InterlockedIncrement64(volatile std::uint64_t* a_target) noexcept;
bool IsDebuggerPresent() noexcept;
std::int32_t LCMapStringEx(const wchar_t* a_locale, std::uint32_t a_flags, const wchar_t* a_src, std::int32_t a_srcLen, wchar_t* a_dst, std::int32_t a_dstLen, NLSVERSIONINFO* a_info, void* a_reserved, std::intptr_t a_sortHandle) noexcept;
void LeaveCriticalSection(CRITICAL_SECTION* a_criticalSection);
HMODULE LoadLibraryA(const char* a_name) noexcept;
HMODULE LoadLibraryW(const wchar_t* a_name) noexcept;
void* MapViewOfFile(HANDLE a_object, std::uint32_t a_desiredAccess, std::uint32_t a_fileOffsetHi, std::uint32_t a_fileOffsetLo, std::size_t a_numBytes) noexcept;
void* MapViewOfFileEx(HANDLE a_object, std::uint32_t a_desiredAccess, std::uint32_t a_fileOffsetHi, std::uint32_t a_fileOffsetLo, std::size_t a_numBytes, void* a_baseAddr) noexcept;
std::int32_t MultiByteToWideChar(std::uint32_t a_codePage, std::uint32_t a_flags, const char* a_src, std::int32_t a_srcLen, wchar_t* a_dst, std::int32_t a_dstLen) noexcept;
HANDLE OpenFileMappingA(std::uint32_t a_desiredAccess, bool a_inheritHandle, const char* a_name) noexcept;
HANDLE OpenFileMappingW(std::uint32_t a_desiredAccess, bool a_inheritHandle, const wchar_t* a_name) noexcept;
void OutputDebugStringA(const char* a_str) noexcept;
void OutputDebugStringW(const wchar_t* a_str) noexcept;
bool QueryPerformanceCounter(std::int64_t* a_counter) noexcept;
bool QueryPerformanceFrequency(std::int64_t* a_frequency) noexcept;
void ReleaseSRWLockShared(SRWLOCK* a_lock) noexcept;
void ReleaseSRWLockExclusive(SRWLOCK* a_lock) noexcept;
std::uint32_t ResumeThread(HANDLE a_handle) noexcept;
std::uint32_t SetCriticalSectionSpinCount(CRITICAL_SECTION* a_criticalSection, std::uint32_t a_spinCount) noexcept;
bool SetEnvironmentVariableA(const char* a_name, const char* a_value) noexcept;
bool SetEnvironmentVariableW(const wchar_t* a_name, const wchar_t* a_value) noexcept;
void Sleep(std::uint32_t a_milliseconds) noexcept;
bool TerminateProcess(HANDLE a_process, std::uint32_t a_exitCode) noexcept;
void* TlsGetValue(std::uint32_t a_index) noexcept;
bool TlsSetValue(std::uint32_t a_index, void* a_value) noexcept;
bool TryAcquireSRWLockExclusive(SRWLOCK* a_lock) noexcept;
bool TryAcquireSRWLockShared(SRWLOCK* a_lock) noexcept;
bool TryEnterCriticalSection(CRITICAL_SECTION* a_criticalSection) noexcept;
bool UnmapViewOfFile(const void* a_baseAddress) noexcept;
void* VirtualAlloc(void* a_address, std::size_t a_size, std::uint32_t a_type, std::uint32_t a_protect) noexcept;
void* VirtualAllocEx(HANDLE a_process, void* a_address, std::size_t a_size, std::uint32_t a_type, std::uint32_t a_protect) noexcept;
bool VirtualFree(void* a_address, std::size_t a_size, std::uint32_t a_type) noexcept;
bool VirtualFreeEx(HANDLE a_process, void* a_address, std::size_t a_size, std::uint32_t a_type) noexcept;
bool VirtualProtect(void* a_address, std::size_t a_size, std::uint32_t a_newProtect, std::uint32_t* a_oldProtect) noexcept;
bool VirtualProtectEx(HANDLE a_process, void* a_address, std::size_t a_size, std::uint32_t a_newProtect, std::uint32_t* a_oldProtect) noexcept;
std::size_t VirtualQuery(const void* a_address, MEMORY_BASIC_INFORMATION* a_buf, std::size_t a_bufLen) noexcept;
std::size_t VirtualQueryEx(HANDLE a_process, const void* a_address, MEMORY_BASIC_INFORMATION* a_buf, std::size_t a_bufLen) noexcept;
std::uint32_t WaitForSingleObject(HANDLE a_handle, std::uint32_t a_milliseconds) noexcept;
std::uint32_t WaitForSingleObjectEx(HANDLE a_handle, std::uint32_t a_milliseconds, bool a_alertable) noexcept;
std::int32_t WideCharToMultiByte(std::uint32_t a_codePage, std::uint32_t a_flags, const wchar_t* a_src, std::int32_t a_srcLen, char* a_dst, std::int32_t a_dstLen, const char* a_default, std::int32_t* a_defaultLen);
bool WriteProcessMemory(HANDLE a_process, void* a_address, const void* a_buf, std::size_t a_bufLen, std::size_t* a_bufWritten) noexcept;
}
@@ -0,0 +1,92 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
struct EXCEPTION_REGISTRATION_RECORD;
struct PEB_LDR_DATA;
struct RTL_USER_PROCESS_PARAMETERS;
struct UNICODE_STRING;
using PS_POST_PROCESS_INIT_ROUTINE = void (*)();
struct LIST_ENTRY
{
struct LIST_ENTRY* fLink;
struct LIST_ENTRY* bLink;
};
struct NT_TIB
{
EXCEPTION_REGISTRATION_RECORD* exceptionList;
void* stackBase;
void* stackLimit;
void* subSystemTib;
union
{
void* fiberData;
std::uint32_t version;
};
void* arbitraryUserPointer;
struct NT_TIB* self;
};
struct PEB
{
std::byte reserved1[2];
std::byte beingDebugged;
std::byte reserved2[1];
void* reserved3[2];
PEB_LDR_DATA* ldr;
RTL_USER_PROCESS_PARAMETERS* processParameters;
void* reserved4[3];
void* atlThunkSListPtr;
void* reserved5;
std::uint32_t reserved6;
void* reserved7;
std::uint32_t reserved8;
std::uint32_t atlThunkSListPtr32;
void* reserved9[45];
std::byte reserved10[96];
PS_POST_PROCESS_INIT_ROUTINE postProcessInitRoutine;
std::byte reserved11[128];
void* reserved12[1];
std::uint32_t sessionID;
};
struct PEB_LDR_DATA
{
std::byte reserved1[8];
void* reserved2[3];
LIST_ENTRY inMemoryOrderModuleList;
};
struct RTL_USER_PROCESS_PARAMETERS
{
std::byte reserved1[16];
void* reserved2[10];
UNICODE_STRING imagePathName;
UNICODE_STRING commandLine;
};
struct TEB
{
void* reserved1[11];
void* threadLocalStoragePointer;
PEB* processEnvironmentBlock;
void* reserved2[399];
std::byte reserved3[1952];
void* tlsSlots[64];
std::byte reserved4[8];
void* reserved5[26];
void* reservedForOle;
void* reserved6[4];
void* tlsExpansionSlots;
};
}
namespace REX::W32
{
TEB* NtCurrentTeb() noexcept;
}
@@ -0,0 +1,8 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
void CoTaskMemFree(void* a_block) noexcept;
}
@@ -0,0 +1,72 @@
#pragma once
#include "REX/TEnumSet.h"
namespace REX::W32
{
using RTTITypeDescriptor = std::type_info;
struct RTTIClassHierarchyDescriptor;
struct RTTIBaseClassDescriptor
{
enum class Attribute : std::uint32_t
{
None = 0,
NotVisible = 1 << 0,
Ambiguous = 1 << 1,
Private = 1 << 2,
PrivateOrProtectedBase = 1 << 3,
Virtual = 1 << 4,
NonPolymorphic = 1 << 5,
HasHierarchyDescriptor = 1 << 6
};
struct PMD
{
// members
std::int32_t mDisp; // 0x00
std::int32_t pDisp; // 0x04
std::int32_t vDisp; // 0x08
};
static_assert(sizeof(PMD) == 0x0C);
// members
std::uint32_t typeDescriptor; // 0x00
std::uint32_t numContainedBases; // 0x04
PMD where; // 0x08
TEnumSet<Attribute> attributes; // 0x14
std::uint32_t classDescriptor; // 0x18
};
static_assert(sizeof(RTTIBaseClassDescriptor) == 0x1C);
struct RTTIClassHierarchyDescriptor
{
enum class Attribute : std::uint32_t
{
NoInheritance = 0,
MultipleInheritance = 1 << 0,
VirtualInheritance = 1 << 1,
AmbiguousInheritance = 1 << 2
};
// members
std::uint32_t signature; // 0x00
TEnumSet<Attribute> attributes; // 0x04
std::uint32_t numBaseClasses; // 0x08
std::uint32_t baseClassArray; // 0x0C
};
static_assert(sizeof(RTTIClassHierarchyDescriptor) == 0x10);
struct RTTICompleteObjectLocator
{
// members
std::uint32_t signature; // 0x00
std::uint32_t offset; // 0x04
std::uint32_t cdOffset; // 0x08
std::uint32_t typeDescriptor; // 0x0C
std::uint32_t classDescriptor; // 0x10
std::uint32_t self; // 0x14
};
static_assert(sizeof(RTTICompleteObjectLocator) == 0x18);
}
@@ -0,0 +1,34 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
// known folder ids
inline constexpr GUID FOLDERID_Documents{ 0xFDD39AD0u, 0x238Fu, 0x46AFu, { 0xADu, 0xB4u, 0x6Cu, 0x85u, 0x48u, 0x03u, 0x69u, 0xC7u } };
inline constexpr GUID FOLDERID_Pictures{ 0x33E28130u, 0x4E1Eu, 0x4676u, { 0x83u, 0x5Au, 0x98u, 0x39u, 0x5Cu, 0x3Bu, 0xC3u, 0xBBu } };
inline constexpr GUID FOLDERID_ProgramData{ 0x62AB5D82u, 0xFDC1u, 0x4DC3u, { 0xA9u, 0xDDu, 0x07u, 0x0Du, 0x1Du, 0x49u, 0x5Du, 0x97u } };
// known folder flags
inline constexpr auto KF_FLAG_DEFAULT{ 0x00000000u };
inline constexpr auto KF_FLAG_FORCE_APP_DATA_REDIRECTION{ 0x00080000u };
inline constexpr auto KF_FLAG_RETURN_FILTER_REDIRECTION_TARGET{ 0x00040000u };
inline constexpr auto KF_FLAG_FORCE_PACKAGE_REDIRECTION{ 0x00020000u };
inline constexpr auto KF_FLAG_NO_PACKAGE_REDIRECTION{ 0x00010000u };
inline constexpr auto KF_FLAG_FORCE_APPCONTAINER_REDIRECTION{ 0x00020000u };
inline constexpr auto KF_FLAG_NO_APPCONTAINER_REDIRECTION{ 0x00010000u };
inline constexpr auto KF_FLAG_CREATE{ 0x00008000u };
inline constexpr auto KF_FLAG_DONT_VERIFY{ 0x00004000u };
inline constexpr auto KF_FLAG_DONT_UNEXPAND{ 0x00002000u };
inline constexpr auto KF_FLAG_NO_ALIAS{ 0x00001000u };
inline constexpr auto KF_FLAG_INIT{ 0x00000800u };
inline constexpr auto KF_FLAG_DEFAULT_PATH{ 0x00000400u };
inline constexpr auto KF_FLAG_NOT_PARENT_RELATIVE{ 0x00000200u };
inline constexpr auto KF_FLAG_SIMPLE_IDLIST{ 0x00000100u };
inline constexpr auto KF_FLAG_ALIAS_ONLY{ 0x80000000u };
}
namespace REX::W32
{
std::int32_t SHGetKnownFolderPath(const GUID& a_id, std::uint32_t a_flags, void* a_token, wchar_t** a_path) noexcept;
}
@@ -0,0 +1,293 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
enum GWLP : std::int32_t
{
GWLP_USERDATA = -21,
GWLP_ID = -12,
GWLP_HWNDPARENT = -8,
GWLP_HINSTANCE = -6,
GWLP_WNDPROC = -4,
};
enum WM : std::uint32_t
{
WM_NULL = 0x0000u,
WM_CREATE = 0x0001u,
WM_DESTROY = 0x0002u,
WM_MOVE = 0x0003u,
WM_SIZE = 0x0005u,
WM_ACTIVATE = 0x0006u,
WM_SETFOCUS = 0x0007u,
WM_KILLFOCUS = 0x0008u,
WM_ENABLE = 0x000Au,
WM_SETREDRAW = 0x000Bu,
WM_SETTEXT = 0x000Cu,
WM_GETTEXT = 0x000Du,
WM_GETTEXTLENGTH = 0x000Eu,
WM_PAINT = 0x000Fu,
WM_CLOSE = 0x0010u,
WM_QUIT = 0x0012u,
WM_ERASEBKGND = 0x0014u,
WM_SHOWWINDOW = 0x0018u,
WM_ACTIVATEAPP = 0x001Cu,
WM_FONTCHANGE = 0x001Du,
WM_TIMECHANGE = 0x001Eu,
WM_CANCELMODE = 0x001Fu,
WM_SETCURSOR = 0x0020u,
WM_MOUSEACTIVATE = 0x0021u,
WM_CHILDACTIVATE = 0x0022u,
};
enum VK : std::uint32_t
{
VK_LBUTTON = 0x1,
VK_RBUTTON = 0x2,
VK_CANCEL = 0x3,
VK_MBUTTON = 0x4,
VK_XBUTTON1 = 0x5,
VK_XBUTTON2 = 0x6,
VK_BACK = 0x8,
VK_TAB = 0x9,
VK_RESERVED_0A = 0xA,
VK_RESERVED_0B = 0xB,
VK_CLEAR = 0xC,
VK_RETURN = 0xD,
VK_SHIFT = 0x10,
VK_CONTROL = 0x11,
VK_MENU = 0x12,
VK_PAUSE = 0x13,
VK_CAPITAL = 0x14,
VK_KANA = 0x15,
VK_HANGUEL = 0x15,
VK_HANGUL = 0x15,
VK_IME_ON = 0x16,
VK_JUNJA = 0x17,
VK_FINAL = 0x18,
VK_HANJA = 0x19,
VK_KANJI = VK_HANJA,
VK_IME_OFF = 0x1A,
VK_ESCAPE = 0x1B,
VK_CONVERT = 0x1C,
VK_NONCONVERT = 0x1D,
VK_ACCEPT = 0x1E,
VK_MODECHANGE = 0x1F,
VK_SPACE = 0x20,
VK_PRIOR = 0x21,
VK_NEXT = 0x22,
VK_END = 0x23,
VK_HOME = 0x24,
VK_LEFT = 0x25,
VK_UP = 0x26,
VK_RIGHT = 0x27,
VK_DOWN = 0x28,
VK_SELECT = 0x29,
VK_PRINT = 0x2A,
VK_EXECUTE = 0x2B,
VK_SNAPSHOT = 0x2C,
VK_INSERT = 0x2D,
VK_DELETE = 0x2E,
VK_HELP = 0x2F,
VK_0 = 0x30,
VK_1 = 0x31,
VK_2 = 0x32,
VK_3 = 0x33,
VK_4 = 0x34,
VK_5 = 0x35,
VK_6 = 0x36,
VK_7 = 0x37,
VK_8 = 0x38,
VK_9 = 0x39,
VK_A = 0x41,
VK_B = 0x42,
VK_C = 0x43,
VK_D = 0x44,
VK_E = 0x45,
VK_F = 0x46,
VK_G = 0x47,
VK_H = 0x48,
VK_I = 0x49,
VK_J = 0x4A,
VK_K = 0x4B,
VK_L = 0x4C,
VK_M = 0x4D,
VK_N = 0x4E,
VK_O = 0x4F,
VK_P = 0x50,
VK_Q = 0x51,
VK_R = 0x52,
VK_S = 0x53,
VK_T = 0x54,
VK_U = 0x55,
VK_V = 0x56,
VK_W = 0x57,
VK_X = 0x58,
VK_Y = 0x59,
VK_Z = 0x5A,
VK_LWIN = 0x5B,
VK_RWIN = 0x5C,
VK_APPS = 0x5D,
VK_RESERVED_5E = 0x5E,
VK_SLEEP = 0x5F,
VK_NUMPAD0 = 0x60,
VK_NUMPAD1 = 0x61,
VK_NUMPAD2 = 0x62,
VK_NUMPAD3 = 0x63,
VK_NUMPAD4 = 0x64,
VK_NUMPAD5 = 0x65,
VK_NUMPAD6 = 0x66,
VK_NUMPAD7 = 0x67,
VK_NUMPAD8 = 0x68,
VK_NUMPAD9 = 0x69,
VK_MULTIPLY = 0x6A,
VK_ADD = 0x6B,
VK_SEPARATOR = 0x6C,
VK_SUBTRACT = 0x6D,
VK_DECIMAL = 0x6E,
VK_DIVIDE = 0x6F,
VK_F1 = 0x70,
VK_F2 = 0x71,
VK_F3 = 0x72,
VK_F4 = 0x73,
VK_F5 = 0x74,
VK_F6 = 0x75,
VK_F7 = 0x76,
VK_F8 = 0x77,
VK_F9 = 0x78,
VK_F10 = 0x79,
VK_F11 = 0x7A,
VK_F12 = 0x7B,
VK_F13 = 0x7C,
VK_F14 = 0x7D,
VK_F15 = 0x7E,
VK_F16 = 0x7F,
VK_F17 = 0x80,
VK_F18 = 0x81,
VK_F19 = 0x82,
VK_F20 = 0x83,
VK_F21 = 0x84,
VK_F22 = 0x85,
VK_F23 = 0x86,
VK_F24 = 0x87,
VK_NUMLOCK = 0x90,
VK_SCROLL = 0x91,
VK_OEMSPECIFIC_92 = 0x92,
VK_OEMSPECIFIC_93 = 0x93,
VK_OEMSPECIFIC_94 = 0x94,
VK_OEMSPECIFIC_95 = 0x95,
VK_OEMSPECIFIC_96 = 0x96,
VK_LSHIFT = 0xA0,
VK_RSHIFT = 0xA1,
VK_LCONTROL = 0xA2,
VK_RCONTROL = 0xA3,
VK_LMENU = 0xA4,
VK_RMENU = 0xA5,
VK_BROWSER_BACK = 0xA6,
VK_BROWSER_FORWARD = 0xA7,
VK_BROWSER_REFRESH = 0xA8,
VK_BROWSER_STOP = 0xA9,
VK_BROWSER_SEARCH = 0xAA,
VK_BROWSER_FAVORITES = 0xAB,
VK_BROWSER_HOME = 0xAC,
VK_VOLUME_MUTE = 0xAD,
VK_VOLUME_DOWN = 0xAE,
VK_VOLUME_UP = 0xAF,
VK_MEDIA_NEXT_TRACK = 0xB0,
VK_MEDIA_PREV_TRACK = 0xB1,
VK_MEDIA_STOP = 0xB2,
VK_MEDIA_PLAY_PAUSE = 0xB3,
VK_LAUNCH_MAIL = 0xB4,
VK_LAUNCH_MEDIA_SELECT = 0xB5,
VK_LAUNCH_APP1 = 0xB6,
VK_LAUNCH_APP2 = 0xB7,
VK_RESERVED_B8 = 0xB8,
VK_RESERVED_B9 = 0xB9,
VK_OEM_1 = 0xBA,
VK_OEM_PLUS = 0xBB,
VK_OEM_COMMA = 0xBC,
VK_OEM_MINUS = 0xBD,
VK_OEM_PERIOD = 0xBE,
VK_OEM_2 = 0xBF,
VK_OEM_3 = 0xC0,
VK_RESERVED_C1 = 0xC1,
VK_RESERVED_C2 = 0xC2,
VK_RESERVED_C3 = 0xC3,
VK_RESERVED_C4 = 0xC4,
VK_RESERVED_C5 = 0xC5,
VK_RESERVED_C6 = 0xC6,
VK_RESERVED_C7 = 0xC7,
VK_RESERVED_C8 = 0xC8,
VK_RESERVED_C9 = 0xC9,
VK_RESERVED_CA = 0xCA,
VK_RESERVED_CB = 0xCB,
VK_RESERVED_CC = 0xCC,
VK_RESERVED_CD = 0xCD,
VK_RESERVED_CE = 0xCE,
VK_RESERVED_CF = 0xCF,
VK_RESERVED_D0 = 0xD0,
VK_RESERVED_D1 = 0xD1,
VK_RESERVED_D2 = 0xD2,
VK_RESERVED_D3 = 0xD3,
VK_RESERVED_D4 = 0xD4,
VK_RESERVED_D5 = 0xD5,
VK_RESERVED_D6 = 0xD6,
VK_RESERVED_D7 = 0xD7,
VK_OEM_4 = 0xDB,
VK_OEM_5 = 0xDC,
VK_OEM_6 = 0xDD,
VK_OEM_7 = 0xDE,
VK_OEM_8 = 0xDF,
VK_RESERVED_E0 = 0xE0,
VK_OEMSPECIFIC_E1 = 0xE1,
VK_OEM_102 = 0xE2,
VK_OEMSPECIFIC_E3 = 0xE3,
VK_OEMSPECIFIC_E4 = 0xE4,
VK_PROCESSKEY = 0xE5,
VK_OEMSPECIFIC_E6 = 0xE6,
VK_PACKET = 0xE7,
VK_OEMSPECIFIC_E9 = 0xE9,
VK_OEMSPECIFIC_EA = 0xEA,
VK_OEMSPECIFIC_EB = 0xEB,
VK_OEMSPECIFIC_EC = 0xEC,
VK_OEMSPECIFIC_ED = 0xED,
VK_OEMSPECIFIC_EE = 0xEE,
VK_OEMSPECIFIC_EF = 0xEF,
VK_OEMSPECIFIC_F0 = 0xF0,
VK_OEMSPECIFIC_F1 = 0xF1,
VK_OEMSPECIFIC_F2 = 0xF2,
VK_OEMSPECIFIC_F3 = 0xF3,
VK_OEMSPECIFIC_F4 = 0xF4,
VK_OEMSPECIFIC_F5 = 0xF5,
VK_ATTN = 0xF6,
VK_CRSEL = 0xF7,
VK_EXSEL = 0xF8,
VK_EREOF = 0xF9,
VK_PLAY = 0xFA,
VK_ZOOM = 0xFB,
VK_NONAME = 0xFC,
VK_PA1 = 0xFD,
VK_OEM_CLEAR = 0xFE,
VK_RESERVED_FF = 0xFF,
};
}
namespace REX::W32
{
using WNDPROC = std::intptr_t (*)(HWND, std::uint32_t, std::uintptr_t, std::intptr_t);
}
namespace REX::W32
{
bool GetClientRect(HWND a_wnd, RECT* a_rect) noexcept;
std::int32_t GetKeyNameTextA(std::int32_t a_param, char* a_buf, std::int32_t a_bufLen) noexcept;
std::int32_t GetKeyNameTextW(std::int32_t a_param, wchar_t* a_buf, std::int32_t a_bufLen) noexcept;
std::int16_t GetKeyState(std::int32_t a_key) noexcept;
bool GetWindowRect(HWND a_wnd, RECT* a_rect) noexcept;
std::int32_t MessageBoxA(HWND a_wnd, const char* a_text, const char* a_caption, std::uint32_t a_type) noexcept;
std::int32_t MessageBoxW(HWND a_wnd, const wchar_t* a_text, const wchar_t* a_caption, std::uint32_t a_type) noexcept;
std::intptr_t SetWindowLongPtrA(HWND a_wnd, std::int32_t a_index, std::intptr_t a_newPtr) noexcept;
std::int32_t ShowCursor(bool a_show) noexcept;
}
@@ -0,0 +1,13 @@
#pragma once
namespace REX::W32
{
bool GetFileVersionInfoA(const char* a_name, std::uint32_t a_handle, std::uint32_t a_dataLen, void* a_data) noexcept;
std::uint32_t GetFileVersionInfoSizeA(const char* a_name, std::uint32_t* a_handle) noexcept;
//std::uint32_t GetFileVersionInfoSizeExA(std::uint32_t a_flags, const char* a_name, std::uint32_t* a_handle) noexcept;
std::uint32_t GetFileVersionInfoSizeExW(std::uint32_t a_flags, const wchar_t* a_name, std::uint32_t* a_handle) noexcept;
std::uint32_t GetFileVersionInfoSizeW(const wchar_t* a_name, std::uint32_t* a_handle) noexcept;
bool GetFileVersionInfoW(const wchar_t* a_name, std::uint32_t a_handle, std::uint32_t a_dataLen, void* a_data) noexcept;
bool VerQueryValueA(const void* a_block, const char* a_subBlock, void** a_buf, std::uint32_t* a_bufLen) noexcept;
bool VerQueryValueW(const void* a_block, const wchar_t* a_subBlock, void** a_buf, std::uint32_t* a_bufLen) noexcept;
}
@@ -0,0 +1,206 @@
#pragma once
#include "REX/W32/BASE.h"
namespace REX::W32
{
// winsock2 values
inline constexpr auto INADDR_ANY{ 0x00000000u };
inline constexpr auto INADDR_LOOPBACK{ 0x7f000001u };
inline constexpr auto INADDR_BROADCAST{ 0xffffffffu };
inline constexpr auto INADDR_NONE{ 0xffffffffu };
}
namespace REX::W32
{
enum ADDRESS_FAMILY : std::uint16_t
{
AF_UNSPEC = 0,
AF_UNIX = 1,
AF_INET = 2,
AF_IMPLINK = 3,
AF_PUP = 4,
AF_CHAOS = 5,
AF_NS = 6,
AF_IPX = AF_NS,
AF_ISO = 7,
AF_OSI = AF_ISO,
AF_ECMA = 8,
AF_DATAKIT = 9,
AF_CCITT = 10,
AF_SNA = 11,
AF_DECnet = 12,
AF_DLI = 13,
AF_LAT = 14,
AF_HYLINK = 15,
AF_APPLETALK = 16,
AF_NETBIOS = 17,
AF_VOICEVIEW = 18,
AF_FIREFOX = 19,
AF_UNKNOWN1 = 20,
AF_BAN = 21,
AF_ATM = 22,
AF_INET6 = 23,
AF_CLUSTER = 24,
AF_12844 = 25,
AF_IRDA = 26,
AF_NETDES = 28,
};
enum WSA_ERROR : std::int32_t
{
WSABASEERR = 10000L,
WSAEINTR = 10004L,
WSAEBADF = 10009L,
WSAEACCES = 10013L,
WSAEFAULT = 10014L,
WSAEINVAL = 10022L,
WSAEMFILE = 10024L,
WSAEWOULDBLOCK = 10035L,
WSAEINPROGRESS = 10036L,
WSAEALREADY = 10037L,
WSAENOTSOCK = 10038L,
WSAEDESTADDRREQ = 10039L,
WSAEMSGSIZE = 10040L,
WSAEPROTOTYPE = 10041L,
WSAENOPROTOOPT = 10042L,
WSAEPROTONOSUPPORT = 10043L,
WSAESOCKTNOSUPPORT = 10044L,
WSAEOPNOTSUPP = 10045L,
WSAEPFNOSUPPORT = 10046L,
WSAEAFNOSUPPORT = 10047L,
WSAEADDRINUSE = 10048L,
WSAEADDRNOTAVAIL = 10049L,
WSAENETDOWN = 10050L,
WSAENETUNREACH = 10051L,
WSAENETRESET = 10052L,
WSAECONNABORTED = 10053L,
WSAECONNRESET = 10054L,
WSAENOBUFS = 10055L,
WSAEISCONN = 10056L,
WSAENOTCONN = 10057L,
WSAESHUTDOWN = 10058L,
WSAETOOMANYREFS = 10059L,
WSAETIMEDOUT = 10060L,
WSAECONNREFUSED = 10061L,
WSAELOOP = 10062L,
WSAENAMETOOLONG = 10063L,
WSAEHOSTDOWN = 10064L,
WSAEHOSTUNREACH = 10065L,
WSAENOTEMPTY = 10066L,
WSAEPROCLIM = 10067L,
WSAEUSERS = 10068L,
WSAEDQUOT = 10069L,
WSAESTALE = 10070L,
WSAEREMOTE = 10071L,
WSASYSNOTREADY = 10091L,
WSAVERNOTSUPPORTED = 10092L,
WSANOTINITIALISED = 10093L,
WSAEDISCON = 10101L,
WSAENOMORE = 10102L,
WSAECANCELLED = 10103L,
WSAEINVALIDPROCTABLE = 10104L,
WSAEINVALIDPROVIDER = 10105L,
WSAEPROVIDERFAILEDINIT = 10106L,
WSASYSCALLFAILURE = 10107L,
WSASERVICE_NOT_FOUND = 10108L,
WSATYPE_NOT_FOUND = 10109L,
WSA_E_NO_MORE = 10110L,
WSA_E_CANCELLED = 10111L,
WSAEREFUSED = 10112L,
WSAHOST_NOT_FOUND = 11001L,
WSATRY_AGAIN = 11002L,
WSANO_RECOVERY = 11003L,
WSANO_DATA = 11004L,
WSA_QOS_RECEIVERS = 11005L,
WSA_QOS_SENDERS = 11006L,
WSA_QOS_NO_SENDERS = 11007L,
WSA_QOS_NO_RECEIVERS = 11008L,
WSA_QOS_REQUEST_CONFIRMED = 11009L,
WSA_QOS_ADMISSION_FAILURE = 11010L,
WSA_QOS_POLICY_FAILURE = 11011L,
WSA_QOS_BAD_STYLE = 11012L,
WSA_QOS_BAD_OBJECT = 11013L,
WSA_QOS_TRAFFIC_CTRL_ERROR = 11014L,
WSA_QOS_GENERIC_ERROR = 11015L,
WSA_QOS_ESERVICETYPE = 11016L,
WSA_QOS_EFLOWSPEC = 11017L,
WSA_QOS_EPROVSPECBUF = 11018L,
WSA_QOS_EFILTERSTYLE = 11019L,
WSA_QOS_EFILTERTYPE = 11020L,
WSA_QOS_EFILTERCOUNT = 11021L,
WSA_QOS_EOBJLENGTH = 11022L,
WSA_QOS_EFLOWCOUNT = 11023L,
WSA_QOS_EUNKOWNPSOBJ = 11024L,
WSA_QOS_EPOLICYOBJ = 11025L,
WSA_QOS_EFLOWDESC = 11026L,
WSA_QOS_EPSFLOWSPEC = 11027L,
WSA_QOS_EPSFILTERSPEC = 11028L,
WSA_QOS_ESDMODEOBJ = 11029L,
WSA_QOS_ESHAPERATEOBJ = 11030L,
WSA_QOS_RESERVED_PETYPE = 11031L,
WSA_SECURE_HOST_NOT_FOUND = 11032L,
WSA_IPSEC_NAME_POLICY_ERROR = 11033L,
};
using SOCKET = std::uintptr_t;
struct sockaddr
{
ADDRESS_FAMILY sa_family;
char sa_data[14];
};
// Originally a struct with several #defines that served as aliases to members
// The defines screwed a lot of things up, so it was made a union.
// This means it won't have compatibility with code that uses in_addrs directly and
// also refers to it by its full type identifier (i.e. `struct in_addr`).
union in_addr
{
union in_addr_D
{
struct
{
std::uint8_t s_b1, s_b2, s_b3, s_b4;
} S_un_b;
struct
{
std::uint16_t s_w1, s_w2;
} S_un_w;
std::uint32_t S_addr;
} S_un;
// getting around the #DEFINEs in inaddr.h
struct
{
std::uint8_t s_net;
std::uint8_t s_host;
std::uint8_t s_lh;
std::uint8_t s_impno;
};
struct
{
std::uint16_t _s_w1, s_imp;
};
std::uint32_t s_addr;
};
struct sockaddr_in
{
ADDRESS_FAMILY sin_family;
std::uint16_t sin_port;
in_addr sin_addr;
char sin_zero[8];
};
}
namespace REX::W32
{
std::uint16_t htons(std::uint16_t a_host) noexcept;
std::uint32_t ntohl(std::uint32_t a_net) noexcept;
std::int32_t WSAGetLastError() noexcept;
}
@@ -0,0 +1,80 @@
#pragma once
namespace REX::W32
{
inline constexpr std::uint16_t XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE{ 7849 };
inline constexpr std::uint16_t XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE{ 8689 };
inline constexpr std::uint8_t XINPUT_GAMEPAD_TRIGGER_THRESHOLD{ 30 };
}
namespace REX::W32
{
enum XINPUT_GAMEPAD_BUTTON : std::uint16_t
{
XINPUT_GAMEPAD_DPAD_UP = 0x0001,
XINPUT_GAMEPAD_DPAD_DOWN = 0x0002,
XINPUT_GAMEPAD_DPAD_LEFT = 0x0004,
XINPUT_GAMEPAD_DPAD_RIGHT = 0x0008,
XINPUT_GAMEPAD_START = 0x0010,
XINPUT_GAMEPAD_BACK = 0x0020,
XINPUT_GAMEPAD_LEFT_THUMB = 0x0040,
XINPUT_GAMEPAD_RIGHT_THUMB = 0x0080,
XINPUT_GAMEPAD_LEFT_SHOULDER = 0x0100,
XINPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200,
XINPUT_GAMEPAD_A = 0x1000,
XINPUT_GAMEPAD_B = 0x2000,
XINPUT_GAMEPAD_X = 0x4000,
XINPUT_GAMEPAD_Y = 0x8000,
XINPUT_GAMEPAD_BUTTON_MASK = XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_START | XINPUT_GAMEPAD_BACK | XINPUT_GAMEPAD_LEFT_THUMB | XINPUT_GAMEPAD_RIGHT_THUMB | XINPUT_GAMEPAD_LEFT_SHOULDER | XINPUT_GAMEPAD_RIGHT_SHOULDER | XINPUT_GAMEPAD_A | XINPUT_GAMEPAD_B | XINPUT_GAMEPAD_X | XINPUT_GAMEPAD_Y,
};
}
namespace REX::W32
{
struct XINPUT_BATTERY_INFORMATION
{
std::uint8_t batteryType;
std::uint8_t batteryLevel;
};
struct XINPUT_GAMEPAD
{
std::uint16_t buttons;
std::uint8_t leftTrigger;
std::uint8_t rightTrigger;
std::int16_t thumbLX;
std::int16_t thumbLY;
std::int16_t thumbRX;
std::int16_t thumbRY;
};
struct XINPUT_KEYSTROKE
{
std::uint16_t virtualKey;
std::uint16_t unicode;
std::uint16_t flags;
std::uint8_t userIndex;
std::uint8_t hidCode;
};
struct XINPUT_STATE
{
std::uint32_t packetNumber;
XINPUT_GAMEPAD gamepad;
};
struct XINPUT_VIBRATION
{
std::uint16_t leftMotorSpeed;
std::uint16_t rightMotorSpeed;
};
struct XINPUT_CAPABILITIES
{
std::uint8_t type;
std::uint8_t subType;
std::uint16_t flags;
XINPUT_GAMEPAD gamepad;
XINPUT_VIBRATION vibration;
};
}
@@ -0,0 +1,34 @@
#include <winres.h>
1 VERSIONINFO
FILEVERSION ${COMMONLIB_PLUGIN_VERSION_MAJOR}, ${COMMONLIB_PLUGIN_VERSION_MINOR}, ${COMMONLIB_PLUGIN_VERSION_PATCH}, 0
PRODUCTVERSION ${COMMONLIB_PROJECT_VERSION_MAJOR}, ${COMMONLIB_PROJECT_VERSION_MINOR}, ${COMMONLIB_PROJECT_VERSION_PATCH}, 0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "${COMMONLIB_PLUGIN_CONTACT}"
VALUE "FileDescription", "${COMMONLIB_PLUGIN_DESCRIPTION}"
VALUE "FileVersion", "${COMMONLIB_PLUGIN_VERSION}.0"
VALUE "InternalName", "${COMMONLIB_PLUGIN_NAME}"
VALUE "LegalCopyright", "${COMMONLIB_PLUGIN_AUTHOR}"
VALUE "LegalTrademarks", "${COMMONLIB_PLUGIN_LICENSE}"
VALUE "ProductName", "${COMMONLIB_PROJECT_NAME}"
VALUE "ProductVersion", "${COMMONLIB_PROJECT_VERSION}.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
@@ -0,0 +1,107 @@
#include "REL/FHook.h"
#include "REL/FHookStore.h"
#include "REX/LOG.h"
namespace REL
{
FHook::FHook(const std::uintptr_t a_address) :
m_address(a_address)
{
m_handle = FHookStore::GetSingleton()->Add(this);
m_name = std::to_string(m_handle);
}
FHook::FHook(const std::uintptr_t a_address, const char* a_name) :
m_address(a_address), m_name(a_name)
{
m_handle = FHookStore::GetSingleton()->Add(this);
}
FHook::FHook(const std::uintptr_t a_address, const EHookType a_type) :
m_address(a_address), m_type(a_type)
{
m_handle = FHookStore::GetSingleton()->Add(this);
m_name = std::to_string(m_handle);
}
FHook::FHook(const std::uintptr_t a_address, const EHookType a_type, const EHookStep a_step) :
m_address(a_address), m_type(a_type), m_step(a_step)
{
m_handle = FHookStore::GetSingleton()->Add(this);
m_name = std::to_string(m_handle);
}
FHook::FHook(const std::uintptr_t a_address, const EHookStep a_step) :
m_address(a_address), m_step(a_step)
{
m_handle = FHookStore::GetSingleton()->Add(this);
m_name = std::to_string(m_handle);
}
FHook::FHook(const std::uintptr_t a_address, const char* a_name, const EHookStep a_step) :
m_address(a_address), m_name(a_name), m_step(a_step)
{
m_handle = FHookStore::GetSingleton()->Add(this);
}
FHook::FHook(const std::uintptr_t a_address, const char* a_name, const EHookType a_type) :
m_address(a_address), m_name(a_name), m_type(a_type)
{
m_handle = FHookStore::GetSingleton()->Add(this);
}
FHook::FHook(const std::uintptr_t a_address, const char* a_name, const EHookType a_type, const EHookStep a_step) :
m_address(a_address), m_name(a_name), m_type(a_type), m_step(a_step)
{
m_handle = FHookStore::GetSingleton()->Add(this);
}
FHook::~FHook()
{
FHookStore::GetSingleton()->Remove(m_handle);
}
bool FHook::Init()
{
REX::TRACE("{}: Init", *this);
return true;
}
FHookHandle FHook::GetHandle() const
{
return m_handle;
}
const char* FHook::GetName() const
{
return m_name.c_str();
}
EHookType FHook::GetType() const
{
return m_type;
}
EHookStep FHook::GetStep() const
{
return m_step;
}
std::size_t FHook::GetSize() const
{
return m_size;
}
std::size_t FHook::GetSizeTrampoline() const
{
return m_sizeTrampoline;
}
bool FHook::GetEnabled() const
{
return m_enabled;
}
}
@@ -0,0 +1,124 @@
#include "REL/FHookStore.h"
#include "REL/IHook.h"
#include "REX/LOG.h"
namespace REL
{
FHookHandle FHookStore::Add(IHook* a_hook)
{
if (a_hook && a_hook->GetHandle() == 0) {
m_hooks.insert({ ++m_handleCount, a_hook });
m_hookQueue.push(m_handleCount);
return m_handleCount;
}
return 0;
}
void FHookStore::Remove(const FHookHandle a_handle)
{
m_hooks.erase(a_handle);
}
void FHookStore::Init()
{
std::size_t count{ 0 };
while (!m_hookQueue.empty()) {
if (m_hooks[m_hookQueue.front()]->Init())
count++;
m_hookQueue.pop();
}
REX::DEBUG("FHookStore: Init {} queued hooks", count);
}
void FHookStore::Enable()
{
std::size_t count{ 0 };
for (auto& [name, hook] : m_hooks) {
if (hook) {
if (hook->Enable())
count++;
}
}
REX::DEBUG("FHookStore: Enabled {} hooks", count);
}
void FHookStore::Enable(const FHookHandle a_handle)
{
if (const auto it = m_hooks.find(a_handle); it != m_hooks.end()) {
if (it->second) {
it->second->Enable();
}
}
}
void FHookStore::Enable(const EHookType a_type)
{
for (auto& [name, hook] : m_hooks) {
if (hook && hook->GetType() == a_type) {
hook->Enable();
}
}
}
void FHookStore::Enable(const EHookStep a_step)
{
std::size_t count{ 0 };
for (auto& [name, hook] : m_hooks) {
if (hook && hook->GetStep() == a_step) {
if (hook->Enable())
count++;
}
}
REX::DEBUG("FHookStore: Enabled {} {} hooks", count, a_step);
}
void FHookStore::Disable()
{
std::size_t count{ 0 };
for (auto& [name, hook] : m_hooks) {
if (hook) {
if (hook->Disable())
count++;
}
}
REX::DEBUG("FHookStore: Disabled {} hooks", count);
}
void FHookStore::Disable(const FHookHandle a_handle)
{
for (auto& [name, hook] : m_hooks) {
if (hook && hook->GetHandle() == a_handle) {
hook->Disable();
}
}
}
void FHookStore::Disable(const EHookType a_type)
{
for (auto& [name, hook] : m_hooks) {
if (hook && hook->GetType() == a_type) {
hook->Disable();
}
}
}
std::size_t FHookStore::GetSizeTrampoline()
{
std::size_t size{ 0 };
for (auto& [name, hook] : m_hooks) {
if (hook) {
size += hook->GetSizeTrampoline();
}
}
return size;
}
}
@@ -0,0 +1,36 @@
#include "REL/IAT.h"
#include "REX/FModule.h"
namespace REL
{
std::uintptr_t GetIATAddr(std::string_view a_dll, std::string_view a_function)
{
const auto mod = REX::FModule::GetExecutingModule();
return mod.GetImportFunctionAddress(a_function, a_dll);
}
std::uintptr_t GetIATAddr(REX::W32::HMODULE a_module, std::string_view a_dll, std::string_view a_function)
{
const auto mod = REX::FModule(a_module);
return mod.GetImportFunctionAddress(a_function, a_dll);
}
void* GetIATPtr(std::string_view a_dll, std::string_view a_function)
{
const auto mod = REX::FModule::GetExecutingModule();
return mod.GetImportFunctionPointer(a_function, a_dll);
}
void* GetIATPtr(REX::W32::HMODULE a_module, std::string_view a_dll, std::string_view a_function)
{
const auto mod = REX::FModule(a_module);
return mod.GetImportFunctionPointer(a_function, a_dll);
}
std::uintptr_t PatchIAT(std::uintptr_t a_newFunc, std::string_view a_dll, std::string_view a_function)
{
const auto mod = REX::FModule::GetExecutingModule();
return mod.SetImportFunctionAddress(a_function, a_dll, a_newFunc);
}
}
@@ -0,0 +1,426 @@
#include "REL/IDDB.h"
#include "REL/Version.h"
#include "REX/FModule.h"
#include "REX/HASH.h"
#include "REX/LOG.h"
#include "REX/W32/KERNEL32.h"
namespace REL
{
class IDDB::STREAM
{
public:
using stream_type = std::ifstream;
using pointer = stream_type*;
using const_pointer = const stream_type*;
using reference = stream_type&;
using const_reference = const stream_type&;
STREAM(const std::filesystem::path a_path, const std::ios_base::openmode a_mode) :
_stream(a_path, a_mode)
{
if (!_stream.is_open())
REX::FAIL(L"Failed to open Address Library file!\nPath: {}", a_path.wstring());
_stream.exceptions(std::ios::badbit | std::ios::failbit | std::ios::eofbit);
}
void ignore(const std::streamsize a_count)
{
_stream.ignore(a_count);
}
template <class T>
void readin(T& a_val)
{
_stream.read(std::bit_cast<char*>(std::addressof(a_val)), sizeof(T));
}
template <class T>
requires(std::is_arithmetic_v<T>)
T readout()
{
T val{};
readin(val);
return val;
}
private:
stream_type _stream;
};
class IDDB::HEADER_V2
{
public:
HEADER_V2(IDDB::STREAM& a_in)
{
a_in.readin(m_gameVersion);
const auto nameLen = a_in.readout<std::uint32_t>();
for (std::uint32_t i = 0; i < nameLen; i++)
a_in.readin(m_name[i]);
m_name[nameLen] = '\0';
a_in.readin(m_pointerSize);
a_in.readin(m_addressCount);
}
std::string_view name() const noexcept { return m_name; }
std::size_t address_count() const noexcept { return static_cast<std::size_t>(m_addressCount); }
std::uint64_t pointer_size() const noexcept { return static_cast<std::uint64_t>(m_pointerSize); }
Version game_version() const noexcept
{
Version version;
for (std::size_t i = 0; i < 4; i++)
version[i] = static_cast<std::uint16_t>(m_gameVersion[i]);
return version;
}
private:
char m_name[64]{};
std::uint32_t m_gameVersion[4]{};
std::int32_t m_pointerSize{ 0 };
std::int32_t m_addressCount{ 0 };
};
class IDDB::HEADER_V5
{
public:
HEADER_V5(IDDB::STREAM& a_in)
{
a_in.readin(m_gameVersion);
a_in.readin(m_name);
a_in.readin(m_pointerSize);
a_in.readin(m_dataFormat);
a_in.readin(m_offsetCount);
}
std::string_view name() const noexcept { return m_name; }
std::size_t offset_count() const noexcept { return static_cast<std::size_t>(m_offsetCount); }
Version game_version() const noexcept
{
Version version;
for (std::size_t i = 0; i < 4; i++)
version[i] = static_cast<std::uint16_t>(m_gameVersion[i]);
return version;
}
private:
std::int32_t m_fileVersion{ 5 };
std::uint32_t m_gameVersion[4]{};
char m_name[64]{};
std::int32_t m_pointerSize{ 0 };
std::int32_t m_dataFormat{ 0 };
std::int32_t m_offsetCount{ 0 };
};
}
namespace REL
{
IDDB::IDDB()
{
std::unordered_map<Loader, std::vector<std::wstring>> g_rootMap{
{ Loader::SKSE, { L"versionlib", L"version" } },
{ Loader::F4SE, { L"version" } },
{ Loader::SFSE, { L"versionlib" } },
{ Loader::OBSE, { L"versionlib" } },
};
std::unordered_map<Loader, std::pair<std::string, std::wstring>> g_loaderMap{
{ Loader::SKSE, { "SKSE", L"SKSE" } },
{ Loader::F4SE, { "F4SE", L"F4SE" } },
{ Loader::SFSE, { "SFSE", L"SFSE" } },
{ Loader::OBSE, { "OBSE", L"OBSE" } },
};
wchar_t buffer[REX::W32::MAX_PATH];
REX::W32::GetModuleFileNameW(REX::W32::GetCurrentModule(), buffer, REX::W32::MAX_PATH);
std::filesystem::path plugin(buffer);
auto loader = plugin.parent_path().parent_path();
auto loaderName = loader.filename().wstring();
std::transform(loaderName.begin(), loaderName.end(), loaderName.begin(), std::towupper);
for (auto& entry : g_loaderMap)
if (loaderName == entry.second.second) {
m_loader = entry.first;
break;
}
if (m_loader == Loader::None)
REX::FAIL("Failed to determine Address Library loader!");
const auto mod = REX::FModule::GetExecutingModule();
const auto version = mod.GetFileVersion().wstring(L"-");
for (const auto& root : g_rootMap[m_loader]) {
const auto name = std::format(L"{}-{}.bin", root, version);
const auto path = plugin.parent_path() / name;
if (std::filesystem::exists(path)) {
if (m_loader == Loader::F4SE && root == L"version")
m_format = Format::V0;
m_path = path;
break;
}
}
if (m_path.empty())
REX::FAIL("Failed to determine Address Library path!\nLoader: {}", g_loaderMap[m_loader].first);
if (m_format == Format::V0) {
load_v0();
return;
}
STREAM stream(m_path, std::ios::in | std::ios::binary);
const auto format = stream.readout<std::uint32_t>();
if (format < 1 || (format > 2 && format < 5) || format > 5)
REX::FAIL("Unsupported Address Library format: {}", format);
m_format = static_cast<Format>(format);
if (m_format == Format::V1 || m_format == Format::V2) {
load_v2(stream);
} else if (m_format == Format::V5) {
load_v5(stream);
}
}
void IDDB::load_v0()
{
const auto mod = REX::FModule::GetExecutingModule();
const auto mapName = std::format("COMMONLIB_IDDB_OFFSETS_{}", mod.GetFileVersion().string("_"));
if (!m_mmap.create(false, m_path, mapName))
REX::FAIL(L"Failed to create Address Library MemoryMap!\nError: {}\nPath: {}", REX::W32::GetLastError(), m_path.wstring());
validate_file();
m_v0 = {
reinterpret_cast<MAPPING*>(m_mmap.data() + sizeof(std::uint64_t)),
*reinterpret_cast<std::uint64_t*>(m_mmap.data())
};
}
void IDDB::load_v2(STREAM& a_stream)
{
try {
HEADER_V2 header(a_stream);
const auto mod = REX::FModule::GetExecutingModule();
const auto modVersion = mod.GetFileVersion();
if (header.game_version() != modVersion) {
REX::FAIL(
"Address Library version mismatch!\n"
"Expected Version: {}\n"
"Actual Version: {}",
modVersion.string(), header.game_version().string());
}
const auto mapName = std::format("COMMONLIB_IDDB_OFFSETS_{}", modVersion.string("_"));
const auto byteSize = static_cast<std::size_t>(header.address_count()) * sizeof(MAPPING);
if (!m_mmap.create(true, mapName, byteSize))
REX::FAIL("Failed to create Address Library MemoryMap!\nError: {}", REX::W32::GetLastError());
validate_file();
m_v0 = { reinterpret_cast<MAPPING*>(m_mmap.data()), header.address_count() };
if (m_mmap.is_owner()) {
unpack_file(a_stream, header);
std::sort(
m_v0.begin(),
m_v0.end(),
[](auto&& a_lhs, auto&& a_rhs) {
return a_lhs.id < a_rhs.id;
});
}
} catch (const std::system_error&) {
REX::FAIL(L"Failed to open Address Library file!\nPath: {}", m_path.wstring());
}
}
void IDDB::load_v5(STREAM& a_stream)
{
try {
HEADER_V5 header(a_stream);
const auto mod = REX::FModule::GetExecutingModule();
const auto modVersion = mod.GetFileVersion();
if (header.game_version() != modVersion) {
REX::FAIL(
"Address Library version mismatch!\n"
"Expected Version: {}\n"
"Actual Version: {}",
modVersion.string(), header.game_version().string());
}
const auto mapName = std::format("COMMONLIB_IDDB_OFFSETS_{}", modVersion.string("_"));
if (!m_mmap.create(false, m_path, mapName))
REX::FAIL(L"Failed to create Address Library MemoryMap!\nError: {}\nPath: {}", REX::W32::GetLastError(), m_path.wstring());
validate_file();
m_v5 = { reinterpret_cast<std::uint32_t*>(m_mmap.data() + sizeof(HEADER_V5)), header.offset_count() };
} catch (const std::system_error&) {
REX::FAIL(L"Failed to open Address Library file!\nPath: {}", m_path.wstring());
}
}
void IDDB::unpack_file(STREAM& a_stream, const HEADER_V2& a_header)
{
std::uint8_t type = 0;
std::uint64_t id = 0;
std::uint64_t offset = 0;
std::uint64_t prevID = 0;
std::uint64_t prevOffset = 0;
for (auto& mapping : m_v0) {
a_stream.readin(type);
const auto lo = static_cast<std::uint8_t>(type & 0xF);
const auto hi = static_cast<std::uint8_t>(type >> 4);
switch (lo) {
case 0:
a_stream.readin(id);
break;
case 1:
id = prevID + 1;
break;
case 2:
id = prevID + a_stream.readout<std::uint8_t>();
break;
case 3:
id = prevID - a_stream.readout<std::uint8_t>();
break;
case 4:
id = prevID + a_stream.readout<std::uint16_t>();
break;
case 5:
id = prevID - a_stream.readout<std::uint16_t>();
break;
case 6:
id = a_stream.readout<std::uint16_t>();
break;
case 7:
id = a_stream.readout<std::uint32_t>();
break;
default:
REX::FAIL("Unhandled type while loading Address Library!");
}
const std::uint64_t tmp = (hi & 8) != 0 ? (prevOffset / a_header.pointer_size()) : prevOffset;
switch (hi & 7) {
case 0:
a_stream.readin(offset);
break;
case 1:
offset = tmp + 1;
break;
case 2:
offset = tmp + a_stream.readout<std::uint8_t>();
break;
case 3:
offset = tmp - a_stream.readout<std::uint8_t>();
break;
case 4:
offset = tmp + a_stream.readout<std::uint16_t>();
break;
case 5:
offset = tmp - a_stream.readout<std::uint16_t>();
break;
case 6:
offset = a_stream.readout<std::uint16_t>();
break;
case 7:
offset = a_stream.readout<std::uint32_t>();
break;
default:
REX::FAIL("Unhandled type while loading Address Library!");
}
if ((hi & 8) != 0) {
offset *= a_header.pointer_size();
}
mapping = { id, offset };
prevOffset = offset;
prevID = id;
}
}
void IDDB::validate_file()
{
// clang-format off
std::unordered_map<Loader, std::vector<std::pair<REL::Version, std::string_view>>> g_blacklistMap{
{ Loader::SKSE, {} },
{ Loader::F4SE, {
{ REL::Version{ 1, 10, 980 }, "2AD60B95388F1B6E77A6F86F17BEB51D043CF95A341E91ECB2E911A393E45FE8156D585D2562F7B14434483D6E6652E2373B91589013507CABAE596C26A343F1"sv },
{ REL::Version{ 1, 11, 159 }, "686D40387F638ED75AD43BB76CA14170576F1A30E91144F280987D13A3012B1CA6A4E04E6BE7A5B99E46C50332C49BE40C3D9448038E17D3D31C40E72A90AE26"sv }
} },
{ Loader::SFSE, {} },
{ Loader::OBSE, {} },
};
// clang-format on
const auto mod = REX::FModule::GetExecutingModule();
const auto modVersion = mod.GetFileVersion();
for (auto& check : g_blacklistMap[m_loader]) {
if (modVersion == check.first) {
auto sha = REX::SHA512({ m_mmap.data(), m_mmap.size() });
if (!sha)
REX::FAIL("Failed to hash Address Library file!\nPath: {}", m_path.string());
if (*sha == check.second)
REX::FAIL("Invalid Address Library loaded!\n\nRedownload Address Library for your game version.\nGame Version: {}", modVersion.string());
}
}
}
std::uint64_t IDDB::offset(std::uint64_t a_id) const
{
const auto mod = REX::FModule::GetExecutingModule();
if (std::to_underlying(m_format) < 5) {
if (m_v0.empty())
REX::FAIL("No Address Library has been loaded!");
const MAPPING elem{ a_id, 0 };
const auto it = std::lower_bound(
m_v0.begin(),
m_v0.end(),
elem,
[](auto&& a_lhs, auto&& a_rhs) {
return a_lhs.id < a_rhs.id;
});
if (it == m_v0.end()) {
REX::FAIL(
"Failed to find offset for Address Library ID!\n"
"Invalid ID: {}\n"
"Game Version: {}",
a_id, mod.GetFileVersion().string());
}
return static_cast<std::size_t>(it->offset);
}
if (m_v5.empty())
REX::FAIL("No Address Library has been loaded!");
const auto offset = static_cast<std::uint64_t>(m_v5[a_id]);
if (!offset) {
REX::FAIL(
"Failed to find offset for Address Library ID!\n"
"Invalid ID: {}\n"
"Game Version: {}",
a_id, mod.GetFileVersion().string());
}
return offset;
}
}

Some files were not shown because too many files have changed in this diff Show More