add all UI-related stuff from API, including index, nodes, actual ui,

resources, md4c; and fix up some minor formatting issues
This commit is contained in:
HJfod 2022-08-01 18:18:03 +03:00
parent 1f0482be97
commit cdaa8ad6dc
164 changed files with 10246 additions and 11 deletions
.github/workflows
.gitmodules
cmake
loader
CMakeLists.txt
hash
include/Geode
md4c
resources
blanks
GEODE_blank00_00_00-uhd.pngGEODE_blank00_00_01-uhd.pngGEODE_blank00_00_02-uhd.pngGEODE_blank00_00_03-uhd.pngGEODE_blank00_00_04-uhd.pngGEODE_blank00_01_00-uhd.pngGEODE_blank00_01_01-uhd.pngGEODE_blank00_01_02-uhd.pngGEODE_blank00_01_03-uhd.pngGEODE_blank00_01_04-uhd.pngGEODE_blank00_02_00-uhd.pngGEODE_blank00_02_01-uhd.pngGEODE_blank00_02_02-uhd.pngGEODE_blank00_02_03-uhd.pngGEODE_blank00_02_04-uhd.pngGEODE_blank00_03_00-uhd.pngGEODE_blank00_03_01-uhd.pngGEODE_blank00_03_02-uhd.pngGEODE_blank00_03_03-uhd.pngGEODE_blank00_03_04-uhd.pngGEODE_blank00_04_00-uhd.pngGEODE_blank00_04_01-uhd.pngGEODE_blank00_04_02-uhd.pngGEODE_blank00_04_03-uhd.pngGEODE_blank00_04_04-uhd.pngGEODE_blank00_05_00-uhd.pngGEODE_blank00_05_01-uhd.pngGEODE_blank00_05_02-uhd.pngGEODE_blank00_05_03-uhd.pngGEODE_blank00_05_04-uhd.pngGEODE_blank00_06_00-uhd.pngGEODE_blank00_06_01-uhd.pngGEODE_blank00_06_02-uhd.pngGEODE_blank00_06_03-uhd.pngGEODE_blank00_06_04-uhd.pngGEODE_blank00_07_00-uhd.pngGEODE_blank00_07_01-uhd.pngGEODE_blank00_07_02-uhd.pngGEODE_blank00_07_03-uhd.pngGEODE_blank00_07_04-uhd.pngGEODE_blank01_00_00-uhd.pngGEODE_blank01_01_00-uhd.pngGEODE_blank02_00_00-uhd.pngGEODE_blank02_00_01-uhd.pngGEODE_blank02_00_02-uhd.pngGEODE_blank03_00_00-uhd.pngGEODE_blank03_00_01-uhd.pngGEODE_blank04_00_00-uhd.pngGEODE_blank05_00_00-uhd.pngGEODE_blank05_00_01-uhd.pngGEODE_blank05_00_02-uhd.pngGEODE_blank05_00_03-uhd.pngGEODE_blank05_00_04-uhd.pngGEODE_blank05_00_05-uhd.pngGEODE_blank05_00_06-uhd.pngGEODE_blank05_00_07-uhd.pngGEODE_blank05_00_08-uhd.pngGEODE_blank06_00_00-uhd.pngGEODE_blank06_00_01-uhd.pngGEODE_blank06_00_02-uhd.png
filters.png
fonts
images
info-alert.pnginfo-warning.png

View file

@ -42,7 +42,7 @@ jobs:
- name: Configure CMake
run: |
${{ matrix.config.prefixes }} cmake -B ${{ github.workspace }}/build ${{ matrix.config.extra_flags }}
${{ matrix.config.prefixes }} cmake -B ${{ github.workspace }}/build ${{ matrix.config.extra_flags }} -DGEODE_DONT_PACKAGE_RESOURCES
- name: Build
run: |

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "loader/md4c"]
path = loader/md4c
url = https://github.com/mity/md4c

View file

@ -23,3 +23,18 @@ function(create_geode_file proname)
endif()
endfunction()
function(package_geode_resources proname src dest prefix)
message(STATUS "Packaging resources from ${src} with prefix ${prefix} into ${dest}")
if(GEODE_CLI STREQUAL "GEODE_CLI-NOTFOUND")
message(WARNING "package_geode_resources called, but Geode CLI was not found - You will need to manually package the resources")
else()
add_custom_target(${proname}_PACKAGE ALL
DEPENDS ${proname}
COMMAND ${GEODE_CLI} resources ${src} ${dest} --prefix ${prefix} --cached
VERBATIM USES_TERMINAL
)
endif()
endfunction()

View file

