chore: Initialize reposoitory

Stingray SDK headers taken from https://github.com/AutodeskGames/stingray-plugin/
This commit is contained in:
Lucas Schwiderski 2023-05-25 15:36:33 +02:00
commit 8739f0a85c
Signed by: lucas
GPG key ID: AA12679AAA6DF4D8
138 changed files with 16767 additions and 0 deletions

9
.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
/target
# Added by cargo
#
# already existing elements were commented out
#/target
/Cargo.lock

9
Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[workspace]
resolver = "2"
members = [
"lib/dt_p2p",
"lib/nat_traversal"
]
# [profile.dev.package.backtrace]
# opt-level = 3

675
LICENSE Normal file
View file

@ -0,0 +1,675 @@
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>.

13
README.adoc Normal file
View file

@ -0,0 +1,13 @@
= Darktide P2P
:idprefix:
:idseparator:
:toc: macro
:toclevels: 1
:!toc-title:
:caution-caption: :fire:
:important-caption: :exclamtion:
:note-caption: :paperclip:
:tip-caption: :bulb:
:warning-caption: :warning:
An engine plugin for Warhammer 40,000 Darktide that implements peer-to-peer networking.

2
lib/dt_p2p/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
/Cargo.lock

14
lib/dt_p2p/Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "dt_p2p"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[lib]
crate-type = ["cdylib", "lib"]
[build-dependencies]
bindgen = "0.65.1"

22
lib/dt_p2p/build.rs Normal file
View file

@ -0,0 +1,22 @@
extern crate bindgen;
use std::env;
use std::path::PathBuf;
const HEADER_NAME: &str = "stingray_sdk.h";
fn main() {
println!("cargo:rerun-if-changed={}", HEADER_NAME);
let bindings = bindgen::Builder::default()
.header(HEADER_NAME)
.clang_arg("-Istingray_sdk/")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}

6
lib/dt_p2p/src/lib.rs Normal file
View file

@ -0,0 +1,6 @@
mod stingray_sdk;
#[cfg(test)]
mod tests {
use super::*;
}

View file

@ -0,0 +1,7 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(clippy::type_complexity)]
#![allow(unused)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

View file

@ -0,0 +1 @@
#include "engine_plugin_api/plugin_api.h"

View file

@ -0,0 +1,13 @@
Copyright 2017 Autodesk Inc. http://www.autodesk.com
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,66 @@
declare module "stingray" {
import 'common/js-extensions';
const stingray: Stingray;
export = stingray;
}
declare module "app" {
import 'angular-bootstrap';
import 'angular-growl';
var app: any;
export = app;
}
declare module "base" {
var baseFileName: string;
function _initModule(): Promise<any>;
function _loadModule(): Promise<any>;
function _keyBinding(): void;
export { baseFileName as name, _initModule as init, _loadModule as run, _keyBinding as initKeyBinding };
}
declare module "program" {
var baseFileName: string;
function loadSystem(): Promise<any>;
export { baseFileName as name, loadSystem as run };
}
declare module "service" {
function runService(): Promise<void>;
const name: string | boolean;
export { name, runService as run };
}
declare module "editor" {
export function run(doNotRunBaseModule?: boolean): any;
export function initKeyBinding(): void;
export const name = "editor";
}
declare module "window" {
import 'docking/docking-service';
import 'docking/docking-directive';
}
declare module "services/thumbnail-service" {
namespace ThumbnailService {
const DISCARDED_REQUEST: Promise<any>;
const THUMBNAIL_SIZE = 256;
class ThumbnailError extends Error {
name: string;
constructor(name: any, msg: any);
}
class Thumbnail {
path: string;
url: string;
time: number;
constructor(path: any, url: any);
}
class ThumbnailJob {
hash: number;
resourcePath: string;
reject: (reason: any) => void;
resolve: (value?: {} | PromiseLike<{}>) => void;
promise: Promise<{}>;
private resourceType;
private resourceName;
constructor(resourceName: any, resourceType: any);
post(): any;
}
function generateThumbnail(resourcePath: any): Promise<Thumbnail | ThumbnailError>;
}
export = ThumbnailService;
}

View file

@ -0,0 +1,271 @@
/**
* Stingray foundation APIs.
*/
interface Stingray {
config: string;
env: {
version: string;
coreDir: string;
}
/**
* Indicates if the system is ran through Team City.
*/
teamCity: any | boolean;
/**
* Checks if we are running in development mode.
*/
isDev: () => boolean;
/**
* Checks the framework is running tests.
* @returns {boolean} true if it is running tests.
*/
isRunningTests: () => boolean;
/**
* Extract query param value for the window URL chain (e.g. from current window to top window)
* @param {string} name - Name of the query param
* @param {boolean} [firstLevelOnly] - Only check the URL of the current window.
*/
getParameterByName: (name: string, firstLevelOnly?: boolean) => string|boolean;
/**
* Returns a GUID
* RFC 4122 Version 4 Compliant solution:
* http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
*/
guid: () => string;
/**
* @deprecated
* Checks if object is a promise
*/
isPromise: (promise: Promise<any>) => boolean;
prependToLogMessage: (type, message) => string;
/**
* Hijack logs to prepend [DEBUG|INFO|ERROR] tags
* @param {string} pageTitle - Page title used if the document don't have any.
*/
hijackConsole: (pageTitle: string) => void;
/**
* Returns an global angular service by name.
* @param serviceName {string} service to be fetched.
*/
getService: (serviceName: string) => Promise<any>;
/**
* Emit a global event in the system.
*/
emitEvent: (name: string, ...args) => Promise<any>;
loadNativeExtension: (path: string) => string;
unloadNativeExtension: (id: string) => boolean;
loadAsyncExtension: (path: string) => Promise<string>;
unloadAsyncExtension: (id: string) => Promise<any>;
hostExecute: (type: string, firstArg?: any) => Promise<any>;
openDevTools: () => void;
location: LocationApi;
host: HostApi;
fs: FileSystemApi;
path: PathApi;
}
/**
* Generic functions to manipulate page location.
*/
interface LocationApi {
removeParam: (paramName) => void;
addParam: (paramName, paramValue) => void;
toFilePath: (string) => string;
}
/**
* Various host interaction API.
*/
interface HostApi {
quit: (exitCode?: number) => Promise<any>;
getCommandLineSwitch: (name: string) => Promise<boolean | any>;
createService: (name, path) => Promise<any>;
setCursorStyle: (style: string) => Promise<boolean>;
openWindow: (url: string, id?: string, options?: object) => Promise<any>;
crash: () => {};
}
interface FileStats {
exists: boolean;
dir: string;
url: string;
size: number;
readonly: boolean;
hidden: boolean;
modified: number;
}
interface FileSystemApi {
exists: (path: string) => boolean;
stats: (path: string) => FileStats;
Filters: any;
FileNotify: any;
FileAction: any;
Permission: any;
}
/**
* Stingray path manipulation API.
*/
interface PathApi {
sep: string;
delimiter: string;
/**
* @description Extract the filename of a path
* @param {string} path
* @param {boolean} [withExtension=true] - Set to false if you want the extension to be omitted.
*/
basename: (path: string, withExtension: boolean) => string;
dirname: (path: string) => string;
join: (path: string, ...paths: string[]) => string;
absolute: (base: string, relative: string, isFileName?: boolean) => string;
clean: (path: string, addSeparatorsAtEnd?: boolean) => string;
resolve: (path: string) => string;
relative: (from: string, to: string) => string;
suffix: (path: string, noLeadingDot: boolean) => string;
ensureValid: (path: string) => string;
areEquals: (path1: string, path2: string) => boolean;
getFilePathWithoutExtension: (path: string) => string;
isFileOrFolderNameValid: (name: string) => boolean;
}
interface Promise<T> {
spread(a: (...args)=>PromiseLike<T>, b?:()=>Promise<T>): Promise<T>;
finally(a, b): Promise<T>;
}
interface String {
hashCode: () => number;
}
interface PromiseConstructor {
filter(array, promiseReturningFilter): Promise<any>;
map(collection, promiseReturningTransformer): Promise<any>;
series(items:any[]|Object, next:any, initialValue?:Promise<any>): Promise<any>;
while(predicate, action, result): Promise<any>;
require(modules:string[]): Promise<any>;
waterfall(funcs:Function[]):Promise<any>;
}
interface Console {
notice: Function;
}
interface CefRequest {
request: string;
persistent: boolean;
onSuccess: (result: string) => void;
onFailure: (code:number, msg:string) => void;
}
interface Window {
stingray: Stingray;
/**
* @typedef {object} CefRequest
* @property {string} request - JSON string sent to CEF as payload.
* @property {function} onSuccess - Callback if the CEF request succeeds.
* @property {function} onFailure - Callback if the CEF request fails.
*
* This function queries the CEF widget for a function.
* @name window.cefQuery
* @function
* @param {CefRequest} request - Request with success and failure callbacks
* @memberof window
*/
cefQuery: (request: CefRequest) => Promise<any>;
gc: () => void;
layoutId: string;
isClosing: boolean;
isMainWindow: boolean;
bindLayout: Function;
saveLayout: Function;
removeLayout: Function;
resetLayout: Function;
reloadTab: Function;
setTitle: Function;
id: string;
root: string;
rootHref: string;
coreRootHref: string;
debugging: boolean;
runningTest: boolean;
isProgram: boolean;
isService: boolean;
isFocused: boolean;
aboutToReload: boolean;
hide: ()=>void;
show: ()=>void;
}
interface Document {
// Document Editing Model Extensions
getParentTab: Function;
getToolName: () => string;
}
interface RequireInternals {
contexts: {_:{config:{paths:object}}};
}
interface Require {
s: RequireInternals;
resolvable: Function;
}
interface WindowEventMap extends GlobalEventHandlersEventMap {
"ConsoleMessage": CustomEvent;
}
interface OffHandler { (): any; promise: Promise<any>; }
// Module not (yet) ported to TypeScript
declare module 'lodash';
declare module 'common/asset-utils';
declare module 'common/keycodes';
declare module 'common/context-menu-utils';
declare module 'components/mithril-ext';
declare module 'components/button';
declare module 'components/textbox';
declare module 'extensions/parser-utils';
declare module 'extensions/services';
declare module 'extensions/events';
declare module 'extensions/menus';
declare module 'services/host-service';
declare module 'services/level-editing-service';
declare module 'services/log-service';
declare module 'services/settings-service';
declare module 'services/plugin-service';
declare module 'services/event-service';

View file

@ -0,0 +1,339 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/*
This file defines the Plugin API for the editor.
The plugin interface is based around a single function:
__declspec(dllexport) void *get_editor_plugin_api(unsigned plugin_api_id);
The API ID is an integer that uniquely identify a specific version of a particular service.
If the plugin can provide the service it returns a pointer to an API struct that contains
function pointers for using the service.
For ABI compatibility and simplicity, only C code is used in the interfaces.
This method is used both by the plugins to provide services to the editor and by the editor
to provide services to the plugins. For the second case, the editor sends a function:
void *get_editor_api(unsigned api_id);
To the plugins when they are initialized. The plugins can use this function to query for
editor interfaces.
If you need to make big changes to an API, so that it is no longer backwards compatible
with the old API, you should create a new API_ID identifier and make sure that the old
API_ID identifier still returns the old API. That way, the code will continue to work
with older plugins that use the old API, while still providing new functionality in the
new API.
Note that during development, the APIs may change frequently. It is only when we lock an
API down for public release that we need to be careful about version management and
backwards compatibility.
Note that all the functions in the APIs are not described in this header file, because in
many cases they are just thin wrappers around existing editor systems.
*/
/* Plugin API_IDs for the different services that a plugin can implement. */
enum EditorPluginApiID
{
EDITOR_PLUGIN_SYNC_API_ID = 0,
EDITOR_PLUGIN_ASYNC_API_ID
};
/* Editor API_IDs for the different services the editor offers. */
enum EditorApiID {
EDITOR_API_ID = 0,
EDITOR_API_V2_ID = 1,
CONFIGDATA_API_ID = 2,
EDITOR_LOGGING_API_ID = 3,
EDITOR_EVAL_API_ID = 4,
EDITOR_ASYNC_API_ID = 5
#if defined(_FUNCTIONAL_)
, EDITOR_API_V3_ID = 6
#endif
, EDITOR_ALLOCATOR_ID = 7
};
enum ProcessId
{
BROWSER = 0,
RENDERER
};
#define CONFIG_DATA_VALUE_TYPE_BITS 3
#define CONFIG_DATA_VALUE_TAG_BITS 29
/* Primitive config value types */
enum {
CD_TYPE_NULL = 0,
CD_TYPE_BOOL = 1,
CD_TYPE_NUMBER = 2,
CD_TYPE_STRING = 3,
CD_TYPE_HANDLE = 4,
CD_TYPE_ARRAY = 5,
CD_TYPE_OBJECT = 6,
CD_TYPE_TRUE, CD_TYPE_FALSE,
CD_TYPE_UNDEFINED = CD_TYPE_NULL
};
struct ConfigValueStruct {
struct {
unsigned type : CONFIG_DATA_VALUE_TYPE_BITS;
unsigned tag : CONFIG_DATA_VALUE_TAG_BITS;
};
union {
double _number;
bool _bool;
};
union {
void* _allocator;
void* _object;
void* _array;
void* _data;
};
};
typedef struct ConfigValueStruct* ConfigValue;
typedef const ConfigValue ConstConfigValue;
typedef ConfigValueStruct* ConfigValueArgs;
typedef ConfigValue* ConfigValueResult;
struct ConfigHandleObject;
typedef ConfigHandleObject* ConfigHandle;
/* Callback used to deallocate a config value user handle */
typedef void(*cd_handle_dealloc)(ConfigHandle handle);
/* This function can be used by the plugin to query for editor API. */
typedef void *(*GetEditorApiFunction)(unsigned api);
/*
This is the main interface provided by the plugins. The functions in this interface will
be called at various points during the editor's setup and shutdown sequence.
The plugin is not obligated to implement all these functions. You can return NULL for the
functions that you do not support.
*/
struct EditorPluginSyncApi
{
/* Called once the plugin has been loaded. */
void (*plugin_loaded)(GetEditorApiFunction get_editor_api);
/* Returns the name of the plugin. */
const char *(*get_name)();
/* Returns the version of the plugin. A version is a string of format 1.0.0.0 */
const char *(*get_version)();
/* Called when the plugins needs to be shutdown */
void (*shutdown)(GetEditorApiFunction get_editor_api);
};
struct EditorPluginAsyncApi
{
/* Called once the plugin has been loaded. */
void (*plugin_loaded)(GetEditorApiFunction get_editor_api);
/* Returns the name of the plugin. */
const char *(*get_name)();
/* Returns the version of the plugin. A version is a string of format 1.0.0.0 */
const char *(*get_version)();
/* Called when the plugins needs to be shutdown */
void (*shutdown)(GetEditorApiFunction get_editor_api);
};
struct EditorApi
{
typedef ConfigValue (*NativeFunctionHandler)(ConfigValueArgs args, int num);
/* Used to register a synchronous function that is executed on the render thread. Can be called using namespace.YOURFUNCTIONNAME(); */
bool (*register_native_function)(const char *ns, const char *name, NativeFunctionHandler handler);
/* Used to unregister a previously registered native function. */
bool (*unregister_native_function)(const char *ns, const char *name);
};
struct EditorApi_V2
{
typedef ConfigValue (*NativeFunctionHandler)(ConfigValueArgs args, int num, GetEditorApiFunction get_editor_api);
/* Used to register a synchronous function that is executed on the render thread. Can be called using namespace.YOURFUNCTIONNAME(); */
bool (*register_native_function)(const char *ns, const char *name, NativeFunctionHandler handler);
/* Used to unregister a previously registered native function. */
bool (*unregister_native_function)(const char *ns, const char *name);
};
struct EditorAsyncApi
{
typedef ConfigValue (*AsyncFunctionHandler)(ConfigValueArgs args, int num, GetEditorApiFunction get_editor_api);
/* Used to register an asynchronous function that is executed on the browser thread. Can be called using stingray.hostExecute('your-function-name', ...); */
bool (*register_async_function)(const char *name, AsyncFunctionHandler handler);
/* Used to unregister a previously registered async function. */
bool (*unregister_async_function)(const char *name);
/* Used to register an asynchronous function that is executed on the gui thread. Can be called using stingray.hostExecute('your-function-name', ...); */
bool (*register_async_gui_function)(const char *name, AsyncFunctionHandler handler);
/* Used to unregister a previously registered async gui function. */
bool (*unregister_async_gui_function)(const char *name);
};
struct EditorAllocatorObject;
typedef EditorAllocatorObject* EditorAllocator;
typedef void * (*EditorAllocateHandler) (size_t size, size_t align, void *param);
typedef size_t (*EditorDeallocateHandler) (void* ptr, void *param);
struct EditorAllocatorApi
{
EditorAllocator (*system_default)();
EditorAllocator (*create)(const char* name, EditorAllocateHandler alloc_handler, EditorDeallocateHandler dealloc_handler, void* user_data);
void (*destroy)(EditorAllocator);
};
struct ConfigDataApi
{
/* Create a new config value. It's type will be defined when you assign a value */
ConfigValue (*make)(EditorAllocator allocator);
/* Releases the memory used by the config value. */
void (*free)(ConfigValue value);
/* Creates a config value that is null. */
ConfigValue(*nil)();
/* Returns the type of a config value, see CD_TYPE_* */
int (*type)(ConfigValue value);
/* Returns the boolean value of the config value. */
int (*to_bool)(ConfigValue value);
/* Returns the numerical value of the config value. */
double (*to_number)(ConfigValue value);
/* Returns the string value of the config value. */
const char *(*to_string)(ConfigValue value);
/* Returns the user handle of the config value. */
ConfigHandle (*to_handle)(ConfigValue value);
/* Returns the deallocator of the user handle config value. */
cd_handle_dealloc (*to_handle_deallocator)(ConfigValue value);
/* Defines the config value as a boolean value. */
void(*set_bool)(ConfigValue value, int b);
/* Defines the config value as a numerical value. */
void(*set_number)(ConfigValue value, double n);
/* Defines the config value as a string value. */
void(*set_string)(ConfigValue value, const char *s);
/* Defines the config value as a user handle. */
void(*set_handle)(ConfigValue value, ConfigHandle handle, cd_handle_dealloc deallocator);
/* Defines the config value as an array. */
ConfigValueArgs(*set_array)(ConfigValue value, int size);
/* Defines the config value as an object. */
void(*set_object)(ConfigValue value);
/* Returns the number of element of the config value. */
int (*array_size)(ConfigValue arr);
/* Returns an element config value of a config value array. */
ConfigValue (*array_item)(ConfigValue arr, int i);
/* Adds an elements to a config value array. */
ConfigValue (*push)(ConfigValue array, ConfigValue item);
/* Returns the number of properties of a config value object. */
int (*object_size)(ConfigValue object);
/* Returns the property name of an object field. */
const char *(*object_key)(ConfigValue object, int i);
/* Returns the property value of an object field. */
ConfigValue(*object_value)(ConfigValue object, int i);
/* Returns the property value of an object field by matching its property
* key if it exists. */
ConfigValue(*object_lookup)(ConfigValue object, const char *key);
/* Adds a null property. */
ConfigValue(*add_nil)(ConfigValue object, const char *key);
/* Adds a boolean property. */
ConfigValue(*add_bool)(ConfigValue object, const char *key, int b);
/* Adds a numerical property. */
ConfigValue(*add_number)(ConfigValue object, const char *key, double n);
/* Adds a string property. */
ConfigValue(*add_string)(ConfigValue object, const char *key, const char* s);
/* Adds an object property. */
ConfigValue(*add_object)(ConfigValue object, const char *key, ConfigValue o);
/* Adds an array property. */
ConfigValue(*add_array)(ConfigValue object, const char *key, ConfigValue a);
/* Alias to object_lookup, to find a property by name. */
ConfigValue(*get)(ConfigValue object, const char *key);
/* Sets the config value of a property by name. */
ConfigValue(*set)(ConfigValue object, const char *key, ConfigValue value);
};
struct EditorLoggingApi
{
/* Used to print only in the dev tools console. */
void (*debug)(const char *message);
/* Used to print an information in the stingray console. */
void (*info)(const char *message);
/* Used to print a warning in the stingray console. */
void (*warning)(const char *message);
/* Used to print an error in the stingray console. */
void (*error)(const char *message);
};
struct EditorEvalApi
{
/* Used to evaluate a javascript code in the global context. `return_value` and `exception` are optional.
* If an exception is thrown and `exception` is not null, it will be populated with an object
* {'message': exception_message}.
*/
bool (*eval)(const char *js_code, ConfigValue return_value, ConfigValue exception);
};
#ifdef __cplusplus
}
#endif
#if defined(__cplusplus) && defined(_FUNCTIONAL_)
struct EditorApi_V3
{
typedef std::function<ConfigValue(ConfigValueArgs, int)> NativeFunctionHandler;
/* Used to register a synchronous function that is executed on the render thread. Can be called using namespace.YOURFUNCTIONNAME(); */
bool (*register_native_function)(const char *ns, const char *name, NativeFunctionHandler handler);
/* Used to unregister a previously registered native function. */
bool (*unregister_native_function)(const char *ns, const char *name);
};
#endif

View file

