mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-20 00:46:34 +00:00
add overlay into main repo
This commit is contained in:
parent
0388a08a16
commit
74576bbe9b
22 changed files with 2228 additions and 4 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -1,3 +1,3 @@
|
|||
[submodule "TrainingModpackOverlay"]
|
||||
path = TrainingModpackOverlay
|
||||
url = https://github.com/jugeeya/TrainingModpackOverlay
|
||||
[submodule "TrainingModpack/libs/libtesla"]
|
||||
path = TrainingModpack/libs/libtesla
|
||||
url = https://github.com/WerWolv/libtesla
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 2a9f0fc2f398e613efd48a63f0c7146ecfcbf2e4
|
70
TrainingModpackOverlay/.clang-format
Normal file
70
TrainingModpackOverlay/.clang-format
Normal file
|
@ -0,0 +1,70 @@
|
|||
---
|
||||
AccessModifierOffset: '-4'
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: 'true'
|
||||
AlignConsecutiveDeclarations: 'true'
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: 'true'
|
||||
AlignTrailingComments: 'true'
|
||||
AllowAllParametersOfDeclarationOnNextLine: 'true'
|
||||
AllowShortBlocksOnASingleLine: 'false'
|
||||
AllowShortCaseLabelsOnASingleLine: 'false'
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: 'true'
|
||||
AllowShortLoopsOnASingleLine: 'true'
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: 'true'
|
||||
AlwaysBreakTemplateDeclarations: 'false'
|
||||
BinPackArguments: 'false'
|
||||
BinPackParameters: 'false'
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: 'true'
|
||||
AfterControlStatement: 'true'
|
||||
AfterEnum: 'true'
|
||||
AfterFunction: 'true'
|
||||
AfterNamespace: 'true'
|
||||
AfterStruct: 'true'
|
||||
AfterUnion: 'true'
|
||||
AfterExternBlock: 'true'
|
||||
BeforeCatch: 'true'
|
||||
BeforeElse: 'true'
|
||||
SplitEmptyFunction: 'false'
|
||||
SplitEmptyRecord: 'false'
|
||||
SplitEmptyNamespace: 'false'
|
||||
BreakBeforeTernaryOperators: 'true'
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakStringLiterals: 'false'
|
||||
ColumnLimit: '128'
|
||||
CompactNamespaces: 'false'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
|
||||
Cpp11BracedListStyle: 'true'
|
||||
FixNamespaceComments: 'true'
|
||||
IncludeBlocks: Regroup
|
||||
IndentCaseLabels: 'false'
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWidth: '4'
|
||||
IndentWrappedFunctionNames: 'true'
|
||||
KeepEmptyLinesAtTheStartOfBlocks: 'false'
|
||||
Language: Cpp
|
||||
MaxEmptyLinesToKeep: '1'
|
||||
PointerAlignment: Left
|
||||
ReflowComments: 'true'
|
||||
SortIncludes: 'false'
|
||||
SortUsingDeclarations: 'false'
|
||||
SpaceAfterCStyleCast: 'false'
|
||||
SpaceAfterTemplateKeyword: 'false'
|
||||
SpaceBeforeAssignmentOperators: 'true'
|
||||
SpaceBeforeParens: Never
|
||||
SpaceInEmptyParentheses: 'false'
|
||||
SpacesInAngles: 'false'
|
||||
SpacesInCStyleCastParentheses: 'false'
|
||||
SpacesInContainerLiterals: 'false'
|
||||
SpacesInParentheses: 'false'
|
||||
SpacesInSquareBrackets: 'false'
|
||||
Standard: Cpp11
|
||||
TabWidth: '4'
|
||||
UseTab: ForIndentation
|
||||
|
||||
...
|
5
TrainingModpackOverlay/.github/FUNDING.yml
vendored
Normal file
5
TrainingModpackOverlay/.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
patreon: werwolv
|
||||
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KP7XRJAND9KWU&source=url
|
||||
github: WerWolv
|
50
TrainingModpackOverlay/.vscode/c_cpp_properties.json
vendored
Normal file
50
TrainingModpackOverlay/.vscode/c_cpp_properties.json
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "DKP Aarch64 Windows",
|
||||
"includePath": [
|
||||
"C:/devkitPro/devkitA64/aarch64-none-elf/include/**",
|
||||
"C:/devkitPro/devkitA64/lib/gcc/aarch64-none-elf/10.1.0/include/**",
|
||||
"C:/devkitPro/libnx/include/**",
|
||||
"C:/devkitPro/portlibs/switch/include/**",
|
||||
"C:/devkitPro/portlibs/switch/include/freetype2/**",
|
||||
"${workspaceFolder}/include/**",
|
||||
"${workspaceFolder}/libs/libtesla/include/**"
|
||||
],
|
||||
"defines": [
|
||||
"SWITCH",
|
||||
"__SWITCH__",
|
||||
"__aarch64__",
|
||||
"VERSION=\"\""
|
||||
],
|
||||
"compilerPath": "C:/devkitPro/devkitA64/bin/aarch64-none-elf-g++",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "gcc-x64"
|
||||
},
|
||||
{
|
||||
"name": "DKP Aarch64 Linux",
|
||||
"includePath": [
|
||||
"/opt/devkitpro/devkitA64/aarch64-none-elf/include/**",
|
||||
"/opt/devkitpro/devkitA64/lib/gcc/aarch64-none-elf/8.3.0/include/**",
|
||||
"/opt/devkitpro/libnx/include/**",
|
||||
"/opt/devkitpro/portlibs/switch/include/**",
|
||||
"/opt/devkitpro/portlibs/switch/include/**",
|
||||
"/opt/devkitpro/portlibs/switch/include/freetype2/**",
|
||||
"${workspaceFolder}/include/**",
|
||||
"${workspaceFolder}/libs/libtesla/include/**"
|
||||
],
|
||||
"defines": [
|
||||
"SWITCH",
|
||||
"__SWITCH__",
|
||||
"__aarch64__",
|
||||
"VERSION=\"\""
|
||||
],
|
||||
"compilerPath": "/opt/devkitpro/devkitA64/bin/aarch64-none-elf-g++",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
61
TrainingModpackOverlay/.vscode/settings.json
vendored
Normal file
61
TrainingModpackOverlay/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"chrono": "cpp",
|
||||
"string_view": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"mutex": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"valarray": "cpp"
|
||||
}
|
||||
}
|
339
TrainingModpackOverlay/LICENSE
Normal file
339
TrainingModpackOverlay/LICENSE
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) 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
|
||||
this service 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 make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. 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.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE 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.
|
||||
|
||||
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
|
||||
convey 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 2 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, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision 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, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This 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.
|
212
TrainingModpackOverlay/Makefile
Normal file
212
TrainingModpackOverlay/Makefile
Normal file
|
@ -0,0 +1,212 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
|
||||
#
|
||||
# NO_ICON: if set to anything, do not use icon.
|
||||
# NO_NACP: if set to anything, no .nacp file is generated.
|
||||
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
|
||||
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
|
||||
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
|
||||
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
|
||||
# ICON is the filename of the icon (.jpg), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.jpg
|
||||
# - icon.jpg
|
||||
# - <libnx folder>/default_icon.jpg
|
||||
#
|
||||
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.json
|
||||
# - config.json
|
||||
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
|
||||
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
|
||||
# NACP building is skipped as well.
|
||||
#---------------------------------------------------------------------------------
|
||||
APP_TITLE := Training Modpack
|
||||
APP_VERSION := 2.05
|
||||
|
||||
TARGET := ovlTrainingModpack
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include libs/libtesla/include
|
||||
|
||||
ifeq ($(RELEASE),)
|
||||
APP_VERSION := $(APP_VERSION)
|
||||
endif
|
||||
|
||||
NO_ICON := 1
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DVERSION=\"v$(APP_VERSION)\"
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-exceptions -std=c++17
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
ifeq ($(strip $(CONFIG_JSON)),)
|
||||
jsons := $(wildcard *.json)
|
||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/$(TARGET).json
|
||||
else
|
||||
ifneq (,$(findstring config.json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/config.json
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ICON)),)
|
||||
icons := $(wildcard *.jpg)
|
||||
ifneq (,$(findstring $(TARGET).jpg,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/$(TARGET).jpg
|
||||
else
|
||||
ifneq (,$(findstring icon.jpg,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/icon.jpg
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_ICON := $(TOPDIR)/$(ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_ICON)),)
|
||||
export NROFLAGS += --icon=$(APP_ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_NACP)),)
|
||||
export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
|
||||
endif
|
||||
|
||||
ifneq ($(APP_TITLEID),)
|
||||
export NACPFLAGS += --titleid=$(APP_TITLEID)
|
||||
endif
|
||||
|
||||
ifneq ($(ROMFS),)
|
||||
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@rm -fr $(BUILD) $(TARGET).ovl $(TARGET).nro $(TARGET).nacp $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all : $(OUTPUT).ovl
|
||||
|
||||
$(OUTPUT).ovl : $(OUTPUT).elf $(OUTPUT).nacp
|
||||
@elf2nro $< $@ $(NROFLAGS)
|
||||
@echo "built ... $(notdir $(OUTPUT).ovl)"
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
7
TrainingModpackOverlay/README.md
Normal file
7
TrainingModpackOverlay/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# ovlSysmodule
|
||||
|
||||
A Tesla overlay that allows you to toggle sysmodules on the fly
|
||||
|
||||
## Installation
|
||||
|
||||
Download the latest ovlSysmodules.ovl from the release page and drop it into the /switch/.overlays folder on your Switch's SD card
|
81
TrainingModpackOverlay/include/clickable_list_item.hpp
Normal file
81
TrainingModpackOverlay/include/clickable_list_item.hpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <tesla.hpp>
|
||||
|
||||
class ClickableListItem : public tsl::elm::ListItem
|
||||
{
|
||||
public:
|
||||
ClickableListItem(std::string text,
|
||||
const std::vector<std::string> values,
|
||||
int* defaultPos,
|
||||
const std::string data,
|
||||
int index,
|
||||
std::string title,
|
||||
std::string help)
|
||||
: tsl::elm::ListItem(text), m_values(values), m_curValue(defaultPos), extdata(data), title(title), help(help)
|
||||
{
|
||||
this->index = index;
|
||||
this->setValue("");
|
||||
}
|
||||
|
||||
~ClickableListItem() {}
|
||||
|
||||
tsl::elm::Element* requestFocus(Element* oldFocus, tsl::FocusDirection direction)
|
||||
{
|
||||
return ListItem::requestFocus(oldFocus, direction);
|
||||
}
|
||||
|
||||
void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight)
|
||||
{
|
||||
ListItem::layout(parentX, parentY, parentWidth, parentHeight);
|
||||
}
|
||||
|
||||
bool onClick(u64 keys)
|
||||
{
|
||||
if(keys & KEY_Y)
|
||||
{
|
||||
if(this->m_helpListener != nullptr)
|
||||
{
|
||||
this->m_helpListener(this->title, this->help);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(keys & KEY_A)
|
||||
{
|
||||
if(this->m_clickListener != nullptr)
|
||||
{
|
||||
this->m_clickListener(this->m_values, this->m_curValue, this->extdata, this->index, this->title, this->help);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int getCurValue() { return *(this->m_curValue); }
|
||||
void setCurValue(int value) { *(this->m_curValue) = value; }
|
||||
|
||||
const std::string getExtData() { return this->extdata; }
|
||||
|
||||
const std::vector<std::string> getValues() { return this->m_values; }
|
||||
|
||||
void setClickListener(
|
||||
std::function<void(const std::vector<std::string>, int*, std::string, int index, std::string title, std::string help)>
|
||||
clickListener)
|
||||
{
|
||||
this->m_clickListener = clickListener;
|
||||
}
|
||||
void setHelpListener(std::function<void(std::string, std::string)> helpListener) { this->m_helpListener = helpListener; }
|
||||
|
||||
private:
|
||||
const std::vector<std::string> m_values;
|
||||
int* m_curValue;
|
||||
std::function<void(const std::vector<std::string>, int*, std::string, int, std::string, std::string)> m_clickListener =
|
||||
nullptr;
|
||||
std::function<void(std::string, std::string)> m_helpListener = nullptr;
|
||||
const std::string extdata;
|
||||
const std::string title;
|
||||
const std::string help;
|
||||
int index;
|
||||
};
|
159
TrainingModpackOverlay/include/cpp_utils.hpp
Normal file
159
TrainingModpackOverlay/include/cpp_utils.hpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<class T, typename U = uint32_t> struct BitFlags
|
||||
{
|
||||
using UnderlyingType = U;
|
||||
using Type = T;
|
||||
|
||||
constexpr static const UnderlyingType s_validMask = (UnderlyingType{1u << *Type::Count} - UnderlyingType{1});
|
||||
|
||||
struct NoneType
|
||||
{};
|
||||
struct AllType
|
||||
{};
|
||||
|
||||
UnderlyingType m_bits;
|
||||
|
||||
constexpr static const AllType All{};
|
||||
constexpr static const NoneType None{};
|
||||
|
||||
BitFlags() = default;
|
||||
BitFlags(const BitFlags&) = default;
|
||||
|
||||
constexpr BitFlags(NoneType) : m_bits(0) {}
|
||||
constexpr BitFlags(AllType) : m_bits(s_validMask) {}
|
||||
constexpr explicit BitFlags(UnderlyingType t) : m_bits(s_validMask & t) {}
|
||||
|
||||
BitFlags& operator=(const BitFlags&) = default;
|
||||
~BitFlags() = default;
|
||||
|
||||
constexpr BitFlags(Type t) : m_bits{UnderlyingType{1} << static_cast<std::underlying_type_t<Type>>(t)} {}
|
||||
|
||||
constexpr BitFlags& operator|=(BitFlags rhs)
|
||||
{
|
||||
m_bits |= rhs.m_bits;
|
||||
return *this;
|
||||
}
|
||||
constexpr BitFlags& operator&=(BitFlags rhs)
|
||||
{
|
||||
m_bits &= rhs.m_bits;
|
||||
return *this;
|
||||
}
|
||||
constexpr BitFlags& operator-=(BitFlags rhs)
|
||||
{
|
||||
m_bits &= ~rhs.m_bits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit operator bool() const { return m_bits != 0; }
|
||||
};
|
||||
|
||||
template<typename T, typename U> constexpr BitFlags<T, U> operator|(BitFlags<T, U> lhs, BitFlags<T, U> rhs)
|
||||
{
|
||||
lhs |= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template<typename T, typename U> constexpr BitFlags<T, U> operator&(BitFlags<T, U> lhs, BitFlags<T, U> rhs)
|
||||
{
|
||||
lhs &= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template<typename T, typename U> constexpr BitFlags<T, U> operator-(BitFlags<T, U> lhs, BitFlags<T, U> rhs)
|
||||
{
|
||||
lhs -= rhs;
|
||||
return lhs;
|
||||
}
|
||||
template<typename T, typename U> constexpr BitFlags<T, U> operator-(BitFlags<T, U> lhs, T rhs)
|
||||
{
|
||||
lhs -= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template<typename T, typename U> constexpr BitFlags<T, U> operator-(T lhs, BitFlags<T, U> rhs)
|
||||
{
|
||||
rhs -= lhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template<typename T, typename U> constexpr BitFlags<T, U> operator|(BitFlags<T, U> lhs, T rhs)
|
||||
{
|
||||
lhs |= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template<typename T, typename U> constexpr BitFlags<T, U> operator|(T lhs, BitFlags<T, U> rhs)
|
||||
{
|
||||
rhs |= lhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template<typename T, typename U> constexpr bool operator&(BitFlags<T, U> lhs, T rhs)
|
||||
{
|
||||
lhs &= rhs;
|
||||
return lhs.m_bits != 0;
|
||||
}
|
||||
|
||||
template<typename T, typename U> constexpr bool operator&(T lhs, BitFlags<T, U> rhs)
|
||||
{
|
||||
rhs &= lhs;
|
||||
return rhs.m_bits != 0;
|
||||
}
|
||||
|
||||
template<typename T> struct FlagType;
|
||||
|
||||
template<typename T> using FlagTypeT = typename FlagType<T>::Type;
|
||||
|
||||
template<class T> struct EnumArray;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#define DEFINE_FLAGS_UT(TypeName, UnderlyingType) \
|
||||
using TypeName##s = detail::BitFlags<TypeName, UnderlyingType>; \
|
||||
constexpr TypeName##s operator|(TypeName lhs, TypeName rhs) { return TypeName##s{lhs} | TypeName##s{rhs}; } \
|
||||
namespace detail \
|
||||
{ \
|
||||
template<> struct FlagType<TypeName> \
|
||||
{ \
|
||||
using Type = TypeName##s; \
|
||||
}; \
|
||||
}
|
||||
|
||||
#define DEFINE_FLAGS(TypeName) DEFINE_FLAGS_UT(TypeName, uint32_t)
|
||||
#define ENUM_X(type, e, y) e,
|
||||
#define ENUM_QUAL_X(type, e, y) type::e,
|
||||
#define ENUM_NAME_PAIR(type, e, y) {type::e, y},
|
||||
#define CASE_X(type, e, y) \
|
||||
case type::e: \
|
||||
return y;
|
||||
#define DEFINE_ENUM_CLASS_TYPE(Name, Type) \
|
||||
enum class Name : Type \
|
||||
{ \
|
||||
ENUM_CLASS_##Name(Name, ENUM_X) Count \
|
||||
}; \
|
||||
constexpr auto operator*(Name t) { return static_cast<std::underlying_type_t<Name>>(t); } \
|
||||
namespace detail \
|
||||
{ \
|
||||
template<> struct EnumArray<Name> \
|
||||
{ \
|
||||
constexpr static const std::array<std::pair<Name, const char*>, *Name::Count> values{ \
|
||||
{ENUM_CLASS_##Name(Name, ENUM_NAME_PAIR)}}; \
|
||||
}; \
|
||||
} \
|
||||
constexpr const char* toString(Name t) \
|
||||
{ \
|
||||
if(t < Name::Count) \
|
||||
{ \
|
||||
return detail::EnumArray<Name>::values[*t].second; \
|
||||
} \
|
||||
return "UNKNWON"; \
|
||||
} \
|
||||
DEFINE_FLAGS_UT(Name, Type)
|
||||
#define DEFINE_ENUM_CLASS(Name) DEFINE_ENUM_CLASS_TYPE(Name, uint32_t)
|
33
TrainingModpackOverlay/include/dir_iterator.hpp
Normal file
33
TrainingModpackOverlay/include/dir_iterator.hpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <switch.h>
|
||||
|
||||
class FsDirIterator
|
||||
{
|
||||
private:
|
||||
FsDir m_dir;
|
||||
FsDirectoryEntry entry;
|
||||
s64 count;
|
||||
|
||||
public:
|
||||
FsDirIterator() = default;
|
||||
FsDirIterator(FsDir dir);
|
||||
|
||||
~FsDirIterator() = default;
|
||||
|
||||
const FsDirectoryEntry& operator*() const;
|
||||
const FsDirectoryEntry* operator->() const;
|
||||
FsDirIterator& operator++();
|
||||
|
||||
bool operator!=(const FsDirIterator& rhs);
|
||||
};
|
||||
|
||||
inline FsDirIterator begin(FsDirIterator iter) noexcept
|
||||
{
|
||||
return iter;
|
||||
}
|
||||
|
||||
inline FsDirIterator end(FsDirIterator) noexcept
|
||||
{
|
||||
return FsDirIterator();
|
||||
}
|
38
TrainingModpackOverlay/include/gui_help.hpp
Normal file
38
TrainingModpackOverlay/include/gui_help.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#include <tesla.hpp>
|
||||
|
||||
static char help_text_global[1024];
|
||||
|
||||
class GuiHelp : public tsl::Gui
|
||||
{
|
||||
public:
|
||||
GuiHelp(std::string title, std::string help) : m_title(std::move(title)), m_help(std::move(help)) {}
|
||||
|
||||
virtual tsl::elm::Element* createUI() override
|
||||
{
|
||||
auto rootFrame = new tsl::elm::OverlayFrame(m_title, "Help");
|
||||
|
||||
snprintf(help_text_global, sizeof help_text_global, "%s", m_help.c_str());
|
||||
|
||||
auto help_text = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer* renderer, u16 x, u16 y, u16 w, u16 h) {
|
||||
renderer->drawString(help_text_global, false, 45, 125, 20, renderer->a(0xFFFF));
|
||||
});
|
||||
|
||||
rootFrame->setContent(help_text);
|
||||
|
||||
return rootFrame;
|
||||
}
|
||||
|
||||
virtual void update() override {}
|
||||
virtual bool handleInput(u64 keysDown,
|
||||
u64 keysHeld,
|
||||
touchPosition touchInput,
|
||||
JoystickPosition leftJoyStick,
|
||||
JoystickPosition rightJoyStick) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string m_title;
|
||||
std::string m_help;
|
||||
};
|
21
TrainingModpackOverlay/include/gui_main.hpp
Normal file
21
TrainingModpackOverlay/include/gui_main.hpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <tesla.hpp>
|
||||
#include "value_list_item.hpp"
|
||||
|
||||
class GuiMain : public tsl::Gui
|
||||
{
|
||||
private:
|
||||
FsFileSystem m_fs;
|
||||
tsl::elm::ToggleListItem* toggleItem = nullptr;
|
||||
std::vector<ValueListItem*> valueListItems;
|
||||
|
||||
public:
|
||||
GuiMain();
|
||||
~GuiMain();
|
||||
|
||||
virtual tsl::elm::Element* createUI();
|
||||
virtual void update() override;
|
||||
void applyChanges();
|
||||
};
|
38
TrainingModpackOverlay/include/gui_sublist.hpp
Normal file
38
TrainingModpackOverlay/include/gui_sublist.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <tesla.hpp>
|
||||
#include "clickable_list_item.hpp"
|
||||
|
||||
class GuiSublist : public tsl::Gui
|
||||
{
|
||||
private:
|
||||
std::vector<tsl::elm::ListItem*> listItems;
|
||||
std::vector<std::string> menuItems;
|
||||
int* index;
|
||||
std::string extData;
|
||||
std::string title;
|
||||
std::string help;
|
||||
|
||||
public:
|
||||
GuiSublist(std::vector<std::string> menuItems, int* index, std::string extData, std::string title, std::string help);
|
||||
~GuiSublist();
|
||||
|
||||
virtual tsl::elm::Element* createUI();
|
||||
virtual void update() override;
|
||||
void applyChanges();
|
||||
virtual void setClickListener(ClickableListItem* item);
|
||||
};
|
||||
|
||||
class GuiLambda : public tsl::Gui
|
||||
{
|
||||
std::function<tsl::elm::Element*()> m_createUI;
|
||||
|
||||
public:
|
||||
virtual tsl::elm::Element* createUI() override
|
||||
{
|
||||
if(m_createUI) return m_createUI();
|
||||
return nullptr;
|
||||
}
|
||||
GuiLambda(std::function<tsl::elm::Element*()> createUIFunc) : m_createUI(std::move(createUIFunc)) {}
|
||||
};
|
270
TrainingModpackOverlay/include/taunt_toggles.hpp
Normal file
270
TrainingModpackOverlay/include/taunt_toggles.hpp
Normal file
|
@ -0,0 +1,270 @@
|
|||
#pragma once
|
||||
|
||||
#define NONE 0
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "cpp_utils.hpp"
|
||||
|
||||
const std::vector<std::string> on_off{"Off", "On"};
|
||||
|
||||
// Frame Advantage
|
||||
const std::vector<std::string> frame_advantage_items{""};
|
||||
const std::string frame_advantage_help = R""""(
|
||||
TODO)"""";
|
||||
|
||||
// Side Taunt
|
||||
|
||||
// DI / Left Stick
|
||||
/*
|
||||
0, 0.785398, 1.570796, 2.356194, -3.14159, -2.356194, -1.570796, -0.785398
|
||||
0, pi/4, pi/2, 3pi/4, pi, 5pi/4, 3pi/2, 7pi/4
|
||||
*/
|
||||
|
||||
/* DI */
|
||||
#define DI_RANDOM_IN_AWAY 9
|
||||
const std::vector<std::string> di_items{"None", "Out", "Up Out", "Up", "Up In", "In", "Down In", "Down", "Down Out", "Random"};
|
||||
const std::string di_help = R""""(
|
||||
Specified Direction
|
||||
CPUs DI in the direction specified
|
||||
(relative to the player's facing
|
||||
position).
|
||||
|
||||
Random Direction
|
||||
CPUs DI randomly in or away.)"""";
|
||||
|
||||
// Left Stick
|
||||
const std::string left_stick_help = R""""(
|
||||
Specified Direction
|
||||
CPUs left stick will be
|
||||
in the direction specified
|
||||
(relative to the player's facing
|
||||
position).
|
||||
|
||||
Currently only used for
|
||||
- air dodge
|
||||
|
||||
)"""";
|
||||
|
||||
// Attack Option
|
||||
#define MASH_NAIR 0
|
||||
#define MASH_FAIR 1
|
||||
#define MASH_BAIR 2
|
||||
#define MASH_UPAIR 3
|
||||
#define MASH_DAIR 4
|
||||
#define MASH_NEUTRAL_B 5
|
||||
#define MASH_SIDE_B 6
|
||||
#define MASH_UP_B 7
|
||||
#define MASH_DOWN_B 8
|
||||
#define MASH_UP_SMASH 9
|
||||
#define MASH_GRAB 10
|
||||
const std::vector<std::string> attack_items{"Neutral Air",
|
||||
"Forward Air",
|
||||
"Back Air",
|
||||
"Up Air",
|
||||
"Down Air",
|
||||
"Neutral B",
|
||||
"Side B",
|
||||
"Up B",
|
||||
"Down B",
|
||||
"Up Smash",
|
||||
"F Smash",
|
||||
"D Smash",
|
||||
"Grab",
|
||||
"Jab",
|
||||
"Ftilt",
|
||||
"Utilt",
|
||||
"Dtilt",
|
||||
"Dash Attack"};
|
||||
const std::string attack_help = R""""(
|
||||
Only active when Mash Toggle is
|
||||
set to Attack.
|
||||
)"""";
|
||||
|
||||
// Ledge Option
|
||||
// clang-format off
|
||||
#define ENUM_CLASS_LedgeFlag(type,x) \
|
||||
x(type,Neutral,"Neutral") \
|
||||
x(type,Roll,"Roll") \
|
||||
x(type,Jump,"Jump") \
|
||||
x(type,Attack,"Attack")
|
||||
|
||||
// clang-format on
|
||||
|
||||
DEFINE_ENUM_CLASS(LedgeFlag);
|
||||
const std::string ledge_help = R""""(
|
||||
CPUs will perform a ledge option.
|
||||
|
||||
Specific ledge options can be
|
||||
chosen and include:
|
||||
Normal, roll, jump, and attack
|
||||
|
||||
CPUs will also perform a defensive
|
||||
option after getting up.
|
||||
)"""";
|
||||
|
||||
// Tech Option
|
||||
|
||||
// clang-format off
|
||||
#define ENUM_CLASS_TechFlag(type,x) \
|
||||
x(type,Miss,"Miss Tech") \
|
||||
x(type,Roll,"Roll") \
|
||||
x(type,InPlace,"In Place")
|
||||
|
||||
// clang-format on
|
||||
DEFINE_ENUM_CLASS(TechFlag);
|
||||
|
||||
constexpr const char* const tech_help = R""""(
|
||||
CPUs will perform a random
|
||||
tech option.
|
||||
|
||||
Specific tech options can be chosen and include:
|
||||
In place, roll, and miss tech
|
||||
|
||||
CPUs will also perform a defensive
|
||||
option after getting up.)"""";
|
||||
|
||||
// Mash States
|
||||
#define MASH_AIRDODGE 1
|
||||
#define MASH_JUMP 2
|
||||
#define MASH_ATTACK 3
|
||||
#define MASH_SPOTDODGE 4
|
||||
#define MASH_ROLL_F 5
|
||||
#define MASH_ROLL_B 6
|
||||
#define MASH_RANDOM 7
|
||||
const std::vector<std::string> mash_items{"None", "Airdodge", "Jump", "Attack", "Spotdodge", "Roll F", "Roll B", "Random"};
|
||||
const std::string mash_help = R""""(
|
||||
Use this toggle along with the Shield
|
||||
Options toggle to practice moves on
|
||||
shield.
|
||||
|
||||
CPUs will mash on the first frame out
|
||||
of hitstun, out of specific states.
|
||||
|
||||
Airdodge
|
||||
- Hitstun
|
||||
CPUs will also shield quickly if they
|
||||
are hit and remain grounded.
|
||||
|
||||
Jump
|
||||
- Hitstun, shieldstun
|
||||
|
||||
Attack
|
||||
- Hitstun, shieldstun, landing.
|
||||
|
||||
Spotdodge
|
||||
- Hitstun, shieldstun, landing.
|
||||
|
||||
Random
|
||||
- Hitstun, shieldstun, landing.)"""";
|
||||
|
||||
// Action items (Follow Up only atm)
|
||||
const std::vector<std::string> action_items{"None", "Airdodge", "Jump", "Spotdodge", "Roll F", "Roll B",
|
||||
"Neutral Air", "Forward Air", "Back Air", "Up Air", "Down Air", "Neutral B",
|
||||
"Side B", "Up B", "Down B", "Up Smash", "F Smash", "D Smash",
|
||||
"Grab", "Jab", "Filt", "Utilt", "Dtilt", "Dash Attack"};
|
||||
const std::string follow_up_help = R""""(
|
||||
Action to buffer
|
||||
after the first mash option
|
||||
)"""";
|
||||
|
||||
// Shield States
|
||||
#define SHIELD_INFINITE 1
|
||||
#define SHIELD_HOLD 2
|
||||
const std::vector<std::string> shield_items{"None", "Infinite", "Hold"};
|
||||
const std::string shield_help = R""""(
|
||||
Use these toggles in conjunction
|
||||
with Mash toggles to practice
|
||||
moves on shield.
|
||||
|
||||
Infinite
|
||||
CPUs will hold a shield that does
|
||||
not deteriorate over time or
|
||||
by damage.
|
||||
|
||||
Hold
|
||||
CPUs will hold a normal shield.)"""";
|
||||
|
||||
// Defensive States
|
||||
#define RANDOM_DEFENSIVE 1
|
||||
#define DEFENSIVE_SPOTDODGE 2
|
||||
#define DEFENSIVE_ROLL 3
|
||||
#define DEFENSIVE_JAB 4
|
||||
#define DEFENSIVE_SHIELD 5
|
||||
const std::vector<std::string> defensive_items{"None", "Random", "Spotdodge", "Roll", "Jab", "Flash Shield"};
|
||||
const std::string defensive_help = R""""(
|
||||
Choose the defensive option a CPU
|
||||
will perform after teching or
|
||||
getting up from the ledge.
|
||||
|
||||
Specific options include:
|
||||
Flash shield, spotdodge, and jab
|
||||
)"""";
|
||||
|
||||
// Hitbox visualization
|
||||
const std::string hitbox_help = R""""(
|
||||
Currently, hitboxes and
|
||||
grabboxes are supported.
|
||||
|
||||
Original move effects are
|
||||
paused during normal attacks
|
||||
and specials when hitbox
|
||||
visualization is active.)"""";
|
||||
|
||||
// Save states
|
||||
const std::vector<std::string> save_state_items{""};
|
||||
const std::string save_states_help = R""""(
|
||||
Press Grab + Down Taunt at any
|
||||
time to save the state of the
|
||||
training mode for you and the
|
||||
CPU.
|
||||
|
||||
Press Grab + Up Taunt at any
|
||||
time to revert to a
|
||||
previously saved state.
|
||||
|
||||
The following attributes
|
||||
are saved:
|
||||
- Percent
|
||||
- Position
|
||||
- Facing direction)"""";
|
||||
|
||||
// OOS
|
||||
const std::vector<std::string> number_list{
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
};
|
||||
const std::string oos_help = R""""(
|
||||
Option to delay oos options
|
||||
until a certain number of hits
|
||||
have connected.
|
||||
|
||||
Consecutive hits that keep the
|
||||
CPU locked in shield stun
|
||||
between hits will count
|
||||
as a single hit.)"""";
|
||||
|
||||
const std::string reaction_time_help = R""""(
|
||||
Additional reaction time
|
||||
in frames
|
||||
|
||||
Used to delay OOS Options.)"""";
|
||||
|
||||
// Mash in neutral
|
||||
const std::string mash_neutral_help = R""""(
|
||||
Force mash options to
|
||||
always occur, not just
|
||||
out of specific states.)"""";
|
||||
|
||||
const std::vector<std::string> number_list_big{
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
|
||||
"15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
|
||||
};
|
168
TrainingModpackOverlay/include/value_list_item.hpp
Normal file
168
TrainingModpackOverlay/include/value_list_item.hpp
Normal file
|
@ -0,0 +1,168 @@
|
|||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <cstdint>
|
||||
#include <tesla.hpp>
|
||||
#include "gui_sublist.hpp"
|
||||
#include "cpp_utils.hpp"
|
||||
|
||||
class ValueListItem : public tsl::elm::ListItem
|
||||
{
|
||||
public:
|
||||
ValueListItem(std::string text,
|
||||
const std::vector<std::string> values,
|
||||
int* defaultPos,
|
||||
const std::string data,
|
||||
const std::string help)
|
||||
: tsl::elm::ListItem(text), m_values(values), m_curValue(defaultPos), extdata(data), help(help)
|
||||
{
|
||||
this->setValue(m_values[*m_curValue]);
|
||||
|
||||
this->initEventListener();
|
||||
}
|
||||
|
||||
~ValueListItem() {}
|
||||
|
||||
void applyChanges()
|
||||
{
|
||||
int value = this->getCurValue();
|
||||
this->setValue(this->getValues()[value]);
|
||||
this->setCurValue(value);
|
||||
}
|
||||
|
||||
tsl::elm::Element* requestFocus(Element* oldFocus, tsl::FocusDirection direction)
|
||||
{
|
||||
return ListItem::requestFocus(oldFocus, direction);
|
||||
}
|
||||
|
||||
void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight)
|
||||
{
|
||||
ListItem::layout(parentX, parentY, parentWidth, parentHeight);
|
||||
}
|
||||
|
||||
bool onClick(u64 keys)
|
||||
{
|
||||
if(keys & KEY_A)
|
||||
{
|
||||
if(this->m_valueChangeListener != nullptr)
|
||||
{
|
||||
this->m_valueChangeListener(this->m_values, this->m_curValue, this->extdata, this->getText(), this->help);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int getCurValue() { return *(this->m_curValue); }
|
||||
void setCurValue(int value) { *(this->m_curValue) = value; }
|
||||
|
||||
const std::string getExtData() { return this->extdata; }
|
||||
|
||||
const std::vector<std::string> getValues() { return this->m_values; }
|
||||
|
||||
void setStateChangedListener(
|
||||
std::function<void(const std::vector<std::string>, int*, std::string, std::string, std::string)> valueChangeListener)
|
||||
{
|
||||
this->m_valueChangeListener = valueChangeListener;
|
||||
}
|
||||
|
||||
protected:
|
||||
void initEventListener()
|
||||
{
|
||||
this->setStateChangedListener(
|
||||
[](std::vector<std::string> menuItems, int* val, std::string data, std::string title, std::string helpTxt) {
|
||||
tsl::changeTo<GuiSublist>(menuItems, val, data, title, helpTxt);
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<std::string> m_values;
|
||||
int* m_curValue;
|
||||
std::function<void(const std::vector<std::string>, int*, std::string, std::string, std::string)> m_valueChangeListener =
|
||||
nullptr;
|
||||
const std::string extdata;
|
||||
const std::string help;
|
||||
};
|
||||
|
||||
template<typename T> class BitFlagToggleListItem : public tsl::elm::ToggleListItem
|
||||
{
|
||||
public:
|
||||
using FlagType = detail::FlagTypeT<T>;
|
||||
|
||||
private:
|
||||
T m_mask;
|
||||
FlagType* m_value;
|
||||
|
||||
public:
|
||||
BitFlagToggleListItem(const std::string& text, T mask, FlagType* value)
|
||||
: tsl::elm::ToggleListItem(text, (mask & *value) != 0), m_mask(mask), m_value(value)
|
||||
{
|
||||
setStateChangedListener([this](bool v) {
|
||||
if(v)
|
||||
{
|
||||
*m_value = *m_value | m_mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_value = *m_value - m_mask;
|
||||
}
|
||||
});
|
||||
}
|
||||
virtual bool onClick(u64 keys) override
|
||||
{
|
||||
// temp band-aid for issues with ToggleListItem
|
||||
if(keys & KEY_A)
|
||||
{
|
||||
setState(!m_state);
|
||||
return ListItem::onClick(keys);
|
||||
}
|
||||
else if(keys & KEY_Y)
|
||||
{}
|
||||
return false;
|
||||
}
|
||||
virtual void setState(bool state) override
|
||||
{
|
||||
// temp band-aid for issues with ToggleListItem
|
||||
bool stateChanged = state != this->m_state;
|
||||
ToggleListItem::setState(state);
|
||||
if(stateChanged && m_stateChangedListener)
|
||||
{
|
||||
m_stateChangedListener(state);
|
||||
}
|
||||
}
|
||||
virtual ~BitFlagToggleListItem() = default;
|
||||
};
|
||||
|
||||
class SetToggleListItem : public tsl::elm::ListItem
|
||||
{
|
||||
std::vector<tsl::elm::ToggleListItem*> m_itemsOn;
|
||||
std::vector<tsl::elm::ToggleListItem*> m_itemsOff;
|
||||
|
||||
public:
|
||||
SetToggleListItem(std::vector<tsl::elm::ToggleListItem*> itemsOn,
|
||||
std::vector<tsl::elm::ToggleListItem*> itemsOff,
|
||||
const std::string& text,
|
||||
const std::string& value = "")
|
||||
: tsl::elm::ListItem(text, value), m_itemsOn(std::move(itemsOn)), m_itemsOff(std::move(itemsOff))
|
||||
{
|
||||
setClickListener([this](u64 keys) -> bool {
|
||||
if(keys & KEY_A)
|
||||
{
|
||||
for(auto it : m_itemsOn)
|
||||
{
|
||||
it->setState(true);
|
||||
}
|
||||
for(auto it : m_itemsOff)
|
||||
{
|
||||
it->setState(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
virtual ~SetToggleListItem() = default;
|
||||
};
|
1
TrainingModpackOverlay/libs/libtesla
Submodule
1
TrainingModpackOverlay/libs/libtesla
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 66285245361a02e5480c7bb7dac9ef6449ae6181
|
27
TrainingModpackOverlay/source/dir_iterator.cpp
Normal file
27
TrainingModpackOverlay/source/dir_iterator.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include "dir_iterator.hpp"
|
||||
|
||||
FsDirIterator::FsDirIterator(FsDir dir) : m_dir(dir)
|
||||
{
|
||||
if(R_FAILED(fsDirRead(&this->m_dir, &this->count, 1, &this->entry))) this->count = 0;
|
||||
}
|
||||
|
||||
const FsDirectoryEntry& FsDirIterator::operator*() const
|
||||
{
|
||||
return this->entry;
|
||||
}
|
||||
|
||||
const FsDirectoryEntry* FsDirIterator::operator->() const
|
||||
{
|
||||
return &**this;
|
||||
}
|
||||
|
||||
FsDirIterator& FsDirIterator::operator++()
|
||||
{
|
||||
if(R_FAILED(fsDirRead(&this->m_dir, &this->count, 1, &this->entry))) this->count = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool FsDirIterator::operator!=(const FsDirIterator& __rhs)
|
||||
{
|
||||
return this->count > 0;
|
||||
}
|
564
TrainingModpackOverlay/source/gui_main.cpp
Normal file
564
TrainingModpackOverlay/source/gui_main.cpp
Normal file
|
@ -0,0 +1,564 @@
|
|||
#include <tesla.hpp>
|
||||
#include "gui_main.hpp"
|
||||
#include "gui_help.hpp"
|
||||
#include "value_list_item.hpp"
|
||||
#include "clickable_list_item.hpp"
|
||||
#include "taunt_toggles.hpp"
|
||||
|
||||
static struct TrainingModpackMenu
|
||||
{
|
||||
int HITBOX_VIS = true;
|
||||
int DI_STATE = NONE;
|
||||
int LEFT_STICK = NONE;
|
||||
int ATTACK_STATE = MASH_NAIR;
|
||||
int FOLLOW_UP = 0;
|
||||
LedgeFlags LEDGE_STATE = LedgeFlags::All;
|
||||
TechFlags TECH_STATE = TechFlags::All;
|
||||
int MASH_STATE = NONE;
|
||||
int SHIELD_STATE = NONE;
|
||||
int DEFENSIVE_STATE = RANDOM_DEFENSIVE;
|
||||
int OOS_OFFSET = 0;
|
||||
int REACTION_TIME = 0;
|
||||
int MASH_IN_NEUTRAL = false;
|
||||
int FAST_FALL = false;
|
||||
int FAST_FALL_DELAY = 0;
|
||||
int FALLING_AERIALS = false;
|
||||
int FULL_HOP = false;
|
||||
} menu;
|
||||
|
||||
static int FRAME_ADVANTAGE = 0;
|
||||
|
||||
u64 pidSmash = 0;
|
||||
static const char* SYSTEM_SETTINGS_FILE = "/atmosphere/config/system_settings.ini";
|
||||
static const char* TRAINING_MOD_LOG = "/TrainingModpack/training_modpack.log";
|
||||
static const char* TRAINING_MOD_FRAME_ADV_LOG = "/TrainingModpack/training_modpack_frame_adv.log";
|
||||
static const char* TRAINING_MOD_CONF = "/TrainingModpack/training_modpack_menu.conf";
|
||||
|
||||
static tsl::hlp::ini::IniData readSettings()
|
||||
{
|
||||
/* Open Sd card filesystem. */
|
||||
FsFileSystem fsSdmc;
|
||||
if(R_FAILED(fsOpenSdCardFileSystem(&fsSdmc))) return {};
|
||||
tsl::hlp::ScopeGuard fsGuard([&] { fsFsClose(&fsSdmc); });
|
||||
|
||||
/* Open config file. */
|
||||
FsFile fileConfig;
|
||||
if(R_FAILED(fsFsOpenFile(&fsSdmc, SYSTEM_SETTINGS_FILE, FsOpenMode_Read, &fileConfig))) return {};
|
||||
tsl::hlp::ScopeGuard fileGuard([&] { fsFileClose(&fileConfig); });
|
||||
|
||||
/* Get config file size. */
|
||||
s64 configFileSize;
|
||||
if(R_FAILED(fsFileGetSize(&fileConfig, &configFileSize))) return {};
|
||||
|
||||
/* Read and parse config file. */
|
||||
std::string configFileData(configFileSize, '\0');
|
||||
u64 readSize;
|
||||
Result rc = fsFileRead(&fileConfig, 0, configFileData.data(), configFileSize, FsReadOption_None, &readSize);
|
||||
if(R_FAILED(rc) || readSize != static_cast<u64>(configFileSize)) return {};
|
||||
|
||||
return tsl::hlp::ini::parseIni(configFileData);
|
||||
}
|
||||
|
||||
static void writeSettings(tsl::hlp::ini::IniData const& iniData)
|
||||
{
|
||||
/* Open Sd card filesystem. */
|
||||
FsFileSystem fsSdmc;
|
||||
if(R_FAILED(fsOpenSdCardFileSystem(&fsSdmc))) return;
|
||||
tsl::hlp::ScopeGuard fsGuard([&] { fsFsClose(&fsSdmc); });
|
||||
|
||||
std::string iniString = tsl::hlp::ini::unparseIni(iniData);
|
||||
|
||||
fsFsDeleteFile(&fsSdmc, SYSTEM_SETTINGS_FILE);
|
||||
fsFsCreateFile(&fsSdmc, SYSTEM_SETTINGS_FILE, iniString.length(), 0);
|
||||
|
||||
/* Open config file. */
|
||||
FsFile fileConfig;
|
||||
if(R_FAILED(fsFsOpenFile(&fsSdmc, SYSTEM_SETTINGS_FILE, FsOpenMode_Write, &fileConfig))) return;
|
||||
tsl::hlp::ScopeGuard fileGuard([&] { fsFileClose(&fileConfig); });
|
||||
|
||||
fsFileWrite(&fileConfig, 0, iniString.c_str(), iniString.length(), FsWriteOption_Flush);
|
||||
}
|
||||
|
||||
static void updateSettings(tsl::hlp::ini::IniData const& changes)
|
||||
{
|
||||
tsl::hlp::ini::IniData iniData = readSettings();
|
||||
for(auto& section : changes)
|
||||
{
|
||||
for(auto& keyValue : section.second)
|
||||
{
|
||||
iniData[section.first][keyValue.first] = keyValue.second;
|
||||
}
|
||||
}
|
||||
writeSettings(iniData);
|
||||
}
|
||||
|
||||
GuiMain::GuiMain()
|
||||
{
|
||||
smInitialize();
|
||||
pminfoInitialize();
|
||||
pmbmInitialize();
|
||||
smExit();
|
||||
|
||||
pmdmntGetProcessId(&pidSmash, 0x01006A800016E000);
|
||||
|
||||
Result rc = fsOpenSdCardFileSystem(&this->m_fs);
|
||||
if(R_FAILED(rc)) return;
|
||||
|
||||
FsFile menuFile;
|
||||
rc = fsFsOpenFile(&this->m_fs, TRAINING_MOD_CONF, FsOpenMode_Read, &menuFile);
|
||||
if(R_FAILED(rc)) return;
|
||||
|
||||
u64 bytesRead;
|
||||
rc = fsFileRead(&menuFile, 0, static_cast<void*>(&menu), sizeof(menu), FsReadOption_None, &bytesRead);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
fsFileWrite(&menuFile, 0, static_cast<void*>(&menu), sizeof(menu), FsOpenMode_Write);
|
||||
}
|
||||
|
||||
fsFileClose(&menuFile);
|
||||
}
|
||||
|
||||
GuiMain::~GuiMain()
|
||||
{
|
||||
smInitialize();
|
||||
pminfoExit();
|
||||
pmbmExit();
|
||||
smExit();
|
||||
}
|
||||
|
||||
static char FrameAdvantage[672];
|
||||
|
||||
class FrameAdvantageOverlayFrame : public tsl::elm::OverlayFrame
|
||||
{
|
||||
public:
|
||||
FrameAdvantageOverlayFrame(const std::string& title, const std::string& subtitle) : tsl::elm::OverlayFrame(title, subtitle)
|
||||
{}
|
||||
|
||||
virtual void draw(tsl::gfx::Renderer* renderer) override
|
||||
{
|
||||
renderer->clearScreen();
|
||||
|
||||
renderer->drawRect(0, 0, tsl::cfg::FramebufferWidth, 85, a(tsl::style::color::ColorFrameBackground));
|
||||
|
||||
renderer->drawString(this->m_title.c_str(), false, 20, 50, 30, a(tsl::style::color::ColorText));
|
||||
renderer->drawString(this->m_subtitle.c_str(), false, 20, 70, 15, a(tsl::style::color::ColorDescription));
|
||||
|
||||
if(this->m_contentElement != nullptr) this->m_contentElement->frame(renderer);
|
||||
}
|
||||
};
|
||||
|
||||
class GuiFrameAdvantage : public tsl::Gui
|
||||
{
|
||||
public:
|
||||
GuiFrameAdvantage()
|
||||
{
|
||||
tsl::hlp::requestForeground(false);
|
||||
smInitialize();
|
||||
pminfoInitialize();
|
||||
pmbmInitialize();
|
||||
smExit();
|
||||
|
||||
pmdmntGetProcessId(&pidSmash, 0x01006A800016E000);
|
||||
|
||||
Result rc = fsOpenSdCardFileSystem(&this->m_fs);
|
||||
if(R_FAILED(rc)) return;
|
||||
}
|
||||
|
||||
~GuiFrameAdvantage()
|
||||
{
|
||||
smInitialize();
|
||||
pminfoExit();
|
||||
pmbmExit();
|
||||
smExit();
|
||||
}
|
||||
|
||||
virtual tsl::elm::Element* createUI() override
|
||||
{
|
||||
snprintf(FrameAdvantage, 256, "Frame Advantage: %d", FRAME_ADVANTAGE);
|
||||
auto rootFrame = new FrameAdvantageOverlayFrame(FrameAdvantage, "\uE0A2 + \uE07B Back");
|
||||
|
||||
this->rootFrame = rootFrame;
|
||||
|
||||
return rootFrame;
|
||||
}
|
||||
|
||||
virtual void update() override
|
||||
{
|
||||
static u32 counter = 0;
|
||||
|
||||
if(counter++ % 10 != 0) return;
|
||||
|
||||
Result rc;
|
||||
Handle debug;
|
||||
|
||||
if(pidSmash != 0)
|
||||
{
|
||||
rc = svcDebugActiveProcess(&debug, pidSmash);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
u64 frame_adv_addr = 0;
|
||||
FsFile menuAddrFile;
|
||||
rc = fsFsOpenFile(&this->m_fs, TRAINING_MOD_FRAME_ADV_LOG, FsOpenMode_Read, &menuAddrFile);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
snprintf(FrameAdvantage, sizeof FrameAdvantage, "Failed to open file with error %d", rc);
|
||||
rootFrame->setTitle(FrameAdvantage);
|
||||
svcCloseHandle(debug);
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[100];
|
||||
u64 bytesRead;
|
||||
rc = fsFileRead(&menuAddrFile, 0, buffer, 100, FsReadOption_None, &bytesRead);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
snprintf(FrameAdvantage, sizeof FrameAdvantage, "Failed to read file with error %d", rc);
|
||||
rootFrame->setTitle(FrameAdvantage);
|
||||
svcCloseHandle(debug);
|
||||
return;
|
||||
}
|
||||
|
||||
fsFileClose(&menuAddrFile);
|
||||
buffer[bytesRead] = '\0';
|
||||
frame_adv_addr = strtoul(buffer, NULL, 16);
|
||||
|
||||
if(frame_adv_addr != 0)
|
||||
{
|
||||
rc = svcReadDebugProcessMemory(&FRAME_ADVANTAGE, debug, frame_adv_addr, sizeof(int));
|
||||
snprintf(FrameAdvantage, sizeof FrameAdvantage, "Frame Advantage: %d", FRAME_ADVANTAGE);
|
||||
rootFrame->setTitle(FrameAdvantage);
|
||||
}
|
||||
|
||||
svcCloseHandle(debug);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(FrameAdvantage, sizeof FrameAdvantage, "Smash is not running.");
|
||||
rootFrame->setTitle(FrameAdvantage);
|
||||
}
|
||||
}
|
||||
virtual bool handleInput(u64 keysDown,
|
||||
u64 keysHeld,
|
||||
touchPosition touchInput,
|
||||
JoystickPosition leftJoyStick,
|
||||
JoystickPosition rightJoyStick) override
|
||||
{
|
||||
if(keysHeld & KEY_DLEFT)
|
||||
{
|
||||
if(keysHeld & KEY_X)
|
||||
{
|
||||
tsl::goBack();
|
||||
tsl::hlp::requestForeground(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// intercept B inputs
|
||||
if(keysDown & KEY_B)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FrameAdvantageOverlayFrame* rootFrame;
|
||||
FsFileSystem m_fs;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T> tsl::elm::ListItem* createBitFlagOption(T* option, const std::string& name, const std::string& help)
|
||||
{
|
||||
using FlagType = typename T::Type;
|
||||
|
||||
auto item = new tsl::elm::ListItem(name);
|
||||
item->setClickListener([name, help, option](u64 keys) -> bool {
|
||||
if(keys & KEY_A)
|
||||
{
|
||||
tsl::changeTo<GuiLambda>([option, name]() -> tsl::elm::Element* {
|
||||
auto toggleList = new tsl::elm::List();
|
||||
std::vector<tsl::elm::ToggleListItem*> items;
|
||||
for(auto& [flag, str] : detail::EnumArray<FlagType>::values)
|
||||
{
|
||||
items.emplace_back(new BitFlagToggleListItem<FlagType>(str, flag, option));
|
||||
}
|
||||
|
||||
auto allOff = new SetToggleListItem({}, items, "None");
|
||||
auto allOn = new SetToggleListItem(items, {}, "All");
|
||||
|
||||
toggleList->addItem(allOn);
|
||||
toggleList->addItem(allOff);
|
||||
|
||||
for(auto it : items)
|
||||
{
|
||||
toggleList->addItem(it);
|
||||
}
|
||||
|
||||
auto frame = new tsl::elm::OverlayFrame(name, "");
|
||||
frame->setContent(toggleList);
|
||||
return frame;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if(keys & KEY_Y)
|
||||
{
|
||||
tsl::changeTo<GuiHelp>(name, help);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return item;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
tsl::elm::Element* GuiMain::createUI()
|
||||
{
|
||||
char buffer[256];
|
||||
snprintf(buffer, 256, "Version %s", VERSION);
|
||||
tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Training Modpack", buffer);
|
||||
|
||||
auto list = new tsl::elm::List();
|
||||
|
||||
Result rc;
|
||||
Handle debug;
|
||||
|
||||
tsl::hlp::ini::IniData iniData = readSettings();
|
||||
bool ease_nro_restriction = false;
|
||||
for(auto& section : iniData)
|
||||
{
|
||||
for(auto& keyValue : section.second)
|
||||
{
|
||||
if(section.first == "ro")
|
||||
{
|
||||
if(keyValue.first == "ease_nro_restriction")
|
||||
{
|
||||
ease_nro_restriction = (readSettings()["ro"]["ease_nro_restriction"] == "u8!0x1");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!ease_nro_restriction)
|
||||
{
|
||||
tsl::elm::Element* iniShow = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer* renderer, u16 x, u16 y, u16 w, u16 h) {
|
||||
renderer->drawString(
|
||||
"Your config file did not have the \nproper configuration to run the \nTraining Modpack.\n\n\nIt has been automatically \nupdated.\n- atmosphere\n---- config\n-------- system_settings.ini\n\n(enable ease_nro_restriction)\n\n\nPlease reboot your Switch.",
|
||||
false,
|
||||
50,
|
||||
225,
|
||||
20,
|
||||
tsl::Color(255, 255, 255, 255));
|
||||
});
|
||||
|
||||
updateSettings({{"ro", {{"ease_nro_restriction", "u8!0x1"}}}});
|
||||
|
||||
rootFrame->setContent(iniShow);
|
||||
return rootFrame;
|
||||
}
|
||||
|
||||
if(pidSmash != 0)
|
||||
{
|
||||
rc = svcDebugActiveProcess(&debug, pidSmash);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
svcCloseHandle(debug);
|
||||
|
||||
ClickableListItem* frameAdvantageItem = new ClickableListItem("Frame Advantage",
|
||||
frame_advantage_items,
|
||||
nullptr,
|
||||
"frameAdvantage",
|
||||
0,
|
||||
"Frame Advantage",
|
||||
frame_advantage_help);
|
||||
frameAdvantageItem->setClickListener([](std::vector<std::string> values,
|
||||
int* curValue,
|
||||
std::string extdata,
|
||||
int index,
|
||||
std::string title,
|
||||
std::string help) { tsl::changeTo<GuiFrameAdvantage>(); });
|
||||
frameAdvantageItem->setHelpListener(
|
||||
[](std::string title, std::string help) { tsl::changeTo<GuiHelp>(title, help); });
|
||||
list->addItem(frameAdvantageItem);
|
||||
|
||||
ValueListItem* hitboxItem =
|
||||
new ValueListItem("Hitbox Visualization", on_off, &menu.HITBOX_VIS, "hitbox", hitbox_help);
|
||||
list->addItem(hitboxItem);
|
||||
valueListItems.push_back(hitboxItem);
|
||||
|
||||
ValueListItem* shieldItem =
|
||||
new ValueListItem("Shield Options", shield_items, &menu.SHIELD_STATE, "shield", shield_help);
|
||||
list->addItem(shieldItem);
|
||||
valueListItems.push_back(shieldItem);
|
||||
|
||||
ValueListItem* mashItem = new ValueListItem("Mash Toggles", mash_items, &menu.MASH_STATE, "mash", mash_help);
|
||||
list->addItem(mashItem);
|
||||
valueListItems.push_back(mashItem);
|
||||
|
||||
ValueListItem* attackItem =
|
||||
new ValueListItem("Attack Toggles", attack_items, &menu.ATTACK_STATE, "attack", attack_help);
|
||||
list->addItem(attackItem);
|
||||
valueListItems.push_back(attackItem);
|
||||
|
||||
ValueListItem* followUp =
|
||||
new ValueListItem("Followup Toggles", action_items, &menu.FOLLOW_UP, "followUp", follow_up_help);
|
||||
list->addItem(followUp);
|
||||
valueListItems.push_back(followUp);
|
||||
|
||||
ValueListItem* mashNeutralItem =
|
||||
new ValueListItem("Mash In Neutral", on_off, &menu.MASH_IN_NEUTRAL, "mash_neutral", mash_neutral_help);
|
||||
list->addItem(mashNeutralItem);
|
||||
valueListItems.push_back(mashNeutralItem);
|
||||
|
||||
list->addItem(createBitFlagOption(&menu.LEDGE_STATE, "Ledge Options", ledge_help));
|
||||
list->addItem(createBitFlagOption(&menu.TECH_STATE, "Tech Options", tech_help));
|
||||
|
||||
ValueListItem* defensiveItem =
|
||||
new ValueListItem("Defensive Options", defensive_items, &menu.DEFENSIVE_STATE, "defensive", defensive_help);
|
||||
list->addItem(defensiveItem);
|
||||
valueListItems.push_back(defensiveItem);
|
||||
|
||||
ValueListItem* diItem = new ValueListItem("Set DI", di_items, &menu.DI_STATE, "di", di_help);
|
||||
list->addItem(diItem);
|
||||
valueListItems.push_back(diItem);
|
||||
|
||||
ValueListItem* leftStickItem =
|
||||
new ValueListItem("Left Stick", di_items, &menu.LEFT_STICK, "leftStick", left_stick_help);
|
||||
list->addItem(leftStickItem);
|
||||
valueListItems.push_back(leftStickItem);
|
||||
|
||||
ValueListItem* oosOffsetItem = new ValueListItem("OOS Offset", number_list, &menu.OOS_OFFSET, "oos", oos_help);
|
||||
list->addItem(oosOffsetItem);
|
||||
valueListItems.push_back(oosOffsetItem);
|
||||
|
||||
ValueListItem* reactionTime =
|
||||
new ValueListItem("Reaction Time", number_list_big, &menu.REACTION_TIME, "reaction_time", reaction_time_help);
|
||||
list->addItem(reactionTime);
|
||||
valueListItems.push_back(reactionTime);
|
||||
|
||||
ValueListItem* fastFallItem = new ValueListItem("Fast Fall", on_off, &menu.FAST_FALL, "fast_fall", "");
|
||||
list->addItem(fastFallItem);
|
||||
valueListItems.push_back(fastFallItem);
|
||||
|
||||
ValueListItem* fastFallDelay =
|
||||
new ValueListItem("Fast Fall Delay", number_list_big, &menu.FAST_FALL_DELAY, "fast_fall", "In Frames");
|
||||
list->addItem(fastFallDelay);
|
||||
valueListItems.push_back(fastFallDelay);
|
||||
|
||||
ValueListItem* fallingAerialsItem =
|
||||
new ValueListItem("Falling Aerials", on_off, &menu.FALLING_AERIALS, "falling_aerials", "");
|
||||
list->addItem(fallingAerialsItem);
|
||||
valueListItems.push_back(fallingAerialsItem);
|
||||
|
||||
ValueListItem* fullHopItem = new ValueListItem("Full Hop", on_off, &menu.FULL_HOP, "full_hop", "");
|
||||
list->addItem(fullHopItem);
|
||||
valueListItems.push_back(fullHopItem);
|
||||
|
||||
ClickableListItem* saveStateItem = new ClickableListItem(
|
||||
"Save States", save_state_items, nullptr, "saveStates", 0, "Save States", save_states_help);
|
||||
saveStateItem->setClickListener([](std::vector<std::string> values,
|
||||
int* curValue,
|
||||
std::string extdata,
|
||||
int index,
|
||||
std::string title,
|
||||
std::string help) { tsl::changeTo<GuiHelp>(title, help); });
|
||||
saveStateItem->setHelpListener([](std::string title, std::string help) { tsl::changeTo<GuiHelp>(title, help); });
|
||||
list->addItem(saveStateItem);
|
||||
|
||||
rootFrame->setContent(list);
|
||||
}
|
||||
else
|
||||
{
|
||||
tsl::elm::Element* warning =
|
||||
new tsl::elm::CustomDrawer([](tsl::gfx::Renderer* renderer, u16 x, u16 y, u16 w, u16 h) {
|
||||
renderer->drawString("\uE150", false, 180, 250, 90, tsl::Color(255, 255, 255, 255));
|
||||
renderer->drawString("Could not debug process memory", false, 110, 340, 25, tsl::Color(255, 255, 255, 255));
|
||||
});
|
||||
|
||||
rootFrame->setContent(warning);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tsl::elm::Element* warning = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer* renderer, u16 x, u16 y, u16 w, u16 h) {
|
||||
renderer->drawString("\uE150", false, 180, 250, 90, tsl::Color(255, 255, 255, 255));
|
||||
renderer->drawString("Smash not running.", false, 110, 340, 25, tsl::Color(255, 255, 255, 255));
|
||||
});
|
||||
|
||||
rootFrame->setContent(warning);
|
||||
}
|
||||
|
||||
return rootFrame;
|
||||
}
|
||||
|
||||
void GuiMain::update()
|
||||
{
|
||||
static u32 counter = 0;
|
||||
|
||||
if(counter++ % 15 != 0) return;
|
||||
|
||||
applyChanges();
|
||||
}
|
||||
|
||||
void GuiMain::applyChanges()
|
||||
{
|
||||
for(ValueListItem* item : valueListItems)
|
||||
{
|
||||
item->applyChanges();
|
||||
}
|
||||
Result rc;
|
||||
Handle debug;
|
||||
|
||||
if(pidSmash != 0)
|
||||
{
|
||||
rc = svcDebugActiveProcess(&debug, pidSmash);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
u64 menu_addr = 0;
|
||||
FsFile menuAddrFile;
|
||||
rc = fsFsOpenFile(&this->m_fs, TRAINING_MOD_LOG, FsOpenMode_Read, &menuAddrFile);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
svcCloseHandle(debug);
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[100];
|
||||
u64 bytesRead;
|
||||
rc = fsFileRead(&menuAddrFile, 0, buffer, 100, FsReadOption_None, &bytesRead);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
svcCloseHandle(debug);
|
||||
return;
|
||||
}
|
||||
|
||||
fsFileClose(&menuAddrFile);
|
||||
buffer[bytesRead] = '\0';
|
||||
menu_addr = strtoul(buffer, NULL, 16);
|
||||
|
||||
if(menu_addr != 0)
|
||||
{
|
||||
rc = svcWriteDebugProcessMemory(debug, &menu, (u64)menu_addr, sizeof(menu));
|
||||
}
|
||||
svcCloseHandle(debug);
|
||||
}
|
||||
}
|
||||
|
||||
FsFile menuFile;
|
||||
fsFsCreateFile(&this->m_fs, TRAINING_MOD_CONF, sizeof(menu), 0);
|
||||
|
||||
rc = fsFsOpenFile(&this->m_fs, TRAINING_MOD_CONF, FsOpenMode_Write, &menuFile);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
fsFileClose(&menuFile);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = fsFileWrite(&menuFile, 0, static_cast<void*>(&menu), sizeof(menu), FsOpenMode_Write);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
fsFileClose(&menuFile);
|
||||
return;
|
||||
}
|
||||
|
||||
fsFileClose(&menuFile);
|
||||
}
|
61
TrainingModpackOverlay/source/gui_sublist.cpp
Normal file
61
TrainingModpackOverlay/source/gui_sublist.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include "gui_sublist.hpp"
|
||||
#include "gui_help.hpp"
|
||||
#include "clickable_list_item.hpp"
|
||||
#include "taunt_toggles.hpp"
|
||||
|
||||
GuiSublist::GuiSublist(std::vector<std::string> menuItems, int* index, std::string extData, std::string title, std::string help)
|
||||
{
|
||||
this->menuItems = menuItems;
|
||||
this->index = index;
|
||||
this->extData = extData;
|
||||
this->title = title;
|
||||
this->help = help;
|
||||
}
|
||||
|
||||
GuiSublist::~GuiSublist() {}
|
||||
|
||||
tsl::elm::Element* GuiSublist::createUI()
|
||||
{
|
||||
tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame(title, "Press \uE0E3 for help with these options.");
|
||||
|
||||
auto list = new tsl::elm::List();
|
||||
|
||||
for(size_t i = 0; i < menuItems.size(); i++)
|
||||
{
|
||||
auto item = new ClickableListItem(menuItems[i], menuItems, this->index, "", i, title, help);
|
||||
setClickListener(item);
|
||||
item->setHelpListener([](std::string title, std::string help) { tsl::changeTo<GuiHelp>(title, help); });
|
||||
list->addItem(item);
|
||||
listItems.push_back(item);
|
||||
}
|
||||
|
||||
list->setFocusedIndex(*index);
|
||||
|
||||
rootFrame->setContent(list);
|
||||
|
||||
return rootFrame;
|
||||
}
|
||||
|
||||
void GuiSublist::setClickListener(ClickableListItem* item)
|
||||
{
|
||||
item->setClickListener([](std::vector<std::string> values,
|
||||
int* curValue,
|
||||
std::string extdata,
|
||||
int index,
|
||||
std::string title,
|
||||
std::string help) {
|
||||
*curValue = index;
|
||||
tsl::goBack();
|
||||
});
|
||||
}
|
||||
|
||||
void GuiSublist::update()
|
||||
{
|
||||
static u32 counter = 0;
|
||||
|
||||
if(counter++ % 15 != 0) return;
|
||||
|
||||
applyChanges();
|
||||
}
|
||||
|
||||
void GuiSublist::applyChanges() {}
|
20
TrainingModpackOverlay/source/main.cpp
Normal file
20
TrainingModpackOverlay/source/main.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#define TESLA_INIT_IMPL
|
||||
#include "gui_main.hpp"
|
||||
|
||||
class TrainingModpackOverlay : public tsl::Overlay
|
||||
{
|
||||
public:
|
||||
TrainingModpackOverlay() {}
|
||||
~TrainingModpackOverlay() {}
|
||||
|
||||
void initServices() override { pmshellInitialize(); }
|
||||
|
||||
void exitServices() override { pmshellExit(); }
|
||||
|
||||
std::unique_ptr<tsl::Gui> loadInitialGui() override { return std::make_unique<GuiMain>(); }
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
return tsl::loop<TrainingModpackOverlay>(argc, argv);
|
||||
}
|
Loading…
Reference in a new issue