@ -3,9 +3,11 @@ cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
project(geode-loader VERSION 0.2.0 LANGUAGES C CXX)
set(PROJECT_VERSION_TYPE Alpha)
# Package info file for internal representation
file(READ resources/about.md LOADER_ABOUT_MD)
configure_file(src/internal/about.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/internal/about.hpp)
# Source files
file(GLOB CORE_SOURCES
src/cocos2d-ext/*.cpp
src/core/*.cpp
@ -22,6 +24,13 @@ file(GLOB CORE_SOURCES
src/utils/*.cpp
src/utils/windows/*.cpp
src/utils/zip/*.cpp
src/index/*.cpp
src/ui/nodes/*.cpp
src/ui/internal/credits/*.cpp
src/ui/internal/dev/*.cpp
src/ui/internal/info/*.cpp
src/ui/internal/list/*.cpp
src/ui/internal/settings/*.cpp
)
file(GLOB OBJC_SOURCES
@ -33,7 +42,7 @@ file(GLOB OBJC_SOURCES
src/utils/mac/*.mm
)
# embed version info in binary
# Embed version info in binary
if (WIN32)
configure_file(src/internal/windows/info.rc.in info.rc)
set(CORE_SOURCES ${CORE_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/info.rc)
@ -55,6 +64,7 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${GEODE_BIN_PATH}"
)
# Move compiled binary into `bin/nightly` directory
if (APPLE)
add_custom_command(
COMMAND
@ -73,10 +83,23 @@ elseif(WIN32)
)
endif()
if (NOT GEODE_DONT_PACKAGE_RESOURCES)
# Package resources for UI
package_geode_resources(
${PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}/resources
${GEODE_BIN_PATH}/nightly/resources
"geode.loader"
)
endif()
target_include_directories(${PROJECT_NAME} PRIVATE
src/internal/
src/platform/
src/gui/
src/index/
md4c/src/
hash/
./ # lilac
)
@ -85,10 +108,15 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAN
target_compile_definitions(${PROJECT_NAME} PUBLIC GEODE_EXPORTING GEODE_PLATFORM_CONSOLE)
# Markdown support
add_subdirectory(md4c)
target_link_libraries(${PROJECT_NAME} md4c)
# Lilac (hooking)
add_subdirectory(lilac)
target_link_libraries(${PROJECT_NAME} z lilac_hook geode-sdk)
target_link_libraries(${PROJECT_NAME} z lilac_hook geode-sdk) # lilac
# Use precompiled headers for faster builds
set_source_files_properties(${OBJC_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
target_precompile_headers(${PROJECT_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/DefaultInclude.hpp"
@ -96,6 +124,7 @@ target_precompile_headers(${PROJECT_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/include/Geode/cocos/cocos2dx/include/cocos2d.h"
)
# Create launcher
if (APPLE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm" OR GEODE_TARGET_PLATFORM STREQUAL "iOS")
add_custom_command(TARGET geode-loader
@ -116,8 +145,12 @@ elseif (WIN32)
target_link_libraries(${PROJECT_NAME} dbghelp)
endif()
# Build test mods if needed
if(NOT GEODE_DONT_BUILD_TEST_MODS)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
add_subdirectory(test)
endif()
endif()
# Build index hashing algorithm test program
add_subdirectory(hash)

View file

@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED On)
project(GeodeChecksum VERSION 1.0)
add_executable(${PROJECT_NAME} hash.cpp)
message(STATUS "Building Checksum Exe")

373
loader/hash/LICENSE Normal file
View file

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

11
loader/hash/hash.cpp Normal file
View file

@ -0,0 +1,11 @@
#include <iostream>
#include "hash.hpp"
int main(int ac, char* av[]) {
if (ac < 2) {
std::cout << "Usage: \"checksum <file>\"\n";
return 1;
}
std::cout << calculateHash(av[1]) << std::hex;
return 0;
}

14
loader/hash/hash.hpp Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include <string>
#include <fstream>
#include <ciso646>
#include "picosha3.h"
#include <vector>
static std::string calculateHash(std::string const& path) {
std::vector<uint8_t> s(picosha3::bits_to_bytes(256));
auto sha3_256 = picosha3::get_sha3_generator<256>();
std::ifstream file(path);
return sha3_256.get_hex_string(file);
}

361
loader/hash/picosha3.h Normal file
View file

@ -0,0 +1,361 @@
#ifndef PICOSHA3_H
#define PICOSHA3_H
#include <array>
#include <cassert>
#include <fstream>
#include <iomanip>
#include <sstream>
namespace picosha3 {
constexpr size_t bits_to_bytes(size_t bits) { return bits / 8; };
constexpr static size_t b_bytes = bits_to_bytes(1600);
constexpr static uint64_t RC[24] = {
0x0000000000000001ull, 0x0000000000008082ull, 0x800000000000808Aull,
0x8000000080008000ull, 0x000000000000808Bull, 0x0000000080000001ull,
0x8000000080008081ull, 0x8000000000008009ull, 0x000000000000008Aull,
0x0000000000000088ull, 0x0000000080008009ull, 0x000000008000000Aull,
0x000000008000808Bull, 0x800000000000008Bull, 0x8000000000008089ull,
0x8000000000008003ull, 0x8000000000008002ull, 0x8000000000000080ull,
0x000000000000800Aull, 0x800000008000000Aull, 0x8000000080008081ull,
0x8000000000008080ull, 0x0000000080000001ull, 0x8000000080008008ull};
using byte_t = uint8_t;
using state_t = std::array<std::array<uint64_t, 5>, 5>;
inline void theta(state_t& A) {
uint64_t C[5] = {0, 0, 0, 0, 0};
for(size_t x = 0; x < 5; ++x) {
C[x] = A[x][0] ^ A[x][1] ^ A[x][2] ^ A[x][3] ^ A[x][4];
};
uint64_t D[5] = {0, 0, 0, 0, 0};
D[0] = C[4] ^ (C[1] << 1 | C[1] >> (64 - 1));
D[1] = C[0] ^ (C[2] << 1 | C[2] >> (64 - 1));
D[2] = C[1] ^ (C[3] << 1 | C[3] >> (64 - 1));
D[3] = C[2] ^ (C[4] << 1 | C[4] >> (64 - 1));
D[4] = C[3] ^ (C[0] << 1 | C[0] >> (64 - 1));
for(size_t x = 0; x < 5; ++x) {
for(size_t y = 0; y < 5; ++y) {
A[x][y] ^= D[x];
}
}
};
inline void rho(state_t& A) {
size_t x{1};
size_t y{0};
for(size_t t = 0; t < 24; ++t) {
size_t offset = ((t + 1) * (t + 2) / 2) % 64;
A[x][y] = (A[x][y] << offset) | (A[x][y] >> (64 - offset));
size_t tmp{y};
y = (2 * x + 3 * y) % 5;
x = tmp;
};
};
inline void pi(state_t& A) {
state_t tmp{A};
for(size_t x = 0; x < 5; ++x) {
for(size_t y = 0; y < 5; ++y) {
A[x][y] = tmp[(x + 3 * y) % 5][x];
}
}
};
inline void chi(state_t& A) {
state_t tmp{A};
for(size_t x = 0; x < 5; ++x) {
for(size_t y = 0; y < 5; ++y) {
A[x][y] =
tmp[x][y] ^ (~(tmp[(x + 1) % 5][y]) & tmp[(x + 2) % 5][y]);
}
}
};
inline void iota(state_t& A, size_t round_index) {
A[0][0] ^= RC[round_index];
};
inline void keccak_p(state_t& A) {
for(size_t round_index = 0; round_index < 24; ++round_index) {
theta(A);
rho(A);
pi(A);
chi(A);
iota(A, round_index);
}
};
namespace {
inline void next(size_t& x, size_t& y, size_t& i) {
if(++i != 8) {
return;
}
i = 0;
if(++x != 5) {
return;
}
x = 0;
if(++y != 5) {
return;
}
}
} // namespace
template <typename InIter>
void absorb(InIter first, InIter last, state_t& A) {
size_t x = 0;
size_t y = 0;
size_t i = 0;
for(; first != last && y < 5; ++first) {
auto tmp = static_cast<uint64_t>(*first);
A[x][y] ^= (tmp << (i * 8));
next(x, y, i);
};
}
template <typename InContainer>
void absorb(const InContainer& src, state_t& A) {
absorb(src.cbegin(), src.cend(), A);
};
template <typename OutIter>
OutIter squeeze(const state_t& A, OutIter first, OutIter last,
size_t rate_bytes) {
size_t x = 0;
size_t y = 0;
size_t i = 0;
for(size_t read_bytes = 0;
first != last && y < 5 && read_bytes < rate_bytes;
++read_bytes, ++first) {
auto tmp = static_cast<uint64_t>(A[x][y]);
auto p = reinterpret_cast<byte_t*>(&tmp);
*first = *(p + i);
next(x, y, i);
}
return first;
};
template <typename OutContainer>
typename OutContainer::iterator
squeeze(const state_t& A, OutContainer& dest, size_t rate_bytes) {
return squeeze(A, dest.begin(), dest.end(), rate_bytes);
}
enum class PaddingType {
SHA,
SHAKE,
};
template <typename InIter>
std::string bytes_to_hex_string(InIter first, InIter last) {
std::stringstream ss;
ss << std::hex;
for(; first != last; ++first) {
ss << std::setw(2) << std::setfill('0')
<< static_cast<uint64_t>(*first);
}
return ss.str();
}
template <typename InContainer>
std::string bytes_to_hex_string(const InContainer& src) {
return bytes_to_hex_string(src.cbegin(), src.cend());
}
template <size_t rate_bytes, size_t d_bytes, PaddingType padding_type>
class HashGenerator {
public:
HashGenerator()
: buffer_{}, buffer_pos_{buffer_.begin()}, A_{}, hash_{},
is_finished_{false} {}
void clear() {
clear_state();
clear_buffer();
is_finished_ = false;
}
template <typename InIter>
void process(InIter first, InIter last) {
static_assert(
sizeof(typename std::iterator_traits<InIter>::value_type) == 1,
"The size of input iterator value_type must be one byte.");
for(; first != last; ++first) {
*buffer_pos_ = *first;
if(++buffer_pos_ == buffer_.end()) {
absorb(buffer_, A_);
keccak_p(A_);
clear_buffer();
}
}
};
void finish() {
add_padding();
absorb(buffer_, A_);
keccak_p(A_);
squeeze_();
is_finished_ = true;
};
template <typename OutIter>
void get_hash_bytes(OutIter first, OutIter last) {
if(!is_finished_) {
throw std::runtime_error("Not finished!");
}
std::copy(hash_.cbegin(), hash_.cend(), first);
};
template <typename OutCotainer>
void get_hash_bytes(OutCotainer& dest) {
get_hash_bytes(dest.begin(), dest.end());
};
template <typename InIter, typename OutIter>
void operator()(InIter in_first, InIter in_last, OutIter out_first,
OutIter out_last) {
static_assert(
sizeof(typename std::iterator_traits<InIter>::value_type) == 1,
"The size of input iterator value_type must be one byte.");
static_assert(
sizeof(typename std::iterator_traits<OutIter>::value_type) == 1,
"The size of output iterator value_type must be one byte.");
process(in_first, in_last);
finish();
std::copy(hash_.cbegin(), hash_.cend(), out_first);
clear();
};
template <typename InIter, typename OutCotainer>
void operator()(InIter in_first, InIter in_last, OutCotainer& dest) {
operator()(in_first, in_last, dest.begin(), dest.end());
};
template <typename InContainer, typename OutIter>
void operator()(const InContainer& src, OutIter out_first,
OutIter out_last) {
operator()(src.cbegin(), src.cend(), out_first, out_last);
};
template <typename InContainer, typename OutContainer>
void operator()(const InContainer& src, OutContainer& dest) {
operator()(src.cbegin(), src.cend(), dest.begin(), dest.end());
};
template <typename OutIter>
void operator()(std::ifstream& ifs, OutIter out_first,
OutIter out_last) {
auto in_first = std::istreambuf_iterator<char>(ifs);
auto in_last = std::istreambuf_iterator<char>();
operator()(in_first, in_last, out_first, out_last);
};
template <typename OutCotainer>
void operator()(std::ifstream& ifs, OutCotainer& dest) {
operator()(ifs, dest.begin(), dest.end());
};
std::string get_hex_string() {
if(!is_finished_) {
throw std::runtime_error("Not finished!");
}
return bytes_to_hex_string(hash_);
};
template <typename InIter>
std::string get_hex_string(InIter in_first, InIter in_last) {
process(in_first, in_last);
finish();
auto hash = get_hex_string();
clear();
return hash;
};
template <typename InContainer>
std::string get_hex_string(const InContainer& src) {
return get_hex_string(src.cbegin(), src.cend());
};
std::string get_hex_string(std::ifstream& ifs) {
auto in_first = std::istreambuf_iterator<char>(ifs);
auto in_last = std::istreambuf_iterator<char>();
return get_hex_string(in_first, in_last);
};
private:
void clear_buffer() {
buffer_.fill(0);
buffer_pos_ = buffer_.begin();
};
void clear_state() {
for(auto& row : A_) {
row.fill(0);
}
};
void add_padding() {
const auto q =
buffer_.size() - std::distance(buffer_pos_, buffer_.begin());
if(padding_type == PaddingType::SHA) {
if(q == 1) {
*buffer_pos_ = 0x86;
} else {
*buffer_pos_ = 0x06;
buffer_.back() = 0x80;
}
} else if(padding_type == PaddingType::SHAKE) {
if(q == 1) {
*buffer_pos_ = 0x9F;
} else {
*buffer_pos_ = 0x1F;
buffer_.back() = 0x80;
}
}
};
void squeeze_() {
auto first = hash_.begin();
auto last = hash_.end();
first = squeeze(A_, first, last, rate_bytes);
while(first != last) {
keccak_p(A_);
first = squeeze(A_, first, last, rate_bytes);
}
};
std::array<byte_t, rate_bytes> buffer_;
typename decltype(buffer_)::iterator buffer_pos_;
state_t A_;
std::array<byte_t, d_bytes> hash_;
bool is_finished_;
};
template <size_t d_bits>
auto get_sha3_generator() {
static_assert(
d_bits == 224 or d_bits == 256 or d_bits == 384 or d_bits == 512,
"SHA3 only accepts digest message length 224, 256 384 or 512 bits.");
constexpr auto d_bytes = bits_to_bytes(d_bits);
constexpr auto capacity_bytes = d_bytes * 2;
constexpr auto rate_bytes = b_bytes - capacity_bytes;
return HashGenerator<rate_bytes, d_bytes, PaddingType::SHA>{};
}
template <size_t strength_bits, size_t d_bits>
auto get_shake_generator() {
static_assert(strength_bits == 128 or strength_bits == 256,
"SHAKE only accepts strength 128 or 256 bits.");
constexpr auto strength_bytes = bits_to_bytes(strength_bits);
constexpr auto capacity_bytes = strength_bytes * 2;
constexpr auto rate_bytes = b_bytes - capacity_bytes;
constexpr auto d_bytes = bits_to_bytes(d_bits);
return HashGenerator<rate_bytes, d_bytes, PaddingType::SHAKE>{};
}
} // namespace picosha3
#endif

View file

@ -3,4 +3,5 @@
#include "Bindings.hpp"
#include "Utils.hpp"
#include "Loader.hpp"
#include "Modify.hpp"
#include "Modify.hpp"
#include "UI.hpp"

View file

@ -0,0 +1,15 @@
#pragma once
#include "ui/BasedButton.hpp"
#include "ui/BasedButtonSprite.hpp"
#include "ui/IconButtonSprite.hpp"
#include "ui/InputNode.hpp"
#include "ui/ListView.hpp"
#include "ui/MDTextArea.hpp"
#include "ui/MenuInputNode.hpp"
#include "ui/Notification.hpp"
#include "ui/Popup.hpp"
#include "ui/SceneManager.hpp"
#include "ui/Scrollbar.hpp"
#include "ui/ScrollLayer.hpp"
#include "ui/TextRenderer.hpp"

View file

@ -13,4 +13,5 @@
#include "utils/ext.hpp"
#include "utils/convert.hpp"
#include "utils/cocos.hpp"
#include "utils/operators.hpp"
#include "utils/operators.hpp"
#include "utils/Ref.hpp"

View file

@ -0,0 +1,24 @@
#pragma once
#include "BasedButtonSprite.hpp"
#pragma warning(disable : 4275)
namespace geode {
class GEODE_DLL TabButton : public CCMenuItemToggler {
public:
static TabButton* create(
TabBaseColor unselected,
TabBaseColor selected,
const char* text,
cocos2d::CCObject* target,
cocos2d::SEL_MenuHandler callback
);
static TabButton* create(
const char* text,
cocos2d::CCObject* target,
cocos2d::SEL_MenuHandler callback
);
};
} // namespace geode

View file

@ -0,0 +1,135 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
enum class CircleBaseSize {
Tiny = 0, // Equivalent to the tiny delete button
Small = 1, // Equivalent to most circular buttons in the editor
Small2 = 2, // Equivalent to the trash button in the editor
Medium = 3, // Equivalent to most buttons
Medium2 = 4, // Equivalent to the bottom buttons in MenuLayer
Big = 5, // Equivalent to the New button
Big2 = 6, // Equivalent to the Account button
Large = 7, // Equivalent to the big Play Button
};
enum class CrossBaseSize {
Small = 0,
Huge = 1,
};
enum class CircleBaseColor {
Green = 0,
Pink = 1,
Gray = 2,
Blue = 3,
Cyan = 4,
Geode = 5,
};
enum class AccountBaseColor {
Blue = 0,
Gray = 1,
Purple = 2,
};
enum class IconSelectBaseColor {
Gray = 0,
Selected = 1,
};
enum class EditorBaseColor {
LightBlue = 0,
Green = 1,
Orange = 2,
DarkGray = 3,
Gray = 4,
Pink = 5,
Teal = 6,
Aqua = 7,
Cyan = 8,
};
enum class TabBaseColor {
Unselected = 0,
Selected = 1,
UnselectedDark = 2,
};
enum class BaseType {
Circle = 0,
Cross = 1,
Account = 2,
IconSelect = 3,
GlobalThing = 4,
Editor = 5,
Tab = 6,
};
/**
* Represents a GD button sprite where there's
* an icon sprite on top another default sprite.
* You know, it has a base. It's based.
* lmao trademark lizbith
*/
class GEODE_DLL BasedButtonSprite : public cocos2d::CCSprite {
protected:
int m_type;
int m_size;
int m_color;
cocos2d::CCNode* m_onTop = nullptr;
bool init(cocos2d::CCNode* ontop, int type, int size, int color);
bool initWithSprite(const char* sprName, float sprScale, int type, int size, int color);
bool initWithSpriteFrameName(const char* sprName, float sprScale, int type, int size, int color);
cocos2d::CCPoint getTopOffset() const;
virtual ~BasedButtonSprite();
public:
static BasedButtonSprite* create(cocos2d::CCNode* ontop, int type, int size, int color);
};
class GEODE_DLL CircleButtonSprite : public BasedButtonSprite {
public:
static CircleButtonSprite* create(
cocos2d::CCNode* top,
CircleBaseColor color = CircleBaseColor::Green,
CircleBaseSize size = CircleBaseSize::Medium
);
static CircleButtonSprite* createWithSprite(
const char* sprName,
float sprScale = 1.f,
CircleBaseColor color = CircleBaseColor::Green,
CircleBaseSize size = CircleBaseSize::Medium
);
static CircleButtonSprite* createWithSpriteFrameName(
const char* sprName,
float sprScale = 1.f,
CircleBaseColor color = CircleBaseColor::Green,
CircleBaseSize size = CircleBaseSize::Medium
);
};
class GEODE_DLL EditorButtonSprite : public BasedButtonSprite {
public:
static EditorButtonSprite* create(cocos2d::CCNode* top, EditorBaseColor color);
static EditorButtonSprite* createWithSprite(
const char* sprName,
float sprScale = 1.f,
EditorBaseColor color = EditorBaseColor::Green
);
static EditorButtonSprite* createWithSpriteFrameName(
const char* sprName,
float sprScale = 1.f,
EditorBaseColor color = EditorBaseColor::Green
);
};
class GEODE_DLL TabButtonSprite : public BasedButtonSprite {
public:
static TabButtonSprite* create(const char* text, TabBaseColor color);
};
}