@ -0,0 +1,72 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ActorCApi
{
int (*is_collision_enabled) (ActorPtr actor);
int (*is_scene_query_enabled) (ActorPtr actor);
int (*is_gravity_enabled) (ActorPtr actor);
void (*set_collision_enabled) (ActorPtr actor, int enabled);
void (*set_scene_query_enabled) (ActorPtr actor, int enabled);
void (*set_gravity_enabled) (ActorPtr actor, int enabled);
int (*is_static) (ActorPtr actor);
int (*is_dynamic) (ActorPtr actor);
int (*is_physical) (ActorPtr actor);
int (*is_kinematic) (ActorPtr actor);
void (*set_kinematic) (ActorPtr actor, int enabled);
float (*mass) (ActorPtr actor);
float (*linear_damping) (ActorPtr actor);
float (*angular_damping) (ActorPtr actor);
void (*set_linear_damping) (ActorPtr actor, float value);
void (*set_angular_damping) (ActorPtr actor, float value);
CApiVector3 (*center_of_mass) (ActorPtr actor);
CApiVector3 (*position) (ActorPtr actor);
CApiQuaternion (*rotation) (ActorPtr actor);
CApiMatrix4x4 (*pose) (ActorPtr actor);
void (*teleport_position) (ActorPtr actor, ConstVector3Ptr position);
void (*teleport_rotation) (ActorPtr actor, ConstQuaternionPtr rotation);
void (*teleport_pose) (ActorPtr actor, ConstMatrix4x4Ptr pose);
void (*set_velocity) (ActorPtr actor, ConstVector3Ptr velocity);
void (*set_angular_velocity) (ActorPtr actor, ConstVector3Ptr velocity);
CApiVector3 (*velocity) (ActorPtr actor);
CApiVector3 (*angular_velocity) (ActorPtr actor);
CApiVector3 (*point_velocity) (ActorPtr actor, ConstVector3Ptr point);
void (*add_impulse) (ActorPtr actor, ConstVector3Ptr amount);
void (*add_velocity) (ActorPtr actor, ConstVector3Ptr amount);
void (*add_torque_impulse) (ActorPtr actor, ConstVector3Ptr amount);
void (*add_angular_velocity) (ActorPtr actor, ConstVector3Ptr amount);
void (*add_impulse_at) (ActorPtr actor, ConstVector3Ptr impulse, ConstVector3Ptr position);
void (*add_velocity_at) (ActorPtr actor, ConstVector3Ptr velocity, ConstVector3Ptr position);
void (*push) (ActorPtr actor, ConstVector3Ptr velocity, float mass);
void (*push_at) (ActorPtr actor, ConstVector3Ptr velocity, float mass, ConstVector3Ptr position);
int (*is_sleeping) (ActorPtr actor);
void (*wake_up) (ActorPtr actor);
void (*put_to_sleep) (ActorPtr actor);
void (*debug_draw) (ActorPtr actor, LineObjectPtr line_object, ConstVector4Ptr optional_color, ConstMatrix4x4Ptr optional_camera_pose);
UnitRef (*unit) (ActorPtr actor);
unsigned (*node) (ActorPtr actor);
void (*set_collision_filter) (ActorPtr actor, unsigned collision_filter_id32);
unsigned (*initial_shape_template) (ActorPtr actor, unsigned shape_index); // returns IdString32.id of the initial shape template name.
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,43 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ApplicationCApi
{
unsigned (*num_worlds) ();
WorldPtr (*world) (unsigned index);
WorldPtr (*new_world) (ConstWorldConfigPtr optional);
WorldPtr (*main_world) ();
void (*release_world) (WorldPtr);
void (*render_world) (WorldPtr, ConstCameraPtr, ConstViewportPtr, ConstShadingEnvironmentPtr, ConstWindowPtr optional);
CApiWorldConfig (*get_default_world_settings) ();
const char* (*build) ();
const char* (*platform) ();
const char* (*build_identifier) ();
const char* (*sysinfo) ();
ConstConfigRootPtr (*settings_root) ();
ViewportPtr (*create_viewport) (WorldPtr, unsigned viewport_template_name_id32);
void (*destroy_viewport) (WorldPtr, ViewportPtr);
unsigned (*can_get) (uint64_t type_id64, uint64_t name_id64);
void (*quit) (int exit_code);
double (*time_since_launch) ();
void (*sleep) (unsigned milliseconds);
void (*set_time_step_policy) (const struct TimeStepPolicyWrapper* const policies, unsigned num_policies);
struct TimeStepPolicyWrapper (*get_time_step_policy) (enum TimeStepPolicyType type);
/* The argv strings will be returned through the MultipleStringsBuffer you provide.
The function call returns the total number of bytes required to store all argv in the buffer. */
unsigned (*argv) (struct MultipleStringsBuffer* const out_result, unsigned buffer_size);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,11 @@
#pragma once
namespace plugin_c_api {namespace api_assert_global {
extern void crash_jump(int line, const char *file, const char *assert, const char *msg);
}}
#if defined(DEVELOPMENT)
#define API_ASSERT(test, msg, ...) if (!(test)) { plugin_c_api::api_assert_global::crash_jump(__LINE__, __FILE__, #test, stingray::eprintf(msg, ## __VA_ARGS__)); }
#else
#define API_ASSERT(test, msg, ...) ((void)0)
#endif

View file

@ -0,0 +1,58 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct CameraCApi
{
ConstVector3Ptr (*local_position)(ConstCameraPtr camera_pointer);
CApiQuaternion (*local_rotation)(ConstCameraPtr camera_pointer);
ConstVector3Ptr (*local_scale)(ConstCameraPtr camera_pointer);
ConstLocalTransformPtr (*local_pose)(ConstCameraPtr camera_pointer);
void (*set_local_position)(CameraPtr camera_pointer, UnitRef unit_ref, ConstVector3Ptr position_pointer);
void (*set_local_rotation)(CameraPtr camera_pointer, UnitRef unit_ref, ConstQuaternionPtr quaternion_pointer);
void (*set_local_scale)(CameraPtr camera_pointer, UnitRef unit_ref, ConstVector3Ptr scale_pointer);
void (*set_local_pose)(CameraPtr camera_pointer, UnitRef unit_ref, ConstLocalTransformPtr local_transform_pointer);
ConstVector3Ptr (*world_position)(ConstCameraPtr camera_pointer);
ConstMatrix4x4Ptr (*world_pose)(ConstCameraPtr camera_pointer);
// Performance-warning; Fetches the world_pose, extracts a Matrix3x3 from it and returns a copy on the stack.
CApiQuaternion (*world_rotation)(ConstCameraPtr camera_pointer);
float (*near_range)(ConstCameraPtr camera_pointer);
float (*far_range)(ConstCameraPtr camera_pointer);
void (*set_near_range)(CameraPtr camera_pointer, float near_range);
void (*set_far_range)(CameraPtr camera_pointer, float far_range);
float (*vertical_fov)(ConstCameraPtr camera_pointer, unsigned index);
void (*set_vertical_fov)(CameraPtr camera_pointer, float fov, unsigned index);
enum CameraProjectionType (*projection_type)(ConstCameraPtr camera_pointer);
void (*set_projection_type)(CameraPtr camera_pointer, enum CameraProjectionType camera_projection_type);
void (*set_orthographic_view)(CameraPtr camera_pointer, float min_x, float max_x, float min_z, float max_z, unsigned index);
void (*set_post_projection_transform)(CameraPtr camera_pointer, ConstMatrix4x4Ptr transform);
void (*set_frustum)(CameraPtr camera_pointer, float left, float right, float bottom, float top, unsigned index);
void (*set_frustum_half_angles)(CameraPtr camera_pointer, float left_tan, float right_tan, float bottom_tan, float top_tan, unsigned index);
float (*inside_frustum)(ConstCameraPtr camera_pointer, ConstVector3Ptr point, ConstWindowPtr optional_window);
CApiMatrix4x4 (*projection)(ConstCameraPtr camera_pointer, float aspect_ratio);
unsigned (*node)(ConstCameraPtr camera_pointer);
enum CameraMode (*mode)(ConstCameraPtr camera_pointer);
void (*set_mode)(CameraPtr camera_pointer, enum CameraMode mode);
void (*set_local)(CameraPtr camera_pointer, ConstMatrix4x4Ptr m, unsigned index);
CApiVector3 (*screen_to_world)(CameraPtr camera_pointer, ConstVector3Ptr point, float depth, unsigned screen_width, unsigned screen_height);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,63 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct DynamicScriptDataUnitApi
{
int (*has_data) (UnitRef, unsigned num_identifiers, ...);
void (*set_data) (UnitRef, DynamicScriptDataItem*, unsigned num_identifiers, ...);
DynamicScriptDataItem (*get_data) (UnitRef, unsigned num_identifiers, ...);
};
struct DynamicScriptDataCameraCApi
{
int (*has_data) (CameraPtr, unsigned num_identifiers, ...);
void (*set_data) (CameraPtr, DynamicScriptDataItem*, unsigned num_identifiers, ...);
DynamicScriptDataItem (*get_data) (CameraPtr, unsigned num_identifiers, ...);
};
struct DynamicScriptDataLevelCApi
{
int (*has_data) (LevelPtr, unsigned num_identifiers, ...);
void (*set_data) (LevelPtr, DynamicScriptDataItem*, unsigned num_identifiers, ...);
DynamicScriptDataItem (*get_data) (LevelPtr, unsigned num_identifiers, ...);
};
struct DynamicScriptDataWorldCApi
{
int (*has_data) (WorldPtr, unsigned num_identifiers, ...);
void (*set_data) (WorldPtr, DynamicScriptDataItem*, unsigned num_identifiers, ...);
DynamicScriptDataItem (*get_data) (WorldPtr, unsigned num_identifiers, ...);
};
struct DynamicScriptDataViewportCApi
{
int (*has_data) (ViewportPtr, unsigned num_identifiers, ...);
void (*set_data) (ViewportPtr, DynamicScriptDataItem*, unsigned num_identifiers, ...);
DynamicScriptDataItem (*get_data) (ViewportPtr, unsigned num_identifiers, ...);
};
struct DynamicScriptDataApplicationCApi
{
int (*has_data) (unsigned num_identifiers, ...);
void (*set_data) (DynamicScriptDataItem*, unsigned num_identifiers, ...);
DynamicScriptDataItem (*get_data) (unsigned num_identifiers, ...);
};
struct DynamicScriptDataCApi
{
struct DynamicScriptDataUnitApi* Unit;
struct DynamicScriptDataCameraCApi* Camera;
struct DynamicScriptDataLevelCApi* Level;
struct DynamicScriptDataWorldCApi* World;
struct DynamicScriptDataViewportCApi* Viewport;
struct DynamicScriptDataApplicationCApi* Application;
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,112 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Manages the lifetime of an entity. */
struct EntityManagerApi
{
EntityRef (*create)(const void *owner);
void (*destroy)(EntityRef entity);
int (*is_alive)(EntityRef entity);
EntityRef (*spawn)(WorldPtr world, uint64_t entity_name_id64, const char *optional_debug_entity_name, ConstMatrix4x4Ptr transform);
};
/* Opaque struct representing the component api extension. */
struct ComponentExtensionApi;
/* Component property api. */
typedef struct ComponentPropertyApi {
/* Set component propery value. */
void (*set_property)(ComponentPtr component, Instance i, EntityPropertyKey key, struct EntityPropertyValue value);
/* Get component property value. */
struct EntityPropertyValue (*get_property)(ComponentPtr component, Instance i, EntityPropertyKey key, struct AllocatorObject *temp_allocator);
} ComponentPropertyApi;
/* Component Api. */
typedef struct ComponentApi
{
/* Gets type name of the entity component. */
uint32_t (*type_name)();
/* Gets the component manager for the specified world. */
ComponentPtr (*component)(void *owner);
/* Creates a new component instance. */
Instance (*create)(ComponentPtr component, EntityRef entity, InstanceId instance_id);
/* Destroy component instance. */
void (*destroy)(ComponentPtr component, Instance i);
/* Destroy all instances of the entity. */
void (*destroy_all)(ComponentPtr component, EntityRef entity);
/* Gets the component instance from the specified component id. */
Instance (*lookup_instance)(ComponentPtr component, EntityRef entity, InstanceId id);
/* Gets the component instance id from the specified component instance. */
struct EntityInstanceId (*lookup_instance_id)(ComponentPtr component, Instance i);
/* Spawn component. */
void (*spawn)(ComponentPtr component, const EntityRef *entities, unsigned num_intances, const unsigned *entity_indicies, const unsigned *instance_ids, const char *data);
/* Set entity parent. */
void (*set_parent)(ComponentPtr component, const EntityRef *entities, unsigned num_entities, const unsigned *parent_index);
/* Called when the entity as been fully constructed and spawned. */
void (*spawned)(ComponentPtr component, const EntityRef *entities, unsigned num_entities);
/* Gets the first component instance for the entity. */
Instance (*first_instance)(ComponentPtr component, EntityRef entity);
/* Gets the next component instance. */
Instance (*next_instance)(ComponentPtr component, Instance i);
/* Gets the component property api. */
ComponentPropertyApi *(*get_property_api)();
/*
Retrieves a pointer to the component type specific API.
To use this cast the ComponentExtensionApi pointer to to the relevant definition represented in it's header file.
*/
struct ComponentExtensionApi *(*get_extension_api)();
} ComponentApi;
typedef ComponentApi *ComponentApiPtr;
struct EntityCApi
{
struct EntityManagerApi* Manager;
/*
Retrieves a pointer to the Component API registered with the specified name.
To use the member functions of the specified Component API cast the ComponentApiPtr to the relevant definition represented in it's header file."
*/
ComponentApiPtr (*component_api)(uint32_t name_id32);
/* Registers a pointer to a component api with the specified name, the caller is responsible for keeping it allocated. */
void (*register_component_api)(uint32_t name_id32, ComponentApiPtr component_api);
/* Returns true (1) if a component api with the specified name has already been registered. */
int (*has_component_api)(uint32_t name_id32);
/* Unregisters a component struct with the specified name. */
void (*unregister_component_api)(uint32_t name_id32);
/* Registers the entity component to the specified world. */
void (*register_entity_component)(WorldPtr world_pointer, ComponentPtr component, struct ComponentApi *component_api);
/* Unregisters the entity component from the specified world. */
void (*unregister_entity_component)(WorldPtr world_pointer, ComponentPtr component);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,56 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct GameSessionCApi_BoolPeerWrapper {
int bool_value;
PeerId peer;
};
struct GameSessionCApi
{
int (*in_session_self) (GameSessionPtr);
int (*in_session) (GameSessionPtr, PeerId);
PeerId (*host) (GameSessionPtr);
void (*make_host) (GameSessionPtr);
void (*shutdown_host) (GameSessionPtr);
int (*host_error_occured) (GameSessionPtr);
void (*migrate_host) (GameSessionPtr);
void (*disconnect_from_host) (GameSessionPtr);
void (*add_peer) (GameSessionPtr, uint64_t);
PeerId (*peer) (GameSessionPtr, unsigned index);
unsigned (*num_peers) (GameSessionPtr);
int (*peer_is_synchronizing) (GameSessionPtr, unsigned index);
UnitSynchronizerPtr (*unit_synchronizer) (GameSessionPtr);
GameObjectId (*create_game_object_with_default_values) (GameSessionPtr, unsigned unit_type_id32);
GameObjectId (*create_game_object) (GameSessionPtr, unsigned unit_type_id32, struct GameObjectField* field_array, unsigned num_elements);
void (*destroy_game_object) (GameSessionPtr, GameObjectId);
int (*game_object_exists) (GameSessionPtr, GameObjectId);
void (*remove_peer) (GameSessionPtr, PeerId, game_object_callback_function game_object_destroyed);
void (*leave) (GameSessionPtr);
struct GameSessionCApi_BoolPeerWrapper (*broken_connection) (GameSessionPtr);
struct GameSessionCApi_BoolPeerWrapper (*wants_to_leave) (GameSessionPtr);
void (*migrate_game_object) (GameSessionPtr, GameObjectId, PeerId new_owner, struct RPCCallback*);
unsigned (*num_game_objects) (GameSessionPtr);
GameObjectId (*game_object_id_from_index) (GameSessionPtr, unsigned);
PeerId (*game_object_owner) (GameSessionPtr, GameObjectId);
int (*game_object_owner_is_self) (GameSessionPtr, GameObjectId);
void (*set_game_object_fields) (GameSessionPtr, GameObjectId, struct GameObjectField* field_array, unsigned num_elements);
struct GameObjectField (*game_object_field) (GameSessionPtr, GameObjectId, unsigned field_name_id32);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,104 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct GuiCApi
{
unsigned (*triangle) (GuiPtr, ConstVector3Ptr p0, ConstVector3Ptr p1, ConstVector3Ptr p2, unsigned layer, ConstVector4Ptr optional_color,
MaterialPtr optional, ConstVector2Ptr optional_uv0, ConstVector2Ptr optional_uv1, ConstVector2Ptr optional_uv2);
void (*update_triangle) (GuiPtr, unsigned id, ConstVector3Ptr p0, ConstVector3Ptr p1, ConstVector3Ptr p2, unsigned layer, ConstVector4Ptr optional_color);
void (*destroy_triangle) (GuiPtr, unsigned id);
unsigned (*rect) (GuiPtr, ConstVector2Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color, MaterialPtr optional_material);
void (*update_rect) (GuiPtr, unsigned id, ConstVector2Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color);
void (*destroy_rect) (GuiPtr, unsigned id);
unsigned (*rect_3d) (GuiPtr, ConstMatrix4x4Ptr transform, ConstVector3Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color, MaterialPtr optional_material);
void (*update_rect_3d) (GuiPtr, unsigned id, ConstMatrix4x4Ptr transform, ConstVector3Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color);
void (*destroy_rect_3d) (GuiPtr, unsigned id);
unsigned (*bitmap) (GuiPtr, MaterialPtr, ConstVector2Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color, ConstVector2Ptr optional_uv00, ConstVector2Ptr optional_uv11);
void (*update_bitmap) (GuiPtr, unsigned id, MaterialPtr, ConstVector2Ptr position, unsigned layer,
ConstVector2Ptr size, ConstVector4Ptr optional_color, ConstVector2Ptr optional_uv00, ConstVector2Ptr optional_uv11);
void (*destroy_bitmap) (GuiPtr, unsigned id);
unsigned (*bitmap_3d) (GuiPtr, ConstMatrix4x4Ptr transform, MaterialPtr, ConstVector3Ptr position, unsigned layer, ConstVector2Ptr size,
ConstVector4Ptr optional_color, ConstVector2Ptr optional_uv00, ConstVector2Ptr optional_uv11);
void (*update_bitmap_3d) (GuiPtr, unsigned id, ConstMatrix4x4Ptr transform, MaterialPtr, ConstVector3Ptr position, unsigned layer,
ConstVector2Ptr size, ConstVector4Ptr optional_color, ConstVector2Ptr optional_uv00, ConstVector2Ptr optional_uv11);
void (*destroy_bitmap_3d) (GuiPtr, unsigned id);
unsigned (*text) (GuiPtr, const char* text, uint64_t font, float font_size, MaterialPtr, ConstVector2Ptr position, unsigned layer, float letter_spacing, ConstVector4Ptr optional_color);
void (*update_text) (GuiPtr, unsigned id, const char* text, uint64_t font, float font_size, MaterialPtr, ConstVector2Ptr position, unsigned layer, float letter_spacing, ConstVector4Ptr optional_color);
void (*destroy_text) (GuiPtr, unsigned id);
unsigned (*text_3d) (GuiPtr, const char* text_3d, uint64_t font, float font_size, MaterialPtr, ConstMatrix4x4Ptr transform,
ConstVector3Ptr position, unsigned layer, ConstVector4Ptr optional_color, float letter_spacing);
void (*update_text_3d) (GuiPtr, unsigned id, const char* text, uint64_t font, float font_size, MaterialPtr, ConstMatrix4x4Ptr transform,
ConstVector3Ptr position, unsigned layer, ConstVector4Ptr optional_color, float letter_spacing);
void (*destroy_text_3d) (GuiPtr, unsigned id);
struct TextExtentsResult (*text_extents) (GuiPtr, const char* text, uint64_t font, float font_size, float letter_spacing);
/* Fills the row_length_buffer with the length of each row after having processed the text with word wrapping.
Returns the total number of rows. */
unsigned (*word_wrap) (GuiPtr, const char* text, uint64_t font, float font_size, float width, const char* whitespace,
const char* soft_dividers, const char* return_dividers, float letter_spacing, unsigned* row_length_buffer, unsigned buffer_size);
unsigned (*video)(GuiPtr gui_pointer, VideoPlayerPtr video_player, MaterialPtr material_pointer,
ConstVector2Ptr pos, unsigned layer, ConstVector2Ptr opt_size, ConstVector4Ptr opt_color);
void (*update_video)(GuiPtr gui_pointer, unsigned id, VideoPlayerPtr video_player, MaterialPtr material_pointer,
ConstVector2Ptr pos, unsigned layer, ConstVector2Ptr opt_size, ConstVector4Ptr opt_color);
void (*destroy_video)(GuiPtr gui_pointer, unsigned id);
unsigned (*video_3d)(GuiPtr gui_pointer, VideoPlayerPtr video_player, ConstMatrix4x4Ptr transform, MaterialPtr material_pointer,
ConstVector3Ptr pos, unsigned layer, ConstVector2Ptr opt_size, ConstVector4Ptr opt_color);
void (*update_video_3d)(GuiPtr gui_pointer, unsigned id, VideoPlayerPtr video_player, ConstMatrix4x4Ptr transform, MaterialPtr material_pointer,
ConstVector3Ptr pos, unsigned layer, ConstVector2Ptr opt_size, ConstVector4Ptr opt_color);
void (*destroy_video_3d)(GuiPtr gui_pointer, unsigned id);
void (*set_visible) (GuiPtr, int visible);
int (*is_visible) (GuiPtr);
MaterialPtr (*material)(GuiPtr gui_pointer, uint64_t material_id64, const char *optional_debug_material_name);
MaterialPtr (*create_material)(GuiPtr gui_pointer, uint64_t material_id64, const char *optional_debug_material_name);
int (*has_all_glyphs) (GuiPtr, const char* text, uint64_t font);
void (*move) (GuiPtr, float x, float y);
void (*move_3d) (GuiPtr, ConstMatrix4x4Ptr transform);
void (*reset) (GuiPtr);
void (*resolution) (ViewportPtr optional_viewport, ConstWindowPtr optional_window, unsigned int *out_width, unsigned int *out_height);
CApiMatrix4x4 (*rotation_2d) (ConstVector2Ptr position_pointer, float angle, ConstVector2Ptr optional_pivot);
/* Equivalent to vector4(255, r, g, b). */
CApiVector4 (*color_rgb) (float r, float g, float b);
/* Equivalent to vector4(a, r, g, b). */
CApiVector4 (*color_argb) (float a, float r, float g, float b);
unsigned(*get_id) (GuiPtr);
void (*set_video_playback_speed)(VideoPlayerPtr video_player, float speed);
void (*set_video_loop)(VideoPlayerPtr video_player, unsigned loop);
unsigned (*video_has_audio)(VideoPlayerPtr video_player);
StreamSourcePtr (*video_sound_stream_source)(VideoPlayerPtr video_player);
void (*set_video_sound_stream_enabled)(VideoPlayerPtr video_player, unsigned enabled);
unsigned (*video_number_of_frames)(VideoPlayerPtr video_player);
unsigned (*video_current_frame)(VideoPlayerPtr video_player);
unsigned (*video_times_looped)(VideoPlayerPtr video_player);
/* Not available in Release builds. */
unsigned (*texture_size) (uint64_t resource_id64, unsigned int *out_width, unsigned int *out_height);
GuiThumbnailPtr (*thumbnail_load_texture)(unsigned num_textures, uint64_t* names_id64);
GuiThumbnailPtr (*thumbnail_load_dds)(const char *path, uint64_t name_id64);
void (*thumbnail_unload)(GuiThumbnailPtr thumbnail);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,51 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct InputControllerCApi;
struct KeyboardCApi;
struct PS4PadCApi;
struct TouchInputCApi;
struct XBoxOnePadCApi;
struct InputCApi
{
struct InputControllerCApi *InputController;
struct KeyboardCApi *Keyboard;
struct PS4PadCApi *PS4Pad;
struct TouchInputCApi *Touch;
struct XBoxOnePadCApi *XBoxOnePad;
void (*raw_input_queue) (struct RawInputEventWrapper* buffer, unsigned buffer_size);
unsigned (*raw_input_queue_size) ();
void (*add_remote_events)(unsigned event_count, struct RemoteEventWrapper* remote_events);
CApiInputControllerPtr (*keyboard)();
CApiInputControllerPtr (*mouse)();
CApiInputControllerPtr (*tablet)();
CApiInputControllerPtr (*touch_panel)(int index);
CApiInputControllerPtr (*simulated_touch_panel)();
int (*num_touch_panels)();
int (*num_pads)();
CApiInputControllerPtr (*pad)(int index);
void (*flush_controllers_state)();
CApiInputControllerPtr (*synergy_mouse)();
CApiInputControllerPtr (*synergy_keyboard)();
void (*synergy_connect)(struct SocketAddressWrapper* address, const char *client_name, int client_width, int client_height);
const char *(*synergy_clipboard)();
int (*num_windows_ps4_pads)();
CApiInputControllerPtr (*windows_ps4_pad)(int index);
void (*scan_for_windows_ps4_pads)();
void (*set_tablet_pen_service_properties)(uint64_t prop);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,49 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct InputControllerCApi
{
enum InputCategory (*category)(CApiInputControllerPtr input_controller);
const char *(*type)(CApiInputControllerPtr input_controller);
const char *(*name)(CApiInputControllerPtr input_controller);
unsigned (*num_buttons)(CApiInputControllerPtr input_controller);
float (*button)(CApiInputControllerPtr input_controller, unsigned id);
int (*pressed)(CApiInputControllerPtr input_controller, unsigned id);
int (*released)(CApiInputControllerPtr input_controller, unsigned id);
unsigned (*any_pressed)(CApiInputControllerPtr input_controller);
unsigned (*any_released)(CApiInputControllerPtr input_controller);
void (*set_down_threshold)(CApiInputControllerPtr input_controller, float threshold);
float (*down_threshold)(CApiInputControllerPtr input_controller);
int (*num_axes)(CApiInputControllerPtr input_controller);
struct CApiVector3 (*axis)(CApiInputControllerPtr input_controller, unsigned axis_index, struct DeadZoneSetting *optional_deadzone_setting);
void (*dead_zone)(CApiInputControllerPtr input_controller, unsigned axis_index, struct DeadZoneSetting *out_deadzone_setting);
void (*set_dead_zone)(CApiInputControllerPtr input_controller, unsigned axis_index, struct DeadZoneSetting *deadzone_setting);
void (*set_rumble_enabled)(CApiInputControllerPtr input_controller, unsigned enabled);
unsigned(*num_rumble_motors)(CApiInputControllerPtr input_controller);
void (*set_rumble)(CApiInputControllerPtr input_controller, unsigned motor_id, float value);
unsigned (*rumble_effect)(CApiInputControllerPtr input_controller, unsigned motor_id, struct RumbleParameters *rumble_parameters);
void (*stop_rumble_effect)(CApiInputControllerPtr input_controller, unsigned motor_id, unsigned rumble_effect_id);
unsigned (*is_rumble_effect_playing)(CApiInputControllerPtr input_controller, unsigned motor_id, unsigned rumble_effect_id);
void (*stop_all_rumble_effects)(CApiInputControllerPtr input_controller, unsigned motor_id);
const char *(*button_name)(CApiInputControllerPtr input_controller, unsigned button_id);
const char *(*button_locale_name)(CApiInputControllerPtr input_controller, unsigned button_id);
unsigned (*button_id)(CApiInputControllerPtr input_controller, unsigned button_name_id32);
const char *(*axis_name)(CApiInputControllerPtr input_controller, unsigned axis_id);
unsigned (*axis_id)(CApiInputControllerPtr input_controller, unsigned axis_name_id32);
const char *(*rumble_motor_name)(CApiInputControllerPtr input_controller, unsigned motor_id);
unsigned (*rumble_motor_id)(CApiInputControllerPtr input_controller, unsigned rumble_motor_name_id32);
unsigned (*active)(CApiInputControllerPtr input_controller);
unsigned (*connected)(CApiInputControllerPtr input_controller);
unsigned (*disconnected)(CApiInputControllerPtr input_controller);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,18 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct KeyboardCApi
{
const int *(*keystrokes)(CApiInputControllerPtr keyboard_input_controller, unsigned *out_num_keystrokes);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,47 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
enum LanCApi_LanLobbyState { LAN_LB_CREATING, LAN_LB_JOINING, LAN_LB_JOINED, LAN_LB_FAILED };
struct LanCApi
{
void (*init_client) (uint64_t network_config_id64, unsigned port, uint64_t peer_id);
void (*shutdown_client) ();
LanLobbyPtr (*create_lobby) (unsigned port, unsigned max_members);
LanLobbyPtr (*join_lobby) (const char* server_address, unsigned port);
void (*leave_lobby) (LanLobbyPtr);
enum LanCApi_LanLobbyState (*state) (LanLobbyPtr);
void (*set_data) (LanLobbyPtr, const char* key, const char* value);
const char* (*data) (ConstLanLobbyPtr, const char* key);
void (*set_game_session_host) (LanLobbyPtr, uint64_t peer_id64);
void (*set_game_session_host_to_none) (LanLobbyPtr);
uint64_t (*game_session_host) (ConstLanLobbyPtr);
uint64_t (*lobby_host) (ConstLanLobbyPtr);
unsigned (*num_members) (ConstLanLobbyPtr);
uint64_t (*member) (ConstLanLobbyPtr, unsigned index);
void (*kick) (LanLobbyPtr, uint64_t peer_id64);
void (*set_member_data) (LanLobbyPtr, const char* key, const char* value);
const char* (*own_data) (LanLobbyPtr, const char* key);
const char* (*member_data) (LanLobbyPtr, uint64_t peer_id64, const char* key);
LanLobbyBrowserPtr (*lobby_browser) ();
struct SocketAddressWrapper (*lobby_address) (ConstLanLobbyBrowserPtr, unsigned index);
unsigned (*num_lobbies) (ConstLanLobbyBrowserPtr);
const char* (*lobby_data) (LanLobbyBrowserPtr, unsigned index, const char* key);
void (*refresh) (LanLobbyBrowserPtr, unsigned port);
int (*is_refreshing) (ConstLanLobbyBrowserPtr);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,60 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct LevelCApi
{
WorldPtr (*world) (LevelPtr level_pointer);
void (*spawn_background) (LevelPtr level_pointer);
UnitRef (*unit_by_index) (LevelPtr level_pointer, unsigned index);
unsigned (*unit_index) (LevelPtr level_pointer, UnitRef unit_ref);
unsigned (*num_units) (LevelPtr level_pointer);
unsigned (*num_nested_levels) (LevelPtr level_pointer);
LevelPtr (*nested_level) (LevelPtr level_pointer, unsigned index);
unsigned (*num_entities) (LevelPtr level_pointer);
EntityRef (*entity) (LevelPtr level_pointer, unsigned index);
CApiVector3 (*random_point_inside_volume) (ConstLevelPtr level_pointer, unsigned volume_name_id32);
CApiVector3 (*next_random_point_inside_volume) (ConstLevelPtr level_pointer, unsigned volume_name_id32, int, int*);
int (*is_point_inside_volume) (ConstLevelPtr level_pointer, unsigned volume_name_id32, ConstVector3Ptr vector3_pointer);
int (*has_volume) (ConstLevelPtr level_pointer, unsigned volume_name_id32);
void (*flow_event) (LevelPtr level_pointer, unsigned event_name_id32);
unsigned (*flow_variable_type) (LevelPtr level_pointer, unsigned variable_name_id32);
void* (*flow_variable) (LevelPtr level_pointer, unsigned variable_name_id32);
void (*set_flow_variable) (LevelPtr level_pointer, unsigned variable_name_id32, void* value);
void (*trigger_event) (LevelPtr level_pointer, unsigned event_name_id32);
void (*trigger_level_loaded) (LevelPtr level_pointer);
void (*trigger_level_shutdown) (LevelPtr level_pointer);
void (*trigger_level_update) (LevelPtr level_pointer);
ConstMatrix4x4Ptr (*pose) (LevelPtr level_pointer);
ConstNavigationMeshPtr (*navigation_mesh)(ConstLevelPtr level_pointer);
struct Vector3ArrayWrapper (*spline)(LevelPtr level_pointer, unsigned spline_name_id32);
unsigned (*num_splines)(LevelPtr level_pointer);
struct Vector3ArrayWrapper (*spline_by_index)(LevelPtr level_pointer, unsigned index);
/* Begin development only functions */
void (*set_pose)(LevelPtr level_pointer, ConstMatrix4x4Ptr pose);
void (*set_visibility)(LevelPtr level_pointer, int visible);
struct OOBBWrapper (*box)(LevelPtr level_pointer);
unsigned (*num_internal_units)(LevelPtr level_pointer);
void (*internal_units)(LevelPtr level_pointer, UnitRef* internal_units);
/* End development only functions */
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,29 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct LineObjectCApi
{
void (*dispatch) (WorldPtr, LineObjectPtr);
void (*reset) (LineObjectPtr);
void (*add_line) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr from, ConstVector3Ptr to);
void (*add_cone) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr from, ConstVector3Ptr to, float radius, unsigned num_segments, unsigned num_bars);
void (*add_circle) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr center, float radius, ConstVector3Ptr normal, unsigned num_segments);
void (*add_sphere) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr center, float radius, unsigned num_segments, unsigned num_parts);
void (*add_half_sphere) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr center, float radius, ConstVector3Ptr normal, unsigned num_segments, unsigned num_parts);
void (*add_box) (LineObjectPtr, ConstVector4Ptr color, ConstMatrix4x4Ptr pose, float radius, ConstVector3Ptr half_extents);
void (*add_capsule) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr from, ConstVector3Ptr to, float radius, unsigned num_segments, unsigned num_circles, unsigned num_bars);
void (*add_axes) (LineObjectPtr, ConstMatrix4x4Ptr pose, float length);
/* Not available in Release builds. If camera_direction is supplied, back-facing triangles will get culled. */
void (*add_unit_meshes) (LineObjectPtr, uint64_t unit_resource_name_id64, const char *optional_debug_unit_resource_name, ConstVector4Ptr color, ConstMatrix4x4Ptr pose, ConstVector3Ptr optional_camera_direction);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,25 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct MaterialCApi
{
void (*set_scalar)(MaterialPtr material_pointer, unsigned variable_name_id32, float value);
void (*set_vector2)(MaterialPtr material_pointer, unsigned variable_name_id32, ConstVector2Ptr value);
void (*set_vector3)(MaterialPtr material_pointer, unsigned variable_name_id32, ConstVector3Ptr value);
void (*set_vector4)(MaterialPtr material_pointer, unsigned variable_name_id32, ConstVector4Ptr value);
unsigned (*material_id)(ConstMaterialPtr material_pointer);
void (*set_shader_pass_flag)(MaterialPtr material_pointer, unsigned flag_name_id32, int enabled);
void (*set_texture)(MaterialPtr material_pointer, unsigned slot_name_id32, uint64_t texture_resource_name_id64, const char *optional_debug_texture_resource_name);
void (*set_resource)(MaterialPtr material_pointer, unsigned slot_name_id32, ConstRenderResourcePtr render_resource);
void (*set_matrix4x4)(MaterialPtr material_pointer, unsigned variable_name_id32, ConstMatrix4x4Ptr value);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,38 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct MeshCApi
{
unsigned (*num_materials) (ConstMeshPtr);
unsigned (*find_material) (ConstMeshPtr, unsigned name_id32);
MaterialPtr (*material) (MeshPtr, unsigned index);
unsigned (*node) (ConstMeshPtr);
void (*set_shader_pass_flag) (MeshPtr, unsigned name_id32, int enabled);
struct BoundingVolumeWrapper (*bounding_volume) (MeshPtr);
void (*set_explicit_sort_value) (MeshPtr, unsigned sort_value);
ConstVector3Ptr (*local_position) (ConstMeshPtr);
struct CApiQuaternion (*local_rotation) (ConstMeshPtr);
ConstVector3Ptr (*local_scale) (ConstMeshPtr);
ConstLocalTransformPtr (*local_pose) (ConstMeshPtr);
void (*set_local_position) (MeshPtr, UnitRef, ConstVector3Ptr);
void (*set_local_rotation) (MeshPtr, UnitRef, ConstQuaternionPtr);
void (*set_local_scale) (MeshPtr, UnitRef, ConstVector3Ptr);
void (*set_local_pose) (MeshPtr, UnitRef, ConstLocalTransformPtr);
ConstVector3Ptr (*world_position) (ConstMeshPtr);
ConstMatrix4x4Ptr (*world_pose) (ConstMeshPtr);
// Performance-warning; Fetches the world_pose, extracts a Matrix3x3 from it and returns a copy on the stack.
struct CApiQuaternion (*world_rotation) (ConstMeshPtr);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,35 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct MoverCApi
{
UnitRef (*unit) (MoverPtr);
void (*set_position) (MoverPtr, ConstVector3Ptr);
CApiVector3 (*position) (MoverPtr);
void (*move) (MoverPtr, ConstVector3Ptr offset, float delta_time);
struct MoverSeparateResult (*separate) (MoverPtr, float permitted_move_threshold);
struct MoverFitsAtResult (*fits_at) (MoverPtr, ConstVector3Ptr, float permitted_move_threshold);
int (*collides_down) (MoverPtr);
int (*collides_up) (MoverPtr);
int (*collides_sides) (MoverPtr);
ActorPtr (*actor_colliding_down) (MoverPtr);
unsigned (*standing_frames) (MoverPtr);
unsigned (*flying_frames) (MoverPtr);
void (*set_collision_filter) (MoverPtr, unsigned collision_filter_id32);
float (*max_slope_angle) (MoverPtr);
void (*set_max_slope_angle) (MoverPtr, float);
float (*radius) (MoverPtr);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,32 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
enum NetworkCApi_LogLevel
{
NET_LOG_SILENT, NET_LOG_WARNINGS, NET_LOG_MESSAGES, NET_LOG_SPEW
};
struct NetworkCApi
{
GameSessionPtr (*create_game_session) ();
GameSessionPtr (*game_session) ();
void (*shutdown_game_session) ();
PeerId (*peer_self) ();
void (*update_receive) (float dt, struct RPCCallback* callback_functions);
void (*update_transmit) ();
void (*send_rpc) (unsigned message_name_id32, PeerId peer, struct RPCMessageParameter* parameter_array, unsigned num_parameters);
int (*fatal_error_occured) ();
void (*write_dump_tag) (const char* msg);
void (*set_log_level) (enum NetworkCApi_LogLevel);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,41 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct PhysicsWorldCApi
{
/*
The raycast, sweep and overlap function calls will return the total number of hits made as an unsigned.
Up to num_elements results will be stored in the pre-allocated out_buffer you provide.
*/
unsigned (*raycast) (struct CollisionHit* out_buffer, unsigned num_elements, PhysicsWorldPtr, ConstVector3Ptr from, ConstVector3Ptr direction,
enum RaycastType, enum ActorTemplate, unsigned collision_filter_id32, float length);
unsigned (*cast) (RaycastId, struct CollisionHit* out_buffer, unsigned num_elements, ConstVector3Ptr from, ConstVector3Ptr direction, float length);
/* Returns a unique id that can be used with the cast() function as many times as needed.
The caller is responsible for deallocating this by calling destroy_raycast(). */
RaycastId (*make_raycast) (PhysicsWorldPtr, enum RaycastType, enum ActorTemplate, unsigned collision_filter_id32);
void (*destroy_raycast) (RaycastId);
unsigned (*overlap) (ActorPtr* out_buffer, unsigned num_elements, PhysicsWorldPtr, enum OverlapShape, ConstVector3Ptr optional_position, ConstQuaternionPtr optional_rotation,
ConstMatrix4x4Ptr optional_pose, ConstVector3Ptr optional_size, enum ActorTemplate, unsigned collision_filter_id32);
unsigned (*linear_sphere_sweep) (struct CollisionHit* out_buffer, unsigned num_elements, PhysicsWorldPtr, ConstVector3Ptr from, ConstVector3Ptr to,
float radius, enum ActorTemplate, unsigned collision_filter_id32, int report_initial_overlap);
unsigned (*linear_capsule_sweep) (struct CollisionHit* out_buffer, unsigned num_elements, PhysicsWorldPtr, ConstVector3Ptr from, ConstVector3Ptr to, ConstQuaternionPtr rotation,
float radius, float half_height, enum ActorTemplate, unsigned collision_filter_id32, int report_initial_overlap);
unsigned (*linear_obb_sweep) (struct CollisionHit* out_buffer, unsigned num_elements, PhysicsWorldPtr, ConstVector3Ptr from, ConstVector3Ptr to, ConstVector3Ptr extents,
ConstQuaternionPtr rotation, enum ActorTemplate, unsigned collision_filter_id32, int report_initial_overlap);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,13 @@
#pragma once
#if defined(PS4)
#include <platforms/ps4/sdk/engine_plugin_api/c_api/c_api_ps4.h>
#else
#ifdef __cplusplus
extern "C" {
#endif
struct Ps4CApi;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,13 @@
#pragma once
#if defined(PS4)
#include <platforms/ps4/sdk/engine_plugin_api/c_api/c_api_ps4_error_dialog.h>
#else
#ifdef __cplusplus
extern "C" {
#endif
struct Ps4ErrorDialogCApi;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,13 @@
#pragma once
#if defined(PS4)
#include <platforms/ps4/sdk/engine_plugin_api/c_api/c_api_ps4_ime_dialog.h>
#else
#ifdef __cplusplus
extern "C" {
#endif
struct Ps4ImeDialogCApi;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,13 @@
#pragma once
#if defined(PS4)
#include <platforms/ps4/sdk/engine_plugin_api/c_api/c_api_ps4_msg_dialog.h>
#else
#ifdef __cplusplus
extern "C" {
#endif
struct Ps4MsgDialogCApi;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,13 @@
#pragma once
#if defined(PS4)
#include <platforms/ps4/sdk/engine_plugin_api/c_api/c_api_ps4_np_commerce_dialog.h>
#else
#ifdef __cplusplus
extern "C" {
#endif
struct Ps4NpCommerceDialogCApi;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,5 @@
#pragma once
#if defined(PS4)
#include <platforms/ps4/sdk/engine_plugin_api/c_api/c_api_ps4_types.h>
#endif

View file

@ -0,0 +1,18 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* This class is solely for managing PS4 Gamepads connected to a PC. */
struct PS4PadCApi
{
void (*set_light_bar_color)(CApiInputControllerPtr ps4pad_input_controller, ConstQuaternionPtr color);
unsigned (*user_id)(CApiInputControllerPtr ps4pad_input_controller);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,13 @@
#pragma once
#if defined(PS4)
#include <platforms/ps4/sdk/engine_plugin_api/c_api/c_api_psn.h>
#else
#ifdef __cplusplus
extern "C" {
#endif
struct PsnCApi;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,23 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct SaveSystemCApi
{
int (*exists) ();
void (*close) (SaveToken);
struct SaveSystemProgress (*get_progress) (SaveToken);
enum SaveSystemError (*get_loaded_data) (SaveToken, save_system_data_callback);
SaveToken (*auto_load) (const char* filename);
SaveToken (*auto_save) (const char* filename, struct SaveParameter* parameter_array, unsigned num_parameters);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,36 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ScatterSystemCApi
{
/* Default values for make_brush parameters are:
ScatterFadeMethod::SCATTER_FADE_POP
fade_range: 5.0
fade_from: (POP) 0.f (SCALE) 0.f (SLIDE_Z) -2.f
fade_to: (POP) 0.f (SCALE) 1.f (SLIDE_Z) 0.f
pool_size: UINT_MAX
preheat_pool: false
user_setting_density: true
*/
ScatterBrushId (*make_brush) (ScatterSystemPtr, uint64_t unit_id64, float spawn_distance, float unspawn_distance, enum ScatterFadeMethod,
float fade_range, float fade_from, float fade_to, unsigned pool_size, int preheat_pool, int user_setting_density);
void (*destroy_brush) (ScatterSystemPtr, ScatterBrushId);
void (*destroy_all_brushes) (ScatterSystemPtr);
ScatterUnitId (*spawn) (ScatterSystemPtr, ScatterBrushId, ConstVector3Ptr position, ConstQuaternionPtr optional_rotation);
void (*unspawn) (ScatterSystemPtr, ScatterUnitId);
ScatterObserverId (*make_observer) (ScatterSystemPtr, ConstVector3Ptr position, ConstQuaternionPtr optional_rotation);
void (*destroy_observer) (ScatterSystemPtr, ScatterObserverId);
void (*move_observer) (ScatterSystemPtr, ScatterObserverId, ConstVector3Ptr position, ConstQuaternionPtr optional_rotation);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,37 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct TouchInputCApi
{
CApiVector3 (*accelerator_resolution)(CApiInputControllerPtr touch_input_controller);
CApiVector2 (*resolution)(CApiInputControllerPtr touch_input_controller);
unsigned (*is_touch_up)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
unsigned (*is_touch_down)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
unsigned (*gesture_tap)(CApiInputControllerPtr touch_input_controller, CApiVector2 *out_location);
unsigned (*gesture_tap_sequence)(CApiInputControllerPtr touch_input_controller, CApiVector2 *out_location_sequence);
unsigned (*gesture_long_press)(CApiInputControllerPtr touch_input_controller, CApiVector2 *out_location);
unsigned (*gesture_pinch)(CApiInputControllerPtr touch_input_controller, TouchPinchGesture *out_pinch_gesture);
unsigned (*gesture_rotate)(CApiInputControllerPtr touch_input_controller, TouchRotationGesture *out_rotation_gesture);
enum SwipeDirection (*gesture_swipe)(CApiInputControllerPtr touch_input_controller);
unsigned (*is_primary)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
float (*size)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
float (*minor_axis_size)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
float (*major_axis_size)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
float (*pressure)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
enum TouchEdge (*edge)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
CApiVector3 (*location)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
CApiVector3 (*location_delta)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
unsigned (*has_contact)(CApiInputControllerPtr touch_input_controller, unsigned contact_id);
unsigned (*contacts)(CApiInputControllerPtr touch_input_controller, unsigned out_contact_ids[MAX_TOUCH_CONTACTS]);
unsigned (*num_contacts)(CApiInputControllerPtr touch_input_controller);
void (*set_enabled)(CApiInputControllerPtr simulated_touch_input_controller, unsigned enabled);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,627 @@
#pragma once
/*
* These types mainly exist to simplify the otherwise ambiguous abstracted void pointers used by the ScriptApi.
* They should be able to be casted to and treated the same way their respective plugin_foundation type is.
*/
/*
* All functions declared as "unsigned find_x(name)" will return UINT_MAX when no index was found.
*/
#include "../plugin_api_types.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef CApiStoryTeller* StoryTellerPtr;
typedef CApiWorld* WorldPtr;
typedef CApiLevel* LevelPtr;
typedef CApiScatterSystem* ScatterSystemPtr;
typedef CApiVectorField* VectorFieldPtr;
typedef CApiCamera* CameraPtr;
typedef CApiViewport* ViewportPtr;
typedef CApiShadingEnvironment* ShadingEnvironmentPtr;
typedef CApiActor* ActorPtr;
typedef void* TerrainPtr;
typedef CApiMover* MoverPtr;
typedef CApiMaterial* MaterialPtr;
typedef void* LanLobbyPtr;
typedef void* LanLobbyBrowserPtr;
typedef void* GameSessionPtr;
typedef CApiUnitSynchronizer* UnitSynchronizerPtr;
typedef CApiMesh* MeshPtr;
typedef void* JointPtr;
typedef void* LodObjectPtr;
typedef CApiLight* LightPtr;
typedef void* VehiclePtr;
typedef void* ClothPtr;
typedef CApiLineObject* LineObjectPtr;
typedef CApiGui* GuiPtr;
typedef CApiQuaternion* QuaternionPtr;
typedef CApiWindow* WindowPtr;
typedef CApiNavigationMesh* NavigationMeshPtr;
typedef CApiVideoPlayer* VideoPlayerPtr;
typedef CApiReplay* ReplayPtr;
typedef CApiCallbackData32* CallbackData32Ptr;
typedef CApiStreamSource* StreamSourcePtr;
typedef CApiTimpaniWorldInterface* TimpaniWorldInterfacePtr;
typedef CApiGuiThumbnail* GuiThumbnailPtr;
typedef CApiCaptureBuffer* CApiCaptureBufferPtr;
typedef CApiInputController* CApiInputControllerPtr;
typedef CApiTransformComponent* TransformComponentPtr;
typedef CApiMeshComponent* MeshComponentPtr;
typedef CApiActorComponent* ActorComponentPtr;
typedef CApiSceneGraphComponent* SceneGraphComponentPtr;
typedef CApiAnimationBlenderComponent* AnimationBlenderComponentPtr;
typedef CApiAnimationStateMachineComponent* AnimationStateMachineComponentPtr;
typedef CApiDebugNameComponent* DebugNameComponentPtr;
typedef CApiDataComponentPtr* DataComponentPtr;
typedef CApiRenderDataComponent* RenderDataComponentPtr;
typedef CApiTagComponent* TagComponentPtr;
typedef CApiComponent* ComponentPtr;
typedef CApiFlowComponent* FlowComponentPtr;
typedef CApiUnitComponent* UnitComponentPtr;
typedef CApiPhysicsWorld* PhysicsWorldPtr;
typedef const CApiWorldConfig* ConstWorldConfigPtr;
typedef const void* ConstConfigRootPtr;
typedef const CApiMatrix4x4* ConstMatrix4x4Ptr;
typedef const CApiVector2* ConstVector2Ptr;
typedef const CApiVector3* ConstVector3Ptr;
typedef const CApiVector4* ConstVector4Ptr;
typedef const CApiLocalTransform* ConstLocalTransformPtr;
typedef const CApiViewport* ConstViewportPtr;
typedef const CApiShadingEnvironment* ConstShadingEnvironmentPtr;
typedef const CApiWindow* ConstWindowPtr;
typedef const CApiCamera* ConstCameraPtr;
typedef const CApiWorld* ConstWorldPtr;
typedef const CApiMaterial* ConstMaterialPtr;
typedef const void* ConstRenderResourcePtr;
typedef const void* ConstLanLobbyPtr;
typedef const void* ConstLanLobbyBrowserPtr;
typedef const CApiQuaternion* ConstQuaternionPtr;
typedef const CApiLevel* ConstLevelPtr;
typedef const CApiMesh* ConstMeshPtr;
typedef const CApiNavigationMesh* ConstNavigationMeshPtr;
typedef CApiMaterialData* MaterialDataPtr;
typedef CApiUnitRef UnitRef;
typedef unsigned ParticleRef;
typedef unsigned GameObjectId;
typedef uint64_t PeerId;
typedef unsigned EntityRef;
typedef CApiInstance Instance;
typedef CApiInstanceId InstanceId;
typedef CApiInstanceWithId InstanceWithId;
typedef unsigned RaycastId;
typedef unsigned SaveToken;
typedef unsigned ScatterBrushId;
typedef unsigned ScatterUnitId;
typedef unsigned ScatterObserverId;
struct WindowRectWrapper {
int pos[4];
};
struct OOBBWrapper {
float tm[16];
float half_ext[3];
};
struct BoundingVolumeWrapper {
CApiVector3 min;
CApiVector3 max;
float radius;
};
struct MoverFitsAtResult {
int fits;
CApiVector3 pos;
};
struct MoverSeparateResult {
int is_colliding;
int can_be_resolved;
CApiVector3 position_after_resolving;
ActorPtr collides_with; /* Can be nullptr even if is_colliding is true, not all collidables are actors. */
};
/*
UINT_MAX represents a nil AnimationState value.
Currently up to 32 states can be returned, use num_states to find out how many are.
*/
enum {MAX_ANIMATION_STATES = 32};
struct AnimationStates {
unsigned states[MAX_ANIMATION_STATES];
unsigned num_states;
};
enum { MAX_ANIMATION_LAYER_SEEDS = 32 };
struct AnimationLayerSeeds {
unsigned seeds[MAX_ANIMATION_LAYER_SEEDS];
unsigned num_seeds;
};
struct AnimationLayerInfo {
float length;
double t;
};
enum { MAX_ANIMATION_EVENT_PARAMETERS = 1 };
enum { ANIMATION_EVENT_PERCENT_SYNC = 0 };
struct AnimationEventParameters
{
unsigned n;
unsigned keys[MAX_ANIMATION_EVENT_PARAMETERS];
float values[MAX_ANIMATION_EVENT_PARAMETERS];
};
/*
* Specifies how units will be faded in/out when un-/spawned by the ScatterSystem
* POP - pop in place
* SLIDE_Z - slide in along object's z-axis
* SCALE - scale to full size
*/
enum ScatterFadeMethod {SCATTER_FADE_POP, SCATTER_FADE_SLIDE_Z, SCATTER_FADE_SCALE};
/*
* Specifies how an animation should be blended with other animations.
* With BT_NORMAL the pose is lerped based on the blend strength.
* With BT_OFFSET the pose is applied as an offset.
*/
enum AnimationBlendType { ANIM_BT_NORMAL, ANIM_BT_OFFSET };
enum WindowKeystrokes
{
WINDOW_KEYSTROKE_WINDOWS,
WINDOW_KEYSTROKE_ALT_TAB,
WINDOW_KEYSTROKE_ALT_ENTER,
WINDOW_KEYSTROKE_ALT_F4,
};
/* Represents both the animation_root_mode and animation_bone_mode types since they are equal. */
enum AnimationBoneRootMode
{
BRM_IGNORE = 0,
BRM_POSITION = 1 << 0,
BRM_ROTATION = 1 << 1,
BRM_SCALE = 1 << 2,
BRM_TRANSFORM = BRM_POSITION | BRM_ROTATION | BRM_SCALE,
BRM_POSITION_AND_ROTATION = BRM_POSITION | BRM_ROTATION,
BRM_POSITION_AND_SCALE = BRM_POSITION | BRM_SCALE,
BRM_ROTATION_AND_SCALE = BRM_ROTATION | BRM_SCALE
};
/* Take note of the escape characters when reading. Example bone_names_list: "bone_hand_1\0bone_hand_2\0etc\0" */
struct BoneNamesWrapper {
const char* bone_names_list;
unsigned num_bones;
};
enum RawInputEventType
{
BUTTON_PRESSED,
BUTTON_RELEASED,
AXIS_CHANGED,
TOUCH_DOWN,
TOUCH_UP,
TOUCH_MOVE,
};
enum RawInputEventController
{
KEYBOARD,
MOUSE,
TOUCH_PANEL,
GAMEPAD,
PS4PAD
};
struct RawInputEventWrapper {
CApiVector3 delta_value;
unsigned char id;
unsigned char controller_index;
unsigned char type; /* RawInputEventType */
unsigned char controller; /* RawInputEventController */
};
enum RemoteEventType {
REMOTE_EVENT_TYPE_KEY_DOWN = 0,
REMOTE_EVENT_TYPE_KEY_UP = 1,
REMOTE_EVENT_TYPE_KEY_PRESS = 2,
REMOTE_EVENT_TYPE_MOUSE_DOWN = 3,
REMOTE_EVENT_TYPE_MOUSE_UP = 4,
REMOTE_EVENT_TYPE_MOUSE_MOVE = 5,
REMOTE_EVENT_TYPE_MOUSE_WHEEL = 6
};
struct RemoteEventWrapper {
unsigned input_type;
int button_id;
int x;
int y;
float dx;
float dy;
float dz;
int key_code;
};
enum InputCategory
{
INPUT_CATEGORY_GAMEPAD = 0,
INPUT_CATEGORY_TOUCH_PANEL = 1,
INPUT_CATEGORY_MOUSE = 2,
INPUT_CATEGORY_KEYBOARD = 3,
INPUT_CATEGORY_POINTER = 4
};
enum Keystroke
{
KS_CHAR_ARROW_LEFT = 1,
KS_CHAR_ARROW_RIGHT = 2,
KS_CHAR_ARROW_UP = 3,
KS_CHAR_ARROW_DOWN = 4,
KS_CHAR_INSERT = 5,
KS_CHAR_HOME = 6,
KS_CHAR_END = 7,
KS_CHAR_BACKSPACE = 8,
KS_CHAR_TAB = 9,
KS_CHAR_PG_UP = 11,
KS_CHAR_PG_DOWN = 12,
KS_CHAR_ENTER = 13,
KS_CHAR_F1 = 14,
KS_CHAR_F2 = 15,
KS_CHAR_F3 = 16,
KS_CHAR_F4 = 17,
KS_CHAR_F5 = 18,
KS_CHAR_F6 = 19,
KS_CHAR_F7 = 20,
KS_CHAR_F8 = 21,
KS_CHAR_F9 = 22,
KS_CHAR_F10 = 23, // magical, does not work
KS_CHAR_F11 = 24,
KS_CHAR_F12 = 25,
KS_CHAR_DELETE = 26,
KS_CHAR_ESCAPE = 27
};
struct TouchPinchGesture
{
unsigned began_last_frame;
unsigned ended_last_frame;
struct CApiVector2 location;
float scale;
float scale_per_second;
};
struct TouchRotationGesture
{
unsigned began_last_frame;
unsigned ended_last_frame;
struct CApiVector2 location;
float accumulated_rotation_rad;
float rotation_per_second_rad;
};
enum SwipeDirection { SWIPE_DIRECTION_NONE = -1, SWIPE_DIRECTION_RIGHT = 1, SWIPE_DIRECTION_LEFT = 2, SWIPE_DIRECTION_UP = 4, SWIPE_DIRECTION_DOWN = 8};
enum TouchEdge { TOUCH_EDGE_NONE = 0, TOUCH_EDGE_TOP = 0x01, TOUCH_EDGE_BOTTOM = 0x02, TOUCH_EDGE_LEFT = 0x04, TOUCH_EDGE_RIGHT = 0x08 };
enum { MAX_TOUCH_CONTACTS = 64 };
enum DeadZoneMode { DEADZONE_MODE_CIRCULAR, DEADZONE_MODE_INDEPENDENT, DEADZONE_MODE_RAW };
struct DeadZoneSetting {
enum DeadZoneMode mode;
float size;
};
struct RumbleParameters
{
float frequency; // Default 0.0f (frequency = 1.0f / period)
float offset; // Default 0.0f
float attack_level; // Default 1.0f
float sustain_level; // Default 1.0f
float attack; // Default 0.0f
float release; // Default 0.0f
float sustain; // Default 0.0f
float decay; // Default 0.0f
};
struct SocketAddressWrapper {
char address_and_port[22];
};
enum RPCParameterType
{
RPC_PARAM_BOOL_TYPE,
RPC_PARAM_INT_TYPE,
RPC_PARAM_FLOAT_TYPE,
RPC_PARAM_VECTOR3_TYPE,
RPC_PARAM_QUATERNION_TYPE,
RPC_PARAM_STRING_TYPE,
RPC_PARAM_IDSTRING32_TYPE,
RPC_PARAM_IDSTRING64_TYPE,
RPC_PARAM_RESOURCE_ID_TYPE,
RPC_PARAM_UINT_64_TYPE,
RPC_PARAM_ARRAY_BEGINS,
RPC_PARAM_ARRAY_ENDS
};
struct RPCMessageParameter
{
enum RPCParameterType type;
void* data_pointer;
};
struct GameObjectField
{
unsigned field_name_id32;
enum RPCParameterType type;
void* data_pointer;
};
typedef void (*game_object_callback_function) (int id, uint64_t sending_peer);
/* These member functions will receive callbacks from the engine during NetworkCApi's update_receive.
You're expected to assign all the function pointers before passing the struct. */
struct RPCCallback {
game_object_callback_function game_object_created;
game_object_callback_function game_object_destroyed;
game_object_callback_function game_object_migrated_to_me;
game_object_callback_function game_object_migrated_away;
void (*game_object_sync_done) (uint64_t sending_peer);
void (*game_session_disconnect) (uint64_t sending_peer);
/* Note: all data passed in the RPCMessageParameter array are temporary allocated and will get destroyed after the callback. */
void (*custom_callback) (uint64_t sending_peer, unsigned message_id32, struct RPCMessageParameter* parameter_array, unsigned num_parameters);
};
struct EntityInstanceId
{
EntityRef entity;
InstanceId instance_id;
};
/* Entity property type. */
enum EntityPropertyType
{
ENTITY_PROPERTY_TYPE_NIL,
ENTITY_PROPERTY_TYPE_BOOL,
ENTITY_PROPERTY_TYPE_FLOAT,
ENTITY_PROPERTY_TYPE_STRING,
ENTITY_PROPERTY_TYPE_FLOAT_ARRAY
};
/* The combined hash of the individual hashes of the separate key strings. */
typedef unsigned EntityPropertyKey;
struct EntityPropertyValueFloatArray
{
float *a;
unsigned n;
};
struct EntityPropertyValue
{
enum EntityPropertyType type;
union {
unsigned b;
float f;
const char *s;
struct EntityPropertyValueFloatArray a;
};
};
enum RaycastType { RAY_TYPE_ANY, RAY_TYPE_CLOSEST, RAY_TYPE_ALL };
enum ActorTemplate { ACTOR_T_STATIC = 1, ACTOR_T_DYNAMIC, ACTOR_T_BOTH };
enum OverlapShape { OVERLAP_SPHERE, OVERLAP_AABB, OVERLAP_OOBB, OVERLAP_CAPSULE };
struct CollisionHit
{
CApiVector3 position;
CApiVector3 normal;
float distance;
ActorPtr actor;
};
enum SaveSystemError
{
SAVEDATA_ERROR_ERROR_MISSING, /* The specified file does not exist. */
SAVEDATA_ERROR_INVALID_FILENAME, /* The specified filename is invalid. */
SAVEDATA_ERROR_IO_ERROR, /* A disk error occurred. */
SAVEDATA_ERROR_BROKEN, /* The saved data is corrupted. */
SAVEDATA_ERROR_UNSUPPORTED_VERSION, /* The data was saved using an old version, and cannot be loaded by this version. */
SAVEDATA_ERROR_INVALID_TOKEN, /* The specified token could not be found. */
SAVEDATA_ERROR_NOT_DONE, /* The specified token has not finished loading yet. */
SAVEDATA_ERROR_NONE /* No error occured. */
};
struct SaveSystemProgress
{
int is_done;
float progress;
enum SaveSystemError error_code;
};
enum SaveParameterType
{
SAVE_PARAM_TABLE_BEGIN,
SAVE_PARAM_TABLE_END,
SAVE_PARAM_NUMBER_FLOAT,
SAVE_PARAM_STRING,
SAVE_PARAM_BOOL,
SAVE_PARAM_VECTOR3,
SAVE_PARAM_VECTOR3_BOX,
SAVE_PARAM_MATRIX4X4,
SAVE_PARAM_MATRIX4X4_BOX,
SAVE_PARAM_NUMBER_DOUBLE
};
struct SaveParameter
{
enum SaveParameterType type;
void* data_pointer;
};
/* Note: You still have to close the token to free the data. */
typedef void (*save_system_data_callback) (struct SaveParameter* parameter_array, unsigned num_parameters);
/* Access the different null-terminated strings via s[i], i must be less than num_strings. The s must be pre-allocated by the user. */
struct MultipleStringsBuffer
{
unsigned num_strings;
char** s;
};
enum TimeStepPolicyType
{
TSP_FRAME_RATE,
TSP_THROTTLE_FRAME_RATE,
TSP_SMOOTHING,
TSP_DEBT_PAYBACK,
TSP_EXTERNAL_STEP_RANGE,
TSP_EXTERNAL_MULTIPLIER,
TSP_SYSTEM_STEP_RANGE,
TSP_CLEAR_HISTORY,
TSP_JUMP
};
struct TimeStepPolicyWrapper
{
enum TimeStepPolicyType type;
union {
int frames;
int fps;
float multiplier;
float time;
float min;
};
union {
int outliers;
float max;
};
union {
float lerp;
};
};
struct WindowOpenParameter
{
int x;
int y;
int width;
int height;
const char* optional_title;
WindowPtr optional_parent;
int explicit_resize;
int main_window;
int visible;
int pass_key_events_to_parent;
int layered;
int frameless;
};
struct Vector3ArrayWrapper
{
int count;
CApiVector3* v;
};
enum ReplayRecordMode
{
REPLAY_RECORD_MODE_DISABLED,
REPLAY_RECORD_MODE_TRANSFORM,
REPLAY_RECORD_MODE_SCENE_GRAPH
};
struct MaterialDecalDrawer {
unsigned material_id32;
unsigned drawer_id32;
};
struct TextExtentsResult
{
struct CApiVector2 min;
struct CApiVector2 max;
struct CApiVector2 caret;
};
enum WorldCApi_OrphanedParticlePolicy
{
WA_OPP_DESTROY_ORPHAN,
WA_OPP_STOP_SPAWNING_ORPHAN,
WA_OPP_UNLINK_ORPHAN
};
enum UnitCApi_VisibilityContext
{
UVC_DEFAULT = 1,
UVC_SHADOW_CASTER = 2,
UVC_OCCLUDER = 4,
UVC_ALL = 255
};
enum DynamicScriptDataType
{
D_DATA_NIL_TYPE,
D_DATA_BOOLEAN_TYPE,
D_DATA_NUMBER_TYPE,
D_DATA_STRING_TYPE,
D_DATA_CUSTOM_TVECTOR2 = 100,
D_DATA_CUSTOM_TVECTOR3,
D_DATA_CUSTOM_TVECTOR4,
D_DATA_CUSTOM_TMATRIX4X4,
D_DATA_CUSTOM_TUNITREFERENCE,
D_DATA_CUSTOM_TPOINTER,
D_DATA_CUSTOM_TLUAREF, /* Custom Lua reference is currently not supported via the C Api's DynamicScriptData. */
D_DATA_CUSTOM_ID64
};
typedef struct DynamicScriptDataItem {
const void *pointer;
enum DynamicScriptDataType type;
unsigned size;
} DynamicScriptDataItem;
enum CameraProjectionType {
CAMERA_PROJ_ORTHOGRAPHIC,
CAMERA_PROJ_PERSPECTIVE
};
enum CameraMode {
CAMERA_MODE_MONO,
CAMERA_MODE_STEREO
};
enum FlowType {
FLOW_NIL_TYPE = 0,
FLOW_UNIT_TYPE = 1,
FLOW_ACTOR_TYPE = 2,
FLOW_MOVER_TYPE = 3,
FLOW_VECTOR3_TYPE = 4,
FLOW_FLOAT_TYPE = 5,
FLOW_BOOL_TYPE = 6,
FLOW_STRING_TYPE = 7,
FLOW_ID64_TYPE = 8,
FLOW_QUATERNION_TYPE = 9,
FLOW_UNSIGNED_TYPE = 10,
FLOW_CAMERA_TYPE = 11,
FLOW_LIGHT_TYPE = 12,
FLOW_MESH_TYPE = 13,
FLOW_MATERIAL_TYPE = 14,
FLOW_ID32_TYPE = 15,
FLOW_ENTITY_TYPE = 16
};
#ifdef __cplusplus
};
#endif

View file

@ -0,0 +1,207 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct UnitCApi
{
ConstVector3Ptr (*local_position) (UnitRef, unsigned index);
CApiQuaternion (*local_rotation) (UnitRef, unsigned index);
ConstVector3Ptr (*local_scale) (UnitRef, unsigned index);
ConstLocalTransformPtr (*local_pose) (UnitRef, unsigned index);
void (*set_local_position) (UnitRef, unsigned index, ConstVector3Ptr);
void (*set_local_rotation) (UnitRef, unsigned index, ConstQuaternionPtr);
void (*set_local_scale) (UnitRef, unsigned index, ConstVector3Ptr);
void (*set_local_pose) (UnitRef, unsigned index, ConstLocalTransformPtr);
ConstVector3Ptr (*world_position) (UnitRef, unsigned index);
ConstMatrix4x4Ptr (*world_pose) (UnitRef, unsigned index);
// Performance-warning; Fetches the world_pose, extracts a Matrix3x3 from it and returns a copy on the stack.
CApiQuaternion (*world_rotation) (UnitRef, unsigned index);
void (*teleport_local_position) (UnitRef, unsigned index, ConstVector3Ptr);
void (*teleport_local_rotation) (UnitRef, unsigned index, ConstQuaternionPtr);
void (*teleport_local_scale) (UnitRef, unsigned index, ConstVector3Ptr);
void (*teleport_local_pose) (UnitRef, unsigned index, ConstLocalTransformPtr);
CApiVector3 (*delta_position) (UnitRef, unsigned index);
CApiQuaternion (*delta_rotation) (UnitRef, unsigned index);
struct CApiMatrix4x4 (*delta_pose) (UnitRef, unsigned index);
ActorPtr (*create_actor) (UnitRef, unsigned index, float inherit_velocity, const char* optional_debug_actor_name);
void (*destroy_actor) (UnitRef, unsigned index, const char* optional_debug_actor_name);
unsigned (*num_actors) (UnitRef);
unsigned (*find_actor) (UnitRef, unsigned actor_name_id32, const char* optional_debug_actor_name);
ActorPtr (*actor) (UnitRef, unsigned index, const char* optional_debug_actor_name);
unsigned (*num_movers) (UnitRef);
unsigned (*find_mover) (UnitRef, unsigned mover_name_id32);
MoverPtr (*set_mover) (UnitRef, unsigned index, const char *optional_debug_mover_name);
void (*set_mover_to_none) (UnitRef);
MoverPtr (*mover) (UnitRef);
struct MoverFitsAtResult (*mover_fits_at) (UnitRef unit_ref, unsigned index, ConstVector3Ptr position, float permitted_move_threshold, const char *optional_debug_mover_name);
void (*trigger_flow_event) (UnitRef, unsigned event_name_id32);
void* (*flow_variable) (UnitRef unit_ref, unsigned variable_name_id32, unsigned *out_type);
void (*set_flow_variable) (UnitRef, unsigned variable_name_id32, void* value);
void (*trigger_unit_spawned)(UnitRef unit_ref);
uint64_t (*set_material) (UnitRef, unsigned slot_name_id32, uint64_t material_resource_name_id64, const char *optional_debug_material_resource_name, unsigned debug_suppress_slot_assignment_warning);
uint64_t (*set_material_to_none) (UnitRef, unsigned slot_name_id32);
unsigned (*query_material)(UnitRef unit_ref, ConstVector3Ptr start, ConstVector3Ptr end, unsigned context_count, unsigned context_id32s[], unsigned out_material[]);
MaterialDataPtr (*save_instance_material_data)(UnitRef unit_ref);
void (*restore_instance_material_data)(UnitRef unit_ref, MaterialDataPtr data);
int (*is_using_material_set)(UnitRef unit_ref);
unsigned (*num_meshes) (UnitRef);
unsigned (*find_mesh) (UnitRef, unsigned mesh_name_id32);
MeshPtr (*mesh) (UnitRef, unsigned index, const char *optional_debug_mesh_name);
struct BoneNamesWrapper (*bones) (UnitRef);
CApiMatrix4x4 (*animation_wanted_root_pose) (UnitRef);
void (*animation_set_bones_lod) (UnitRef, unsigned);
enum AnimationBoneRootMode (*animation_root_mode) (UnitRef);
enum AnimationBoneRootMode (*animation_bone_mode) (UnitRef);
void (*set_animation_root_mode) (UnitRef, enum AnimationBoneRootMode);
void (*set_animation_bone_mode) (UnitRef, enum AnimationBoneRootMode);
unsigned (*animation_find_constraint_target) (UnitRef unit_ref, unsigned constraint_target_name_id32, const char *optional_debug_target_name);
unsigned (*animation_has_constraint_target)(UnitRef unit_ref, unsigned constraint_target_name_id32);
ConstMatrix4x4Ptr (*animation_get_constraint_target) (UnitRef, unsigned index);
void (*animation_set_constraint_target_pose) (UnitRef, unsigned index, ConstMatrix4x4Ptr);
void (*animation_set_constraint_target_position) (UnitRef, unsigned index, ConstVector3Ptr);
void (*animation_set_constraint_target_rotation) (UnitRef, unsigned index, ConstQuaternionPtr);
unsigned (*crossfade_animation) (UnitRef, uint64_t animation_name_id64, const char *optional_debug_animation_name, unsigned layer, float blend_time, int should_loop, enum AnimationBlendType);
unsigned (*is_crossfading_animation) (UnitRef);
void (*crossfade_animation_set_time) (UnitRef, unsigned id, float time, int should_cap_to_range);
void (*crossfade_animation_set_speed) (UnitRef, unsigned id, float speed);
void (*disable_animation_state_machine) (UnitRef);
void (*enable_animation_state_machine) (UnitRef);
void (*set_animation_state_machine) (UnitRef, uint64_t machine_name_id64, const char *optional_debug_machine_name);
int (*has_animation_state_machine) (UnitRef);
int (*has_animation_blender) (UnitRef);
int (*has_animation_event) (UnitRef, unsigned event_name_id32);
void (*animation_trigger_event) (UnitRef unit_ref, unsigned event_name_id32, const char *optional_debug_event_name);
void (*animation_trigger_event_with_parameters) (UnitRef unit_ref, unsigned event_name_id32, const char *optional_debug_event_name, struct AnimationEventParameters *parameters);
unsigned (*animation_find_variable) (UnitRef, unsigned variable_name_id32, const char *optional_debug_variable_name);
int (*animation_has_variable)(UnitRef unit_ref, unsigned variable_name_id32);
float (*animation_get_variable) (UnitRef, unsigned index);
void (*animation_set_variable) (UnitRef, unsigned index, float value);
void (*animation_set_state) (UnitRef, struct AnimationStates*);
struct AnimationStates (*animation_get_state) (UnitRef);
void(*animation_set_seeds) (UnitRef, struct AnimationLayerSeeds*);
struct AnimationLayerSeeds(*animation_get_seeds) (UnitRef);
struct AnimationLayerInfo (*animation_layer_info) (UnitRef, unsigned index);
void (*set_animation_merge_options) (UnitRef, float max_start_time, float max_drift, float clock_fidelity);
void (*animation_set_moving)(UnitRef unit_ref, unsigned frames);
int (*animation_get_curve_value)(UnitRef unit_ref, unsigned object_id32, unsigned parameter_id32, unsigned int float_index, float *out_curve_value);
void (*set_animation_logging)(UnitRef unit_ref, int enable);
void (*play_simple_animation)(UnitRef unit_ref, float from, float to, float speed, int loop, unsigned optional_group, const char *optional_debug_group_name);
void (*stop_simple_animation)(UnitRef unit_ref, unsigned optional_group, const char *optional_debug_group_name);
unsigned (*num_terrains) (UnitRef);
unsigned (*find_terrain) (UnitRef, unsigned terrain_name_id32);
TerrainPtr (*terrain) (UnitRef, unsigned index, const char *optional_debug_terrain_name);
void (*terrain_update_height_field)(UnitRef unit_ref, void *data);
JointPtr (*create_joint) (UnitRef, unsigned joint_name_id32, const char *optional_debug_joint_name);
void (*destroy_joint) (UnitRef, unsigned joint_name_id32);
JointPtr (*create_custom_joint) (UnitRef, unsigned joint_name_id32, ActorPtr optional_actor_1, ActorPtr optional_actor_2, ConstVector3Ptr optional_anchor_1,
ConstVector3Ptr optional_anchor_2, ConstVector3Ptr optional_global_anchor, ConstVector3Ptr optional_global_axis,
const char *optional_debug_joint_name);
// Length of key_id32_array depenends on the path for the property
void (*set_property) (UnitRef unit_ref, float value, unsigned key_id32_array[]);
float (*get_property) (UnitRef unit_ref, unsigned key_id32_array[]);
unsigned (*num_scene_graph_items) (UnitRef);
unsigned (*find_scene_graph_parent) (UnitRef, unsigned index);
void (*scene_graph_link) (UnitRef, unsigned index, unsigned parent_index);
void (*scene_graph_link_to_none) (UnitRef, unsigned index);
void (*copy_scene_graph_local_from) (UnitRef destination, UnitRef source);
unsigned (*num_lod_objects) (UnitRef);
unsigned (*find_lod_object) (UnitRef, unsigned lod_name_id32);
LodObjectPtr (*lod_object) (UnitRef, unsigned index, const char *optional_debug_lod_name);
unsigned (*num_steps_lod) (LodObjectPtr lod_obj_ptr);
void (*lod_step_range) (LodObjectPtr lod_obj_ptr, unsigned step_index, float out_range[2]);
unsigned (*num_mesh_lod_step) (LodObjectPtr lod_obj_ptr, unsigned step_index);
const unsigned* (*lod_step_meshes) (LodObjectPtr lod_obj_ptr, unsigned step_index);
unsigned (*num_lights) (UnitRef);
unsigned (*find_light) (UnitRef, unsigned light_name_id32);
LightPtr (*light) (UnitRef, unsigned index, const char *optional_debug_light_name);
void (*set_light_material)(UnitRef unit_ref, LightPtr light_pointer, uint64_t material_name);
VehiclePtr (*create_vehicle) (UnitRef);
void (*destroy_vehicle) (UnitRef);
int (*has_vehicle) (UnitRef);
VehiclePtr (*vehicle) (UnitRef);
void (*enable_physics) (UnitRef);
void (*disable_physics) (UnitRef);
void (*apply_initial_actor_velocities) (UnitRef, int should_wake_sleeping_actors);
void (*set_unit_visibility) (UnitRef, int enabled);
void (*set_mesh_visibility) (UnitRef unit_ref, unsigned index, unsigned visbility_context_id32, int enabled, const char *optional_debug_mesh_name, const char *optional_debug_visbility_context_name);
void (*set_cloth_visibility) (UnitRef unit_ref, unsigned index, unsigned state, unsigned visbility_context_id32, const char *optional_debug_cloth_name, const char *optional_debug_visbility_context_name);
void (*set_visibility_group) (UnitRef, unsigned group_name_id32, int enabled, const char *optional_debug_group_name);
int (*has_visibility_group) (UnitRef, unsigned group_name_id32);
ClothPtr (*create_cloth) (UnitRef unit_ref, unsigned index, const char *optional_debug_cloth_name);
void (*destroy_cloth) (UnitRef unit_ref, unsigned index, const char *optional_debug_cloth_name);
unsigned (*num_cloths) (UnitRef unit_ref);
unsigned (*find_cloth) (UnitRef unit_ref, unsigned cloth_name_id32);
ClothPtr (*cloth) (UnitRef unit_ref, unsigned index, const char *optional_debug_cloth_name);
unsigned (*num_cameras) (UnitRef);
unsigned (*find_camera) (UnitRef, unsigned camera_name_id32);
CameraPtr (*camera) (UnitRef, unsigned index, const char *optional_debug_camera_name);
int (*has_node) (UnitRef, unsigned node_name_id32);
unsigned (*node) (UnitRef, unsigned node_name_id32, const char *optional_debug_node_name);
int (*resource_has_node)(uint64_t unit_resource_id64, unsigned node_id32, const char *optional_debug_unit_resource_name);
unsigned (*resource_node)(uint64_t unit_resource_id64, unsigned node_id32, const char *optional_debug_unit_resource_name, const char *optional_debug_node_name);
// Performance-warning; Fetches the local_pose, extracts a Matrix4x4 from it and returns a copy on the stack.
CApiMatrix4x4 (*resource_local_pose)(uint64_t unit_resource_id64, unsigned node_index, const char *optional_debug_unit_resource_name);
WorldPtr (*world) (UnitRef);
LevelPtr (*level) (UnitRef);
int (*is_alive) (UnitRef);
uint64_t (*id_in_level) (UnitRef);
int (*is_of_resource_type) (UnitRef, uint64_t resource_name);
const char *(*unit_name_s)(UnitRef unit_ref);
struct OOBBWrapper (*box) (UnitRef unit_ref, unsigned ignore_invisible_meshes);
const char * (*debug_name)(UnitRef unit_ref);
void (*name_hash)(UnitRef unit_ref, char out_name[8]);
int (*is_a)(UnitRef unit_ref, uint64_t resource_id64);
void (*set_id_in_level)(UnitRef unit_ref, uint64_t id);
void (*draw_tree)(UnitRef unit_ref);
unsigned (*mesh_raycast)(UnitRef unit_ref, ConstVector3Ptr from, ConstVector3Ptr dir, float threshold, int include_hidden_meshes,
float *out_distance, CApiVector3 *out_normal_world);
unsigned (*mesh_pick_raycast)(UnitRef unit_ref, ConstVector3Ptr from, ConstVector3Ptr dir, float threshold, int include_hidden_meshes,
float *out_distance, CApiVector3 *out_normal_world, unsigned *out_best_mesh_index, unsigned *out_best_triangle_index);
unsigned (*mesh_closest_point_raycast)(UnitRef unit_ref, ConstVector3Ptr from, ConstVector3Ptr dir, float ray_length,
CApiVector3 *out_best_point_world, float *out_best_point_distance_along_ray, float *out_best_point_distance_to_ray);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,21 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct UnitSynchronizerCApi
{
void (*set_world) (UnitSynchronizerPtr unit_synchronizer_pointer, WorldPtr world_pointer);
UnitRef (*spawn_unit)(UnitSynchronizerPtr unit_synchronizer_pointer, unsigned type_id32, uint64_t unit_name_id64, ConstMatrix4x4Ptr transform, const char *optional_debug_unit_name);
void (*destroy_unit)(UnitSynchronizerPtr unit_synchronizer_pointer, UnitRef unit_ref);
UnitRef (*game_object_id_to_unit)(UnitSynchronizerPtr unit_synchronizer_pointer, GameObjectId id);
GameObjectId (*unit_to_game_object_id)(UnitSynchronizerPtr unit_synchronizer_pointer, UnitRef unit_ref);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,24 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct UtilitiesProfilerApi
{
void (*start) (const char* name);
void (*stop) ();
void (*record_statistics_float) (const char* name, float);
void (*record_statistics_vector3) (const char* name, ConstVector3Ptr);
};
struct UtilitiesCApi
{
struct UtilitiesProfilerApi* Profiler;
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,16 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ViewportCApi
{
void (*set_rect) (ViewportPtr, float x, float y, float width, float height);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,85 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void(*WindowCApi_KeyDownFunction)(void *obj, int virtual_key, int repeat_count, int scan_code, int extended, int previous_state);
typedef void(*WindowCApi_CharDownFunction)(void *obj, int char_code);
typedef void(*WindowCApi_KeyUpFunction)(void *obj, int virtual_key, int scan_code, int extended);
typedef void(*WindowCApi_MouseButtonFunction)(void *obj, int button);
typedef void(*WindowCApi_MouseMoveFunction)(void *obj, ConstVector3Ptr delta);
typedef void(*WindowCApi_CursorPosFunction)(void *obj, unsigned x, unsigned y);
typedef void(*WindowCApi_ActivateFunction)(void *obj, int active);
typedef void(*WindowCApi_ResizeFunction)(void *obj, WindowPtr window, int x, int y, int width, int heigh);
typedef void(*WindowCApi_ToggleFullscreenFunction)(void *obj, WindowPtr window);
typedef void(*WindowCApi_SetFocusFunction)(void *obj);
struct WindowCApi
{
int (*has_mouse_focus) (ConstWindowPtr optional);
int (*has_focus) (ConstWindowPtr optional);
void (*set_mouse_focus) (WindowPtr optional, int enabled);
void (*set_focus) (WindowPtr optional);
int (*show_cursor) (WindowPtr optional);
int (*clip_cursor) (WindowPtr optional);
void (*set_cursor) (WindowPtr optional, const char* optional_mouse_cursor);
void (*set_show_cursor) (WindowPtr optional, int enabled, int restore_cursor_pos);
void (*set_clip_cursor)(WindowPtr optional, int enabled);
int (*is_resizable)(ConstWindowPtr optional);
void (*set_resizable) (WindowPtr optional, int enabled);
void (*set_resolution) (WindowPtr optional, unsigned width, unsigned height);
float (*get_dpi_scale) ();
void (*set_title) (WindowPtr optional, const char* title);
int (*has_window) (ConstWindowPtr);
WindowPtr (*get_main_window)();
void (*minimize) (WindowPtr optional);
void (*maximize) (WindowPtr optional);
void (*restore) (WindowPtr optional);
int (*is_closing) (WindowPtr optional);
void (*close) (WindowPtr optional);
void (*trigger_resize) (WindowPtr optional);
void (*set_ime_enabled) (WindowPtr optional, int enabled);
void (*set_foreground) (WindowPtr optional);
void (*set_keystroke_enabled) (enum WindowKeystrokes, int enabled);
void (*fill_default_open_parameter) (struct WindowOpenParameter* out_result);
unsigned (*id) (WindowPtr optional);
WindowPtr (*open) (struct WindowOpenParameter* const);
struct WindowRectWrapper (*rect) (WindowPtr optional);
void (*set_rect)(WindowPtr optional, struct WindowRectWrapper rect);
void (*add_key_down_callback)(WindowPtr window, void *obj, WindowCApi_KeyDownFunction f);
void (*remove_key_down_callback)(WindowPtr window, void *obj, WindowCApi_KeyDownFunction f);
void (*add_char_down_callback)(WindowPtr window, void *obj, WindowCApi_CharDownFunction f);
void (*remove_char_down_callback)(WindowPtr window, void *obj, WindowCApi_CharDownFunction f);
void (*add_key_up_callback)(WindowPtr window, void *obj, WindowCApi_KeyUpFunction f);
void (*remove_key_up_callback)(WindowPtr window, void *obj, WindowCApi_KeyUpFunction f);
void (*add_mouse_down_callback)(WindowPtr window, void *obj, WindowCApi_MouseButtonFunction f);
void (*remove_mouse_down_callback)(WindowPtr window, void *obj, WindowCApi_MouseButtonFunction f);
void (*add_mouse_up_callback)(WindowPtr window, void *obj, WindowCApi_MouseButtonFunction f);
void (*remove_mouse_up_callback)(WindowPtr window, void *obj, WindowCApi_MouseButtonFunction f);
void (*add_mouse_move_callback)(WindowPtr window, void *obj, WindowCApi_MouseMoveFunction f);
void (*remove_mouse_move_callback)(WindowPtr window, void *obj, WindowCApi_MouseMoveFunction f);
void (*add_wheel_move_callback)(WindowPtr window, void *obj, WindowCApi_MouseMoveFunction f);
void (*remove_wheel_move_callback)(WindowPtr window, void *obj, WindowCApi_MouseMoveFunction f);
void (*add_cursor_pos_callback)(WindowPtr window, void *obj, WindowCApi_CursorPosFunction f);
void (*remove_cursor_pos_callback)(WindowPtr window, void *obj, WindowCApi_CursorPosFunction f);
void (*add_activate_callback)(WindowPtr window, void *obj, WindowCApi_ActivateFunction f);
void (*remove_activate_callback)(WindowPtr window, void *obj, WindowCApi_ActivateFunction f);
void (*add_resize_callback)(WindowPtr window, void *obj, WindowCApi_ResizeFunction f);
void (*remove_resize_callback)(WindowPtr window, void *obj, WindowCApi_ResizeFunction f);
void (*add_toggle_fullscreen_callback)(WindowPtr window, void *obj, WindowCApi_ToggleFullscreenFunction f);
void (*remove_toggle_fullscreen_callback)(WindowPtr window, void *obj, WindowCApi_ToggleFullscreenFunction f);
void (*add_set_focus_callback)(WindowPtr window, void *obj, WindowCApi_SetFocusFunction f);
void (*remove_set_focus_callback)(WindowPtr window, void *obj, WindowCApi_SetFocusFunction f);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,100 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Defines what should happen if a linked effect becomes orphaned. Should it
be destroyed, stop spawning or be unlinked and continue to spawn. */
struct WorldCApi
{
UnitRef (*spawn_unit) (WorldPtr world_pointer, uint64_t unit_name_id64, const char *optional_debug_unit_name, ConstMatrix4x4Ptr transform);
void (*destroy_unit) (WorldPtr world_pointer, UnitRef unit_ref);
unsigned (*num_units) (ConstWorldPtr world_pointer);
UnitRef (*unit_by_name) (WorldPtr world_pointer, uint64_t unit_name);
UnitRef (*unit_by_id) (WorldPtr world_pointer, uint64_t unit_id);
UnitRef (*unit_by_index) (WorldPtr world_pointer, unsigned index);
unsigned (*num_units_by_resource) (WorldPtr world_pointer, uint64_t resource_name);
unsigned (*units_by_resource)(WorldPtr world_pointer, uint64_t resource_name, unsigned max_unit_count, UnitRef* units);
void (*link_unit) (WorldPtr world_pointer, UnitRef child, unsigned child_node_index, UnitRef parent, unsigned parent_node_index);
void (*unlink_unit) (WorldPtr world_pointer, UnitRef child);
void (*update_unit) (WorldPtr world_pointer, UnitRef unit_ref);
ParticleRef (*create_particles) (WorldPtr world_pointer, uint64_t name_id64, const char *optional_debug_name, ConstMatrix4x4Ptr transform);
void (*destroy_particles) (WorldPtr world_pointer, ParticleRef id);
void (*stop_spawning_particles) (WorldPtr world_pointer, ParticleRef id);
int (*are_particles_playing) (ConstWorldPtr world_pointer, ParticleRef id);
void (*set_particles_collision_filter) (ConstWorldPtr world_pointer, uint32_t collision_filter_name);
void (*move_particles) (WorldPtr world_pointer, ParticleRef id, ConstMatrix4x4Ptr transform);
void (*link_particles) (WorldPtr world_pointer, ParticleRef id, UnitRef unit_ref, unsigned unit_node_index, ConstMatrix4x4Ptr local_pose, enum WorldCApi_OrphanedParticlePolicy orphaned_policy);
unsigned (*find_particles_variable) (ConstWorldPtr world_pointer, uint64_t name_id64, const char *optional_debug_name, unsigned variable_name_id32);
void (*set_particles_variable) (WorldPtr world_pointer, ParticleRef id, unsigned variable, ConstVector3Ptr value);
LevelPtr (*load_level) (WorldPtr world_pointer, uint64_t level_name_id64, const char *optional_debug_level_name, ConstMatrix4x4Ptr transform, uint64_t optional_level_id);
void (*destroy_level) (WorldPtr world_pointer, LevelPtr level_pointer);
unsigned (*num_levels) (ConstWorldPtr world_pointer);
LevelPtr (*level) (WorldPtr world_pointer, unsigned index);
void (*update) (WorldPtr world_pointer, float dt);
void (*update_animations) (WorldPtr world_pointer, float dt, CApiCallbackFunction optional_callback, CallbackData32Ptr callback_data32);
void (*update_scene) (WorldPtr world_pointer, float dt);
float (*delta_time) (ConstWorldPtr world_pointer);
float (*time) (ConstWorldPtr world_pointer);
StoryTellerPtr (*storyteller) (WorldPtr world_pointer);
VectorFieldPtr (*vector_field) (WorldPtr world_pointer, unsigned vector_field_name_id32);
ScatterSystemPtr (*scatter_system) (WorldPtr world_pointer);
ShadingEnvironmentPtr (*create_shading_environment) (WorldPtr world_pointer, uint64_t name_id64, const char *optional_debug_name);
ShadingEnvironmentPtr (*create_default_shading_environment) (WorldPtr world_pointer);
void (*destroy_shading_environment) (WorldPtr world_pointer, ShadingEnvironmentPtr shading_environment_pointer);
void (*set_shading_environment) (WorldPtr world_pointer, ShadingEnvironmentPtr shading_environment, uint64_t name_id64, const char *optional_debug_name);
LineObjectPtr (*create_line_object) (WorldPtr world_pointer, int disable_depth_test);
void (*destroy_line_object) (WorldPtr world_pointer, LineObjectPtr line_object_pointer);
void (*clear_permanent_lines) (WorldPtr world_pointer);
GuiPtr (*create_screen_gui) (WorldPtr world_pointer, ConstVector2Ptr optional_position, ConstVector2Ptr optional_scale, int immediate, int dock_right, int dock_top);
GuiPtr (*create_world_gui) (WorldPtr world_pointer, ConstMatrix4x4Ptr transform, float width, float height, int shadow_caster, int immediate);
void (*destroy_gui) (WorldPtr world_pointer, GuiPtr gui_pointer);
GuiPtr (*get_gui_by_id) (WorldPtr world_pointer, unsigned gui_id);
PhysicsWorldPtr (*physics_world) (WorldPtr world_pointer);
VideoPlayerPtr (*create_video_player) (WorldPtr world_pointer, uint64_t resource_id64, int loop);
void (*destroy_video_player) (WorldPtr world_pointer, VideoPlayerPtr video_player);
ConstMatrix4x4Ptr (*debug_camera_pose) (WorldPtr world_pointer);
/* Begin Development functions */
void (*set_flow_enabled) (WorldPtr world_pointer, int enable);
void (*set_editor_flow_enabled) (WorldPtr world_pointer, int enable);
unsigned (*num_particles)(WorldPtr world_pointer, unsigned* optional_effect_id, unsigned* optional_cloud_index);
void (*advance_particles_time)(WorldPtr world_pointer, unsigned id, float time);
void (*set_frustum_inspector_camera) (WorldPtr world_pointer, CameraPtr camera_pointer);
ReplayPtr (*replay)(WorldPtr world_pointer);
void (*start_playback)(ReplayPtr replay_ptr);
void (*stop_playback)(ReplayPtr replay_ptr);
int (*is_playing_back)(ReplayPtr replay_ptr);
int (*num_frames)(ReplayPtr replay_ptr);
int (*frame)(ReplayPtr replay_ptr);
void (*set_frame)(ReplayPtr replay_ptr, unsigned frame_index);
void (*record_debug_line)(ReplayPtr replay_ptr, ConstVector4Ptr color, ConstVector2Ptr p1, ConstVector2Ptr p2);
void (*record_screen_debug_text)(ReplayPtr replay_ptr, ConstVector4Ptr color, ConstVector2Ptr screen_position, const char* text);
void (*record_world_debug_text)(ReplayPtr replay_ptr, ConstVector4Ptr color, ConstVector3Ptr world_position, const char* text);
void (*set_unit_record_mode)(ReplayPtr replay_ptr, UnitRef unit, enum ReplayRecordMode replay_record_mode);
/* End Development functions */
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,16 @@
#pragma once
#include "c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct XBoxOnePadCApi
{
unsigned (*user_id)(CApiInputControllerPtr xboxone_pad_input_controller);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,25 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ActorComponentCApi
{
Instance (*create_capsule)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, float radius, float height,
unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32);
Instance (*create_plane)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, ConstVector3Ptr normal_pointer,
unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32);
Instance (*create_box)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, ConstVector3Ptr half_extents_pointer,
unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32);
Instance (*create_sphere)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, float radius,
unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32);
Instance (*create_mesh)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, void *physics_mesh,
unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,27 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct AnimationBlenderComponentCApi
{
unsigned (*crossfade)(AnimationBlenderComponentPtr comp, EntityRef e_ref, uint64_t animation_name_id64,
const char *optional_debug_animation_name, unsigned layer, float blend_time, int should_loop, enum AnimationBlendType anim_blend_type);
void (*set_time)(AnimationBlenderComponentPtr comp, EntityRef e_ref, unsigned id, float time, int should_cap_to_range);
void (*set_speed)(AnimationBlenderComponentPtr comp, EntityRef e_ref, unsigned id, float speed);
int (*is_crossfading)(AnimationBlenderComponentPtr comp, EntityRef e_ref);
void (*set_root_mode)(AnimationBlenderComponentPtr comp, EntityRef e_ref, enum AnimationBoneRootMode mode);
void (*set_bone_mode) (AnimationBlenderComponentPtr comp, EntityRef e_ref, enum AnimationBoneRootMode mode);
void (*set_bones_lod)(AnimationBlenderComponentPtr comp, EntityRef e_ref, unsigned lod_level);
CApiMatrix4x4 (*delta_transform)(AnimationBlenderComponentPtr comp, EntityRef e_ref);
enum AnimationBoneRootMode (*root_mode)(AnimationBlenderComponentPtr comp, EntityRef e_ref);
enum AnimationBoneRootMode (*bone_mode)(AnimationBlenderComponentPtr comp, EntityRef e_ref);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,25 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct AnimationStateMachineComponentCApi
{
int (*has_event)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned event_name_id32);
void (*trigger_event)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned event_name_id32, const char *optional_debug_event_name);
unsigned (*find_variable)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned variable_name_id32);
float (*get_variable)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index);
void (*set_variable)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index, float value);
void (*set_logging)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, int enabled);
void (*set_constraint_target)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index, ConstMatrix4x4Ptr pose);
void (*set_constraint_target_position)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index, ConstVector3Ptr pos);
void (*set_constraint_target_rotation)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index, ConstQuaternionPtr rot);
ConstMatrix4x4Ptr (*get_constraint_target)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,16 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct DataComponentCApi
{
unsigned (*instance_ids_with_tag)(DataComponentPtr comp, EntityRef e_ref, unsigned tag_id32, InstanceId *buffer, unsigned buffer_size);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,16 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct DebugNameComponentCApi
{
void (*set_debug_name)(DebugNameComponentPtr comp, EntityRef entity, const char *debug_name);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,20 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct FlowComponentCApi
{
/* Triggers an event on the Flow attached to the specified Flow component instance. */
void (*trigger_flow_event)(FlowComponentPtr component, Instance instance, unsigned event_id32);
/* Returns a pointer to an external flow variable and an identifier specifying its type. */
char *(*external_variable)(FlowComponentPtr component, Instance instance, unsigned variable_id32, unsigned *flow_variable_type);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,20 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct MeshComponentCApi
{
void (*set_mesh_resource)(MeshComponentPtr comp, Instance instance, uint64_t scene_resource_id64,
const char *optional_debug_scene_resource_name, unsigned mesh_name_id32, const char *optional_debug_mesh_name);
void (*set_mesh_object)(MeshComponentPtr comp, Instance instance, MeshPtr mesh_object);
void (*set_material)(MeshComponentPtr comp, Instance instance, unsigned key_id32, uint64_t material_resource_id64,
const char *optional_debug_material_resource_name, unsigned material_id32, const char *optional_debug_material_name);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,23 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct EntityWithInstanceId
{
EntityRef entity;
InstanceId instance_id;
};
struct RenderDataComponentCApi
{
unsigned (*instance_ids_with_tag)(RenderDataComponentPtr comp, unsigned tag, EntityWithInstanceId* out_buffer, unsigned buffer_size);
void (*add_instance_to_tags)(RenderDataComponentPtr comp, Instance instance, const unsigned* tags, const unsigned num_tags);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,32 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct SceneGraphComponentCApi
{
unsigned (*num_nodes)(SceneGraphComponentPtr comp, EntityRef e_ref);
unsigned (*node_index)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_name_id32);
unsigned (*parent)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index);
void (*set_local_position)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index, ConstVector3Ptr new_pos);
void (*set_local_rotation)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index, ConstQuaternionPtr new_rot);
void (*set_local_scale)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index, ConstVector3Ptr new_scale);
void (*set_local_pose)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index, ConstLocalTransformPtr new_pose);
ConstVector3Ptr (*local_position)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index);
CApiQuaternion (*local_rotation)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index);
ConstVector3Ptr (*local_scale)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index);
ConstLocalTransformPtr (*local_pose)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index);
ConstVector3Ptr (*world_position)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index);
CApiQuaternion (*world_rotation)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index);
ConstMatrix4x4Ptr (*world_pose)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,22 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct TagComponentCApi
{
// Fills the specified buffer with up to (buffer_size) number of entities that has the tag.
// Returns the total number of entities the tag has.
unsigned (*get_entities)(TagComponentPtr comp, unsigned tag_id32, EntityRef *buffer, unsigned buffer_size);
void (*add_tag)(TagComponentPtr comp, EntityRef e_ref, unsigned tag_id32);
void (*remove_tag)(TagComponentPtr comp, EntityRef e_ref, unsigned tag_id32);
int (*has_tag)(TagComponentPtr comp, EntityRef e_ref, unsigned tag_id32);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,37 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct TransformComponentCApi
{
// Fills the specified buffer with up to (buffer_size) number of children of the component.
// Returns the total number of children the component has.
unsigned (*children)(TransformComponentPtr comp, Instance the_parent, EntityRef *buffer, unsigned buffer_size);
EntityRef (*parent)(TransformComponentPtr comp, Instance the_child);
void (*unlink)(TransformComponentPtr comp, Instance the_child);
void (*link)(TransformComponentPtr comp, Instance the_child, Instance the_parent, ConstLocalTransformPtr child_local_pose);
void (*link_to_scene_graph)(TransformComponentPtr comp, Instance the_child, Instance the_parent, unsigned parent_node_index, ConstLocalTransformPtr child_local_pose);
void (*set_local_position)(TransformComponentPtr comp, Instance instance, ConstVector3Ptr new_pos);
void (*set_local_rotation)(TransformComponentPtr comp, Instance instance, ConstQuaternionPtr new_rot);
void (*set_local_scale)(TransformComponentPtr comp, Instance instance, ConstVector3Ptr new_scale);
void (*set_local_pose)(TransformComponentPtr comp, Instance instance, ConstLocalTransformPtr new_pose);
ConstVector3Ptr (*local_position)(TransformComponentPtr comp, Instance instance);
CApiQuaternion (*local_rotation)(TransformComponentPtr comp, Instance instance);
ConstVector3Ptr (*local_scale)(TransformComponentPtr comp, Instance instance);
ConstLocalTransformPtr (*local_pose)(TransformComponentPtr comp, Instance instance);
ConstVector3Ptr (*world_position)(TransformComponentPtr comp, Instance instance);
CApiQuaternion (*world_rotation)(TransformComponentPtr comp, Instance instance);
ConstMatrix4x4Ptr (*world_pose)(TransformComponentPtr comp, Instance instance);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,17 @@
#pragma once
#include "../c_api_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct UnitComponentCApi
{
/* Gets the unit attached to the unit component. */
CApiUnitRef (*unit)(UnitComponentPtr component, Instance instance);
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,19 @@
#pragma once
#if defined(WINDOWSPC)
#ifdef PLATFORM_64BIT
#define ENGINE_DEFAULT_PLUGIN_SUFFIX_BIT "w64"
#else
#define ENGINE_DEFAULT_PLUGIN_SUFFIX_BIT "w32"
#endif
#if defined(_DEBUG)
#define ENGINE_DEFAULT_PLUGIN_SUFFIX_CONFIG "debug"
#elif defined(DEVELOPMENT)
#define ENGINE_DEFAULT_PLUGIN_SUFFIX_CONFIG "dev"
#else
#define ENGINE_DEFAULT_PLUGIN_SUFFIX_CONFIG "release"
#endif
#define ENGINE_DEFAULT_PLUGIN_SUFFIX "_plugin" ENGINE_DEFAULT_PLUGIN_SUFFIX_BIT "_" ENGINE_DEFAULT_PLUGIN_SUFFIX_CONFIG ".dll"
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,136 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Opaque struct representing a memory allocator. */
struct AllocatorObject;
typedef struct CApiUnit CApiUnit;
typedef struct CApiWindow CApiWindow;
typedef struct CApiWorld CApiWorld;
typedef struct CApiLevel CApiLevel;
typedef struct CApiActor CApiActor;
typedef struct CApiMover CApiMover;
typedef struct CApiCamera CApiCamera;
typedef struct CApiViewport CApiViewport;
typedef struct CApiLight CApiLight;
typedef struct CApiMaterial CApiMaterial;
typedef struct CApiMesh CApiMesh;
typedef struct CApiShadingEnvironment CApiShadingEnvironment;
typedef struct CApiNavigationMesh CApiNavigationMesh;
typedef struct CApiPhysicsWorld CApiPhysicsWorld;
typedef struct CApiLineObject CApiLineObject;
typedef struct CApiGui CApiGui;
typedef struct CApiStoryTeller CApiStoryTeller;
typedef struct CApiVideoPlayer CApiVideoPlayer;
typedef struct CApiReplay CApiReplay;
typedef struct CApiVectorField CApiVectorField;
typedef struct CApiScatterSystem CApiScatterSystem;
typedef struct CApiMaterialData CApiMaterialData;
typedef struct CApiStreamSource CApiStreamSource;
typedef struct CApiTimpaniWorldInterface CApiTimpaniWorldInterface;
typedef struct CApiGuiThumbnail CApiGuiThumbnail;
typedef struct CApiCaptureBuffer CApiCaptureBuffer;
typedef struct CApiInputController CApiInputController;
typedef struct CApiUnitSynchronizer CApiUnitSynchronizer;
typedef struct CApiTransformComponent CApiTransformComponent;
typedef struct CApiMeshComponent CApiMeshComponent;
typedef struct CApiActorComponent CApiActorComponent;
typedef struct CApiSceneGraphComponent CApiSceneGraphComponent;
typedef struct CApiAnimationBlenderComponent CApiAnimationBlenderComponent;
typedef struct CApiAnimationStateMachineComponent CApiAnimationStateMachineComponent;
typedef struct CApiDebugNameComponent CApiDebugNameComponent;
typedef struct CApiDataComponentPtr CApiDataComponentPtr;
typedef struct CApiRenderDataComponent CApiRenderDataComponent;
typedef struct CApiTagComponent CApiTagComponent;
typedef struct CApiComponent CApiComponent;
typedef struct CApiFlowComponent CApiFlowComponent;
typedef struct CApiUnitComponent CApiUnitComponent;
typedef unsigned CApiUnitRef;
typedef unsigned CApiInstance;
typedef unsigned CApiInstanceId;
typedef struct CApiInstanceWithId
{
CApiInstance instance;
CApiInstanceId id;
} CApiInstanceWithId;
typedef struct CApiVector2
{
union { float x; float u; };
union { float y; float v; };
} CApiVector2;
typedef struct CApiVector3
{
float x, y, z;
} CApiVector3;
typedef struct CApiVector4
{
float x, y, z, w;
} CApiVector4;
typedef struct CApiQuaternion
{
float x,y,z,w;
} CApiQuaternion;
typedef struct CApiMatrix3x3
{
CApiVector3 x, y, z;
} CApiMatrix3x3;
typedef struct CApiMatrix4x4
{
float v[16];
} CApiMatrix4x4;
typedef struct CApiTransform
{
CApiQuaternion q;
CApiVector3 p;
} CApiTransform;
typedef struct CApiLocalTransform
{
CApiMatrix3x3 rot;
CApiVector3 pos;
CApiVector3 scale;
float dummy; // Force 16 byte alignment
} CApiLocalTransform;
typedef struct CApiPhysicsWorldSettings
{
char apex_cloth;
float apex_lod_resource_budget;
int step_frequency;
int max_substeps;
char async_timestep;
char swept_integration;
} CApiPhysicsWorldSettings;
typedef struct CApiWorldConfig {
char disable_physics;
char disable_sound;
char disable_rendering;
char enable_replay;
CApiPhysicsWorldSettings physics_world_settings;
unsigned long long decals;
} CApiWorldConfig;
typedef void (*CApiCallbackFunction)(const void*);
typedef struct CApiCallbackData32 {
char _data[32];
} CApiCallbackData32;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,73 @@
#pragma once
#include "c_api/c_api_input.h"
#include "c_api/c_api_world.h"
#include "c_api/c_api_application.h"
#include "c_api/c_api_unit.h"
#include "c_api/c_api_camera.h"
#include "c_api/c_api_material.h"
#include "c_api/c_api_lan.h"
#include "c_api/c_api_network.h"
#include "c_api/c_api_game_session.h"
#include "c_api/c_api_unit_synchronizer.h"
#include "c_api/c_api_level.h"
#include "c_api/c_api_utilities.h"
#include "c_api/c_api_psn.h"
#include "c_api/c_api_dynamic_script_data.h"
#include "c_api/c_api_entity.h"
#include "c_api/c_api_line_object.h"
#include "c_api/c_api_gui.h"
#include "c_api/c_api_physics_world.h"
#include "c_api/c_api_actor.h"
#include "c_api/c_api_mover.h"
#include "c_api/c_api_save_system.h"
#include "c_api/c_api_viewport.h"
#include "c_api/c_api_mesh.h"
#include "c_api/c_api_ps4.h"
#include "c_api/c_api_ps4_ime_dialog.h"
#include "c_api/c_api_ps4_msg_dialog.h"
#include "c_api/c_api_ps4_error_dialog.h"
#include "c_api/c_api_ps4_np_commerce_dialog.h"
#include "c_api/c_api_window.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ScriptApi
{
struct InputCApi *Input;
struct WorldCApi* World;
struct ApplicationCApi* Application;
struct UnitCApi* Unit;
struct CameraCApi* Camera;
struct MaterialCApi* Material;
struct LanCApi* Lan;
struct NetworkCApi* Network;
struct GameSessionCApi* GameSession;
struct UnitSynchronizerCApi* UnitSynchronizer;
struct LevelCApi* Level;
struct UtilitiesCApi* Utilities;
struct PsnCApi* Psn;
struct DynamicScriptDataCApi* DynamicScriptData;
struct EntityCApi* Entity;
struct LineObjectCApi* LineObject;
struct GuiCApi* Gui;
struct PhysicsWorldCApi* PhysicsWorld;
struct ActorCApi* Actor;
struct MoverCApi* Mover;
struct SaveSystemCApi* SaveSystem;
struct ViewportCApi* Viewport;
struct MeshCApi* Mesh;
struct Ps4CApi* Ps4;
struct Ps4ImeDialogCApi* Ps4ImeDialog;
struct Ps4MsgDialogCApi* Ps4MsgDialog;
struct Ps4ErrorDialogCApi* Ps4ErrorDialog;
struct Ps4NpCommerceDialogCApi* Ps4NpCommerceDialog;
struct WindowCApi* Window;
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,347 @@
#pragma once
#ifdef CAN_COMPILE
#include <stdarg.h>
#include <stdint.h>
#include <stddef.h>
enum SDB_ChannelType {
SDCT_FLOAT1 = 0,
SDCT_FLOAT2,
SDCT_FLOAT3,
SDCT_FLOAT4,
SDCT_MATRIX4x4,
SDCT_QUATERNION,
SDCT_FLOAT3_CMP_11_11_10,
SDCT_HALF1,
SDCT_HALF2,
SDCT_HALF3,
SDCT_HALF4,
SDCT_UBYTE4,
SDCT_SHORT1,
SDCT_SHORT2,
SDCT_SHORT3,
SDCT_SHORT4,
SDCT_COUNT
};
/* Direct Access, No extra memory copy */
struct SD_Scene;
struct SD_Indices;
struct SD_Geometry;
struct SD_GeometryMaterial;
struct SD_Animation;
struct SD_AnimationTake;
struct SD_Stream;
struct SD_Channel;
struct SD_BlendShapeTarget;
struct SD_Streams;
/* Indirect Access, Copy memory */
struct SDB_StringList {
uint32_t size;
const char **data;
};
struct SDB_Channel {
const char *name;
uint32_t index;
SDB_ChannelType type;
};
struct SDB_Stream {
uint32_t n_channels;
SDB_Channel *channels;
uint32_t size;
uint32_t stride;
uint32_t n_data;
uint8_t *data;
};
struct SDB_Node {
const char *name;
const char *parent;
SDB_StringList children;
float local[16];
SDB_StringList geometries;
uint8_t viewport_visible;
uint8_t has_local_mirroring;
};
struct SDB_IndicesStream {
uint32_t n_indices;
uint32_t *indices;
};
struct SDB_Indices {
uint32_t n_indices;
uint32_t n_streams;
SDB_IndicesStream *streams;
};
struct SDB_Joint {
const char *name;
float inv_bind_matrix[16];
};
struct SDB_Skin {
const char *name;
uint32_t max_affecting_bones;
uint32_t n_joints;
SDB_Joint *joints;
};
struct SDB_GeometryInstance {
const char *name;
const char *geometry;
SDB_StringList materials;
};
struct SDB_GeometryMaterial {
const char *name;
uint32_t n_primitives;
uint32_t *primitives;
};
struct SDB_GeometryBlendShapeTarget {
const char *name;
uint32_t n_streams;
SDB_Stream *streams;
};
struct SDB_Geometry {
const char *name;
uint32_t n_streams;
SDB_Stream *streams;
SDB_Indices indices;
const char *skin;
uint32_t n_materials;
SDB_GeometryMaterial *materials;
uint32_t n_primitive_smoothing;
uint32_t *primitive_smoothing;
uint32_t n_blend_shape_targets;
SDB_GeometryBlendShapeTarget *blend_shape_targets;
uint8_t shadow_caster;
uint32_t n_vertex_position_remapping;
uint32_t *vertex_position_remapping;
uint32_t n_vertex_normal_remapping;
uint32_t *vertex_normal_remapping;
};
enum SDB_LightDefinitionType {
OMNI = 0,
SPOT = 1,
BOX = 2,
DIRECTIONAL = 3
};
struct SDB_Light {
const char *name;
SDB_LightDefinitionType type;
float color[4];
float falloff_start;
float falloff_end;
float spot_angle_start;
float spot_angle_end;
uint8_t cast_shadow;
};
enum SDB_CameraDefinitionType {
ORTHOGRAPHIC,
PERSPECTIVE
};
struct SDB_Camera {
const char *name;
SDB_CameraDefinitionType type;
float near_plane;
float far_plane;
float vertical_fov;
};
struct SDB_Animation {
const char *node;
const char *parameter;
uint32_t n_times;
float *times;
SDB_Stream data;
};
struct SDB_AnimationTake {
const char *name;
float start_time;
float end_time;
uint32_t nb_samples;
uint32_t n_animations;
SDB_Animation *animations;
};
struct SDB_SurfaceMaterialProperty {
const char *name;
uint32_t n_integers;
int integer;
uint32_t n_floats;
float floats[4];
const char *value_string;
SDB_StringList textures;
};
struct SDB_SurfaceMaterialProperties {
uint32_t size;
SDB_SurfaceMaterialProperty *data;
};
enum SDB_SurfaceMaterialDefinitionType {
LAMBERT = 0,
PHONG = 1,
SHADER = 2
};
struct SDB_SurfaceMaterial {
const char *name;
SDB_SurfaceMaterialDefinitionType type;
SDB_SurfaceMaterialProperties properties;
uint32_t nb_influences;
};
struct SDB_Texture {
const char *name;
const char *file_path;
const char *relative_path;
uint8_t embedded;
float uv_offset[2];
float uv_scale[2];
float uv_rotation;
};
struct SDB_LevelOfDetailStep {
SDB_StringList nodes;
float min_pct;
float max_pct;
};
struct SDB_LevelOfDetail {
const char *name;
const char *orientation_node;
const char *bounding_volume;
uint8_t requires_predefined_pct;
uint32_t n_steps;
SDB_LevelOfDetailStep *steps;
};
enum SDB_SceneImportTangents {
TANGENTS_IMPORT,
TANGENTS_MIKKTSPACE
};
struct SDB_SceneImportOptions {
uint8_t combine_meshes;
uint8_t combine_meshes_by_material;
uint8_t reverse_forward_axis;
uint8_t skip_create_extra_root;
uint8_t skip_textures;
uint8_t skip_lights;
uint8_t skip_cameras;
uint8_t create_missing_uvs;
SDB_SceneImportTangents tangents;
};
struct SDB_Property {
const char *first;
const char *second;
};
struct SDB_Nodes {
uint32_t size;
SDB_Node *data;
};
struct SDB_GeometryInstances {
uint32_t size;
SDB_GeometryInstance *data;
};
struct SDB_Geometries {
uint32_t size;
SDB_Geometry *data;
};
struct SDB_Lights {
uint32_t size;
SDB_Light *data;
};
struct SDB_Cameras {
uint32_t size;
SDB_Camera *data;
};
struct SDB_Skins {
typedef SDB_Skin value_type;
uint32_t size;
SDB_Skin *data;
};
struct SDB_SurfaceMaterials {
uint32_t size;
SDB_SurfaceMaterial *data;
};
struct SDB_Textures {
uint32_t size;
SDB_Texture *data;
};
struct SDB_LevelOfDetails {
uint32_t size;
SDB_LevelOfDetail *data;
};
struct SDB_AnimationTakes {
uint32_t size;
SDB_AnimationTake *data;
};
struct SDB_Properties {
uint32_t size;
SDB_Property *data;
};
struct SDB_SceneDatabase {
SDB_Nodes nodes;
SDB_StringList roots;
SDB_GeometryInstances geometry_instances;
SDB_Geometries geometries;
SDB_Lights lights;
SDB_Cameras cameras;
SDB_Skins skins;
SDB_SurfaceMaterials materials;
SDB_Textures textures;
SDB_LevelOfDetails lods;
SDB_AnimationTakes anim_takes;
const char *source_path;
SDB_SceneImportOptions import_options;
SDB_Properties properties;
};
struct SceneDatabaseApi
{
void (*scene)(SD_Scene *scene, SDB_SceneDatabase *dest, struct AllocatorObject *allocator);
void (*set_scene)(SD_Scene *scene, const SDB_SceneDatabase *source);
void (*geometries)(SD_Scene *scene, SDB_Geometries *dest, struct AllocatorObject *allocator);
const char * (*source_path)(const SD_Scene *scene);
void (*set_source_path)(SD_Scene *scene, const char *text);
SDB_SceneImportOptions (*import_options)(SD_Scene *scene);
void (*set_import_options)(SD_Scene *scene, const SDB_SceneImportOptions *source);
/* Utilities */
SD_Scene * (*create)(struct DataCompileParameters *params, const char *resource_name);
void (*destroy)(SD_Scene *scene);
uint32_t (*channel_size)(SDB_ChannelType channel_type);
void (*apply_modifiers)(SD_Scene *scene, const char *platform_name, const char *resource_name, bool modify_tangents);
};
#endif /* CAN_COMPILE */

View file

@ -0,0 +1,106 @@
#pragma once
#include "../engine_plugin_api/plugin_api.h"
#define _XKEYCHECK_H
#define alignof(x) __alignof(x)
namespace stingray_plugin_foundation {
// Abstract base class for allocators.
//
// Allocators can be thread-safe or not, see the separate documentation for each
// alloactor.
class Allocator
{
Allocator(const Allocator &);
Allocator & operator=(const Allocator &);
public:
static const int DEFAULT_ALIGN = 4;
Allocator() {}
virtual ~Allocator() {}
// Convenience method for allocating when you don't care about allocated size.
virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) = 0;
// Frees the memory pointed to by p, the memory must have been allocated by the allocate()
// function. Returns the size of the allocated memomry.
virtual size_t deallocate(void *p) = 0;
};
// Allocator class that wraps the AllocatorApi exposed by the engine's plugin interface.
class ApiAllocator : public Allocator
{
AllocatorObject *_object;
AllocatorApi *_api;
public:
ApiAllocator(AllocatorApi *api, AllocatorObject *object) : _object(object), _api(api) {}
ApiAllocator(const ApiAllocator &a) : _object(a._object), _api(a._api) {}
ApiAllocator & operator=(const ApiAllocator &a) { _object = a._object; _api = a._api; return *this; }
virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) override {return _api->allocate(_object, size, align);}
virtual size_t deallocate(void *p) override {return _api->deallocate(_object, p);}
AllocatorObject *object() { return _object; }
AllocatorApi *api() { return _api; }
};
template <class T> void make_delete(Allocator &a, T *p) {
if (p) {
p->~T();
a.deallocate(p);
}
}
// Allocator that allocates from a static buffer.
class StaticAllocator : public Allocator
{
char *_start;
char *_p;
char *_end;
public:
StaticAllocator(char *p, char *end) : _start(p), _p(p), _end(end) {}
virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) override
{
if (size == 0)
return nullptr;
unsigned rem = (_p - (const char *)0) % align;
if (rem)
_p += (align - rem);
char *ret = _p + size > _end ? nullptr : _p;
_p += size;
return ret;
}
size_t deallocate(void *p) override { return 0; }
char *start() {return _start;}
bool out_of_memory() {return _p > _end;}
size_t wanted_memory() {return (size_t)(_p - _start);}
};
// Allocations released only by destructor
class TempAllocator : public ApiAllocator
{
public:
TempAllocator(AllocatorApi *api) : ApiAllocator(api, api->make_temp_allocator()) {}
virtual ~TempAllocator() { api()->destroy_temp_allocator(object()); }
};
// Add this in the public section of classes to specify that they want to be initialized with an
// allocator.
#define ALLOCATOR_AWARE typedef int allocator_aware
// Macro versions of make_new and make_delete to avoid template combinatorial explosion and
// make sure errors are reported in the file where the macro is called.
#define MAKE_NEW(a, T, ...) (new ((a).allocate(sizeof(T), alignof(T))) T(__VA_ARGS__))
#define MAKE_DELETE(a, p) (make_delete(a,p))
#define MAKE_DELETE_TYPE(a, T, p) do {if (p) {(p)->~T(); (a).deallocate(p);}} while (0)
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,149 @@
#pragma once
#include "allocator.h"
#include <algorithm>
namespace stingray_plugin_foundation {
struct NoAllocator;
// An Array<> is a simplified Vector<> for POD types that does not call
// constructors or destructors for its elements (it doesn't even zero the
// memory). It also assumes that the members can be moved and copied with
// a memmove operation and compared with memcmp.
template <class T>
class Array
{
public:
// Type definitions
typedef Array<T> this_type;
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef pointer iterator;
typedef const_pointer const_iterator;
// Constructors
// Creates an array that uses the specified allocator to allocate memory.
Array(Allocator &allocator);
// Creates an array and presizes it to the specified size.
Array(unsigned size, Allocator &allocator);
// Creates an array without an allocator, one must be provided later with
// set_allocator() before the array is resized.
Array(const NoAllocator &);
// Sets the allocator of the array. You can only call this before any
// allocations have been made by the array.
void set_allocator(Allocator &allocator);
Array( const Array<T> &o );
~Array() {reset();}
// Asignment operator -- note that we do not support chained assignments.
void operator=(const Array<T> &o);
// std::vector interface
iterator begin() {return _data;}
const_iterator begin() const {return _data;}
iterator end() {return _data + _size;}
const_iterator end() const {return _data + _size;}
unsigned size() const {return _size;}
unsigned capacity() const {return _capacity;}
bool any() const {return _size != 0;}
bool empty() const {return _size == 0;}
reference operator[](unsigned i);
const_reference operator[](unsigned i) const;
void reserve(unsigned capacity);
reference front() {return _data[0];}
const_reference front() const {return _data[0];}
reference back() {return _data[_size-1];}
const_reference back() const {return _data[_size-1];}
template <class ASSIGNABLE> void push_back(const ASSIGNABLE &item);
void pop_back();
void swap(Array<T> &o);
template <class ASSIGNABLE> iterator insert(iterator pos, const ASSIGNABLE & x);
iterator insert(iterator pos);
void insert(iterator pos, const_iterator from, const_iterator to);
iterator erase(iterator pos);
iterator erase(iterator first, iterator last);
void clear() {resize(0);}
void resize(unsigned size);
// Serializes the array to the stream.
template <class STREAM> void serialize(STREAM &stream);
bool operator==(const Array<T> &o) const;
bool operator<(const Array<T> &o) const;
// Array extensions
// Resets the array to initial state (no memory allocated).
void reset() {set_capacity(0);}
// Extends the array with the specified number of elements and returns a pointer to the first new element.
pointer extend(unsigned elements) { resize(size() + elements); return _data + _size - elements; }
// Extends the array with one elements and returns a reference to the newly created element.
reference extend() { resize(size() + 1); return back(); }
// Returns the allocator of the array.
Allocator &allocator() const {return *_allocator;}
// Sets the capacity of the array to exactly the specified ammount.
// This operation always reallocates the memory of the array, no
// swap trick is necessary to enforce reallocation.
void set_capacity(unsigned capacity);
// Trims the array so that the capacity corresponds to its current size.
void trim() {set_capacity(size());}
// Finds the first occurrence of x in the array and returns it.
template <typename EQUATABLE> iterator find(const EQUATABLE &x) {return std::find(begin(), end(), x);}
// Finds the first occurrence of x in the array and returns it.
template <typename EQUATABLE> const_iterator find(const EQUATABLE &x) const {return std::find(begin(), end(), x);}
// Returns the index of x in the array (or size() if it is not in the array).
template <typename EQUATABLE> unsigned index_of(const EQUATABLE &x) const {return (unsigned)(find(x) - begin());}
// Returns if x is in the array
template <typename EQUATABLE> bool has(const EQUATABLE &x) const {return (find(x) != end());}
// Erases the first occurrence of x in the array.
template <typename EQUATABLE> void erase(const EQUATABLE &item);
// "Steals" the data buffer from the array. The array will be empty after this operation. The "stealer" is
// responsible for deallocating the stolen buffer.
pointer steal();
private:
void move(pointer to, pointer from, unsigned n);
void copy(pointer to, const_pointer from, unsigned n);
void grow(unsigned min_capacity = 0);
private:
unsigned _size;
unsigned _capacity;
pointer _data;
Allocator * _allocator;
};
} // namespace stingray_plugin_foundation
#include "array.inl"

View file

@ -0,0 +1,276 @@
#include "assert.h"
namespace stingray_plugin_foundation {
template <class T> Array<T>::Array(Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator)
{
}
template <class T> Array<T>::Array(unsigned size, Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator)
{
resize(size);
}
template <class T> Array<T>::Array(const NoAllocator &) : _size(0), _capacity(0), _data(0), _allocator(0)
{
}
template <class T> void Array<T>::set_allocator(Allocator &allocator)
{
_allocator = &allocator;
}
template <class T> Array<T>::Array( const Array<T> &o ) : _size(0), _capacity(0), _data(0), _allocator(o._allocator)
{
set_capacity(o.size());
copy(_data, o._data, o.size());
_size = o.size();
}
template <class T> void Array<T>::operator=(const Array<T> &o)
{
resize(o.size());
copy(_data, o._data, o.size());
}
template <class T> typename Array<T>::reference Array<T>::operator[](unsigned i) {
XENSURE(i < _size);
return _data[i];
}
template <class T> typename Array<T>::const_reference Array<T>::operator[](unsigned i) const {
XENSURE(i < _size);
return _data[i];
}
template <class T> void Array<T>::reserve(unsigned capacity)
{
if (capacity > _capacity)
grow(capacity);
}
template <class T> template <class ASSIGNABLE>
void Array<T>::push_back(const ASSIGNABLE &item)
{
if (_size + 1 > _capacity)
grow();
_data[_size++] = item;
}
template <class T> void Array<T>::pop_back()
{
_size--;
}
template <class T> void Array<T>::swap(Array<T> &o)
{
XENSURE(_allocator == o._allocator);
std::swap(_size, o._size);
std::swap(_capacity, o._capacity);
std::swap(_data, o._data);
std::swap(_allocator, o._allocator);
}
template <class T> template <class ASSIGNABLE>
typename Array<T>::iterator Array<T>::insert(iterator pos, const ASSIGNABLE& x)
{
if (_size + 1 > _capacity) {
unsigned i = (unsigned)(pos - _data);
grow();
pos = _data + i;
}
move(pos + 1, pos, (unsigned)((_data + _size) - pos));
*pos = x;
++_size;
return pos;
}
template <class T> typename Array<T>::iterator Array<T>::insert(iterator pos)
{
if (_size + 1 > _capacity) {
unsigned i = pos - _data;
grow();
pos = _data + i;
}
move(pos + 1, pos, (_data + _size) - pos);
++_size;
return pos;
}
template <class T> void Array<T>::insert(iterator pos, const_iterator from, const_iterator to)
{
unsigned add = (unsigned)(to - from);
if (_size + add > _capacity) {
size_t i = pos - _data;
grow(_size + add);
pos = _data + i;
}
move(pos + add, pos, (unsigned)((_data + _size) - pos));
copy(pos, from, add);
_size += add;
}
template <class T> typename Array<T>::iterator Array<T>::erase(iterator pos)
{
XASSERT(pos >= begin() && pos < end(), "Trying to remove outside array.");
move(pos, pos + 1, (unsigned)((_data + _size) - pos - 1));
--_size;
return pos;
}
template <class T> typename Array<T>::iterator Array<T>::erase(iterator first, iterator last)
{
move(first, last, (unsigned)((_data + _size) - last));
_size -= (unsigned)(last - first);
return first;
}
template <class T> template <typename EQUATABLE> void Array<T>::erase(const EQUATABLE &item)
{
iterator it = find(item);
XENSURE(it != end());
erase(it);
}
template <class T> void Array<T>::resize(unsigned size)
{
if (size > _capacity)
grow(size);
_size = size;
}
template <class T> void Array<T>::set_capacity(unsigned capacity)
{
if (capacity == _capacity)
return;
if (capacity < _size)
resize(capacity);
pointer new_data = 0;
if (capacity > 0) {
unsigned align = alignof(value_type) > 4 ? alignof(value_type) : 4;
new_data = (pointer)_allocator->allocate(sizeof(value_type)*capacity, align);
copy(new_data, _data, _size);
}
_allocator->deallocate(_data);
_data = new_data;
_capacity = capacity;
}
template <class T> void Array<T>::move(pointer to, pointer from, unsigned n)
{
memmove((void *)to, (void *)from, sizeof(T) * n);
}
template <class T> void Array<T>::copy(pointer to, const_pointer from, unsigned n)
{
memcpy((void *)to, (void *)from, sizeof(T) * n);
}
template <class T>
template <class STREAM> void Array<T>::serialize(STREAM &stream)
{
unsigned sz = size();
stream & sz;
resize(sz);
for (unsigned i=0; i<sz; ++i)
stream & (*this)[i];
}
template <class STREAM, class T>
void raw_array_serialize(STREAM &s, Array<T> &data)
{
unsigned n = data.size();
s & n;
data.resize(n);
if (n > 0) {
if (s.is_output())
s.write(data.begin(), n * sizeof(T));
else
s.read(data.begin(), n * sizeof(T));
}
}
template <>
template <class STREAM> void Array<char>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<uint8_t>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<int8_t>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<uint16_t>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<int16_t>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<uint32_t>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<int32_t>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<int64_t>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<uint64_t>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template<class T> bool Array<T>::operator==(const Array<T> &o) const
{
if (size() != o.size())
return false;
return memcmp(_data, o._data, sizeof(T)*size()) == 0;
}
template<class T> bool Array<T>::operator<(const Array<T> &o) const
{
if (size() != o.size())
return size() < o.size();
return memcmp(_data, o._data, sizeof(T)*size()) < 0;
}
template <class T> void Array<T>::grow(unsigned min_capacity)
{
uint64_t new_capacity = (uint64_t)_capacity*2 + 10;
if (new_capacity < min_capacity)
new_capacity = min_capacity;
else if (new_capacity > UINT32_MAX)
new_capacity = UINT32_MAX;
set_capacity((unsigned)new_capacity);
}
template <class T> typename Array<T>::pointer Array<T>::steal()
{
pointer return_value = _data;
_data = 0;
_capacity = 0;
_size = 0;
return return_value;
}
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,38 @@
#pragma once
#include <assert.h>
#include "../engine_plugin_api/plugin_api.h"
#if defined(DEVELOPMENT)
namespace stingray_plugin_foundation {
inline struct ErrorApi *&error_api()
{
static struct ErrorApi *api = nullptr;
return api;
}
inline void set_error_api(struct ErrorApi *api)
{
error_api() = api;
}
}
#define XASSERT_BASE(test, test_msg, msg, ...) \
do {if (!(test)) { \
struct ErrorApi *api = stingray_plugin_foundation::error_api(); \
if (api && api->report_assert_failure) \
api->report_assert_failure(__LINE__, __FILE__, test_msg, api->eprintf(msg, ## __VA_ARGS__)); \
else \
assert(test); \
}} while (0)
#define XASSERT(test, msg, ...) do {XASSERT_BASE(test, #test, msg, ## __VA_ARGS__);} while(0)
#define XENSURE(test) do {XASSERT_BASE(test, #test, "Assertion failed");} while(0)
#define XERROR(msg, ...) do {XASSERT_BASE(false, nullptr, msg, ## __VA_ARGS__);} while(0)
#else
#define XASSERT(test, msg, ...) ((void)0)
#define XENSURE(test) ((void)0)
#define XERROR(msg, ...) ((void)0)
namespace stingray_plugin_foundation {
inline void set_error_api(struct ErrorApi *api) {}
}
#endif

View file

@ -0,0 +1,97 @@
#pragma once
namespace stingray_plugin_foundation {
template <class CONTAINER, class ITEM>
class ConstBucketIterator;
// A helper class that makes an iterator for a bucket based data structure.
// Such a data structure has a number of random access buckets which may be
// "valid" or not. The iterator iterates over the valid buckets only.
template <class CONTAINER, class ITEM>
class BucketIterator {
public:
typedef BucketIterator<CONTAINER, ITEM> iterator;
friend class ConstBucketIterator<CONTAINER, ITEM>;
typedef ITEM value_type;
typedef ITEM* pointer;
typedef ITEM& reference;
typedef ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
inline BucketIterator() : _i(0) { }
inline BucketIterator(CONTAINER &container, unsigned i);
inline BucketIterator(const BucketIterator &other);
inline bool operator==(const iterator &rhs) const { return cmp(rhs) == 0; }
inline bool operator!=(const iterator &rhs) const { return cmp(rhs) != 0; }
inline bool operator<(const iterator &rhs) const { return cmp(rhs) < 0; }
inline bool operator<=(const iterator &rhs) const { return cmp(rhs) <= 0; }
inline bool operator>(const iterator &rhs) const { return cmp(rhs) > 0; }
inline bool operator>=(const iterator &rhs) const { return cmp(rhs) >= 0; }
inline iterator operator++();
inline iterator operator++(int);
inline ITEM &operator*() { return _container->bucket_value(_i); }
inline ITEM *operator->() { return &_container->bucket_value(_i); }
private:
inline int cmp(const iterator &rhs) const {
if(_container < rhs._container) return -1;
else if(_container > rhs._container) return 1;
else if(_i < rhs._i) return -1;
else if(_i > rhs._i) return 1;
else return 0;
}
void advance_to_valid_bucket();
CONTAINER *_container;
unsigned _i;
};
// A helper class that makes an iterator for a bucket based data structure.
// Such a data structure has a number of random access buckets which may be
// "valid" or not. The iterator iterates over the valid buckets only.
template <class CONTAINER, class ITEM>
class ConstBucketIterator {
public:
typedef ConstBucketIterator<CONTAINER, ITEM> iterator;
typedef ITEM value_type;
typedef ITEM* pointer;
typedef ITEM& reference;
typedef ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
inline ConstBucketIterator() : _i(0) {}
inline ConstBucketIterator(const CONTAINER &container, unsigned i);
inline ConstBucketIterator(const ConstBucketIterator<CONTAINER, ITEM> &rhs);
inline ConstBucketIterator(const BucketIterator<CONTAINER, ITEM> &rhs);
inline bool operator==(const iterator &rhs) const { return cmp(rhs) == 0; }
inline bool operator!=(const iterator &rhs) const { return cmp(rhs) != 0; }
inline bool operator<(const iterator &rhs) const { return cmp(rhs) < 0; }
inline bool operator<=(const iterator &rhs) const { return cmp(rhs) <= 0; }
inline bool operator>(const iterator &rhs) const { return cmp(rhs) > 0; }
inline bool operator>=(const iterator &rhs) const { return cmp(rhs) >= 0; }
inline iterator operator++();
inline iterator operator++(int);
inline const ITEM &operator*() { return _container->bucket_value(_i); }
inline const ITEM *operator->() { return &_container->bucket_value(_i); }
private:
inline int cmp(const iterator &rhs) const {if (_container != rhs._container) return (int)(_container - rhs._container); return (int)(_i - rhs._i);}
void advance_to_valid_bucket();
const CONTAINER *_container;
unsigned _i;
};
} // namespace stingray_plugin_foundation
#include "bucket_iterator.inl"

View file

@ -0,0 +1,89 @@
namespace stingray_plugin_foundation {
// ----------------------------------------------------------------------
// BucketIterator
// ----------------------------------------------------------------------
template <class CONTAINER, class ITEM>
BucketIterator<CONTAINER, ITEM>::BucketIterator(CONTAINER &container, unsigned int i) : _container(&container), _i(i)
{
advance_to_valid_bucket();
}
template <class CONTAINER, class ITEM>
BucketIterator<CONTAINER, ITEM>::BucketIterator(const iterator &other) : _container(other._container), _i(other._i)
{}
template <class CONTAINER, class ITEM>
BucketIterator<CONTAINER, ITEM> BucketIterator<CONTAINER, ITEM>::operator++()
{
//XASSERT(_i < _container->num_buckets(), "iterating past end of container");
XENSURE(_i < _container->num_buckets());
++_i;
advance_to_valid_bucket();
return *this;
}
template <class CONTAINER, class ITEM>
BucketIterator<CONTAINER, ITEM> BucketIterator<CONTAINER, ITEM>::operator++(int)
{
iterator result = *this;
++(*this);
return result;
}
template <class CONTAINER, class ITEM>
void BucketIterator<CONTAINER, ITEM>::advance_to_valid_bucket()
{
unsigned int size = _container->num_buckets();
for (; _i < size; ++_i)
if (_container->bucket_valid(_i))
break;
}
// ----------------------------------------------------------------------
// ConstBucketIterator
// ----------------------------------------------------------------------
template <class CONTAINER, class ITEM>
ConstBucketIterator<CONTAINER, ITEM>::ConstBucketIterator(const CONTAINER &container, unsigned int i) : _container(&container), _i(i)
{
advance_to_valid_bucket();
}
template <class CONTAINER, class ITEM>
ConstBucketIterator<CONTAINER, ITEM>::ConstBucketIterator(const iterator &other) : _container(other._container), _i(other._i)
{}
template <class CONTAINER, class ITEM>
ConstBucketIterator<CONTAINER, ITEM>::ConstBucketIterator(const BucketIterator<CONTAINER,ITEM> &other) : _container(other._container), _i(other._i)
{}
template <class CONTAINER, class ITEM>
ConstBucketIterator<CONTAINER, ITEM> ConstBucketIterator<CONTAINER, ITEM>::operator++()
{
XASSERT(_i < _container->num_buckets(), "iterating past end of container");
++_i;
advance_to_valid_bucket();
return *this;
}
template <class CONTAINER, class ITEM>
ConstBucketIterator<CONTAINER, ITEM> ConstBucketIterator<CONTAINER, ITEM>::operator++(int)
{
iterator result = *this;
++(*this);
return result;
}
template <class CONTAINER, class ITEM>
void ConstBucketIterator<CONTAINER, ITEM>::advance_to_valid_bucket()
{
unsigned int size = _container->num_buckets();
for (; _i < size; ++_i)
if (_container->bucket_valid(_i))
break;
}
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,73 @@
#pragma once
#include "stream.h"
//#include "array.h"
#include "allocator.h"
// sourced from engine's data_compiler.h
namespace stingray_plugin_foundation {
namespace buffer
{
//Buffer buffer(const Array<char> &resource, Allocator &allocator) {
// Buffer result;
// result.len = resource.size();
// result.p = (char *)allocator.allocate(result.len);
// memmove(result.p, resource.begin(), result.len);
// return result;
//}
//Buffer buffer(const Array<char> &header, const Array<char> &data, Allocator &allocator) {
// Buffer result;
// result.len = header.size() + data.size();
// XENSURE(result.len > 0);
// result.p = (char *)allocator.allocate(result.len);
// memcpy(result.p, header.begin(), header.size());
// memcpy(result.p + header.size(), data.begin(), data.size());
// return result;
//}
//Buffer buffer(const StringStream &os, Allocator &allocator) {
// Buffer result;
// result.p = (char *)allocator.allocate(os.size());
// result.len = os.size();
// memcpy(result.p, os.c_str(), os.size());
// return result;
//}
//Buffer buffer(MemoryOutputBuffer &ob, Allocator &allocator) {
// Buffer result;
// result.len = (unsigned)ob.position();
// result.p = (char *)allocator.allocate(result.len);
// ob.read(result.p);
// return result;
//}
//Buffer copy(Buffer b, Allocator &allocator)
//{
// Buffer result;
// result.len = b.len;
// result.p = (char *)allocator.allocate(result.len);
// memcpy(result.p, b.p, result.len);
// return result;
//}
//template <class T> Buffer serialize(T &t, Allocator &allocator) {
// MemoryOutputBuffer mob(allocator);
// OutputArchive oa = SharedPtr<OutputBuffer>(mob);
// oa & t;
// return buffer(mob, allocator);
//}
template <class T> Buffer pack(T &t, Allocator &allocator) {
Buffer result;
result.len = sizeof(T);
result.p = (char *)allocator.allocate(result.len);
char *p = result.p;
stream::pack(p, t);
return result;
}
} // namespace buffer
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,16 @@
#pragma once
#include "pair.h"
#include "vector"
namespace stingray_plugin_foundation {
template <class T>
inline void swap_erase(T &v, typename T::iterator it);
template <class T>
inline void swap_erase(T &v, int i);
} // namespace stingray_plugin_foundation
#include "collection_tools.inl"

View file

@ -0,0 +1,16 @@
namespace stingray_plugin_foundation {
template <class T>
inline void swap_erase(T &v, typename T::iterator it)
{
std::swap(*it, v.back());
v.pop_back();
}
template <class T>
inline void swap_erase(T &v, int i)
{
swap_erase(v, v.begin() + i);
}
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,23 @@
#pragma once
#include "platform.h"
namespace stingray_plugin_foundation {
typedef unsigned int Color8;
__forceinline Color8 color8(unsigned char a, unsigned char r, unsigned char g, unsigned char b)
{
return (a << 24) | (r << 16) | (g << 8) | b;
}
__forceinline unsigned char alpha(Color8 c) {return (c >> 24) & 0xff;}
__forceinline unsigned char red(Color8 c) {return (c >> 16) & 0xff;}
__forceinline unsigned char green(Color8 c) {return (c >> 8) & 0xff;}
__forceinline unsigned char blue(Color8 c) {return (c >> 0) & 0xff;}
struct Color32 {
float r, g, b, a;
};
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,31 @@
#pragma once
#if defined(WINDOWSPC) || defined(XBOXONE)
namespace stingray_plugin_foundation {
template<typename T>
class ComPtr {
public:
explicit ComPtr(T* ptr = 0);
ComPtr(const ComPtr<T>& rhs);
~ComPtr();
ComPtr<T>& operator=(const ComPtr<T>& rhs);
T& operator*() const;
T* operator->() const;
T* get() const;
T* abandon() const;
T** init_ptr();
private:
T* _ptr;
mutable bool _owned;
};
#endif
}
#include "com_ptr.inl"

View file

@ -0,0 +1,66 @@
namespace stingray_plugin_foundation {
#if defined(WINDOWSPC) || defined(XBOXONE)
template<typename T>
ComPtr<T>::ComPtr(T* ptr = 0) : _owned(true), _ptr(ptr) {
}
template<typename T>
ComPtr<T>::ComPtr(const ComPtr<T>& rhs) : _owned(rhs._owned), _ptr(rhs.abandon()) {
}
template<typename T>
ComPtr<T>::~ComPtr() {
if(_owned && _ptr) {
_ptr->Release();
}
}
template<typename T>
ComPtr<T>& ComPtr<T>::operator=(const ComPtr<T>& rhs) {
if( this != &rhs ) {
if( _ptr != rhs.get() && _owned && _ptr)
_ptr->Release();
_owned = rhs._owned;
_ptr = rhs.abandon();
}
return *this;
}
template<typename T>
T& ComPtr<T>::operator*() const {
return *get();
}
template<typename T>
T* ComPtr<T>::operator->() const {
return get();
}
template<typename T>
T* ComPtr<T>::get() const {
return _ptr;
}
template<typename T>
T* ComPtr<T>::abandon() const {
_owned=false;
return _ptr;
}
template<typename T>
T** ComPtr<T>::init_ptr() {
if(_owned && _ptr)
_ptr->Release();
_ptr=0;
_owned=true;
return &_ptr;
}
#endif
}

View file

@ -0,0 +1,168 @@
#pragma once
#include <string.h>
#include "assert.h"
#include "platform.h"
// This file is the runtime representation of a config data structure. A config data structure
// is a JSON-like object for representing generic data. This format is suitable when the
// development cost of creating a custom binary format is big and the benefits are small.
// (I.e. for any data that is not massive bulk data -- such as small configuration files.)
//
// The runtime format is essential (type, data) where type is a four-byte type identifier
// and data is four bytes of data. We use four bytes for the type identifier for alignment
// purposes. Note that the runtime format represent an entire config object as a single
// memory block. Local pointers inside the memory block are used to build structure.
//
// Note that it is possible to optimize this format further to squeeze out a few more bytes.
namespace stingray_plugin_foundation {
struct ConstConfigArray;
struct ConstConfigObject;
namespace const_config
{
// Type used for offset parameters
typedef unsigned offset_t;
// The supported value types
enum ValueType {NIL, BOOL, INTEGER, FLOAT, STRING, ARRAY, OBJECT};
// Generic representation of a value of one of the types.
union Value {
int b;
int i;
float f;
offset_t s; // Offset to char *
offset_t a; // Offset to ConstConfigArray *
offset_t o; // Offset toConstConfigObject *
};
}
// Represents the root object (the first item in the memory block).
struct ConstConfigRoot
{
int type; // ValueType
const_config::Value value;
};
// Represents an array. Note that the type is only stored once, all objects in an array
// must have the same type. In the memory layout, the ConstConfigArray block is followed
// by *size* data items (which are bool, int, float, etc) depending on type.
struct ConstConfigArray
{
int type; // ValueType
int size;
const_config::Value first_item; // size data items follows in memory
};
// Represents an entry in a ConstConfigObject. Stores the key (always a string), the
// type of the entry and the value.
struct ConstConfigObjectEntry
{
const_config::offset_t name; // Offset to name
int type; // ValueType
const_config::Value value;
};
// Represents an object. In the memory layout, ConstConfigObject is followed by
// *size* ConstConfigObjectEntry structures that contain the actual objects.
struct ConstConfigObject
{
int size;
ConstConfigObjectEntry first_entry;
};
// Convenience class used to access config data.
class ConstConfigItem
{
public:
// Creates a nil config item.
ConstConfigItem() : _base(nullptr), _type(const_config::NIL) {}
// Creates a config item from the specified root.
ConstConfigItem(const ConstConfigRoot &root) : _base((const char *)&root), _type(root.type), _value(root.value) {}
// Creates a config item with the specified base, type and data.
ConstConfigItem(const char *base, const_config::ValueType t, const_config::Value v) : _base(base), _type(t), _value(v) {}
bool is_nil() const {return _type == const_config::NIL;}
bool is_bool() const {return _type == const_config::BOOL;}
bool is_false() const {return _type == const_config::BOOL && !_value.b;}
bool is_true() const {return _type == const_config::BOOL && _value.b;}
bool is_integer() const {return _type == const_config::INTEGER;}
bool is_float() const {return _type == const_config::FLOAT;}
bool is_number() const {return is_integer() || is_float();}
bool is_string() const {return _type == const_config::STRING;}
bool is_resource() const { return is_string() || is_object() && (*this)["$resource_name"].is_string(); }
bool is_resource(const char *type) const { return is_resource() && (is_string() || (*this)["$resource_type"].is_string() && strcmp((*this)["$resource_type"].to_string(),type)==0); }
bool is_array() const { return _type == const_config::ARRAY; }
bool is_object() const {return _type == const_config::OBJECT;}
bool to_bool() const {XENSURE(is_bool()); return _value.b != 0;}
int to_integer() const {XENSURE(is_integer()); return _value.i;}
float to_float() const {return is_float() ? _value.f : float(to_integer());}
const char *to_string() const {XENSURE(is_string()); return raw_s();}
const char *to_resource(const char *type) const {
XENSURE(is_resource(type));
if (is_string()) {
return to_string();
}
return (*this)["$resource_name"].to_string();
}
bool operator||(bool b) const {return is_bool() ? to_bool() : b;}
int operator||(int i) const {return is_integer() ? _value.i : i;}
unsigned operator||(unsigned i) const {return is_integer() ? unsigned(_value.i) : i;}
float operator||(float f) const {return is_float() ? _value.f : (is_integer() ? _value.i : f);}
const char *operator||(const char *s) const {return is_string() ? raw_s() : s;}
ConstConfigItem operator||(ConstConfigItem o) {return is_nil() ? o : *this;}
int size() const {return is_array() ? raw_a()->size : 0;}
int n_items() const {return is_object() ? raw_o()->size : 0;}
ConstConfigItem operator[](int i) const {
if (!is_array())
return ConstConfigItem();
if (i<0 || i>=raw_a()->size)
return ConstConfigItem();
const ConstConfigArray &arr = *raw_a();
return ConstConfigItem(_base, (const_config::ValueType)arr.type, *(&arr.first_item + i));
}
ConstConfigItem operator[](const char *s) const {
if (!is_object())
return ConstConfigItem();
const ConstConfigObject &obj = *raw_o();
for (int i=0; i<obj.size; ++i) {
const ConstConfigObjectEntry &e = *(&obj.first_entry + i);
if (strcmp(_base + e.name, s) == 0)
return ConstConfigItem(_base, (const_config::ValueType)e.type, e.value);
}
return ConstConfigItem();
}
ConstConfigItem item(int i, const char **s = 0) const {
if (!is_object())
return ConstConfigItem();
const ConstConfigObject &obj = *raw_o();
if (i<0 || i>=obj.size)
return ConstConfigItem();
const ConstConfigObjectEntry &e = *(&obj.first_entry + i);
if(s) *s = _base + e.name;
return ConstConfigItem(_base, (const_config::ValueType)e.type, e.value);
}
private:
const char *raw_s() const {return _base + _value.s;}
const ConstConfigArray *raw_a() const {return (ConstConfigArray *)(_base + _value.a);}
const ConstConfigObject *raw_o() const {return (ConstConfigObject *)(_base + _value.o);}
const char *_base; // Base for offsets
int _type; // ValueType
const_config::Value _value;
};
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,84 @@
#pragma once
namespace stingray_plugin_foundation {
template<class T> class Array;
class Allocator;
// Functions for string encoding.
namespace encoding
{
// Encodes the unicode character `c` in UTF-8 at the position pointed
// to by `buffer`. `buffer` must have room for at least 5 bytes.
// Returns a pointer to the first character in buffer after the end of
// the encoding.
char *utf8_encode(int codepoint, char *utf8);
// Decodes the UTF-8 character at the start of `buffer` into a unicode
// code point and returns it in `res`. Returns a pointer to the first
// character in the buffer after the UTF-8 character that was just
// consumed.
const char *utf8_decode(const char *utf8, int &codepoint);
// Returns the number of bytes used by the UTF-8 codepoint pointed to by
// buffer. Advance by this amount to get to the next code point.
unsigned utf8_codepoint_bytes(const char *utf8);
// Decodes an UTF-8 string to a vector of codepoints.
void utf8_decode(const char *utf8, Array<unsigned> &codepoints);
// Encode a vector of codepoints to an array of UTF-8 characters.
void utf8_encode(const Array<unsigned> &codepoints, Array<char> &utf8);
// Encode an array of codepoints to an array of UTF-8 characters.
void utf8_encode(const unsigned *codepoints, unsigned size, Array<char> &utf8);
// Determines the begin and end position of the utf8 codepoint at
// `utf8`[index]. `end` is an index pointing to the byte after the
// utf-8 codepoint.
void utf8_location(const char *utf8, unsigned index, unsigned &begin, unsigned &end);
// Returns a pointer to the next character if the character at utf8 is valid, otherwise
// returns nullptr.
const char *utf8_valid_first(const char *utf8);
// Returns true if the string utf8 contains only valid UTF-8 code points and
// false otherwise.
bool utf8_valid_all(const char *utf8);
// Returns the number of of bytes needed to store the UCS-2 encoded wchar_t *
// as an UTF-8 value, including the zero byte at the end of the UTF-8 string.
unsigned wstr_to_utf8_bytes(const wchar_t *ucs2);
// Converts an UCS-2 encoded w_char * to an UTF-8 encoded char *.
// `size` specifies the size of the buffer. If the conversion requires
// more than `size` bytes, an assert is thrown.
void wstr_to_utf8(const wchar_t *ucs2, char *utf8, unsigned size);
// Converts an UCS-2 encoded w_char * to an UTF-8 encoded char *,
// allocating memory as necessary.
void wstr_to_utf8(const wchar_t *ucs2, Array<char> &utf8);
// Returns the number of of tokens needed to store the UTF-8 encoded char *
// as an UCS-2 value, including the zero token at the end of the UCS-2 string.
unsigned utf8_to_wstr_tokens(const char *utf8);
// Converts an UTF-8 encoded char * to an UCS-2 encoded wchar_t *.
// `tokens` specifies the number of tokens in the buffer. If the
// converted string contains more tokens, an assert is thrown.
void utf8_to_wstr(const char *utf8, wchar_t *ucs2, unsigned tokens);
// Converts an UTF-8 encoded char * to an UCS-2 encoded wchar_t *,
// allocating memory as necessary.
void utf8_to_wstr(const char *utf8, Array<wchar_t> &ucs2);
// Converts an UTF-8 encoded char * to an UCS-2 encoded wchar_t *,
// allocated using the specified allocator.
wchar_t *utf8_to_wstr(const char *utf8, Allocator &a);
} // namespace encoding
} // namespace stingray_plugin_foundation
#include "encoding.inl"

View file

@ -0,0 +1,211 @@
#include "assert.h"
#include "array.h"
#include <wchar.h>
#include <string.h>
namespace stingray_plugin_foundation {
inline char *encoding::utf8_encode(int c, char *utf8)
{
if (c<0x80) {
*utf8 = c;
return utf8 + 1;
} else if (c<0x800) {
utf8[0] = (c>>6)|0xC0;
utf8[1] = (c&0x3F)|0x80;
return utf8 + 2;
} else if (c<0x10000) {
utf8[0] = (c>>12)|0xE0;
utf8[1] = ((c>>6)&0x3F)|0x80;
utf8[2] = (c&0x3F)|0x80;
return utf8 + 3;
} else if (c<0x110000) {
utf8[0] = (c>>18)|0xf0;
utf8[1] = ((c>>12)&0x3F)|0x80;
utf8[2] = ((c>>6)&0x3F)|0x80;
utf8[3] = (c&0x3F)|0x80;
return utf8 + 4;
} else {
XERROR("Cannot encode character");
}
return utf8;
}
inline const char *encoding::utf8_decode(const char *utf8, int &codepoint)
{
char c = *utf8;
if ((c&0x80)==0x0) {
codepoint = c;
return utf8 + 1;
} else if ((c&0xE0)==0xC0) {
unsigned char d = utf8[1];
XASSERT((d&0xC0)==0x80, "Archive not utf-8 encoded %s", utf8);
codepoint = (static_cast<int>(c&0x1F)<<6) | static_cast<int>(d&0x3F);
return utf8 + 2;
} else if ((c&0xF0)==0xE0) {
const char *d = utf8 + 1;
XASSERT(((d[0]&0xC0)==0x80) && ((d[1]&0xC0)==0x80), "Archive not utf-8 encoded %s", utf8);
codepoint = (static_cast<int>(c&0x0f)<<12) | (static_cast<int>(d[0]&0x3f)<<6) |
static_cast<int>(d[1]&0x3f);
return utf8 + 3;
} else if ((c&0xf8)==0xf0) {
const char *d = utf8 + 1;
XASSERT(((d[0]&0xc0)==0x80) && ((d[1]&0xc0)==0x80) &&
((d[2]&0xc0)==0x80), "Archive not utf-8 encoded %s", utf8);
codepoint = (static_cast<int>(c&0x07)<<18) | (static_cast<int>(d[0]&0x3f)<<12) |
(static_cast<int>(d[1]&0x3f)<<6) | static_cast<int>(d[2]&0x3f);
return utf8 + 4;
} else {
XERROR("Archive not utf-8 encoded %s", utf8);
return utf8;
}
}
inline unsigned encoding::utf8_codepoint_bytes(const char *buffer)
{
char c = *buffer;
if ((c&0x80)==0x0)
return 1;
else if ((c&0xE0)==0xC0)
return 2;
else if ((c&0xF0)==0xE0)
return 3;
else if ((c&0xf8)==0xf0)
return 4;
else {
XERROR("Length on part of utf-8 character");
return 1;
}
}
inline void encoding::utf8_decode(const char *utf8, Array<unsigned> &codepoints)
{
while (*utf8) {
int c;
utf8 = utf8_decode(utf8, c);
codepoints.push_back((unsigned)c);
}
}
inline void encoding::utf8_encode(const Array<unsigned> &codepoints, Array<char> &utf8)
{
utf8_encode(codepoints.begin(), codepoints.size(), utf8);
}
inline void encoding::utf8_encode(const unsigned *codepoints, unsigned size, Array<char> &utf8)
{
const unsigned *it(codepoints), *end(codepoints + size);
for(; it != end; ++it) {
utf8.reserve(utf8.size() + 4);
const char *new_ptr = utf8_encode(*it, utf8.end());
utf8.resize((unsigned)(new_ptr - utf8.begin()));
}
}
inline void encoding::utf8_location(const char *utf8, unsigned index, unsigned &begin, unsigned &end)
{
XASSERT(index < strlen(utf8), "Index out of string");
// walk backwards to find beginning of utf8 character
begin = index;
while(true) {
if (begin == 0)
break;
if ((utf8[begin] & 0xc0) != 0x80)
break;
--begin;
}
end = begin + utf8_codepoint_bytes(utf8 + begin);
}
inline const char * encoding::utf8_valid_first(const char *utf8)
{
char c = *utf8;
const char *d = utf8 + 1;
if ((c&0x80)==0x0) return utf8 + 1;
else if ((c&0xE0)==0xC0) return (d[0]&0xC0)==0x80 ? utf8+2 : nullptr;
else if ((c&0xF0)==0xE0) return (d[0]&0xC0)==0x80 && (d[1]&0xC0)==0x80 ? utf8+3 : nullptr;
else if ((c&0xf8)==0xf0) return (d[0]&0xc0)==0x80 && (d[1]&0xc0)==0x80 && (d[2]&0xc0)==0x80 ? utf8+4 : nullptr;
else return nullptr;
}
inline bool encoding::utf8_valid_all(const char *utf8)
{
while (*utf8) {
utf8 = utf8_valid_first(utf8);
if (!utf8)
return false;
}
return true;
}
inline unsigned encoding::wstr_to_utf8_bytes(const wchar_t *ucs2)
{
char buffer[5];
unsigned size = 0;
while (*ucs2) {
size += (unsigned)(utf8_encode(*ucs2, &buffer[0]) - &buffer[0]);
++ucs2;
}
++size;
return size;
}
inline void encoding::wstr_to_utf8(const wchar_t *ucs2, char *utf8, unsigned size)
{
char *b = utf8;
while (*ucs2) {
b = utf8_encode(*ucs2, b);
++ucs2;
}
XENSURE(unsigned(b - utf8) < size);
*b = 0;
}
inline void encoding::wstr_to_utf8(const wchar_t *ucs2, Array<char> &utf8)
{
unsigned n = wstr_to_utf8_bytes(ucs2);
utf8.resize(n);
wstr_to_utf8(ucs2, utf8.begin(), n);
}
inline unsigned encoding::utf8_to_wstr_tokens(const char *utf8)
{
unsigned tokens = 0;
while (*utf8) {
++tokens;
utf8 += utf8_codepoint_bytes(utf8);
}
++tokens;
return tokens;
}
inline void encoding::utf8_to_wstr(const char *utf8, wchar_t *ucs2, unsigned tokens)
{
wchar_t *b = ucs2;
while (*utf8) {
int c;
utf8 = utf8_decode(utf8, c);
*b = c;
++b;
}
XENSURE(unsigned(b - ucs2) < tokens);
*b = 0;
}
inline void encoding::utf8_to_wstr(const char *utf8, Array<wchar_t> &ucs2)
{
unsigned n = utf8_to_wstr_tokens(utf8);
ucs2.resize(n);
utf8_to_wstr(utf8, ucs2.begin(), n);
}
inline wchar_t *encoding::utf8_to_wstr(const char *utf8, Allocator &a)
{
unsigned n = utf8_to_wstr_tokens(utf8);
wchar_t *res = (wchar_t *)a.allocate(sizeof(wchar_t)*n);
utf8_to_wstr(utf8, res, n);
return res;
}
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,33 @@
#pragma once
#if (defined(WINDOWSPC) || defined(XBOXONE)) && defined(DEVELOPMENT)
#include <float.h>
namespace stingray_plugin_foundation {
// Disable FPU exceptions in scope and restore on exit.
struct FpuUnsafeScope {
unsigned _initial_control_word;
FpuUnsafeScope() {
_initial_control_word = _controlfp(0,0);
_controlfp(~0U, _MCW_EM);
}
~FpuUnsafeScope() {
_clearfp();
_controlfp(_initial_control_word, _MCW_EM);
}
};
}
#else
namespace stingray_plugin_foundation {
struct FpuUnsafeScope {
FpuUnsafeScope() {}
~FpuUnsafeScope() {}
};
}
#endif

View file

@ -0,0 +1,51 @@
#pragma once
#include "../engine_plugin_api/plugin_api.h"
#include "id_string.h"
namespace stingray_plugin_foundation {
inline const char *get_c_string(const FlowString& flow_string)
{
XENSURE(flow_string.is_id64 == 0);
return flow_string.plain;
}
inline void set_c_string(FlowString& flow_string, const char *string)
{
flow_string.is_id64 = 0;
if (string == nullptr)
flow_string.plain[0] = 0;
strncpy(flow_string.plain, string, PLUGIN_FLOW_STRING_VARIABLE_LENGTH);
}
inline IdString64 get_id64(const FlowId* flow_id)
{
if (flow_id == nullptr)
return IdString64();
if (flow_id->is_id64 == 0)
return IdString64(((const FlowString*)flow_id)->plain);
return IdString64(flow_id->id);
}
inline const char *get_c_string(const FlowId* flow_id)
{
if (flow_id == nullptr)
return nullptr;
if (flow_id->is_id64 == 0)
return ((const FlowString*)flow_id)->plain;
return IdString64(flow_id->id).to_string();
}
inline void set_id64(FlowId& flow_id, IdString64 id)
{
flow_id.is_id64 = 1;
flow_id.id = id.id();
}
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,17 @@
#pragma once
namespace stingray_plugin_foundation {
struct less
{
template <class A, class B> bool operator()(const A& a, const B& b) const {return (a < b);}
void swap(less &other) {}
};
struct equal_to
{
template <class A, class B> bool operator()(const A& a, const B& b) const {return (a == b);}
void swap(less &other) {}
};
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,192 @@
#pragma once
#include <stdint.h>
#include <string.h>
namespace stingray_plugin_foundation {
// Implementation of the 64 bit murmur hash function
// http://murmurhash.googlepages.com/
inline uint64_t murmur_hash_64(const void * key, int len, uint64_t seed)
{
const uint64_t m = 0xc6a4a7935bd1e995ULL;
const int r = 47;
uint64_t h = seed ^ (len * m);
const uint64_t * data = (const uint64_t *)key;
const uint64_t * end = data + (len/8);
while(data != end)
{
#if defined(ANDROID) || defined(IOS) || defined(WEB) // Unaligned 64bit reads not supported!
uint64_t k;
char *p = (char *)&k, *d = (char *)data;
p[0] = d[0]; p[1] = d[1]; p[2] = d[2]; p[3] = d[3];
p[4] = d[4]; p[5] = d[5]; p[6] = d[6]; p[7] = d[7];
data++;
#elif defined(WINDOWSPC) || defined(UWP) || defined(XBOXONE) || defined(__ORBIS__) || defined(MACOSX) || defined(LINUXPC)
uint64_t k = *data++;
#else
#error Unaligned 64bit reads undefined!
#endif
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
}
const unsigned char * data2 = (const unsigned char*)data;
switch(len & 7)
{
case 7: h ^= uint64_t(data2[6]) << 48;
case 6: h ^= uint64_t(data2[5]) << 40;
case 5: h ^= uint64_t(data2[4]) << 32;
case 4: h ^= uint64_t(data2[3]) << 24;
case 3: h ^= uint64_t(data2[2]) << 16;
case 2: h ^= uint64_t(data2[1]) << 8;
case 1: h ^= uint64_t(data2[0]);
h *= m;
};
h ^= h >> r;
h *= m;
h ^= h >> r;
return h;
}
inline uint64_t hash64(const char *s)
{
return murmur_hash_64(s, int(strlen(s)), 0);
}
inline unsigned hash32(const char *s)
{
uint64_t id64 = murmur_hash_64(s, int(strlen(s)), 0);
return unsigned(id64 >> 32);
}
inline unsigned hash32(const void * key, int len)
{
uint64_t id64 = murmur_hash_64(key, len, 0);
return unsigned(id64 >> 32);
}
// A quick hash for four byte sized values based on a single
// iteration of the murmur hash function.
//
// Another option would be to convert the bit pattern directly to
// an int. That would be faster, but might lead to clustering if
// the input values do not distribute evenly.
inline unsigned int four_byte_hash(const void * key)
{
const unsigned int m = 0x5bd1e995;
const int r = 24;
unsigned int k = *(unsigned int *)key;
k *= m;
k ^= k >> r;
k *= m;
return k;
}
inline uint64_t eight_byte_hash_64(const void * key)
{
const uint64_t m = 0xc6a4a7935bd1e995ULL;
const int r = 47;
uint64_t k = *(const uint64_t *)key;
k *= m;
k ^= k >> r;
k *= m;
return k;
}
// Default hashing for builtin-types.
template <class T> struct default_hash
{
static constexpr bool value = false;
unsigned operator()(T t) const { static_assert(value, "default_hash not implemented for this type!"); return 0; }
};
template <class T> struct default_hash<T *>
{
unsigned operator()(T *t) const
{
#ifdef PLATFORM_64BIT
return (unsigned)eight_byte_hash_64(&t);
#else
return four_byte_hash(&t);
#endif
}
};
template <class T> struct default_hash<const T *>
{
unsigned operator()(const T *t) const
{
#ifdef PLATFORM_64BIT
return (unsigned)eight_byte_hash_64(&t);
#else
return four_byte_hash(&t);
#endif
}
};
template <> struct default_hash<unsigned>
{
unsigned operator()(unsigned t) const { return four_byte_hash(&t); }
};
template <> struct default_hash<int>
{
unsigned operator()(int t) const { return four_byte_hash(&t); }
};
template <> struct default_hash<uint64_t>
{
unsigned operator()(uint64_t t) const { return hash32(&t, sizeof(t)); }
};
template <> struct default_hash<int64_t>
{
unsigned operator()(int64_t t) const { return hash32(&t, sizeof(t)); }
};
// Utility functions
inline uint64_t mix(uint64_t h, uint64_t k)
{
const uint64_t m = 0xc6a4a7935bd1e995ULL;
const int r = 47;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
return h;
}
inline unsigned mix(unsigned h, unsigned k)
{
const unsigned int m = 0x5bd1e995;
const int r = 24;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
return h;
}
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,24 @@
#pragma once
#include <stdint.h>
#include <string.h>
#include "string.h"
#include "hash_function.h"
namespace stingray_plugin_foundation {
struct string_hash
{
unsigned operator()(const char *t) const {return hash32(t);}
unsigned operator()(const ConstString &t) const {return hash32(t.c_str(), t.size());}
unsigned operator()(const DynamicString &t) const {return hash32(t.c_str(), t.size());}
};
struct string_hash64
{
uint64_t operator()(const char *t) const {return murmur_hash_64(t, strlen32(t),0);}
uint64_t operator()(const ConstString &t) const {return murmur_hash_64(t.c_str(), t.size(),0);}
uint64_t operator()(const DynamicString &t) const {return murmur_hash_64(t.c_str(), t.size(),0);}
};
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,145 @@
#pragma once
#include "hash_function.h"
#include "pair.h"
#include "bucket_iterator.h"
#include "vector.h"
#include "functional.h"
namespace stingray_plugin_foundation {
// Implements an unordered map using a hash table.
//
// The hash table allocates its memory in a single block to be as cache
// friendly as possible. Hash collisions are resolved by chaining into
// a separate region of that memory block. This avoids clustering while
// also avoiding the cache inefficiency of linked lists.
//
// A lookup in the spillover area will likely lead to a cache miss, so
// from a cache perspective linear probing might be more efficient.
// OTOH linear probing has a tendency to cause clustering which can
// heavily degrade performance. It also complicates hash table deletes.
//
// For a randomly distributed hash function, a lookup in this hash table
// on average has too look at 1.3 nodes. The expected memory use is
//
// $ 1.37 n (K_s D_s + 4) $,
//
// where `n` is the number of elements and `K_s` is the size of
// the key elements and `D_s` is the size of the data elements. The
// spillover region is set to 37 % of the hash region size. Experimentally
// this has been found to be a good trade off value.
//
// HashMap is a good choice when you need to insert and lookup continuously
// (so you can't use SortMap) and you don't need to do an ordered traversal
// of the items.
// \tparam K the key type
// \tparam D the data type
// \tparam HASH hash functor, defaults to default_hash>
// \tparam EQUAL equality functor, defaults to std::equal_to<K>
template <class K, class D, class HASH = default_hash<K>, class EQUAL = equal_to >
class HashMap
{
public:
ALLOCATOR_AWARE;
typedef K key_type;
typedef D data_type;
typedef HASH key_hash;
typedef EQUAL key_equal;
typedef HashMap<K, D, HASH, EQUAL> this_type;
typedef Pair<key_type, data_type, IS_ALLOCATOR_AWARE(key_type), IS_ALLOCATOR_AWARE(data_type)> value_type;
// Special values for marker
enum {END_OF_LIST = 0x7fffffff, UNUSED = 0xfffffffe, END_OF_FREELIST = 0xffffffff};
typedef BucketIterator<this_type, value_type> iterator;
typedef ConstBucketIterator<this_type, value_type> const_iterator;
HashMap(Allocator &a);
// Creates an unordered map presized to the specified number of buckets and
// spill-over buckets. It is recommended that spill = 0.37 * buckets.
HashMap(unsigned buckets, unsigned spill, Allocator &a);
HashMap(const HashMap<K,D,HASH,EQUAL> &o);
~HashMap();
void operator=(const HashMap<K,D,HASH,EQUAL> &o);
void swap(HashMap<K,D,HASH,EQUAL> &o);
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
template <class KEY_EQ> const_iterator find(const KEY_EQ &k) const;
template <class KEY_EQ> iterator find(const KEY_EQ &k);
Allocator & allocator() const;
void reserve(unsigned size);
unsigned size() const;
bool empty() const;
// Returns true if the key is in the hash
template <class KEY_EQ> bool has(const KEY_EQ &k) const;
template <class KEY_EQ> data_type &operator[](const KEY_EQ &k);
template <class KEY_EQ> value_type &get_pair(const KEY_EQ &k);
template <class KEY_EQ> const data_type &operator[](const KEY_EQ &k) const;
// Returns the value for `k` if it exists and `def` otherwise.
template <class KEY_EQ> data_type &get(const KEY_EQ &k, data_type &def);
template <class KEY_EQ> const data_type &get(const KEY_EQ &k, const data_type &def) const;
void clear();
// Inserts the data point (`k`, `v`) in the map.
template <class KEY_EQ, class DATA_EQ> void insert(const KEY_EQ &k, const DATA_EQ &v);
template <class KEY_EQ> void erase(const KEY_EQ &k);
// Rehashes the data to the specified number of buckets (and a spill
// region of 0.37 * buckets).
// You can use this to reserve memory in the hash before inserting a lot
// of elements to avoid rehashing during insertion. You can also use it
// to shrink a hash, but you cannot shrink a hash beyond its current size.
void rehash(unsigned new_buckets);
// Used by iterator
unsigned num_buckets() const;
bool bucket_valid(unsigned i) const;
value_type &bucket_value(unsigned i);
const value_type &bucket_value(unsigned i) const;
// Serializes the hash map to the stream.
template <class STREAM> void serialize(STREAM &stream);
private:
template <class KEY_EQ> unsigned find_or_fail(const KEY_EQ &k) const;
template <class KEY_EQ> unsigned find_or_make(const KEY_EQ &k);
template <class KEY_EQ> void find_and_erase(const KEY_EQ &k);
bool full() const;
void grow();
template <class KEY_EQ> unsigned hash(const KEY_EQ &k) const;
unsigned allocate_spill();
void free_spill(unsigned i);
void clear_freelist();
void allocate_data(unsigned count);
void construct(value_type &p) { new (&p) value_type(_allocator); }
void destruct(value_type &p) { p.~value_type(); }
struct Data {
Data() : size(), marker(), value() {}
unsigned size;
unsigned *marker;
value_type *value;
};
key_hash _hash;
key_equal _equal;
Data _data;
unsigned _used;
unsigned _buckets;
unsigned _spill_unused;
unsigned _spill_freelist;
Allocator &_allocator;
};
} // namespace stingray_plugin_foundation
#include "hash_map.inl"

View file

@ -0,0 +1,518 @@
namespace stingray_plugin_foundation {
template <class K, class D, class H, class E>
HashMap<K,D,H,E>::HashMap(Allocator &a) : _data(), _used(0), _buckets(0),
_spill_unused(0), _spill_freelist(END_OF_FREELIST), _allocator(a)
{
}
template <class K, class D, class H, class E>
HashMap<K,D,H,E>::HashMap(unsigned buckets, unsigned spill, Allocator &a) :
_data(), _used(0), _buckets(buckets), _spill_unused(spill), _spill_freelist(END_OF_FREELIST)
, _allocator(a)
{
allocate_data(buckets + spill);
for (unsigned i=0; i<_data.size; ++i)
_data.marker[i] = UNUSED;
}
template <class K, class D, class H, class E>
HashMap<K,D,H,E>::HashMap(const HashMap<K,D,H,E> &o) :
_hash(o._hash), _equal(o._equal),
_data(), _used(o._used), _buckets(o._buckets),
_spill_unused(o._spill_unused), _spill_freelist(o._spill_freelist),
_allocator(o._allocator)
{
allocate_data(o._data.size);
for (unsigned i = 0; i < _data.size; ++i) {
if (o._data.marker[i] != UNUSED && (o._data.marker[i] & 0x80000000) == 0) {
construct(_data.value[i]);
_data.value[i] = o._data.value[i];
}
_data.marker[i] = o._data.marker[i];
}
}
template <class K, class D, class H, class E>
void HashMap<K,D,H,E>::operator=(const HashMap<K,D,H,E> &o)
{
if (this == &o)
return;
clear();
_hash = o._hash;
_equal = o._equal;
_allocator.deallocate(_data.marker);
_data.marker = nullptr;
allocate_data(o._data.size);
for (unsigned i = 0; i < _data.size; ++i) {
if (o._data.marker[i] != UNUSED && (o._data.marker[i] & 0x80000000) == 0) {
construct(_data.value[i]);
_data.value[i] = o._data.value[i];
}
_data.marker[i] = o._data.marker[i];
}
_used = o._used;
_buckets = o._buckets;
_spill_unused = o._spill_unused;
_spill_freelist = o._spill_freelist;
}
template <class K, class D, class H, class E>
HashMap<K, D, H, E>::~HashMap()
{
clear();
_allocator.deallocate(_data.marker);
}
template <class K, class D, class H, class E>
void HashMap<K,D,H,E>::swap(HashMap<K,D,H,E> &o)
{
XENSURE(&_allocator == &o._allocator);
std::swap(_hash, o._hash);
std::swap(_equal, o._equal);
std::swap(_data.size, o._data.size);
std::swap(_data.marker, o._data.marker);
std::swap(_data.value, o._data.value);
std::swap(_used, o._used);
std::swap(_buckets, o._buckets);
std::swap(_spill_unused, o._spill_unused);
std::swap(_spill_freelist, o._spill_freelist);
}
template <class K, class D, class H, class E>
typename HashMap<K,D,H,E>::iterator HashMap<K,D,H,E>::begin()
{
return iterator(*this, 0);
}
template <class K, class D, class H, class E>
typename HashMap<K,D,H,E>::iterator HashMap<K,D,H,E>::end()
{
return iterator(*this, num_buckets());
}
template <class K, class D, class H, class E>
typename HashMap<K,D,H,E>::const_iterator HashMap<K,D,H,E>::begin() const
{
return const_iterator(*this, 0);
}
template <class K, class D, class H, class E>
typename HashMap<K,D,H,E>::const_iterator HashMap<K,D,H,E>::end() const
{
return const_iterator(*this, num_buckets());
}
template <class K, class D, class H, class E> template <class KEY_EQ>
typename HashMap<K,D,H,E>::const_iterator HashMap<K,D,H,E>::find(const KEY_EQ &k) const{
auto i = find_or_fail(k);
return (i == END_OF_LIST) ? end() : const_iterator(*this, i);
}
template <class K, class D, class H, class E> template <class KEY_EQ>
typename HashMap<K,D,H,E>::iterator HashMap<K,D,H,E>::find(const KEY_EQ &k){
auto i = find_or_fail(k);
return (i == END_OF_LIST) ? end() : iterator(*this, i);
}
template <class K, class D, class H, class E>
Allocator & HashMap<K,D,H,E>::allocator() const
{
return _allocator;
}
template <class K, class D, class H, class E>
unsigned HashMap<K,D,H,E>::size() const
{
return _used;
}
template <class K, class D, class H, class E>
bool HashMap<K,D,H,E>::empty() const
{
return _used == 0;
}
template <class K, class D, class H, class E> template <class KEY_EQ>
bool HashMap<K,D,H,E>::has(const KEY_EQ &k) const
{
return find_or_fail(k) != END_OF_LIST;
}
template <class K, class D, class H, class E> template <class KEY_EQ>
typename HashMap<K,D,H,E>::data_type &HashMap<K,D,H,E>::operator[](const KEY_EQ &k)
{
if (full()) {
unsigned i = find_or_fail(k);
if (i != END_OF_LIST)
return _data.value[i].second;
grow();
}
return _data.value[find_or_make(k)].second;
}
template <class K, class D, class H, class E> template <class KEY_EQ>
typename HashMap<K, D, H, E>::value_type &HashMap<K, D, H, E>::get_pair(const KEY_EQ &k)
{
if (full()) {
unsigned i = find_or_fail(k);
if (i != END_OF_LIST)
return _data.value[i];
grow();
}
return _data.value[find_or_make(k)];
}
template <class K, class D, class H, class E> template <class KEY_EQ>
const typename HashMap<K,D,H,E>::data_type &HashMap<K,D,H,E>::operator[](const KEY_EQ &k) const
{
unsigned i = find_or_fail(k);
XASSERT(i != END_OF_LIST, "key not in map");
return _data.value[i].second;
}
template <class K, class D, class H, class E> template <class KEY_EQ>
typename HashMap<K,D,H,E>::data_type &HashMap<K,D,H,E>::get(const KEY_EQ &k, data_type &def)
{
unsigned i = find_or_fail(k);
if (i == END_OF_LIST)
return def;
else
return _data.value[i].second;
}
template <class K, class D, class H, class E> template <class KEY_EQ>
const typename HashMap<K,D,H,E>::data_type &HashMap<K,D,H,E>::get(const KEY_EQ &k, const data_type &def) const
{
unsigned i = find_or_fail(k);
if (i == END_OF_LIST)
return def;
else
return _data.value[i].second;
}
template <class K, class D, class H, class E>
void HashMap<K,D,H,E>::clear()
{
_used = 0;
_spill_freelist = END_OF_FREELIST;
_spill_unused = _data.size - _buckets;
for (unsigned i=0; i<_data.size; ++i) {
if (bucket_valid(i))
destruct(_data.value[i]);
_data.marker[i] = UNUSED;
}
}
template <class K, class D, class H, class E> template <class KEY_EQ, class DATA_EQ>
void HashMap<K,D,H,E>::insert(const KEY_EQ &k, const DATA_EQ &v)
{
(*this)[k] = v;
}
template <class K, class D, class H, class E> template <class KEY_EQ>
void HashMap<K,D,H,E>::erase(const KEY_EQ &k)
{
find_and_erase(k);
}
template <class K, class D, class H, class E>
void HashMap<K,D,H,E>::rehash(unsigned new_buckets)
{
XENSURE(new_buckets >= _used);
clear_freelist();
unsigned spill = int(new_buckets * 0.37f + 1);
unsigned old_size = _data.size;
if (_data.size == 0) {
allocate_data(new_buckets + spill);
_buckets = new_buckets;
_spill_unused = spill;
for (unsigned i = 0; i<_data.size; ++i)
_data.marker[i] = UNUSED;
return;
}
this_type new_hash(new_buckets, spill, _allocator);
for (unsigned o=0; o<old_size; ++o) {
if (_data.marker[o] == UNUSED) {
continue;
}
// Find/allocate entry
auto &k = _data.value[o].first;
auto &d = _data.value[o].second;
unsigned i = new_hash.hash(k);
if (new_hash._data.marker[i] == UNUSED) {
new_hash._data.marker[i] = END_OF_LIST;
++new_hash._used;
}
else {
// Walk the hash chain until the end and add a new entry
while (new_hash._data.marker[i] != END_OF_LIST)
i = new_hash._data.marker[i];
unsigned j = new_hash.allocate_spill();
new_hash._data.marker[i] = j;
i = j;
new_hash._data.marker[i] = END_OF_LIST;
}
memmove(&new_hash._data.value[i].first, &k, sizeof(K));
memmove(&new_hash._data.value[i].second, &d, sizeof(D));
_data.marker[o] = UNUSED;
}
swap(new_hash);
}
template <class K, class D, class H, class E>
void HashMap<K,D,H,E>::reserve(unsigned items)
{
unsigned buckets = int(items * 1.37f);
if (buckets < 26)
buckets = 26;
rehash(buckets);
}
template <class K, class D, class H, class E>
unsigned HashMap<K,D,H,E>::num_buckets() const
{
return _data.size;
}
template <class K, class D, class H, class E>
bool HashMap<K,D,H,E>::bucket_valid(unsigned i) const
{
return (_data.marker[i] & 0x80000000) == 0;
}
template <class K, class D, class H, class E>
typename HashMap<K,D,H,E>::value_type &HashMap<K,D,H,E>::bucket_value(unsigned i)
{
return _data.value[i];
}
template <class K, class D, class H, class E>
const typename HashMap<K,D,H,E>::value_type &HashMap<K,D,H,E>::bucket_value(unsigned i) const
{
return _data.value[i];
}
// Searches for `k` in the map. Returns the index of the entry if found and
// END_OF_LIST if not found.
template <class K, class D, class H, class E> template <class KEY_EQ>
unsigned HashMap<K,D,H,E>::find_or_fail(const KEY_EQ &k) const
{
// Is hash empty?
if (empty())
return END_OF_LIST;
unsigned i = hash(k);
// Is primary slot unused?
if (_data.marker[i] == UNUSED)
return END_OF_LIST;
// Walk the hash chain until key matches or end is reached.
while (true) {
if (i == END_OF_LIST || _equal(k, _data.value[i].first))
return i;
i = _data.marker[i];
}
}
// Searches for `k` in the map. Returns the index if it is found. If it is
// not found a new hash slot is create for `k` and its index is returned.
template <class K, class D, class H, class E> template <class KEY_EQ>
unsigned HashMap<K,D,H,E>::find_or_make(const KEY_EQ &k)
{
unsigned i = hash(k);
// Is primary slot unused?
if (_data.marker[i] == UNUSED) {
++_used;
construct(_data.value[i]);
_data.value[i].first = k;
_data.marker[i] = END_OF_LIST;
return i;
}
while (true) {
// Walk the hash chain until found
if (_equal(k, _data.value[i].first) )
return i;
// Or until end of hash chain, in which case we add a new entry
// to the end.
if (_data.marker[i] == END_OF_LIST) {
unsigned j = allocate_spill();
_data.marker[i] = j;
i = j;
construct(_data.value[i]);
_data.value[i].first = k;
_data.marker[i] = END_OF_LIST;
return i;
}
i = _data.marker[i];
}
}
// Searches for `k` in the map. If it is found, it is erased.
template <class K, class D, class H, class E> template <class KEY_EQ>
void HashMap<K,D,H,E>::find_and_erase(const KEY_EQ &k)
{
// early out to avoid division by zero in hash method if the map is empty.
if (_buckets == 0)
return;
unsigned i = hash(k);
// Is primary slot unused?
if (_data.marker[i] == UNUSED)
return;
// Did the primary slot match?
if (_equal(k, _data.value[i].first)) {
// If there is no chain, just return the primary value
if (_data.marker[i] == END_OF_LIST) {
_data.marker[i] = UNUSED;
destruct(_data.value[i]);
--_used;
// If there is a chain, bring in the first value from the
// chain and mark it as free in the spillover region.
} else {
unsigned del = _data.marker[i];
_data.marker[i] = _data.marker[del];
_data.value[i] = _data.value[del];
destruct(_data.value[del]);
free_spill(del);
}
return;
}
// If not, search the hash chain for a match
unsigned prev = i;
while (true) {
// If there is a match remove that value from the chain and
// mark it as free in the spillover region.
if (_equal(k, _data.value[i].first) ) {
_data.marker[prev] = _data.marker[i];
destruct(_data.value[i]);
free_spill(i);
return;
}
// If end of chain was reached without finding the key just return
if (_data.marker[i] == END_OF_LIST)
return;
prev = i;
i = _data.marker[i];
}
}
template <class K, class D, class H, class E>
bool HashMap<K,D,H,E>::full() const
{
// Hash map is full when spillover region is full
return _spill_unused == 0 && _spill_freelist == END_OF_FREELIST;
}
template <class K, class D, class H, class E>
void HashMap<K,D,H,E>::grow()
{
do {
unsigned new_buckets = _buckets * 2 + 1;
if (new_buckets < 19)
new_buckets = 19;
rehash(new_buckets);
} while (full());
}
template <class K, class D, class H, class E> template <class KEY_EQ>
unsigned HashMap<K,D,H,E>::hash(const KEY_EQ &k) const
{
XENSURE(_buckets > 0);
return _hash(k) % _buckets;
}
// Allocate a slot in the spillover region and return it.
template <class K, class D, class H, class E>
unsigned HashMap<K,D,H,E>::allocate_spill()
{
++_used;
// If there spillover free list is non-empty, use its
// first item.
if (_spill_freelist != END_OF_FREELIST) {
unsigned i = _spill_freelist & 0x7fffffff;
_spill_freelist = _data.marker[i];
return i;
}
// Return the first unused item from the spillover region.
XENSURE(_spill_unused > 0);
unsigned i = _data.size - _spill_unused;
--_spill_unused;
_data.marker[i] = UNUSED;
return i;
}
template <class K, class D, class H, class E>
void HashMap<K,D,H,E>::free_spill(unsigned i)
{
// Free a spillover item by inserting it in the freelist.
--_used;
_data.marker[i] = _spill_freelist;
_spill_freelist = i | 0x80000000;
}
// Clears the spillover freelist (marks all items as unused).
template <class K, class D, class H, class E>
void HashMap<K,D,H,E>::clear_freelist()
{
while (_spill_freelist != END_OF_FREELIST) {
unsigned i = _spill_freelist & 0x7fffffff;
_spill_freelist = _data.marker[i];
_data.marker[i] = UNUSED;
}
}
template <class K, class D, class H, class E>
void HashMap<K, D, H, E>::allocate_data(unsigned count)
{
XASSERT(_data.marker == nullptr, "Data must be deallocated/cleared before allocating new data");
if (count == 0) {
_data = Data();
return;
}
auto marker_size = (((sizeof(unsigned) * count) + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*);
auto value_size = sizeof(value_type) * count;
auto data_size = marker_size + value_size;
_data.marker = (unsigned*)_allocator.allocate(data_size);
_data.value = (value_type*)&(((char*)_data.marker)[marker_size]);
_data.size = count;
}
template<class K, class D, class H, class E>
template <class STREAM> void HashMap<K,D,H,E>::serialize(STREAM &stream)
{
unsigned n = size();
stream & n;
if (stream.is_output()) {
iterator it(this->begin());
iterator end(this->end());
for (; it != end; ++it)
stream & (*it);
} else {
reserve(n);
for (unsigned i=0; i<n; ++i) {
value_type v(_allocator);
stream & v;
insert(v.first, v.second);
}
}
}
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,93 @@
#pragma once
#include "vector.h"
#include "hash_function.h"
#include "bucket_iterator.h"
#include "allocator.h"
#include "template_tools.h"
#include "functional.h"
namespace stingray_plugin_foundation {
// Implementation of set using the same technique as HashMap.
// @see HashMap
template <class K, class HASH = default_hash<K>, class EQUAL = equal_to >
class HashSet
{
public:
ALLOCATOR_AWARE;
typedef K key_type;
typedef HASH key_hash;
typedef EQUAL key_equal;
typedef HashSet<K, HASH, EQUAL> this_type;
typedef ConstBucketIterator<this_type, key_type> const_iterator;
typedef BucketIterator<this_type, key_type> iterator;
enum {END_OF_LIST = 0x7fffffff, UNUSED = 0xfffffffe, END_OF_FREELIST = 0xffffffff};
HashSet(Allocator &a);
HashSet(unsigned buckets, unsigned spill, Allocator &a);
HashSet(const HashSet<K,HASH,EQUAL> &o);
~HashSet();
void operator=(const HashSet<K,HASH,EQUAL> &o);
void reserve(unsigned size);
void swap(HashSet<K,HASH,EQUAL> &o);
Allocator & allocator() const;
unsigned size() const;
bool empty() const;
template <class KEY_EQ> bool has(const KEY_EQ &k) const;
void clear();
template <class KEY_EQ> void insert(const KEY_EQ &k);
template <class KEY_EQ> void erase(const KEY_EQ &k);
void rehash(unsigned new_buckets);
const_iterator begin() const;
const_iterator end() const;
unsigned num_buckets() const;
bool bucket_valid(unsigned i) const;
const key_type &bucket_value(unsigned i) const;
key_type &bucket_value(unsigned i);
template <class STREAM> void serialize(STREAM &stream);
private:
template <class KEY_EQ> unsigned find_or_fail(const KEY_EQ &k) const;
template <class KEY_EQ> unsigned find_or_make(const KEY_EQ &k);
template <class KEY_EQ> void find_and_erase(const KEY_EQ &k);
bool full() const;
void grow();
template <class KEY_EQ> unsigned hash(const KEY_EQ &k) const;
unsigned allocate_spill();
void free_spill(unsigned i);
void clear_freelist();
void allocate_data(unsigned count);
void construct(key_type &p, const Int2Type<true> &) { new (&p) key_type(_allocator); }
void construct(key_type &p, const Int2Type<false> &) { new (&p) key_type(); }
void destruct(key_type &p) { p.~key_type(); }
struct Data {
Data() : size(), marker(), key() {}
unsigned size;
unsigned *marker;
key_type *key;
};
key_hash _hash;
key_equal _equal;
Data _data;
unsigned _used;
unsigned _buckets;
unsigned _spill_unused;
unsigned _spill_freelist;
Allocator &_allocator;
};
} // namespace stingray_plugin_foundation
#include "hash_set.inl"

View file

@ -0,0 +1,404 @@
#include "assert.h"
namespace stingray_plugin_foundation {
template<class K, class H, class E>
HashSet<K,H,E>::HashSet(Allocator &a) : _data(), _used(0), _buckets(0),
_spill_unused(0), _spill_freelist(END_OF_FREELIST), _allocator(a)
{}
template<class K, class H, class E>
HashSet<K,H,E>::HashSet(unsigned buckets, unsigned spill, Allocator &a) : _data(),
_used(0), _buckets(buckets), _spill_unused(spill), _spill_freelist(END_OF_FREELIST)
, _allocator(a)
{
allocate_data(buckets + spill);
for (unsigned i=0; i<_data.size; ++i)
_data.marker[i] = UNUSED;
}
template<class K, class H, class E>
HashSet<K,H,E>::HashSet(const HashSet<K,H,E> &o) :
_hash(o._hash), _equal(o._equal),
_data(), _used(o._used), _buckets(o._buckets),
_spill_unused(o._spill_unused), _spill_freelist(o._spill_freelist),
_allocator(o._allocator)
{
allocate_data(o._data.size);
for (unsigned i = 0; i < _data.size; ++i) {
if (o._data.marker[i] != UNUSED && (o._data.marker[i] & 0x80000000) == 0) {
construct(_data.key[i], IS_ALLOCATOR_AWARE_TYPE(K)());
_data.key[i] = o._data.key[i];
}
_data.marker[i] = o._data.marker[i];
}
}
template<class K, class H, class E>
void HashSet<K,H,E>::operator=(const HashSet<K,H,E> &o)
{
if (this == &o)
return;
clear();
_hash = o._hash;
_equal = o._equal;
_allocator.deallocate(_data.marker);
_data.marker = nullptr;
allocate_data(o._data.size);
for (unsigned i = 0; i < _data.size; ++i) {
if (o._data.marker[i] != UNUSED && (o._data.marker[i] & 0x80000000) == 0) {
construct(_data.key[i], IS_ALLOCATOR_AWARE_TYPE(K)());
_data.key[i] = o._data.key[i];
}
_data.marker[i] = o._data.marker[i];
}
_used = o._used;
_buckets = o._buckets;
_spill_unused = o._spill_unused;
_spill_freelist = o._spill_freelist;
}
template<class K, class H, class E>
HashSet<K, H, E>::~HashSet()
{
clear();
_allocator.deallocate(_data.marker);
}
template <class K, class H, class E>
void HashSet<K,H,E>::reserve(unsigned items)
{
unsigned buckets = int(items * 1.37f);
if (buckets < int(19*1.37f))
buckets = int(19*1.37f);
rehash(buckets);
}
template<class K, class H, class E>
void HashSet<K,H,E>::swap(HashSet<K,H,E> &o)
{
XENSURE(&_allocator == &o._allocator);
std::swap(_hash, o._hash);
std::swap(_equal, o._equal);
std::swap(_data.size, o._data.size);
std::swap(_data.marker, o._data.marker);
std::swap(_data.key, o._data.key);
std::swap(_used, o._used);
std::swap(_buckets, o._buckets);
std::swap(_spill_unused, o._spill_unused);
std::swap(_spill_freelist, o._spill_freelist);
}
template<class K, class H, class E>
Allocator & HashSet<K,H,E>::allocator() const
{
return _allocator;
}
template<class K, class H, class E>
unsigned HashSet<K,H,E>::size() const
{
return _used;
}
template<class K, class H, class E>
bool HashSet<K,H,E>::empty() const
{
return _used == 0;
}
template<class K, class H, class E> template <class KEY_EQ>
unsigned HashSet<K,H,E>::find_or_fail(const KEY_EQ &k) const
{
if (empty())
return END_OF_LIST;
unsigned i = hash(k);
if (_data.marker[i] == UNUSED)
return END_OF_LIST;
while (true) {
if (i == END_OF_LIST || _equal(k, _data.key[i]))
return i;
i = _data.marker[i];
}
}
template<class K, class H, class E> template <class KEY_EQ>
unsigned HashSet<K,H,E>::find_or_make(const KEY_EQ &k)
{
unsigned i = hash(k);
if (_data.marker[i] == UNUSED) {
++_used;
construct(_data.key[i], IS_ALLOCATOR_AWARE_TYPE(K)());
_data.key[i] = k;
_data.marker[i] = END_OF_LIST;
return i;
}
while (true) {
if (_equal(k, _data.key[i]) )
return i;
if (_data.marker[i] == END_OF_LIST) {
unsigned j = allocate_spill();
_data.marker[i] = j;
i = j;
construct(_data.key[i], IS_ALLOCATOR_AWARE_TYPE(K)());
_data.key[i] = k;
_data.marker[i] = END_OF_LIST;
return j;
} else
i = _data.marker[i];
}
}
template<class K, class H, class E> template <class KEY_EQ>
void HashSet<K,H,E>::find_and_erase(const KEY_EQ &k)
{
unsigned i = hash(k);
if (_data.marker[i] == UNUSED)
return;
if (_equal(k, _data.key[i])) {
if (_data.marker[i] == END_OF_LIST) {
_data.marker[i] = UNUSED;
destruct(_data.key[i]);
--_used;
} else {
unsigned del = _data.marker[i];
_data.marker[i] = _data.marker[del];
_data.key[i] = _data.key[del];
destruct(_data.key[del]);
free_spill(del);
}
return;
}
unsigned prev = i;
while (true) {
if (_equal(k, _data.key[i]) ) {
_data.marker[prev] = _data.marker[i];
destruct(_data.key[i]);
free_spill(i);
return;
}
if (_data.marker[i] == END_OF_LIST)
return;
prev = i;
i = _data.marker[i];
}
}
template<class K, class H, class E> template <class KEY_EQ>
bool HashSet<K,H,E>::has(const KEY_EQ &k) const
{
return find_or_fail(k) != END_OF_LIST;
}
template<class K, class H, class E>
void HashSet<K,H,E>::clear()
{
_used = 0;
_spill_freelist = END_OF_FREELIST;
_spill_unused = _data.size - _buckets;
for (unsigned i = 0; i<_data.size; ++i) {
if (bucket_valid(i))
destruct(_data.key[i]);
_data.marker[i] = UNUSED;
}
}
template<class K, class H, class E> template <class KEY_EQ>
void HashSet<K,H,E>::insert(const KEY_EQ &k)
{
if (full()) {
unsigned i = find_or_fail(k);
if (i != END_OF_LIST)
return;
grow();
}
find_or_make(k);
}
template<class K, class H, class E> template <class KEY_EQ>
void HashSet<K,H,E>::erase(const KEY_EQ &k)
{
find_and_erase(k);
}
template<class K, class H, class E>
void HashSet<K,H,E>::rehash(unsigned new_buckets)
{
XENSURE(new_buckets >= _used);
clear_freelist();
unsigned spill = int(new_buckets * 0.37f + 1);
unsigned old_size = _data.size;
if (_data.size == 0) {
allocate_data(new_buckets + spill);
_buckets = new_buckets;
_spill_unused = spill;
for (unsigned i = 0; i<_data.size; ++i)
_data.marker[i] = UNUSED;
return;
}
this_type new_set(new_buckets, spill, _allocator);
for (unsigned o = 0; o<old_size; ++o) {
if (_data.marker[o] == UNUSED) {
continue;
}
// Find/allocate entry
auto &k = _data.key[o];
unsigned i = new_set.hash(k);
if (new_set._data.marker[i] == UNUSED) {
new_set._data.marker[i] = END_OF_LIST;
++new_set._used;
}
else {
// Walk the hash chain until the end and add a new entry
while (new_set._data.marker[i] != END_OF_LIST)
i = new_set._data.marker[i];
unsigned j = new_set.allocate_spill();
new_set._data.marker[i] = j;
i = j;
new_set._data.marker[i] = END_OF_LIST;
}
memmove(&new_set._data.key[i], &k, sizeof(K));
_data.marker[o] = UNUSED;
}
swap(new_set);
}
template<class K, class H, class E>
typename HashSet<K,H,E>::const_iterator HashSet<K,H,E>::begin() const
{
return const_iterator(*this, 0);
}
template<class K, class H, class E>
typename HashSet<K,H,E>::const_iterator HashSet<K,H,E>::end() const
{
return const_iterator(*this, num_buckets());
}
template<class K, class H, class E>
unsigned HashSet<K,H,E>::num_buckets() const
{
return _data.size;
}
template<class K, class H, class E>
bool HashSet<K,H,E>::bucket_valid(unsigned i) const
{
return (_data.marker[i] & 0x80000000) == 0;
}
template<class K, class H, class E>
const typename HashSet<K,H,E>::key_type &HashSet<K,H,E>::bucket_value(unsigned i) const
{
return _data.key[i];
}
template<class K, class H, class E>
typename HashSet<K,H,E>::key_type &HashSet<K,H,E>::bucket_value(unsigned i)
{
return _data.key[i];
}
template<class K, class H, class E>
bool HashSet<K,H,E>::full() const
{
return _spill_unused == 0 && _spill_freelist == END_OF_FREELIST;
}
template<class K, class H, class E>
void HashSet<K,H,E>::grow()
{
do {
unsigned new_buckets = _buckets * 2 + 1;
if (new_buckets < 19)
new_buckets = 19;
rehash(new_buckets);
} while (full());
}
template<class K, class H, class E> template <class KEY_EQ>
unsigned HashSet<K,H,E>::hash(const KEY_EQ &k) const
{
return _hash(k) % _buckets;
}
template<class K, class H, class E>
unsigned HashSet<K,H,E>::allocate_spill()
{
++_used;
unsigned i = 0;
if (_spill_freelist != END_OF_FREELIST) {
i = _spill_freelist & 0x7fffffff;
_spill_freelist = _data.marker[i];
return i;
} else {
XENSURE(_spill_unused > 0);
i = _data.size - _spill_unused;
--_spill_unused;
}
_data.marker[i] = UNUSED;
return i;
}
template<class K, class H, class E>
void HashSet<K,H,E>::free_spill(unsigned i)
{
--_used;
_data.marker[i] = _spill_freelist;
_spill_freelist = i | 0x80000000;
}
template<class K, class H, class E>
void HashSet<K,H,E>::clear_freelist()
{
while (_spill_freelist != END_OF_FREELIST) {
unsigned i = _spill_freelist & 0x7fffffff;
_spill_freelist = _data.marker[i];
_data.marker[i] = UNUSED;
}
}
template<class K, class H, class E>
void HashSet<K, H, E>::allocate_data(unsigned count)
{
XASSERT(_data.marker == nullptr, "Data must be deallocated/cleared before allocating new data");
if (count == 0) {
_data = Data();
return;
}
auto marker_size = (((sizeof(unsigned) * count) + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*);
auto key_size = sizeof(key_type) * count;
auto data_size = marker_size + key_size;
_data.marker = (unsigned*)_allocator.allocate(data_size);
_data.key = (key_type*)&(((char*)_data.marker)[marker_size]);
_data.size = count;
}
template<class K, class H, class E>
template <class STREAM> void HashSet<K,H,E>::serialize(STREAM &stream)
{
unsigned n = _used;
stream & n;
if (stream.is_output()) {
iterator it(*this, 0);
iterator end(*this, num_buckets());
for (; it != end; ++it)
stream & *it;
} else {
for (unsigned i=0; i<n; ++i) {
key_type k(_allocator);
stream & k;
insert(k);
}
}
}
} // namespace stingray_plugin_foundation

View file

@ -0,0 +1,109 @@
#pragma once
#include <stdio.h>
#include <stdint.h>
#include "platform.h"
namespace stingray_plugin_foundation {
#define ID32_FORMAT "#ID[%08x]"
#define ID64_FORMAT "#ID[%016llx]"
// An IdString64 is a 64-bit hash of a string value. It can be used
// instead of strings to save memory and processing time.
//
// If you know that the keyspace is small and want to save memory
// you can use an IdString32 instead of an IdString64. IdString32
// uses the same hash function as IdString64, but just keeps the
// first 32 bits of the hash so you can do a reverse lookup using
// the same tables.
class IdString64
{
public:
IdString64();
explicit IdString64(uint64_t id);
explicit IdString64(const char *s);
IdString64(const char *s, uint64_t id);
IdString64(unsigned len, const char *s);
// Returns the stored hash value.
uint64_t id() const {return _id;}
// True if this is the empty string.
bool empty() const {return _id == 0;}
// True if this is not the empty string.
bool nonempty() const {return _id != 0;}
bool operator==(const IdString64 &o) const {return _id == o._id;}
bool operator!=(const IdString64 &o) const {return _id != o._id;}
bool operator<(const IdString64 &o) const {return _id < o._id;}
// Converts the id to a string on the format #ID[xxxxxxxxxxxxxxxx].
// Returns a pointer to a static copy of the result. This will be
// overwritten by next call.
const char *to_string() const {return to_id_hex();}
// Converts the id to a string on the format #ID[xxxxxxxxxxxxxxxx].
// Returns a pointer to a static copy of the result. This will be
// overwritten by next call.
const char *to_id_hex() const;
static const int HEX_BUFFER_SIZE = 17;
// Writes a hexadecimal null terminated string to the memory pointed
// to by `s`. There must be 17 bytes of allocated memory where `s`
// is pointing.
void to_hex(char *s) const {sprintf(s, "%016llx", (unsigned long long)_id);}
private:
uint64_t _id;
};
// A 32 bit hashed string value. If your keyspace is too big and you
// get collisions with this hash, you should switch to an IdString64
// instead.
class IdString32
{
public:
IdString32();
explicit IdString32(unsigned id);
explicit IdString32(uint64_t id64);
explicit IdString32(const char *s);
IdString32(const char *s, unsigned id);
IdString32(unsigned len, const char *s);
template <class STREAM> void serialize(STREAM &s) {
s & _id;
}
// Returns the stored hash value.
unsigned id() const {return _id;}
// True if this is the empty string.
bool empty() const {return _id == 0;}
// True if this is not the empty string.
bool nonempty() const {return _id != 0;}
bool operator==(const IdString32 &o) const {return _id == o._id;}
bool operator!=(const IdString32 &o) const {return _id != o._id;}
bool operator<(const IdString32 &o) const {return _id < o._id;}
const char *to_string() const {return to_id_hex();}
const char *to_id_hex() const;
static const int HEX_BUFFER_SIZE = 9;
char *to_hex(char *s) const {sprintf(s, "%08x", _id); return s;}
private:
unsigned _id;
};
struct idstring_hash {
unsigned operator()(const IdString64 &t) const {return (t.id() >> 32);}
unsigned operator()(const IdString32 &t) const {return t.id();}
};
}
#include "id_string.inl"

View file

@ -0,0 +1,88 @@
#include <stdint.h>
#include "hash_function.h"
#include "array.h"
namespace stingray_plugin_foundation {
inline IdString64::IdString64() : _id(0)
{
}
inline IdString64::IdString64(uint64_t id) : _id(id)
{
}
inline IdString64::IdString64(const char *s)
{
_id = murmur_hash_64(s, (unsigned)strlen(s), 0);
}
inline IdString64::IdString64(unsigned len, const char *s)
{
_id = murmur_hash_64(s, len, 0);
}
inline IdString64::IdString64(const char *s, uint64_t id)
{
_id = id;
#if defined(_DEBUG) && defined(XASSERT)
XASSERT(_id == murmur_hash_64(s, (unsigned)strlen(s), 0), "Bad static idstring `%s`", s);
#endif
}
inline const char *IdString64::to_id_hex() const
{
static char buffer[200];
static char *p = &buffer[0];
if (p + HEX_BUFFER_SIZE + 10 > &buffer[200])
p = &buffer[0];
char hex[HEX_BUFFER_SIZE];
to_hex(hex);
sprintf(p, "#ID[%s]", hex);
char *s = p;
p += strlen(p) + 1;
return s;
}
inline IdString32::IdString32() : _id(0) {}
inline IdString32::IdString32(unsigned id) : _id(id) {}
inline IdString32::IdString32(const char *s)
{
uint64_t id64 = murmur_hash_64(s, (unsigned)strlen(s), 0);
_id = (id64 >> 32);
}
inline IdString32::IdString32(unsigned len, const char *s)
{
uint64_t id64 = murmur_hash_64(s, len, 0);
_id = (id64 >> 32);
}
inline const char *IdString32::to_id_hex() const
{
static char buffer[200];
static char *p = &buffer[0];
if (p + HEX_BUFFER_SIZE + 10 > &buffer[200])
p = &buffer[0];
char hex[HEX_BUFFER_SIZE];
to_hex(hex);
sprintf(p, "#ID[%s]", hex);
char *s = p;
p += strlen(p) + 1;
return s;
}
template <>
template <class STREAM> void Array<IdString64>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
template <>
template <class STREAM> void Array<IdString32>::serialize(STREAM &stream) {
raw_array_serialize(stream, *this);
}
}

View file

@ -0,0 +1,25 @@
#pragma once
#include "vector.h"
#include "types.h"
#include "color.h"
namespace stingray_plugin_foundation
{
namespace line_shapes
{
typedef Vector<Vector3> PointList;
typedef Vector<Color8> ColorList;
void line(const Vector3 &p1, const Vector3 &p2, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors);
void xyz_cross(const Vector3 &pos, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors);
void circle(const Vector3 &pos, float radius, const Vector3 &normal, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments=20);
void cone(const Vector3 &p1, const Vector3 &p2, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments = 20, int bars = 10);
void arrow(const Vector3 &from, const Vector3 &to, float head_height, float head_radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors);
void sphere(const Vector3 &pos, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments = 20, int parts = 2);
} // namespace line_shapes
} // namespace stingray_plugin_foundation
#include "line_shapes.inl"

View file

@ -0,0 +1,80 @@
#include "vector3.h"
namespace stingray_plugin_foundation
{
inline void line_shapes::line(const Vector3 &p1, const Vector3 &p2, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors)
{
out_starts.push_back(p1);
out_ends.push_back(p2);
out_colors.push_back(color);
}
inline void line_shapes::xyz_cross(const Vector3 &pos, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors)
{
line(pos - vector3(radius,0,0), pos + vector3(radius,0,0), color, out_starts, out_ends, out_colors);
line(pos - vector3(0,radius,0), pos + vector3(0,radius,0), color, out_starts, out_ends, out_colors);
line(pos - vector3(0,0,radius), pos + vector3(0,0,radius), color, out_starts, out_ends, out_colors);
}
inline void line_shapes::circle(const Vector3 &pos, float radius, const Vector3 &normal, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments)
{
Vector3 x, y;
make_axes(normal, x, y);
x *= radius;
y *= radius;
Vector3 prev;
for( int i = 0; i <= segments; ++i ) {
float t = ((math::pi*2.0f) / ((float)segments)) * (float)i;
Vector3 point = pos + x * cosf(t) + y * sinf(t);
if (i != 0)
line(prev, point, color, out_starts, out_ends, out_colors);
prev = point;
}
}
inline void line_shapes::cone(const Vector3 &p1, const Vector3 &p2, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments, int bars)
{
Vector3 n = normalize(p1 - p2);
Vector3 x, y;
make_axes(n, x, y);
circle(p2, radius, n, color, out_starts, out_ends, out_colors, segments);
for (int i=0; i<bars; ++i) {
float angle = (float(i)/float(bars)) * 2.0f * math::pi;
Vector3 end = p2 + x*cosf(angle)*radius + y * sinf(angle)*radius;
line(p1, end, color, out_starts, out_ends, out_colors);
}
}
inline void line_shapes::arrow(const Vector3 &from, const Vector3 &to, float head_height, float head_radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors)
{
const Vector3 line_normal = normalize(to - from);
line(from, to, color, out_starts, out_ends, out_colors);
cone(to, to - line_normal * head_height, head_radius, color, out_starts, out_ends, out_colors, 12, 6);
}
inline void line_shapes::sphere(const Vector3 &pos, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments, int parts)
{
if (radius == 0)
return;
for (int i=0; i<parts; ++i) {
float offset = radius*float(i)/float(parts);
float r = sqrtf(radius*radius - offset*offset);
int seg = int( float(segments) * r / radius + 0.5f);
circle(pos + vector3(0,0,offset), r, vector3(0,0,1), color, out_starts, out_ends, out_colors, seg);
circle(pos + vector3(0,offset,0), r, vector3(0,1,0), color, out_starts, out_ends, out_colors, seg);
circle(pos + vector3(offset,0,0), r, vector3(1,0,0), color, out_starts, out_ends, out_colors, seg);
if (i != 0) {
circle(pos - vector3(0,0,offset), r, vector3(0,0,1), color, out_starts, out_ends, out_colors, seg);
circle(pos - vector3(0,offset,0), r, vector3(0,1,0), color, out_starts, out_ends, out_colors, seg);
circle(pos - vector3(offset,0,0), r, vector3(1,0,0), color, out_starts, out_ends, out_colors, seg);
}
}
}
}

View file

@ -0,0 +1,47 @@
#pragma once
#include "types.h"
namespace stingray_plugin_foundation {
// ----------------------------------------------------------------------
// Matrix3x3
// ----------------------------------------------------------------------
// Constructors
inline Matrix3x3 matrix3x3_identity();
// Operations
inline void set_to_identity(Matrix3x3 &tm);
inline Matrix3x3 operator*(const Matrix3x3 &a, const Matrix3x3 &b);
// Conversions
inline Matrix3x3 matrix3x3(const Quaternion &q);
inline Matrix3x3 matrix3x3(const Matrix4x4 &m);
// ----------------------------------------------------------------------
// LocalTransform
// ----------------------------------------------------------------------
// Constructors
inline LocalTransform local_transform(const Matrix3x3 &rot, const Vector3 &pos);
inline LocalTransform local_transform(const Matrix3x3 &rot, const Vector3 &pos, const Vector3 &scale);
inline LocalTransform local_transform_identity();
// Operations
inline void set_to_identity(LocalTransform &tm);
inline LocalTransform operator*(const LocalTransform &a, const LocalTransform &b);
inline void operator*=(LocalTransform &a, const LocalTransform &b);
inline LocalTransform relative(LocalTransform &child, const LocalTransform &parent);
// Conversions
inline LocalTransform local_transform(const Matrix4x4 &tm);
inline Matrix4x4 matrix4x4(const LocalTransform &tm);
// Utility
inline Vector3 transform(const LocalTransform &tm, const Vector3 &p);
inline Vector3 transform_without_translation(const LocalTransform &tm, const Vector3 &p);
}
#include "local_transform.inl"

View file

@ -0,0 +1,189 @@
#include "vector3.h"
#include "quaternion.h"
namespace stingray_plugin_foundation {
// ----------------------------------------------------------------------
// Matrix3x3
// ----------------------------------------------------------------------
inline Matrix3x3 matrix3x3_identity()
{
Matrix3x3 m;
set_to_identity(m);
return m;
}
inline void set_to_identity(Matrix3x3 &m)
{
m.x = vector3(1,0,0);
m.y = vector3(0,1,0);
m.z = vector3(0,0,1);
}
inline Matrix3x3 operator*(const Matrix3x3 &a, const Matrix3x3 &b)
{
Matrix3x3 m;
m.x.x = a.x.x*b.x.x + a.x.y*b.y.x + a.x.z*b.z.x;
m.x.y = a.x.x*b.x.y + a.x.y*b.y.y + a.x.z*b.z.y;
m.x.z = a.x.x*b.x.z + a.x.y*b.y.z + a.x.z*b.z.z;
m.y.x = a.y.x*b.x.x + a.y.y*b.y.x + a.y.z*b.z.x;
m.y.y = a.y.x*b.x.y + a.y.y*b.y.y + a.y.z*b.z.y;
m.y.z = a.y.x*b.x.z + a.y.y*b.y.z + a.y.z*b.z.z;
m.z.x = a.z.x*b.x.x + a.z.y*b.y.x + a.z.z*b.z.x;
m.z.y = a.z.x*b.x.y + a.z.y*b.y.y + a.z.z*b.z.y;
m.z.z = a.z.x*b.x.z + a.z.y*b.y.z + a.z.z*b.z.z;
return m;
}
inline Matrix3x3 matrix3x3(const Quaternion &q)
{
const float d = dot(q,q);
float s = d ? 2.0f / d : 1.0f;
const float xs = q.x * s;
const float ys = q.y * s;
const float zs = q.z * s;
const float wx = q.w * xs;
const float wy = q.w * ys;
const float wz = q.w * zs;
const float xx = q.x * xs;
const float xy = q.x * ys;
const float xz = q.x * zs;
const float yy = q.y * ys;
const float yz = q.y * zs;
const float zz = q.z * zs;
Matrix3x3 m;
m.x = vector3((1.0f - yy - zz), (xy + wz), (xz - wy));
m.y = vector3((xy - wz), (1.0f - xx - zz), (yz + wx));
m.z = vector3((xz + wy), (yz - wx), (1.0f - xx - yy));
return m;
}
inline Matrix3x3 matrix3x3(const Matrix4x4 &tm)
{
Matrix3x3 m;
m.x = x_axis(tm);
m.y = y_axis(tm);
m.z = z_axis(tm);
return m;
}
// ----------------------------------------------------------------------
// LocalTransform
// ----------------------------------------------------------------------
inline LocalTransform local_transform(const Matrix3x3 &rot, const Vector3 &pos)
{
LocalTransform tm;
tm.rot = rot;
tm.pos = pos;
tm.scale = vector3(1,1,1);
tm.dummy = 0.0f;
return tm;
}
inline LocalTransform local_transform(const Matrix3x3 &rot, const Vector3 &pos, const Vector3 &scale)
{
LocalTransform tm;
tm.rot = rot;
tm.pos = pos;
tm.scale = scale;
tm.dummy = 0.0f;
return tm;
}
inline LocalTransform local_transform_identity()
{
LocalTransform tm;
set_to_identity(tm);
return tm;
}
inline void set_to_identity(LocalTransform &tm)
{
set_to_identity(tm.rot);
tm.pos = vector3(0,0,0);
tm.scale = vector3(1,1,1);
tm.dummy = 0.0f;
}
inline Vector3 transform(const LocalTransform &tm, const Vector3 &p)
{
return tm.pos + p.x*tm.rot.x*tm.scale.x + p.y*tm.rot.y*tm.scale.y + p.z*tm.rot.z*tm.scale.z;
}
inline Vector3 transform_without_translation(const LocalTransform &tm, const Vector3 &p)
{
return p.x*tm.rot.x*tm.scale.x + p.y*tm.rot.y*tm.scale.y + p.z*tm.rot.z*tm.scale.z;
}
inline LocalTransform operator*(const LocalTransform &a, const LocalTransform &b)
{
Matrix3x3 a_rs = a.rot;
Matrix3x3 b_rs = b.rot;
a_rs.x = a_rs.x * a.scale.x;
a_rs.y = a_rs.y * a.scale.y;
a_rs.z = a_rs.z * a.scale.z;
b_rs.x = b_rs.x * b.scale.x;
b_rs.y = b_rs.y * b.scale.y;
b_rs.z = b_rs.z * b.scale.z;
LocalTransform res;
res.rot = a_rs * b_rs;
res.scale = vector3(length(res.rot.x), length(res.rot.y), length(res.rot.z));
res.rot.x /= res.scale.x; res.rot.y /= res.scale.y; res.rot.z /= res.scale.z;
res.pos = transform(b, a.pos);
return res;
}
inline void operator*=(LocalTransform &a, const LocalTransform &b)
{
a = a*b;
}
inline LocalTransform relative(LocalTransform &child, const LocalTransform &parent)
{
Matrix4x4 p4i = inverse(matrix4x4(parent));
Matrix4x4 rm = matrix4x4(child) * p4i;
return local_transform(rm);
}
inline LocalTransform local_transform(const Matrix4x4 &m4)
{
LocalTransform tm;
tm.rot.x = x_axis(m4);
tm.rot.y = y_axis(m4);
tm.rot.z = z_axis(m4);
tm.scale = vector3( length(tm.rot.x), length(tm.rot.y), length(tm.rot.z) );
if (tm.scale.x && tm.scale.y && tm.scale.z) {
tm.rot.x /= tm.scale.x;
tm.rot.y /= tm.scale.y;
tm.rot.z /= tm.scale.z;
} else
tm.rot = matrix3x3_identity();
tm.pos = translation(m4);
tm.dummy = 0.0f;
return tm;
}
inline Matrix4x4 matrix4x4(const LocalTransform &tm)
{
Matrix4x4 m4 = matrix4x4_identity();
x_axis(m4) = tm.rot.x * tm.scale.x;
y_axis(m4) = tm.rot.y * tm.scale.y;
z_axis(m4) = tm.rot.z * tm.scale.z;
translation(m4) = tm.pos;
return m4;
}
}

View file

@ -0,0 +1,171 @@
#pragma once
#include "platform.h"
#include <math.h>
#include <limits>
#include <float.h>
namespace stingray_plugin_foundation {
// Common math functions.
namespace math {
const float pi = 3.141592654f;
__forceinline bool is_pow2(unsigned);
__forceinline float square_root(float);
__forceinline float degrees_to_radians(float);
__forceinline float radians_to_degrees(float f);
#undef max
template <class T> __forceinline T max(T a, T b);
template <class T> __forceinline T max3(T a, T b, T c);
#undef min
template <class T> __forceinline T min(T a, T b);
template <class T> __forceinline T min3(T a, T b, T c);
template <class T> __forceinline T clamp(T x, T min, T max);
template <class T> __forceinline T abs(T x);
template <class T> __forceinline T sign(T x);
unsigned branchless_max(unsigned a, unsigned b);
unsigned branchless_min(unsigned a, unsigned b);
unsigned div_ceil(unsigned a, unsigned b);
unsigned div_round(unsigned a, unsigned b);
__forceinline unsigned round_down_to_align(unsigned x, unsigned align) {return x - x%align;}
__forceinline unsigned round_up_to_align(unsigned x, unsigned align) {return round_down_to_align(x+align-1, align);}
__forceinline bool valid(const float *fa, unsigned n)
{
for (unsigned i=0; i<n; ++i) {
float f = fa[i];
if (f != f || f >= FLT_MAX || f <= -FLT_MAX)
return false;
}
return true;
}
__forceinline unsigned log2(unsigned a)
{
unsigned log2 = 0;
while(a >>= 1) log2++;
return log2;
}
}
__forceinline float lerp(float a, float b, float t);
// Finds the maximum value and its source from a number of tested
// values.
template <class SOURCE>
class FindMaximum
{
public:
// Initiates the search for the maximum value.
// * `start` The start value of the search.
FindMaximum(float start = -std::numeric_limits<float>::max()) : _value(start) {}
// Tests if value is the biggest value encountered so far.
// If it is, the value and the source are recorded and the
// function returns true, otherwise it returns false.
bool test(float value, const SOURCE &source) {
if (value > _value) {
_value = value;
_source = source;
return true;
} else
return false;
}
// Returns true if any value bigger than the start value was
// found.
bool found(float start = -std::numeric_limits<float>::max()) {return _value > start;}
// Returns the maximum value found.
const float &value() {return _value;}
// Returns the source of the maximum value found
const SOURCE &source() {return _source;}
private:
float _value;
SOURCE _source;
};
// Finds the minimum value and its source from a number of tested
// values.
template <class SOURCE>
class FindMinimum
{
public:
// Initiates the search for the minimum avlue.
// * `start` The start value of the search
FindMinimum(float start = std::numeric_limits<float>::max()) : _value(start) {}
// Tests if value is the smallest value encountered so far.
// If it is, the value and the source are recorded and the
// function returns true, otherwise it returns false.
bool test(const float &value, const SOURCE &source) {
if (value < _value) {
_value = value;
_source = source;
return true;
} else
return false;
}
// Returns true if any value smaller than the start value was
// found.
bool found(float start = std::numeric_limits<float>::max()) {return _value < start;}
// Returns the maximum value found.
const float &value() {return _value;}
// Returns the source of the maximum value found
const SOURCE &source() {return _source;}
private:
float _value;
SOURCE _source;
};
// Class that represents a cross fade.
// A cross fade is a mix between an in fade and an out fade.
class Crossfade
{
public:
// Creates a new crossfade that is fully faded in.
Crossfade() : _fade_in(1), _fade_in_t(FLT_MAX), _fade_out(0), _fade_out_t(FLT_MAX) {}
// Creates a new crossfade that fades in over time `bt`.
Crossfade(float bt) : _fade_in(0), _fade_in_t(bt), _fade_out(0), _fade_out_t(FLT_MAX) {}
// Fades out the current crossfade over time bt.
void fade_out(float bt) {
if (bt < _fade_out_t)
_fade_out_t = bt;
if (_fade_in_t != FLT_MAX && bt < _fade_in_t)
_fade_in_t = bt;
}
// Updates this crossfade
void update(float dt);
// Returns true if the crossfade is done
bool is_done() {return _fade_out == 1;}
// Returns the current blend value for the crossfade
float blend() {return _fade_in - _fade_out;}
private:
float _fade_in, _fade_in_t;
float _fade_out, _fade_out_t;
};
}
#include "math.inl"

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