View file

@ -0,0 +1,51 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
class GEODE_DLL IconButtonSprite :
public cocos2d::CCSprite,
public cocos2d::CCLabelProtocol
{
protected:
cocos2d::extension::CCScale9Sprite* m_bg = nullptr;
cocos2d::CCLabelBMFont* m_label = nullptr;
cocos2d::CCNode* m_icon = nullptr;
bool init(
const char* bg,
bool bgIsFrame,
cocos2d::CCNode* icon,
const char* text,
const char* font
);
void updateLayout();
IconButtonSprite() = default;
IconButtonSprite(IconButtonSprite&&) = delete;
IconButtonSprite& operator=(IconButtonSprite&&) = delete;
public:
static IconButtonSprite* create(
const char* bg,
cocos2d::CCNode* icon,
const char* text,
const char* font
);
static IconButtonSprite* createWithSpriteFrameName(
const char* bg,
cocos2d::CCNode* icon,
const char* text,
const char* font
);
void setBG(const char* bg, bool isFrame);
void setIcon(cocos2d::CCNode* icon);
cocos2d::CCNode* getIcon() const;
void setString(const char* label) override;
const char* getString() override;
};
}

View file

@ -0,0 +1,53 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
class GEODE_DLL InputNode : public cocos2d::CCNode {
protected:
cocos2d::extension::CCScale9Sprite* m_bgSprite;
CCTextInputNode* m_input;
bool init(float, float, const char*, const char*, std::string const&, int);
bool init(float, const char*, const char*, std::string const&, int);
public:
static InputNode* create(
float width,
const char* placeholder,
const char* fontFile,
std::string const& filter,
int limit
);
static InputNode* create(
float width,
const char* placeholder,
std::string const& filter,
int limit
);
static InputNode* create(
float width,
const char* placeholder,
std::string const& filter
);
static InputNode* create(
float width,
const char* placeholder,
const char* fontFile
);
static InputNode* create(
float width,
const char* placeholder
);
CCTextInputNode* getInputNode() const;
cocos2d::extension::CCScale9Sprite* getBGSprite() const;
void setEnabled(bool);
void setString(const char*);
const char* getString();
};
}

View file

@ -0,0 +1,48 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
class GEODE_DLL GenericListCell : public TableViewCell {
protected:
GenericListCell(const char* name, cocos2d::CCSize size);
void draw() override;
public:
static GenericListCell* create(const char* key, cocos2d::CCSize size);
void updateBGColor(int index);
};
/**
* Class for a generic scrollable list of
* items like the level list in GD
*/
class GEODE_DLL ListView : public CustomListView {
protected:
void setupList() override;
TableViewCell* getListCell(const char* key) override;
void loadCell(TableViewCell* cell, unsigned int index) override;
public:
/**
* Create a generic scrollable list of
* items
* @param items Nodes to add as children
* @param itemHeight Height of each child
* @param width Width of the list
* @param height Height of the list
* @returns The created ListView, or nullptr
* on error
*/
static ListView* create(
cocos2d::CCArray* items,
float itemHeight = 40.f,
float width = 358.f,
float height = 220.f
);
};
}

View file

@ -0,0 +1,74 @@
#pragma once
#include <Geode/Geode.hpp>
#include "TextRenderer.hpp"
#include "ScrollLayer.hpp"
struct MDParser;
namespace geode {
/**
* TextArea for static markdown content. Supports the
* following features:
* - Links
* - Images (sprites & spritesheets)
* - Headings
* - Paragraphs
* - Code blocks
* - Code spans
* - TextArea color tags (<cr>, <cy>, etc.)
* - Strikethrough
* - Underline
* - Bold & italic
* - Horizontal rules
* - Lists
* Note that links also have some special protocols.
* Use `user:<id>` or `user:<name>` to link to a GD
* account; `level:<id>` to link to a GD level and
* `mod:<id>` to link to another Geode mod.
*/
class GEODE_DLL MDTextArea :
public cocos2d::CCLayer,
public cocos2d::CCLabelProtocol,
public FLAlertLayerProtocol
{
protected:
std::string m_text;
cocos2d::CCSize m_size;
cocos2d::extension::CCScale9Sprite* m_bgSprite = nullptr;
cocos2d::CCMenu* m_content = nullptr;
CCScrollLayerExt* m_scrollLayer = nullptr;
TextRenderer* m_renderer = nullptr;
bool init(std::string const& str, cocos2d::CCSize const& size);
virtual ~MDTextArea();
void onLink(CCObject*);
void onGDProfile(CCObject*);
void FLAlert_Clicked(FLAlertLayer*, bool btn) override;
friend struct ::MDParser;
public:
/**
* Create a markdown text area. See class
* documentation for details on supported
* features & notes.
* @param str String to render
* @param size Size of the textarea
*/
static MDTextArea* create(std::string const& str, cocos2d::CCSize const& size);
/**
* Update the label's content; call
* sparingly as rendering may be slow
*/
void updateLabel();
void setString(const char* text) override;
const char* getString() override;
CCScrollLayerExt* getScrollLayer() const;
};
}

View file

@ -0,0 +1,39 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
/**
* Simple wrapper around CCTextInputNode that
* turns it into a CCMenuItem that can be used
* in a CCMenu. Can help with touch dispatcher
* issues. Also comes with a background sprite
*/
class GEODE_DLL MenuInputNode : public cocos2d::CCMenuItem {
protected:
cocos2d::extension::CCScale9Sprite* m_bgSprite = nullptr;
CCTextInputNode* m_input;
bool init(
float width,
float height,
const char* placeholder,
const char* font,
bool bg
);
public:
static MenuInputNode* create(
float width,
float height,
const char* placeholder,
const char* font,
bool bg = false
);
void selected() override;
CCTextInputNode* getInput() const;
};
}

View file

@ -0,0 +1,188 @@
#pragma once
#include <Geode/Geode.hpp>
#include "SceneManager.hpp"
#include <chrono>
#include "../utils/Ref.hpp"
namespace geode {
enum class NotificationLocation {
TopLeft,
TopCenter,
TopRight,
BottomLeft,
BottomCenter,
BottomRight,
};
static constexpr float DEFAULT_NOTIFICATION_TIME = 4.f;
static constexpr NotificationLocation PLATFORM_NOTIFICATION_LOCATION =
#ifdef GEODE_IS_DESKTOP
NotificationLocation::BottomRight;
#else
NotificationLocation::TopCenter;
#endif;
class Notification;
class NotificationManager;
struct GEODE_DLL NotificationBuilder {
Mod* m_owner = Mod::get();
std::string m_title = "";
std::string m_text = "";
std::string m_icon = "GJ_infoIcon_001.png";
Ref<cocos2d::CCNode> m_iconNode = nullptr;
std::string m_bg = "GJ_square02.png";
std::function<void(Notification*)> m_callback = nullptr;
float m_time = DEFAULT_NOTIFICATION_TIME;
NotificationLocation m_location = PLATFORM_NOTIFICATION_LOCATION;
bool m_hideOnClick = true;
inline NotificationBuilder& from(Mod* owner) {
m_owner = owner;
return *this;
}
inline NotificationBuilder& title(std::string const& title) {
m_title = title;
return *this;
}
inline NotificationBuilder& text(std::string const& text) {
m_text = text;
return *this;
}
inline NotificationBuilder& icon(std::string const& icon) {
m_icon = icon;
m_iconNode = nullptr;
return *this;
}
inline NotificationBuilder& icon(cocos2d::CCNode* icon) {
m_icon = "";
m_iconNode = icon;
return *this;
}
inline NotificationBuilder& loading() {
auto spr = cocos2d::CCSprite::create("loadingCircle.png");
spr->runAction(cocos2d::CCRepeat::create(
cocos2d::CCRotateBy::create(1.f, 360.f), 40000
));
spr->setBlendFunc({ GL_ONE, GL_ONE });
return this->icon(spr);
}
inline NotificationBuilder& bg(std::string const& bg) {
m_bg = bg;
return *this;
}
inline NotificationBuilder& location(NotificationLocation location) {
m_location = location;
return *this;
}
inline NotificationBuilder& time(float time) {
m_time = time;
return *this;
}
inline NotificationBuilder& stay() {
m_time = .0f;
return *this;
}
inline NotificationBuilder& clicked(
std::function<void(Notification*)> cb,
bool hide = true
) {
m_callback = cb;
m_hideOnClick = hide;
return *this;
}
Notification* show();
};
class GEODE_DLL Notification : public cocos2d::CCLayer {
protected:
Mod* m_owner;
std::function<void(Notification*)> m_callback = nullptr;
cocos2d::extension::CCScale9Sprite* m_bg;
cocos2d::CCNode* m_icon = nullptr;
cocos2d::CCLabelBMFont* m_title = nullptr;
Ref<cocos2d::CCArray> m_labels = nullptr;
cocos2d::CCPoint m_showDest;
cocos2d::CCPoint m_hideDest;
cocos2d::CCPoint m_posAtTouchStart;
NotificationLocation m_location;
float m_time;
bool m_hiding = false;
bool m_clicking;
bool m_hovered;
bool m_hideOnClicked = true;
float m_targetScale = 1.f;
bool init(
Mod* owner,
std::string const& title,
std::string const& text,
cocos2d::CCNode* icon,
const char* bg,
std::function<void(Notification*)> callback,
bool hideOnClick
);
Notification();
virtual ~Notification();
bool ccTouchBegan(
cocos2d::CCTouch* touch, cocos2d::CCEvent* event
) override;
void ccTouchEnded(
cocos2d::CCTouch* touch, cocos2d::CCEvent* event
) override;
void ccTouchMoved(
cocos2d::CCTouch* touch, cocos2d::CCEvent* event
) override;
void registerWithTouchDispatcher() override;
void clicked();
void animateIn();
void animateOut();
void animateOutClicked();
void animateClicking();
void hidden();
void showForReal();
friend class NotificationManager;
public:
static Notification* create(
Mod* owner,
std::string const& title,
std::string const& text,
cocos2d::CCNode* icon,
const char* bg,
std::function<void(Notification*)> callback,
bool hideOnClick
);
static NotificationBuilder build();
void show(
NotificationLocation = PLATFORM_NOTIFICATION_LOCATION,
float time = DEFAULT_NOTIFICATION_TIME
);
void hide();
};
class NotificationManager {
protected:
std::unordered_map<
NotificationLocation, std::vector<Ref<Notification>>
> m_notifications;
void push(Notification*);
void pop(Notification*);
bool isInQueue(Notification*);
friend class Notification;
public:
static NotificationManager* get();
};
}

View file

@ -0,0 +1,74 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
template<typename T, typename... InitArgs>
class GEODE_DLL Popup : public FLAlertLayer {
protected:
cocos2d::CCSize m_size;
cocos2d::extension::CCScale9Sprite* m_bgSprite;
bool init(
float width,
float height,
InitArgs... args,
const char* bg = "GJ_square01.png"
) {
auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
m_size = cocos2d::CCSize{width, height};
if (!this->initWithColor({0, 0, 0, 105})) return false;
m_mainLayer = cocos2d::CCLayer::create();
this->addChild(m_mainLayer);
m_bgSprite = cocos2d::extension::CCScale9Sprite::create(bg, {0.0f, 0.0f, 80.0f, 80.0f});
m_bgSprite->setContentSize(m_size);
m_bgSprite->setPosition(winSize.width / 2, winSize.height / 2);
m_mainLayer->addChild(m_bgSprite);
m_buttonMenu = cocos2d::CCMenu::create();
m_mainLayer->addChild(m_buttonMenu);
cocos2d::CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
this->registerWithTouchDispatcher();
this->setup(args...);
auto closeSpr = cocos2d::CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png");
closeSpr->setScale(.8f);
auto closeBtn = CCMenuItemSpriteExtra::create(closeSpr, this, (cocos2d::SEL_MenuHandler)(&Popup::onClose));
closeBtn->setPosition(-m_size.width / 2 + 3.f, m_size.height / 2 - 3.f);
m_buttonMenu->addChild(closeBtn);
this->setKeypadEnabled(true);
this->setTouchEnabled(true);
return true;
}
virtual void setup(InitArgs... args) = 0;
void keyDown(cocos2d::enumKeyCodes key) {
if (key == cocos2d::enumKeyCodes::KEY_Escape) return this->onClose(nullptr);
if (key == cocos2d::enumKeyCodes::KEY_Space) return;
return FLAlertLayer::keyDown(key);
}
virtual void onClose(cocos2d::CCObject*) {
this->setKeyboardEnabled(false);
this->removeFromParentAndCleanup(true);
}
};
void GEODE_DLL createQuickPopup(
const char* title,
std::string const& content,
const char* btn1,
const char* btn2,
std::function<void(FLAlertLayer*, bool)> selected
);
}

View file

@ -0,0 +1,22 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
class GEODE_DLL SceneManager {
protected:
cocos2d::CCArray* m_persistedNodes;
bool setup();
virtual ~SceneManager();
public:
static SceneManager* get();
void keepAcrossScenes(cocos2d::CCNode* node);
void forget(cocos2d::CCNode* node);
void willSwitchToScene(cocos2d::CCScene* scene);
};
}

View file

@ -0,0 +1,46 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
/**
* CCContentLayer expects all of its children
* to be TableViewCells, which is not ideal for
* a generic content layer
*/
class GEODE_DLL GenericContentLayer : public CCContentLayer {
public:
static GenericContentLayer* create(
float width, float height
);
void setPosition(cocos2d::CCPoint const& pos) override;
};
class GEODE_DLL ScrollLayer : public CCScrollLayerExt {
protected:
bool m_scrollWheelEnabled;
ScrollLayer(
cocos2d::CCRect const& rect,
bool scrollWheelEnabled,
bool vertical
);
public:
static ScrollLayer* create(
cocos2d::CCRect const& rect,
bool scrollWheelEnabled = true,
bool vertical = true
);
static ScrollLayer* create(
cocos2d::CCSize const& size,
bool scrollWheelEnabled = true,
bool vertical = true
);
void scrollWheel(float y, float) override;
void enableScrollWheel(bool enable = true);
};
}

View file

@ -0,0 +1,34 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
class GEODE_DLL Scrollbar :
public cocos2d::CCLayer
// public ExtMouseDelegate
{
protected:
CCScrollLayerExt* m_target = nullptr;
cocos2d::extension::CCScale9Sprite* m_track;
cocos2d::extension::CCScale9Sprite* m_thumb;
cocos2d::CCPoint m_clickOffset;
float m_width;
bool m_resizeThumb;
bool m_trackIsRotated;
bool m_hoverHighlight;
// bool mouseDownExt(MouseEvent, cocos2d::CCPoint const&) override;
// bool mouseUpExt(MouseEvent, cocos2d::CCPoint const&) override;
// void mouseMoveExt(cocos2d::CCPoint const&) override;
void scrollWheel(float y, float x) override;
void draw() override;
bool init(CCScrollLayerExt*);
public:
void setTarget(CCScrollLayerExt* list);
static Scrollbar* create(CCScrollLayerExt* list);
};
}

View file

@ -0,0 +1,398 @@
#pragma once
#include <Geode/Geode.hpp>
namespace geode {
enum class TextAlignment {
Begin,
Center,
End,
};
enum class TextCapitalization {
Normal,
AllUpper,
AllLower,
};
// enum only as these are flags
enum TextStyle {
TextStyleRegular = 0b0,
TextStyleBold = 0b1,
TextStyleItalic = 0b10,
};
// enum only as these are flags
enum TextDecoration {
TextDecorationNone = 0b0,
TextDecorationUnderline = 0b1,
TextDecorationStrikethrough= 0b10,
};
class TextDecorationWrapper;
class TextLinkedButtonWrapper;
/**
* Utility class for creating rich text content.
* Use to incrementally render strings, and push
* variables to modify the renderer's state. Use
* `begin` to start rendering to a target and
* `end` to finish rendering.
*
* Works for any type of label, although relies
* heavily on content sizes for labels and nodes.
*
* Not too well-performant and the rendering is
* done linearly without so this is not suitable
* for dynamic content. For something like a
* static rich text -area though this can prove
* useful. Used in MDTextArea.
*/
class GEODE_DLL TextRenderer : public cocos2d::CCObject {
public:
/**
* Represents a label. As CCLabelBMFont and
* CCLabelTTF have different inheritance
* structures, this class can handle either
* one universally. All relevant vtables are
* stored in-class to avoid needing to
* `dynamic_cast` everything.
*/
struct Label {
/**
* Label's CCNode vtable
*/
cocos2d::CCNode* m_node;
/**
* Label's CCLabelProtocol vtable
*/
cocos2d::CCLabelProtocol* m_labelProtocol;
/**
* Label's CCRGBAProtocol vtable
*/
cocos2d::CCRGBAProtocol* m_rgbaProtocol;
/**
* Line height. If 0, the renderer will dynamically
* calculate line height based on content size.
*/
float m_lineHeight;
explicit inline Label() {
m_node = nullptr;
m_labelProtocol = nullptr;
m_rgbaProtocol = nullptr;
m_lineHeight = .0f;
}
template<class T>
Label(T* label, float lineHeight = .0f) {
static_assert(std::is_base_of_v<cocos2d::CCNode, T>, "Label must inherit from CCNode!");
static_assert(std::is_base_of_v<cocos2d::CCLabelProtocol, T>, "Label must inherit from CCLabelProtocol!");
static_assert(std::is_base_of_v<cocos2d::CCRGBAProtocol, T>, "Label must inherit from CCRGBAProtocol!");
m_node = label;
m_labelProtocol = label;
m_rgbaProtocol = label;
if (lineHeight) {
m_lineHeight = lineHeight;
} else {
if constexpr (std::is_same_v<cocos2d::CCLabelBMFont, T>) {
m_lineHeight = label->getConfiguration()->m_nCommonHeight / cocos2d::CC_CONTENT_SCALE_FACTOR();
}
}
}
};
/**
* Label generator function. The `int` parameter
* represents the current text style flags. Use
* to distinguish between bold, italic and
* regular text.
*/
using Font = std::function<Label(int)>;
protected:
cocos2d::CCPoint m_origin = cocos2d::CCPointZero;
cocos2d::CCSize m_size = cocos2d::CCSizeZero;
cocos2d::CCPoint m_cursor = cocos2d::CCPointZero;
cocos2d::CCNode* m_target = nullptr;
std::vector<Font> m_fontStack;
std::vector<float> m_scaleStack;
std::vector<int> m_styleStack;
std::vector<cocos2d::ccColor3B> m_colorStack;
std::vector<GLubyte> m_opacityStack;
std::vector<int> m_decorationStack;
std::vector<TextCapitalization> m_capsStack;
std::vector<Label> m_lastRendered;
std::vector<float> m_indentationStack;
std::vector<float> m_wrapOffsetStack;
std::vector<TextAlignment> m_hAlignmentStack;
std::vector<TextAlignment> m_vAlignmentStack;
std::vector<cocos2d::CCNode*> m_renderedLine;
cocos2d::CCNode* m_lastRenderedNode = nullptr;
bool init();
Label addWrappers(
Label const& label,
bool isButton,
cocos2d::CCObject* target,
cocos2d::SEL_MenuHandler callback
);
bool render(std::string const& word, cocos2d::CCNode* to, cocos2d::CCLabelProtocol* label);
float adjustLineAlignment();
public:
/**
* Create a TextRenderer
* @returns Created TextRenderer
*/
static TextRenderer* create();
virtual ~TextRenderer();
/**
* Initialize renderer
* @param target Target node to render to. If nullptr,
* a new CCNode will be created.
* @param pos Position to render to
* @param size Size of the render area. Needed for
* text wrapping & alignment
*/
void begin(
cocos2d::CCNode* target,
cocos2d::CCPoint const& pos = cocos2d::CCPointZero,
cocos2d::CCSize const& size = cocos2d::CCSizeZero
);
/**
* Finish rendering and clean up renderer
* @param fitToContent Resize the target's content
* size to match the rendered content
* @param horizontalAlign Horizontal alignment of
* the rendered text
* @param verticalAlign Vertical alignment of
* the rendered text
* @returns Target that was rendered onto
*/
cocos2d::CCNode* end(
bool fitToContent = true,
TextAlignment horizontalAlign = TextAlignment::Begin,
TextAlignment verticalAlign = TextAlignment::Begin
);
/**
* Render a string with specific settings, bypassing
* current variable stacks.
* @param str String to render
* @param font Font function to use
* @param scale Scale of label
* @param color Label color
* @param opacity Label opacity
* @param style Label style (TextStyle enum)
* @param deco Label decorations (TextDecoration enum)
* @param caps String capitalization
* @param addToTarget Whether to add the created label(s)
* onto the target
* @param isButton If the label should be created as an
* interactive linked button
* @param buttonTarget Target for the label if isButton is
* true, defaults to current renderer target
* @param callback Callback for the label if isButton is
* true
* @returns Vector of rendered labels. The label may be
* split on multiple lines if it exceeds bounds
*/
std::vector<Label> renderStringEx(
std::string const& str,
Font font,
float scale,
cocos2d::ccColor3B color = { 255, 255, 255 },
GLubyte opacity = 255,
int style = TextStyleRegular,
int deco = TextDecorationNone,
TextCapitalization caps = TextCapitalization::Normal,
bool addToTarget = true,
bool isButton = false,
cocos2d::CCObject* buttonTarget = nullptr,
cocos2d::SEL_MenuHandler callback = nullptr
);
/**
* Render a string to target. Uses current variable stacks
* for styling and parameters
* @param str String to render
* @returns Vector of rendered labels. The label may be
* split on multiple lines if it exceeds bounds
*/
std::vector<Label> renderString(std::string const& str);
/**
* Render a string to target as a button. Note that the
* target should be a CCMenu for the button to do
* anything. Uses current variable stacks for styling
* and parameters
* @param str String to render
* @param buttonTarget Target for the label if isButton is
* true, defaults to current renderer target
* @param callback Callback for the label if isButton is
* true
* @returns Vector of rendered labels. The label may be
* split on multiple lines if it exceeds bounds
*/
std::vector<Label> renderStringInteractive(
std::string const& str,
cocos2d::CCObject* buttonTarget,
cocos2d::SEL_MenuHandler callback
);
/**
* Render a node to the current target, use for adding
* images & other content in the middle of text
* @param node Node to render
* @returns Rendered node
*/
cocos2d::CCNode* renderNode(cocos2d::CCNode* node);
/**
* Start next line
* @param y Y offset amount from previous line. If 0,
* will dynamically figure out based on content size
*/
void breakLine(float y = .0f);
/**
* Helper for pushing a CCLabelBMFont. Make
* sure the const char* outlives the renderer.
*/
void pushBMFont(const char* bmFont);
void pushFont(Font const& font);
void popFont();
Font getCurrentFont() const;
void pushScale(float scale);
void popScale();
float getCurrentScale() const;
void pushStyleFlags(int style);
void popStyleFlags();
int getCurrentStyle() const;
void pushColor(cocos2d::ccColor3B const& color);
void popColor();
cocos2d::ccColor3B getCurrentColor() const;
void pushOpacity(GLubyte opacity);
void popOpacity();
GLubyte getCurrentOpacity() const;
void pushDecoFlags(int deco);
void popDecoFlags();
int getCurrentDeco() const;
void pushCaps(TextCapitalization caps);
void popCaps();
TextCapitalization getCurrentCaps() const;
void pushIndent(float indent);
void popIndent();
float getCurrentIndent() const;
void pushWrapOffset(float wrapOffset);
void popWrapOffset();
float getCurrentWrapOffset() const;
void pushVerticalAlign(TextAlignment align);
void popVerticalAlign();
TextAlignment getCurrentVerticalAlign() const;
void pushHorizontalAlign(TextAlignment align);
void popHorizontalAlign();
TextAlignment getCurrentHorizontalAlign() const;
void moveCursor(cocos2d::CCPoint const& pos);
cocos2d::CCPoint const& getCursorPos();
};
/**
* Wrapper node for adding decorations (strikethrough,
* underline) to an arbitary label. Is not agnostic of
* font and as such will always render simple lines
*/
class TextDecorationWrapper : public cocos2d::CCNodeRGBA, public cocos2d::CCLabelProtocol {
protected:
int m_deco;
TextRenderer::Label m_label;
bool init(
TextRenderer::Label const& label,
int decoration,
cocos2d::ccColor3B const& color,
GLubyte opacity
);
void draw() override;
public:
static TextDecorationWrapper* create(
TextRenderer::Label const& label,
int decoration,
cocos2d::ccColor3B const& color,
GLubyte opacity
);
static TextDecorationWrapper* wrap(
TextRenderer::Label const& label,
int decoration,
cocos2d::ccColor3B const& color,
GLubyte opacity
);
void setColor(cocos2d::ccColor3B const& color) override;
void setOpacity(GLubyte opacity) override;
void updateDisplayedColor(cocos2d::ccColor3B const& color) override;
void updateDisplayedOpacity(GLubyte opacity) override;
void setString(const char* text) override;
const char* getString() override;
};
/**
* Wrapper node for making a label clickable.
* Note that this should always be the top
* wrapper above all other wrappers
*/
class TextLinkedButtonWrapper :
public cocos2d::CCMenuItemSprite,
public cocos2d::CCLabelProtocol
{
protected:
TextRenderer::Label m_label;
GLubyte m_opacity;
cocos2d::ccColor3B m_color;
std::vector<TextLinkedButtonWrapper*> m_linked;
bool init(
TextRenderer::Label const& label,
cocos2d::CCObject* target,
cocos2d::SEL_MenuHandler handler
);
public:
static TextLinkedButtonWrapper* create(
TextRenderer::Label const& label,
cocos2d::CCObject* target,
cocos2d::SEL_MenuHandler handler
);
static TextLinkedButtonWrapper* wrap(
TextRenderer::Label const& label,
cocos2d::CCObject* target,
cocos2d::SEL_MenuHandler handler
);
void link(TextLinkedButtonWrapper* other);
void selectedWithoutPropagation(bool selected);
void selected() override;
void unselected() override;
void setColor(cocos2d::ccColor3B const& color) override;
void setOpacity(GLubyte opacity) override;
void updateDisplayedColor(cocos2d::ccColor3B const& color) override;
void updateDisplayedOpacity(GLubyte opacity) override;
void setString(const char* text) override;
const char* getString() override;
};
}

View file

@ -0,0 +1,97 @@
#pragma once
#include <cocos2d.h>
namespace geode {
/**
* A smart pointer to a managed CCObject-deriving class. Retains shared
* ownership over the managed instance. Releases the object when the Ref
* is destroyed, or assigned another object or nullptr.
*
* Use-cases include, for example, non-CCNode class members, or nodes that
* are not always in the scene tree.
*
* @example class MyNode : public CCNode {
* protected:
* // no need to manually call retain or
* // release on this array; Ref manages it
* // for you :3
* Ref<CCArray> m_list = CCArray::create();
* };
*/
template<class T>
class Ref final {
static_assert(
std::is_base_of_v<cocos2d::CCObject, T>,
"Ref can only be used with a CCObject-inheriting class!"
);
T* m_obj = nullptr;
public:
/**
* Construct a Ref of an object. The object will be retained and
* managed until Ref goes out of scope
*/
Ref(T* obj) : m_obj(obj) {
CC_SAFE_RETAIN(obj);
}
Ref(Ref<T> const& other) : Ref(other.data()) {}
Ref(Ref<T>&& other) : m_obj(other.m_obj) {
other.m_obj = nullptr;
}
/**
* Construct an empty Ref (the managed object will be null)
*/
Ref() = default;
~Ref() {
CC_SAFE_RELEASE(m_obj);
}
/**
* Swap the managed object with another object. The managed object
* will be released, and the new object retained
* @param other The new object to swap to
*/
void swap(T* other) {
CC_SAFE_RELEASE(m_obj);
m_obj = other;
CC_SAFE_RETAIN(other);
}
/**
* Return the managed object
* @returns The managed object
*/
T* data() const {
return m_obj;
}
operator T*() const {
return m_obj;
}
T* operator*() const {
return m_obj;
}
T* operator->() const {
return m_obj;
}
T* operator=(T* obj) {
this->swap(obj);
return obj;
}
Ref<T>& operator=(Ref<T> const& other) {
this->swap(other.data());
return *this;
}
Ref<T>& operator=(Ref<T>&& other) {
this->swap(other.data());
return *this;
}
bool operator==(T* other) const {
return m_obj == other;
}
bool operator==(Ref<T> const& other) const {
return m_obj == other.m_obj;
}
};
}

1
loader/md4c Submodule

@ -0,0 +1 @@
Subproject commit e9ff661ff818ee94a4a231958d9b6768dc6882c9

Binary file not shown.

After

(image error) Size: 8.8 KiB

Binary file not shown.

After

(image error) Size: 6.7 KiB

Binary file not shown.

After

(image error) Size: 6.5 KiB

Binary file not shown.

After

(image error) Size: 7.2 KiB

Binary file not shown.

After

(image error) Size: 8.6 KiB

Binary file not shown.

After

(image error) Size: 18 KiB

Binary file not shown.

After

(image error) Size: 12 KiB

Binary file not shown.

After

(image error) Size: 15 KiB

Binary file not shown.

After

(image error) Size: 13 KiB

Binary file not shown.

After

(image error) Size: 12 KiB

Binary file not shown.

After

(image error) Size: 19 KiB

Binary file not shown.

After

(image error) Size: 13 KiB

Binary file not shown.

After

(image error) Size: 10 KiB

Binary file not shown.

After

(image error) Size: 14 KiB

Binary file not shown.

After

(image error) Size: 18 KiB

Binary file not shown.

After

(image error) Size: 20 KiB

Binary file not shown.

After

(image error) Size: 17 KiB

Binary file not shown.

After

(image error) Size: 26 KiB

Binary file not shown.

After

(image error) Size: 17 KiB

Binary file not shown.

After

(image error) Size: 19 KiB

Binary file not shown.

After

(image error) Size: 20 KiB

Binary file not shown.

After

(image error) Size: 19 KiB

Binary file not shown.

After

(image error) Size: 29 KiB

Binary file not shown.

After

(image error) Size: 20 KiB

Binary file not shown.

After

(image error) Size: 25 KiB

Binary file not shown.

After

(image error) Size: 31 KiB

Binary file not shown.

After

(image error) Size: 17 KiB

Binary file not shown.

After

(image error) Size: 30 KiB

Binary file not shown.

After

(image error) Size: 22 KiB

Binary file not shown.

After

(image error) Size: 28 KiB

Binary file not shown.

After

(image error) Size: 34 KiB

Binary file not shown.

After

(image error) Size: 23 KiB

Binary file not shown.

After

(image error) Size: 36 KiB

Binary file not shown.

After

(image error) Size: 21 KiB

Binary file not shown.

After

(image error) Size: 30 KiB

Binary file not shown.

After

(image error) Size: 51 KiB

Binary file not shown.

After

(image error) Size: 31 KiB

Binary file not shown.

After

(image error) Size: 64 KiB

Binary file not shown.

After

(image error) Size: 36 KiB

Binary file not shown.

After

(image error) Size: 46 KiB

Binary file not shown.

After

(image error) Size: 51 KiB

Binary file not shown.

After

(image error) Size: 105 KiB

Binary file not shown.

After

(image error) Size: 7.3 KiB

Binary file not shown.

After

(image error) Size: 7.9 KiB

Binary file not shown.

After

(image error) Size: 14 KiB

Binary file not shown.

After

(image error) Size: 6.3 KiB

Binary file not shown.

After

(image error) Size: 9.3 KiB

Binary file not shown.

After

(image error) Size: 10 KiB

Binary file not shown.

After

(image error) Size: 8.6 KiB

Binary file not shown.

After

(image error) Size: 9.7 KiB

Binary file not shown.

After

(image error) Size: 8.1 KiB

Binary file not shown.

After

(image error) Size: 6.4 KiB

Binary file not shown.

After

(image error) Size: 7.7 KiB

Binary file not shown.

After

(image error) Size: 6.3 KiB

Binary file not shown.

After

(image error) Size: 6.6 KiB

Binary file not shown.

After

(image error) Size: 7.2 KiB

Binary file not shown.

After

(image error) Size: 9 KiB

Binary file not shown.

After

(image error) Size: 25 KiB

Binary file not shown.

After

(image error) Size: 32 KiB

Binary file not shown.

After

(image error) Size: 30 KiB

Binary file not shown.

After

(image error) Size: 1.6 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

(image error) Size: 2.7 KiB

Binary file not shown.

After

(image error) Size: 2.8 KiB

Binary file not shown.

After

(image error) Size: 2.8 KiB

Binary file not shown.

After

(image error) Size: 2.9 KiB

Binary file not shown.

After

(image error) Size: 801 B

Binary file not shown.

After

(image error) Size: 6.1 KiB

Binary file not shown.

After

(image error) Size: 6.9 KiB

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