mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-24 05:14:40 -04:00
Merge branch 'main' of https://github.com/geode-sdk/geode into tulip-hook
This commit is contained in:
commit
9e30870c79
30 changed files with 401 additions and 1023 deletions
|
@ -961,6 +961,9 @@ class cocos2d::extension::CCControlColourPicker {
|
|||
auto ccTouchBegan(cocos2d::CCTouch*, cocos2d::CCEvent*) = mac 0x1aae10;
|
||||
auto init() = mac 0x1aa400;
|
||||
static auto colourPicker() = mac 0x1aaa30;
|
||||
cocos2d::ccColor3B const& getColorValue() const {
|
||||
return m_rgb;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -744,10 +744,10 @@ class ColorSelectLiveOverlay : FLAlertLayer {
|
|||
|
||||
class ColorSelectPopup : FLAlertLayer, cocos2d::extension::ColorPickerDelegate, TextInputDelegate, GJSpecialColorSelectDelegate {
|
||||
virtual void colorValueChanged(cocos2d::ccColor3B color) = mac 0x423520, win 0x46ee0;
|
||||
|
||||
ColorSelectPopup() {}
|
||||
bool init(EffectGameObject* triggerObj, cocos2d::CCArray* triggerObjs, ColorAction* colorAction) = mac 0x41ee70, win 0x43ae0;
|
||||
void updateColorValue() = win 0x46f30;
|
||||
void updateCopyColorTextInputLabel() = win 0x479c0;
|
||||
void updateCopyColorTextInputLabel() = win 0x479c0, mac 0x422ed0;
|
||||
void closeColorSelect(cocos2d::CCObject* sender) = mac 0x421af0, win 0x46d80;
|
||||
|
||||
cocos2d::extension::CCControlColourPicker* m_colorPicker;
|
||||
|
@ -1078,14 +1078,12 @@ class EditButtonBar : cocos2d::CCNode {
|
|||
}
|
||||
|
||||
class EditLevelLayer : cocos2d::CCLayer, FLAlertLayerProtocol, TextInputDelegate, UploadActionDelegate, UploadPopupDelegate, SetIDPopupDelegate {
|
||||
static void scene(GJGameLevel* level) {
|
||||
static cocos2d::CCScene* scene(GJGameLevel* level) {
|
||||
auto scene = cocos2d::CCScene::create();
|
||||
|
||||
scene->addChild(EditLevelLayer::create(level));
|
||||
|
||||
cocos2d::CCDirector::sharedDirector()->replaceScene(
|
||||
cocos2d::CCTransitionFade::create(.5f, scene)
|
||||
);
|
||||
|
||||
AppDelegate::get()->m_runningScene = scene;
|
||||
return scene;
|
||||
}
|
||||
|
||||
static EditLevelLayer* create(GJGameLevel* level) = mac 0xe1e50, win 0x6f530, ios 0x82420;
|
||||
|
@ -1463,6 +1461,7 @@ class EndLevelLayer {
|
|||
static EndLevelLayer* create() = mac 0x2787d0, win 0x94b50;
|
||||
|
||||
void onMenu(cocos2d::CCObject* sender) = mac 0x27a500, win 0x96c10;
|
||||
void onEdit(cocos2d::CCObject* sender) = mac 0x27a640, win 0x96d30;
|
||||
}
|
||||
|
||||
class EndPortalObject : GameObject {
|
||||
|
@ -3532,14 +3531,12 @@ class LeaderboardsLayer : cocos2d::CCLayer {
|
|||
}
|
||||
|
||||
class LevelBrowserLayer : cocos2d::CCLayer {
|
||||
static void scene(GJSearchObject* search) {
|
||||
static cocos2d::CCScene* scene(GJSearchObject* search) {
|
||||
auto scene = cocos2d::CCScene::create();
|
||||
|
||||
scene->addChild(LevelBrowserLayer::create(search));
|
||||
|
||||
cocos2d::CCDirector::sharedDirector()->pushScene(
|
||||
cocos2d::CCTransitionFade::create(.5f, scene)
|
||||
);
|
||||
AppDelegate::get()->m_runningScene = scene;
|
||||
return scene;
|
||||
}
|
||||
|
||||
bool init(GJSearchObject* search) = mac 0x2513f0, win 0x15a040;
|
||||
|
@ -3593,13 +3590,10 @@ class LevelEditorLayer : GJBaseGameLayer, LevelSettingsDelegate {
|
|||
}
|
||||
static cocos2d::CCScene* scene(GJGameLevel* level) {
|
||||
auto scene = cocos2d::CCScene::create();
|
||||
|
||||
scene->addChild(LevelEditorLayer::create(level));
|
||||
scene->setObjType(cocos2d::kCCObjectTypeLevelEditorLayer);
|
||||
|
||||
cocos2d::CCDirector::sharedDirector()->replaceScene(
|
||||
cocos2d::CCTransitionFade::create(0.5f, scene)
|
||||
);
|
||||
scene->setObjType(cocos2d::CCObjectType::LevelEditorLayer);
|
||||
|
||||
AppDelegate::get()->m_runningScene = scene;
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
@ -3690,6 +3684,9 @@ class LevelEditorLayer : GJBaseGameLayer, LevelSettingsDelegate {
|
|||
void updateToggledGroups() = mac 0x9bb10;
|
||||
void updateVisibility(float) = mac 0x92c70, win 0x1632b0;
|
||||
|
||||
void groupStickyObjects(cocos2d::CCArray* objects) = mac 0x99dd0, win 0x164860;
|
||||
void ungroupStickyObjects(cocos2d::CCArray* objects) = mac 0x99ee0, win 0x164950;
|
||||
|
||||
void setStartPosObject(StartPosObject* obj) {
|
||||
CC_SAFE_RETAIN(obj);
|
||||
CC_SAFE_RELEASE(m_currentStartPos);
|
||||
|
@ -3955,6 +3952,7 @@ class LoadingLayer : cocos2d::CCLayer {
|
|||
static cocos2d::CCScene* scene(bool fromReload) {
|
||||
auto scene = cocos2d::CCScene::create();
|
||||
scene->addChild(LoadingLayer::create(fromReload));
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
@ -4302,7 +4300,16 @@ class PlayLayer : GJBaseGameLayer, CCCircleWaveDelegate, CurrencyRewardDelegate,
|
|||
void resume() = mac 0x80480, win 0x20d5c0;
|
||||
void resumeAndRestart() = mac 0x80400, win 0x20d4c0;
|
||||
void saveRecordAction(bool, PlayerObject*) = mac 0x78750, win 0x20ad40;
|
||||
static cocos2d::CCScene* scene(GJGameLevel*) = mac 0x6b500, win 0x1fb690;
|
||||
|
||||
static cocos2d::CCScene* scene(GJGameLevel* level) {
|
||||
auto scene = cocos2d::CCScene::create();
|
||||
scene->addChild(PlayLayer::create(level));
|
||||
scene->setObjType(cocos2d::CCObjectType::PlayLayer);
|
||||
|
||||
AppDelegate::get()->m_runningScene = scene;
|
||||
return scene;
|
||||
}
|
||||
|
||||
void setupLevelStart(LevelSettingsObject*) = mac 0x6f560, win 0x1fb780;
|
||||
void setupReplay(gd::string) = mac 0x7e1e0;
|
||||
void shakeCamera(float, float, float) = mac 0x744a0, win 0x1ff210;
|
||||
|
@ -4769,7 +4776,7 @@ class PlayerObject : GameObject, AnimatedSpriteDelegate {
|
|||
PAD = mac 0x24, win 0x24;
|
||||
float m_decelerationRate;
|
||||
PAD = mac 0x14, win 0x14;
|
||||
GameObject* m_unk59C;
|
||||
GameObject* m_snappedObject;
|
||||
PAD = mac 0x10, win 0x8;
|
||||
GJRobotSprite* m_robotSprite;
|
||||
GJSpiderSprite* m_spiderSprite;
|
||||
|
@ -4821,7 +4828,7 @@ class PlayerObject : GameObject, AnimatedSpriteDelegate {
|
|||
cocos2d::CCLayer* m_unk65C;
|
||||
bool m_isSliding;
|
||||
bool m_isRising;
|
||||
bool m_unk662;
|
||||
bool m_isLocked;
|
||||
cocos2d::CCPoint m_lastGroundedPos;
|
||||
cocos2d::CCArray* m_touchingRings;
|
||||
GameObject* m_lastActivatedPortal;
|
||||
|
@ -5014,11 +5021,12 @@ class SetupPickupTriggerPopup : FLAlertLayer {
|
|||
}
|
||||
|
||||
class SetupPulsePopup : FLAlertLayer, cocos2d::extension::ColorPickerDelegate, TextInputDelegate, GJSpecialColorSelectDelegate {
|
||||
virtual void colorValueChanged(cocos2d::ccColor3B color) = win 0x242660;
|
||||
virtual void colorValueChanged(cocos2d::ccColor3B color) = win 0x242660, mac 0x1ec680;
|
||||
SetupPulsePopup() {}
|
||||
|
||||
bool init(EffectGameObject* triggerObj, cocos2d::CCArray* triggerObjs) = win 0x23e980;
|
||||
bool init(EffectGameObject* triggerObj, cocos2d::CCArray* triggerObjs) = win 0x23e980, mac 0x1e7010;
|
||||
void updateColorValue() = win 0x2426b0;
|
||||
void onSelectPulseMode(cocos2d::CCObject*) = win 0x241420;
|
||||
void onSelectPulseMode(cocos2d::CCObject*) = win 0x241420, mac 0x1eb020;
|
||||
void updatePulseMode() = win 0x242cf0;
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
|
||||
project(Broma LANGUAGES C CXX)
|
||||
|
||||
add_library(Broma ${CMAKE_CURRENT_SOURCE_DIR}/src/broma.cpp)
|
||||
|
||||
target_compile_features(Broma PRIVATE cxx_std_17)
|
||||
|
||||
target_include_directories(Broma PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
target_compile_definitions(Broma PUBLIC TAO_PEGTL_GHC_FILESYSTEM=1)
|
||||
|
||||
target_link_libraries(Broma taocpp::pegtl ghc_filesystem)
|
|
@ -1,138 +0,0 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
enum class Platform {
|
||||
Mac,
|
||||
iOS,
|
||||
Windows,
|
||||
Android
|
||||
};
|
||||
|
||||
struct PlatformNumber {
|
||||
size_t mac = 0;
|
||||
size_t ios = 0;
|
||||
size_t win = 0;
|
||||
size_t android = 0;
|
||||
};
|
||||
|
||||
struct Type {
|
||||
bool is_struct = false;
|
||||
std::string name;
|
||||
|
||||
bool operator==(Type const& t) const {
|
||||
return name == t.name;
|
||||
}
|
||||
};
|
||||
|
||||
enum class FunctionType {
|
||||
Normal,
|
||||
Ctor,
|
||||
Dtor
|
||||
};
|
||||
|
||||
struct FunctionBegin {
|
||||
Type ret;
|
||||
FunctionType type = FunctionType::Normal;
|
||||
std::vector<std::pair<Type, std::string>> args;
|
||||
bool is_const = false;
|
||||
bool is_virtual = false;
|
||||
bool is_static = false;
|
||||
std::string docs;
|
||||
std::string name;
|
||||
|
||||
inline bool operator==(FunctionBegin const& f) const {
|
||||
if (name != f.name || is_const != f.is_const || args.size() != f.args.size())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < args.size(); ++i) {
|
||||
if (!(args[i].first == f.args[i].first))
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << f.ret.name << " " << f.name << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct MemberField {
|
||||
std::string name;
|
||||
Type type;
|
||||
size_t count = 0;
|
||||
};
|
||||
|
||||
struct PadField {
|
||||
PlatformNumber amount;
|
||||
};
|
||||
|
||||
struct FunctionBindField {
|
||||
FunctionBegin beginning;
|
||||
PlatformNumber binds;
|
||||
};
|
||||
|
||||
struct OutOfLineField {
|
||||
FunctionBegin beginning;
|
||||
std::string inner;
|
||||
};
|
||||
|
||||
struct InlineField {
|
||||
std::string inner;
|
||||
};
|
||||
|
||||
struct Class;
|
||||
struct Field {
|
||||
size_t field_id;
|
||||
std::string parent;
|
||||
std::variant<InlineField, OutOfLineField, FunctionBindField, PadField, MemberField> inner;
|
||||
|
||||
template <typename T>
|
||||
T* get_as() {
|
||||
return std::get_if<T>(&inner);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T const* get_as() const {
|
||||
return std::get_if<T>(&inner);
|
||||
}
|
||||
|
||||
inline FunctionBegin* get_fn() {
|
||||
if (auto fn = get_as<OutOfLineField>()) {
|
||||
return &fn->beginning;
|
||||
} else if (auto fn = get_as<FunctionBindField>()) {
|
||||
return &fn->beginning;
|
||||
} else return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct Class {
|
||||
std::string name;
|
||||
std::vector<std::string> superclasses;
|
||||
std::vector<std::string> depends;
|
||||
std::vector<Field> fields;
|
||||
|
||||
inline bool operator==(Class const& c) const {
|
||||
return name == c.name;
|
||||
}
|
||||
inline bool operator==(std::string const& n) const {
|
||||
return name == n;
|
||||
}
|
||||
};
|
||||
|
||||
struct Root {
|
||||
std::vector<Class> classes;
|
||||
|
||||
inline Class* operator[](std::string const& name) {
|
||||
auto it = std::find_if(classes.begin(), classes.end(), [name](Class& cls) {
|
||||
return cls.name == name;
|
||||
});
|
||||
|
||||
if (it == classes.end())
|
||||
return nullptr;
|
||||
|
||||
return &*it;
|
||||
}
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
#include "ast.hpp"
|
||||
|
||||
namespace broma {
|
||||
Root parse_file(std::string const& fname);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <tao/pegtl.hpp>
|
||||
using namespace tao::pegtl;
|
||||
|
||||
#include "basic_components.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
namespace broma {
|
||||
template <typename Name, typename ...Parse>
|
||||
struct basic_attribute : seq<
|
||||
Name,
|
||||
one<'('>,
|
||||
|
||||
if_then_else<
|
||||
at<one<')'>>,
|
||||
success,
|
||||
seq<Parse...>
|
||||
>,
|
||||
|
||||
one<')'>
|
||||
> {};
|
||||
|
||||
struct docs_attribute : basic_attribute<TAO_PEGTL_KEYWORD("docs"), string_literal> {};
|
||||
struct depends_attribute : basic_attribute<TAO_PEGTL_KEYWORD("depends"), tagged_rule<depends_attribute, qualified>> {};
|
||||
|
||||
struct attribute :
|
||||
if_must<ascii::string<'[', '['>,
|
||||
sor<docs_attribute, depends_attribute>,
|
||||
ascii::string<']', ']'>
|
||||
> {};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<depends_attribute, qualified>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_class.depends.push_back(input.string());
|
||||
}
|
||||
};
|
||||
} // namespace broma
|
|
@ -1,68 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <tao/pegtl.hpp>
|
||||
using namespace tao::pegtl;
|
||||
|
||||
namespace broma {
|
||||
struct comment :
|
||||
disable<sor<
|
||||
seq<ascii::string<'/', '/'>, until<eolf>>,
|
||||
seq<ascii::string<'/', '*'>, until<seq<ascii::string<'*', '/'>>>>
|
||||
>> {};
|
||||
|
||||
struct ignore : sor<comment, one<'\n', '\t', '\r', ' '>> {};
|
||||
|
||||
struct sep : star<ignore> {};
|
||||
struct whitespace : plus<ignore> {};
|
||||
|
||||
template <typename ...Args>
|
||||
struct pad_space : seq<Args..., whitespace> {};
|
||||
|
||||
template <typename ...Args>
|
||||
struct rpad_space : seq<whitespace, Args...> {};
|
||||
|
||||
template <typename R, typename ...S>
|
||||
struct if_then_must : if_then_else<R, must<S...>, seq<S...>> {};
|
||||
|
||||
template <char Quote>
|
||||
struct basic_literal : if_must<one<Quote>, until<one<Quote>>> {};
|
||||
struct string_literal : sor<basic_literal<'"'>, basic_literal<'\''>> {};
|
||||
|
||||
struct brace_end;
|
||||
struct brace_start : seq<one<'{'>, brace_end> {};
|
||||
struct brace_end : until<one<'}'>, sor<string_literal, brace_start, any>> {};
|
||||
|
||||
struct template_end;
|
||||
struct template_start : seq<one<'<'>, template_end> {};
|
||||
struct template_end : until<one<'>'>, sor<string_literal, template_start, any>> {};
|
||||
|
||||
template <typename T, typename ...Args>
|
||||
struct tagged_rule : seq<Args...> {};
|
||||
|
||||
template <typename T>
|
||||
struct rule_begin : success {};
|
||||
|
||||
#define $named_rule(name, ...) tagged_rule<TAO_PEGTL_INTERNAL_STRING(ascii::string, name), __VA_ARGS__>
|
||||
|
||||
#define $keyword(name) struct keyword_##name : TAO_PEGTL_KEYWORD(#name) {}
|
||||
|
||||
$keyword(const);
|
||||
$keyword(static);
|
||||
$keyword(virtual);
|
||||
$keyword(inline);
|
||||
$keyword(class);
|
||||
$keyword(struct);
|
||||
$keyword(unsigned);
|
||||
$keyword(mac);
|
||||
$keyword(win);
|
||||
$keyword(ios);
|
||||
$keyword(android);
|
||||
$keyword(PAD);
|
||||
|
||||
struct qualified : list<seq<identifier, opt<template_start>>, ascii::string<':', ':'>> {};
|
||||
|
||||
// point of no return: '0x'
|
||||
struct hex : if_must<ascii::string<'0', 'x'>, plus<ascii::xdigit>> {};
|
||||
|
||||
struct platform : sor<keyword_mac, keyword_win, keyword_ios, keyword_android> {};
|
||||
} // namespace broma
|
|
@ -1,83 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <tao/pegtl.hpp>
|
||||
using namespace tao::pegtl;
|
||||
|
||||
#include "basic_components.hpp"
|
||||
#include "state.hpp"
|
||||
#include <sstream>
|
||||
|
||||
namespace broma {
|
||||
struct bind :
|
||||
seq<rule_begin<bind>, opt_must<
|
||||
one<'='>,
|
||||
sep,
|
||||
list<opt<
|
||||
sep,
|
||||
sor<keyword_mac, keyword_win, keyword_ios, keyword_android>,
|
||||
sep,
|
||||
tagged_rule<bind, hex>
|
||||
>, one<','>>,
|
||||
sep
|
||||
>, one<';'>> {};
|
||||
|
||||
template <>
|
||||
struct run_action<rule_begin<bind>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_bind = PlatformNumber();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<bind, hex>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
size_t out = std::stoul(input.string(), nullptr, 16);
|
||||
|
||||
switch (scratch->wip_bind_platform) {
|
||||
case Platform::Mac:
|
||||
scratch->wip_bind.mac = out;
|
||||
break;
|
||||
case Platform::iOS:
|
||||
scratch->wip_bind.ios = out;
|
||||
break;
|
||||
case Platform::Windows:
|
||||
scratch->wip_bind.win = out;
|
||||
break;
|
||||
case Platform::Android:
|
||||
scratch->wip_bind.android = out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<keyword_mac> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_bind_platform = Platform::Mac;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct run_action<keyword_ios> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_bind_platform = Platform::iOS;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct run_action<keyword_win> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_bind_platform = Platform::Windows;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct run_action<keyword_android> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_bind_platform = Platform::Android;
|
||||
}
|
||||
};
|
||||
} // namespace broma
|
|
@ -1,129 +0,0 @@
|
|||
#include <tao/pegtl.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "attribute.hpp"
|
||||
#include "basic_components.hpp"
|
||||
#include "function.hpp"
|
||||
#include "member.hpp"
|
||||
#include "state.hpp"
|
||||
#include "post_process.hpp"
|
||||
#include "preprocessor.hpp"
|
||||
|
||||
using namespace tao::pegtl;
|
||||
|
||||
namespace broma {
|
||||
struct inline_expr :
|
||||
if_must<
|
||||
keyword_inline,
|
||||
if_then_else<
|
||||
at<rematch<until<eolf>, until<one<'{'>>>>,
|
||||
until<brace_start>,
|
||||
until<eolf>
|
||||
>
|
||||
> {};
|
||||
|
||||
template <>
|
||||
struct run_action<inline_expr> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
InlineField inf;
|
||||
inf.inner = input.string();
|
||||
|
||||
scratch->wip_field.inner = inf;
|
||||
}
|
||||
};
|
||||
|
||||
struct field : sor<inline_expr, pad_expr, member_expr, bind_expr, ool_expr> {};
|
||||
|
||||
template <>
|
||||
struct run_action<field> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_field.parent = scratch->wip_class.name;
|
||||
static size_t index = 0;
|
||||
scratch->wip_field.field_id = index++;
|
||||
scratch->wip_class.fields.push_back(scratch->wip_field);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct class_statement :
|
||||
seq<
|
||||
opt<attribute>,
|
||||
sep,
|
||||
must<keyword_class>,
|
||||
whitespace,
|
||||
must<$named_rule("class name", qualified)>,
|
||||
sep,
|
||||
opt_must<
|
||||
one<':'>,
|
||||
sep,
|
||||
list<seq<
|
||||
sep,
|
||||
$named_rule("superclass", qualified),
|
||||
sep
|
||||
>, one<','>>
|
||||
>,
|
||||
one<'{'>,
|
||||
sep,
|
||||
until<one<'}'>, sep, must<field>, sep>
|
||||
> {};
|
||||
|
||||
template <>
|
||||
struct run_action<$named_rule("superclass", qualified)> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
if (scratch->wip_class.name == input.string())
|
||||
throw parse_error("Class subclasses itself", input.position());
|
||||
|
||||
scratch->wip_class.superclasses.push_back(input.string());
|
||||
scratch->wip_class.depends.push_back(input.string());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<$named_rule("class name", qualified)> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_class.name = input.string();
|
||||
|
||||
if (std::find(root->classes.begin(), root->classes.end(), input.string()) != root->classes.end()) {
|
||||
scratch->errors.push_back(parse_error("Class duplicate!", input.position()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct run_action<class_statement> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
root->classes.push_back(std::move(scratch->wip_class));
|
||||
//std::cout << "class end\n";
|
||||
scratch->wip_class = Class();
|
||||
}
|
||||
};
|
||||
|
||||
struct root_grammar : until<eof, sep, must<sor<include_expr, class_statement>>, sep> {};
|
||||
|
||||
Root parse_file(std::string const& fname) {
|
||||
file_input<> input(fname);
|
||||
|
||||
Root root;
|
||||
ScratchData scratch;
|
||||
parse<must<root_grammar>, run_action>(input, &root, &scratch);
|
||||
post_process(root);
|
||||
|
||||
if (scratch.errors.size()) {
|
||||
std::cerr << "[Broma] errors found on parsing: \n";
|
||||
|
||||
for (auto& e : scratch.errors) {
|
||||
std::cerr << "\t" << e.what() << "\n";
|
||||
}
|
||||
|
||||
//abort();
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
} // namespace broma
|
|
@ -1,152 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <tao/pegtl.hpp>
|
||||
using namespace tao::pegtl;
|
||||
|
||||
#include "basic_components.hpp"
|
||||
#include "attribute.hpp"
|
||||
#include "type.hpp"
|
||||
#include "bind.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
namespace broma {
|
||||
struct function_begin :
|
||||
seq<rule_begin<function_begin>, opt<attribute>, sep, sor<
|
||||
// ctor, dtor
|
||||
seq<
|
||||
$named_rule("structor", success),
|
||||
opt<pad_space<keyword_virtual>>,
|
||||
opt<tagged_rule<function_begin, one<'~'>>>,
|
||||
tagged_rule<function_begin, identifier>,
|
||||
arg_list
|
||||
>,
|
||||
|
||||
// not ctor, dtor
|
||||
if_then_must<
|
||||
sor<keyword_static, keyword_virtual>,
|
||||
$named_rule("fn_normal", success),
|
||||
sep,
|
||||
tagged_rule<function_begin, type>,
|
||||
sep,
|
||||
tagged_rule<function_begin, identifier>,
|
||||
arg_list,
|
||||
sep,
|
||||
opt<tagged_rule<function_begin, keyword_const>>
|
||||
>
|
||||
>> {};
|
||||
|
||||
template <>
|
||||
struct run_action<rule_begin<function_begin>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin = FunctionBegin();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<function_begin> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
for (auto& f : scratch->wip_class.fields) {
|
||||
if (auto fn = f.get_fn()) {
|
||||
if (*fn == scratch->wip_fn_begin) {
|
||||
scratch->errors.push_back(parse_error("Function duplicate!", input.position()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<function_begin, identifier>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.name = input.string();
|
||||
|
||||
if (scratch->wip_fn_begin.type == FunctionType::Dtor)
|
||||
scratch->wip_fn_begin.name = "~" + scratch->wip_fn_begin.name;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<function_begin, keyword_const>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.is_const = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<function_begin, type>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.ret = scratch->wip_type;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<$named_rule("fn_normal", success)> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.type = FunctionType::Normal;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<$named_rule("structor", success)> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.type = FunctionType::Ctor;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<keyword_static> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.is_static = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<function_begin, one<'~'>>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.type = FunctionType::Dtor;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<keyword_virtual> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.is_virtual = true;
|
||||
}
|
||||
};
|
||||
|
||||
struct ool_expr : seq<function_begin, sep, tagged_rule<ool_expr, brace_start>> {};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<ool_expr, brace_start>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
OutOfLineField f;
|
||||
f.beginning = scratch->wip_fn_begin;
|
||||
f.inner = input.string();
|
||||
scratch->wip_field.inner = f;
|
||||
}
|
||||
};
|
||||
|
||||
struct bind_expr : seq<function_begin, sep, bind> {};
|
||||
|
||||
template <>
|
||||
struct run_action<bind_expr> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
FunctionBindField f;
|
||||
f.beginning = scratch->wip_fn_begin;
|
||||
f.binds = scratch->wip_bind;
|
||||
scratch->wip_field.inner = f;
|
||||
}
|
||||
};
|
||||
} // namespace broma
|
|
@ -1,68 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <tao/pegtl.hpp>
|
||||
using namespace tao::pegtl;
|
||||
|
||||
#include "type.hpp"
|
||||
#include "bind.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
namespace broma {
|
||||
struct member_expr :
|
||||
seq<
|
||||
rule_begin<member_expr>,
|
||||
type,
|
||||
whitespace,
|
||||
tagged_rule<member_expr, identifier>,
|
||||
sep,
|
||||
opt<array>,
|
||||
sep,
|
||||
one<';'>
|
||||
> {};
|
||||
|
||||
template <>
|
||||
struct run_action<rule_begin<member_expr>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
MemberField f;
|
||||
scratch->wip_field.inner = f;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<member_expr, identifier>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_field.get_as<MemberField>()->name = input.string();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<member_expr> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_field.get_as<MemberField>()->type = scratch->wip_type;
|
||||
}
|
||||
};
|
||||
|
||||
struct pad_expr : seq<keyword_PAD, sep, bind> {};
|
||||
|
||||
template <>
|
||||
struct run_action<keyword_PAD> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
PadField f;
|
||||
PlatformNumber p;
|
||||
scratch->wip_field.inner = f;
|
||||
scratch->wip_bind = p;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<pad_expr> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_field.get_as<PadField>()->amount = scratch->wip_bind;
|
||||
}
|
||||
};
|
||||
} // namespace broma
|
|
@ -1,25 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "state.hpp"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
namespace broma {
|
||||
inline void sortClass(Class cls, Root& root, std::vector<Class>& output) {
|
||||
root.classes.erase(std::remove(root.classes.begin(), root.classes.end(), cls), root.classes.end());
|
||||
for (auto name : cls.depends) {
|
||||
if (root[name])
|
||||
sortClass(*root[name], root, output);
|
||||
}
|
||||
output.push_back(cls);
|
||||
}
|
||||
|
||||
inline void post_process(Root& root) {
|
||||
std::vector<Class> out;
|
||||
|
||||
while (root.classes.size())
|
||||
sortClass(root.classes[0], root, out);
|
||||
|
||||
root.classes = out;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#include "basic_components.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
namespace broma {
|
||||
struct include_name : until<at<one<'>'>>> {};
|
||||
|
||||
struct include_expr : seq<ascii::string<'#', 'i', 'n', 'c', 'l', 'u', 'd', 'e'>, sep, one<'<'>, include_name, one<'>'>> {};
|
||||
|
||||
struct root_grammar;
|
||||
|
||||
template <>
|
||||
struct run_action<include_name> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
file_input<> file_input(input.string());
|
||||
|
||||
parse<root_grammar, broma::run_action>(file_input, root, scratch);
|
||||
}
|
||||
};
|
||||
} // namespace broma
|
|
@ -1,20 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <tao/pegtl.hpp>
|
||||
#include <ast.hpp>
|
||||
|
||||
namespace broma {
|
||||
template <typename Rule>
|
||||
struct run_action {};
|
||||
|
||||
struct ScratchData {
|
||||
Class wip_class;
|
||||
Field wip_field;
|
||||
PlatformNumber wip_bind;
|
||||
Platform wip_bind_platform;
|
||||
Type wip_type;
|
||||
FunctionBegin wip_fn_begin;
|
||||
|
||||
std::vector<tao::pegtl::parse_error> errors;
|
||||
};
|
||||
} // namespace broma
|
|
@ -1,103 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <tao/pegtl.hpp>
|
||||
using namespace tao::pegtl;
|
||||
|
||||
#include "basic_components.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
namespace broma {
|
||||
struct type_content :
|
||||
if_then_must<
|
||||
pad_space<sor<keyword_const, keyword_struct>>,
|
||||
|
||||
sor<pad_space<keyword_const>, pad_space<keyword_struct>, success>,
|
||||
|
||||
if_then_else<pad_space<keyword_unsigned>, opt<qualified>, qualified>,
|
||||
|
||||
opt<rpad_space<keyword_const>>,
|
||||
star<seq<sep, one<'&', '*'>>>
|
||||
> {};
|
||||
|
||||
struct type : seq<rule_begin<type>, sep, type_content> {};
|
||||
|
||||
template <>
|
||||
struct run_action<rule_begin<type>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_type = Type();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<keyword_struct> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_type.is_struct = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<type_content> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_type.name = input.string();
|
||||
}
|
||||
};
|
||||
|
||||
struct array : if_must<one<'['>, tagged_rule<array, plus<ascii::digit>>, one<']'>> {};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<array, plus<ascii::digit>>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_field.get_as<MemberField>()->count = std::stoul(input.string(), nullptr, 10);
|
||||
}
|
||||
};
|
||||
|
||||
struct arg_name : opt<identifier> {};
|
||||
struct arg_list :
|
||||
seq<
|
||||
rule_begin<arg_list>,
|
||||
one<'('>,
|
||||
if_then_else<
|
||||
at<one<')'>>,
|
||||
success,
|
||||
list<seq<
|
||||
sep,
|
||||
tagged_rule<arg_list, type>,
|
||||
sep,
|
||||
arg_name,
|
||||
sep
|
||||
>, one<','>>
|
||||
>,
|
||||
one<')'>
|
||||
> {};
|
||||
|
||||
template <>
|
||||
struct run_action<rule_begin<arg_list>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.args.clear();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<tagged_rule<arg_list, type>> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
scratch->wip_fn_begin.args.push_back({scratch->wip_type, ""});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct run_action<arg_name> {
|
||||
template <typename T>
|
||||
static void apply(T& input, Root* root, ScratchData* scratch) {
|
||||
if (input.string() == "")
|
||||
scratch->wip_fn_begin.args.back().second = std::string("p") + std::to_string(scratch->wip_fn_begin.args.size() - 1);
|
||||
else
|
||||
scratch->wip_fn_begin.args.back().second = input.string();
|
||||
}
|
||||
};
|
||||
} // namespace broma
|
|
@ -4,10 +4,7 @@ project(Codegen LANGUAGES C CXX)
|
|||
include(../cmake/CPM.cmake)
|
||||
|
||||
CPMAddPackage("gh:fmtlib/fmt#9.1.0")
|
||||
CPMAddPackage("gh:gulrak/filesystem#3e5b930")
|
||||
CPMAddPackage("gh:matcool/PEGTL#8faeb5d")
|
||||
|
||||
add_subdirectory(Broma)
|
||||
CPMAddPackage("gh:camila314/Broma#1.0.0")
|
||||
|
||||
file(GLOB SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
|
||||
|
@ -16,7 +13,7 @@ file(GLOB SOURCES
|
|||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
target_compile_features(Codegen PUBLIC cxx_std_17)
|
||||
|
||||
target_link_libraries(Codegen PRIVATE fmt::fmt Broma ghc_filesystem)
|
||||
target_link_libraries(Codegen PRIVATE fmt::fmt Broma)
|
||||
target_include_directories(Codegen PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
|
|
@ -48,11 +48,12 @@ NS_CC_BEGIN
|
|||
*/
|
||||
|
||||
RT_ADD(
|
||||
typedef enum {
|
||||
kCCObjectTypePlayLayer = 5,
|
||||
kCCObjectTypeLevelEditorLayer = 6,
|
||||
kCCObjectTypeMenuLayer = 15,
|
||||
} CCObjectType;
|
||||
// please someone tell we why in higher being(s)'s name rob did this
|
||||
enum class CCObjectType {
|
||||
PlayLayer = 5,
|
||||
LevelEditorLayer = 6,
|
||||
MenuLayer = 15,
|
||||
};
|
||||
)
|
||||
|
||||
class CCZone;
|
||||
|
@ -156,8 +157,6 @@ public:
|
|||
inline void setObjType(CCObjectType type) {
|
||||
m_eObjType = type;
|
||||
}
|
||||
|
||||
//i have no idea if vtable function order matters so
|
||||
)
|
||||
|
||||
friend class CCAutoreleasePool;
|
||||
|
|
|
@ -90,6 +90,22 @@ namespace geode {
|
|||
this->enable();
|
||||
}
|
||||
|
||||
EventListener(EventListener&& other)
|
||||
: m_callback(std::move(other.m_callback)),
|
||||
m_filter(std::move(other.m_filter))
|
||||
{
|
||||
other.disable();
|
||||
this->enable();
|
||||
}
|
||||
|
||||
EventListener(EventListener const& other)
|
||||
: m_callback(other.m_callback),
|
||||
m_filter(other.m_filter)
|
||||
{
|
||||
other.disable();
|
||||
this->enable();
|
||||
}
|
||||
|
||||
void bind(std::function<Callback> fn) {
|
||||
m_callback = fn;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "Traits.hpp"
|
||||
#include <cocos2d.h>
|
||||
|
||||
#include <Geode/loader/Loader.hpp>
|
||||
#include <cocos2d.h>
|
||||
#include <vector>
|
||||
|
||||
namespace cocos2d {
|
||||
class CCNode;
|
||||
}
|
||||
|
||||
namespace geode {
|
||||
template <class, class>
|
||||
class Modify;
|
||||
}
|
||||
|
||||
namespace geode::modifier {
|
||||
class FieldContainer {
|
||||
private:
|
||||
|
@ -41,37 +47,42 @@ namespace geode::modifier {
|
|||
return node->getFieldContainer();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
GEODE_DLL size_t getFieldIndexForClass(size_t hash);
|
||||
|
||||
template <class Parent, class Base>
|
||||
class FieldIntermediate {
|
||||
using Intermediate = Modify<Parent, Base>;
|
||||
// Padding used for guaranteeing any member of parents
|
||||
// will be in between sizeof(Intermediate) and sizeof(Parent)
|
||||
uintptr_t m_padding;
|
||||
|
||||
public:
|
||||
// the constructor that constructs the fields.
|
||||
// we construct the Parent first,
|
||||
static void fieldConstructor(void* offsetField) {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
|
||||
auto parent = new (parentContainer.data()) Parent();
|
||||
|
||||
parent->Base::~Base();
|
||||
parent->Intermediate::~Intermediate();
|
||||
|
||||
std::memcpy(
|
||||
offsetField, std::launder(&parentContainer[sizeof(Base)]),
|
||||
sizeof(Parent) - sizeof(Base)
|
||||
offsetField,
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
}
|
||||
|
||||
static void fieldDestructor(void* offsetField) {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
|
||||
auto parent = new (parentContainer.data()) Base();
|
||||
auto parent = new (parentContainer.data()) Intermediate();
|
||||
|
||||
std::memcpy(
|
||||
std::launder(&parentContainer[sizeof(Base)]), offsetField,
|
||||
sizeof(Parent) - sizeof(Base)
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
offsetField,
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
|
||||
static_cast<Parent*>(parent)->Parent::~Parent();
|
||||
|
@ -80,23 +91,31 @@ namespace geode::modifier {
|
|||
template <class = std::enable_if_t<true>>
|
||||
Parent* operator->() {
|
||||
// get the this pointer of the base
|
||||
auto node =
|
||||
reinterpret_cast<Parent*>(reinterpret_cast<std::byte*>(this) - sizeof(Base));
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we canget the base from ourself
|
||||
auto node = reinterpret_cast<Parent*>(reinterpret_cast<std::byte*>(this) - sizeof(Base));
|
||||
static_assert(sizeof(Base) == offsetof(Parent, m_fields), "offsetof not correct");
|
||||
|
||||
// generating the container if it doesn't exist
|
||||
auto container = FieldContainer::from(node);
|
||||
|
||||
// the index is global across all mods, so the
|
||||
// function is defined in the loader source
|
||||
static size_t index = getFieldIndexForClass(typeid(Base).hash_code());
|
||||
// this pointer is offset
|
||||
|
||||
// the fields are actually offset from their original
|
||||
// offset, this is done to save on allocation and space
|
||||
auto offsetField = container->getField(index);
|
||||
if (!offsetField) {
|
||||
offsetField = container->setField(
|
||||
index, sizeof(Parent) - sizeof(Base), &FieldIntermediate::fieldDestructor
|
||||
index, sizeof(Parent) - sizeof(Intermediate), &FieldIntermediate::fieldDestructor
|
||||
);
|
||||
|
||||
FieldIntermediate::fieldConstructor(offsetField);
|
||||
}
|
||||
|
||||
return reinterpret_cast<Parent*>(
|
||||
reinterpret_cast<std::byte*>(offsetField) - sizeof(Base)
|
||||
reinterpret_cast<std::byte*>(offsetField) - sizeof(Intermediate)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -82,6 +82,17 @@ namespace geode {
|
|||
static inline auto s_applyRef = &Modify::s_apply;
|
||||
|
||||
public:
|
||||
// abusing the internal stuff
|
||||
// basically we dont want modify to invoke base ctors and dtors
|
||||
// we already have utilities for these, which are ccdestructor
|
||||
// and the monostate constructor
|
||||
Modify() : Base(std::monostate(), sizeof(Base)) {}
|
||||
~Modify() {
|
||||
cocos2d::CCDestructor::lock(this) = true;
|
||||
}
|
||||
Modify(Modify const&) = delete;
|
||||
Modify(Modify&&) = delete;
|
||||
|
||||
modifier::FieldIntermediate<Derived, Base> m_fields;
|
||||
|
||||
static void onModify(auto& self) {}
|
||||
|
|
|
@ -17,29 +17,19 @@ See [Documentation](https://geode-sdk.github.io/docs) for info about developing
|
|||
Developed by
|
||||
|
||||
* [PoweredByPie](https://github.com/poweredbypie/)
|
||||
|
||||
* [Mat](https://github.com/matcool/)
|
||||
|
||||
* [HJfod](user:104257)
|
||||
|
||||
* [Camila314](https://github.com/camila314/)
|
||||
|
||||
* [Alk1m123](https://github.com/altalk23/)
|
||||
|
||||
* [FireCubez](https://github.com/FireCubez)
|
||||
|
||||
* [fig](https://github.com/FigmentBoy)
|
||||
|
||||
Using
|
||||
|
||||
* [Cocos2d-x](https://github.com/cocos2d/cocos2d-x/tree/cocos2d-x-2.2.3)
|
||||
|
||||
* [FMOD](https://www.fmod.com/)
|
||||
|
||||
* [fmt](https://fmt.dev/latest/index.html)
|
||||
|
||||
* [PEGTL](https://github.com/taocpp/PEGTL)
|
||||
|
||||
* [md4c](https://github.com/mity/md4c)
|
||||
|
||||
Special thanks to [RobTop Games](https://twitter.com/RobTopGames/) for making this amazing game and providing us and so many others with hours of entertainment <3
|
||||
|
|
|
@ -21,15 +21,16 @@ struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
|
|||
|
||||
auto count = Loader::get()->getAllMods().size();
|
||||
|
||||
auto label =
|
||||
CCLabelBMFont::create(fmt::format("Geode: Loaded {} mods", count).c_str(), "goldFont.fnt");
|
||||
auto label = CCLabelBMFont::create(
|
||||
fmt::format("Geode: Loaded {} mods", count).c_str(),
|
||||
"goldFont.fnt"
|
||||
);
|
||||
label->setPosition(winSize.width / 2, 30.f);
|
||||
label->setScale(.45f);
|
||||
label->setID("geode-loaded-info");
|
||||
this->addChild(label);
|
||||
|
||||
// for some reason storing the listener as a field caused the
|
||||
// destructor for the field not to be run
|
||||
// fields have unpredictable destructors
|
||||
this->addChild(EventListenerNode<ResourceDownloadFilter>::create(
|
||||
this, &CustomLoadingLayer::updateResourcesProgress
|
||||
));
|
||||
|
@ -62,10 +63,12 @@ struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
|
|||
[&](UpdateFailed const& error) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
"Error updating resources",
|
||||
"Unable to update Geode resources: " +
|
||||
error + ".\n"
|
||||
"You will have to install resources manually by downloading resources.zip "
|
||||
"from the latest release on GitHub: "
|
||||
"https://github.com/geode-sdk/geode/releases/latest.\n"
|
||||
"The game will be loaded as normal, but please be aware "
|
||||
"that it may very likely crash."
|
||||
"that it is very likely to crash. "
|
||||
);
|
||||
this->setUpdateText("Resource Download Failed");
|
||||
m_fields->m_updatingResources = false;
|
||||
|
|
69
loader/src/ids/EditLevelLayer.cpp
Normal file
69
loader/src/ids/EditLevelLayer.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include <Geode/modify/EditLevelLayer.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "AddIDs.hpp"
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
$register_ids(EditLevelLayer) {
|
||||
setIDs(this, 0,
|
||||
"background",
|
||||
"bottom-left-art",
|
||||
"bottom-right-art",
|
||||
"level-name-background",
|
||||
"level-name-input",
|
||||
"description-background",
|
||||
"description-input",
|
||||
"description-text-area",
|
||||
"level-action-menu",
|
||||
"level-length",
|
||||
"level-song",
|
||||
"level-verified",
|
||||
"version-label",
|
||||
"level-id-label",
|
||||
"right-side-menu",
|
||||
"back-button-menu",
|
||||
"info-button-menu"
|
||||
);
|
||||
|
||||
if (auto menu = this->getChildByID("level-action-menu")) {
|
||||
setIDs(menu, 0,
|
||||
"edit-button",
|
||||
"play-button",
|
||||
"share-button"
|
||||
);
|
||||
}
|
||||
|
||||
if (auto menu = this->getChildByID("right-side-menu")) {
|
||||
setIDs(menu, 0,
|
||||
"delete-button",
|
||||
"help-button",
|
||||
"duplicate-button",
|
||||
"move-to-top-button",
|
||||
"folder-button"
|
||||
);
|
||||
|
||||
detachAndCreateMenu(menu,
|
||||
"folder-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("folder-button")
|
||||
);
|
||||
}
|
||||
|
||||
if (auto menu = this->getChildByID("back-button-menu"))
|
||||
setIDSafe(menu, 0, "back-button");
|
||||
|
||||
if (auto menu = this->getChildByID("info-button-menu"))
|
||||
setIDSafe(menu, 0, "info-button");
|
||||
}
|
||||
|
||||
class $modify(EditLevelLayer) {
|
||||
bool init(GJGameLevel* l) {
|
||||
if (!EditLevelLayer::init(l))
|
||||
return false;
|
||||
|
||||
NodeIDs::get()->provide(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
#include <Geode/Modify.hpp>
|
||||
#include <Geode/modify/EditorUI.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "AddIDs.hpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <Geode/Modify.hpp>
|
||||
#include <Geode/modify/GJGarageLayer.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "AddIDs.hpp"
|
||||
|
|
|
@ -6,71 +6,75 @@
|
|||
USE_GEODE_NAMESPACE();
|
||||
|
||||
$register_ids(LevelSettingsLayer) {
|
||||
bool startPos = m_mainLayer->getChildrenCount() < 10;
|
||||
|
||||
if (startPos) {
|
||||
setIDSafe(m_mainLayer, 0, "back-button");
|
||||
}
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(m_mainLayer, 0)) {
|
||||
menu->setID("song-select-menu");
|
||||
|
||||
setIDs(menu, 0,
|
||||
"bg-color-button",
|
||||
"g-color-button",
|
||||
"g2-color-button",
|
||||
"line-color-button",
|
||||
"obj-color-button",
|
||||
"more-color-button",
|
||||
"3dl-color-button",
|
||||
"bg-quick-edit-button",
|
||||
"g-quick-edit-button",
|
||||
"g2-quick-edit-button",
|
||||
"line-quick-edit-button",
|
||||
"cube-button",
|
||||
"ship-button",
|
||||
"ball-button",
|
||||
"ufo-button",
|
||||
"wave-button",
|
||||
"robot-button",
|
||||
"spider-button",
|
||||
"background-select-button",
|
||||
"ground-select-button",
|
||||
"mini-toggle",
|
||||
"dual-toggle",
|
||||
"font-button",
|
||||
"ok-button",
|
||||
"2-player-toggle",
|
||||
"2-player-help-button",
|
||||
"prev-song-button",
|
||||
"next-song-button",
|
||||
"normal-song-button",
|
||||
"custom-song-button",
|
||||
"select-custom-song-button",
|
||||
"new-song-button",
|
||||
"half-speed-button",
|
||||
"normal-speed-button",
|
||||
"2x-speed-button",
|
||||
"3x-speed-button",
|
||||
"4x-speed-button"
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"color-button-menu",
|
||||
RowLayout::create(),
|
||||
menu->getChildByID("bg-color-button"),
|
||||
menu->getChildByID("g-color-button"),
|
||||
menu->getChildByID("g2-color-button"),
|
||||
menu->getChildByID("line-color-button"),
|
||||
menu->getChildByID("obj-color-button"),
|
||||
menu->getChildByID("3dl-color-button"),
|
||||
menu->getChildByID("more-color-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"color-quick-edit-menu",
|
||||
RowLayout::create(),
|
||||
menu->getChildByID("bg-quick-edit-button"),
|
||||
menu->getChildByID("g-quick-edit-button"),
|
||||
menu->getChildByID("g2-quick-edit-button"),
|
||||
menu->getChildByID("line-quick-edit-button")
|
||||
);
|
||||
if (startPos) {
|
||||
setIDs(menu, 0,
|
||||
"cube-button",
|
||||
"ship-button",
|
||||
"ball-button",
|
||||
"ufo-button",
|
||||
"wave-button",
|
||||
"robot-button",
|
||||
"spider-button",
|
||||
"mini-toggle",
|
||||
"dual-toggle",
|
||||
"ok-button",
|
||||
"flip-gravity-toggle",
|
||||
"half-speed-button",
|
||||
"normal-speed-button",
|
||||
"2x-speed-button",
|
||||
"3x-speed-button",
|
||||
"4x-speed-button"
|
||||
);
|
||||
} else {
|
||||
setIDs(menu, 0,
|
||||
"bg-color-button",
|
||||
"g-color-button",
|
||||
"g2-color-button",
|
||||
"line-color-button",
|
||||
"obj-color-button",
|
||||
"more-color-button",
|
||||
"3dl-color-button",
|
||||
"bg-quick-edit-button",
|
||||
"g-quick-edit-button",
|
||||
"g2-quick-edit-button",
|
||||
"line-quick-edit-button",
|
||||
"cube-button",
|
||||
"ship-button",
|
||||
"ball-button",
|
||||
"ufo-button",
|
||||
"wave-button",
|
||||
"robot-button",
|
||||
"spider-button",
|
||||
"background-select-button",
|
||||
"ground-select-button",
|
||||
"mini-toggle",
|
||||
"dual-toggle",
|
||||
"font-button",
|
||||
"ok-button",
|
||||
"2-player-toggle",
|
||||
"2-player-help-button",
|
||||
"prev-song-button",
|
||||
"next-song-button",
|
||||
"normal-song-button",
|
||||
"custom-song-button",
|
||||
"select-custom-song-button",
|
||||
"new-song-button",
|
||||
"half-speed-button",
|
||||
"normal-speed-button",
|
||||
"2x-speed-button",
|
||||
"3x-speed-button",
|
||||
"4x-speed-button"
|
||||
);
|
||||
}
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
|
@ -85,14 +89,6 @@ $register_ids(LevelSettingsLayer) {
|
|||
menu->getChildByID("spider-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"scenery-selection-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("background-select-button"),
|
||||
menu->getChildByID("ground-select-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"right-toggle-menu",
|
||||
|
@ -101,21 +97,6 @@ $register_ids(LevelSettingsLayer) {
|
|||
menu->getChildByID("dual-toggle")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"font-button-menu",
|
||||
RowLayout::create()->setAlignment(Alignment::End),
|
||||
menu->getChildByID("font-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"2-player-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("2-player-help-button"),
|
||||
menu->getChildByID("2-player-toggle")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"speed-selection-menu",
|
||||
|
@ -126,6 +107,61 @@ $register_ids(LevelSettingsLayer) {
|
|||
menu->getChildByID("3x-speed-button"),
|
||||
menu->getChildByID("4x-speed-button")
|
||||
);
|
||||
|
||||
if (startPos) {
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"flip-gravity-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("flip-gravity-toggle")
|
||||
);
|
||||
} else {
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"color-button-menu",
|
||||
RowLayout::create(),
|
||||
menu->getChildByID("bg-color-button"),
|
||||
menu->getChildByID("g-color-button"),
|
||||
menu->getChildByID("g2-color-button"),
|
||||
menu->getChildByID("line-color-button"),
|
||||
menu->getChildByID("obj-color-button"),
|
||||
menu->getChildByID("3dl-color-button"),
|
||||
menu->getChildByID("more-color-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"color-quick-edit-menu",
|
||||
RowLayout::create(),
|
||||
menu->getChildByID("bg-quick-edit-button"),
|
||||
menu->getChildByID("g-quick-edit-button"),
|
||||
menu->getChildByID("g2-quick-edit-button"),
|
||||
menu->getChildByID("line-quick-edit-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"scenery-selection-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("background-select-button"),
|
||||
menu->getChildByID("ground-select-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"2-player-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("2-player-help-button"),
|
||||
menu->getChildByID("2-player-toggle")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"font-button-menu",
|
||||
RowLayout::create()->setAlignment(Alignment::End),
|
||||
menu->getChildByID("font-button")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setIDs(m_mainLayer, 2,
|
||||
|
@ -156,7 +192,7 @@ class $modify(LevelSettingsLayer) {
|
|||
if (!LevelSettingsLayer::init(levelSettings, editor))
|
||||
return false;
|
||||
|
||||
NodeIDs::get()->provide(this);
|
||||
//NodeIDs::get()->provide(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
78
loader/src/ids/PauseLayer.cpp
Normal file
78
loader/src/ids/PauseLayer.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include <Geode/modify/PauseLayer.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "AddIDs.hpp"
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
$register_ids(PauseLayer) {
|
||||
setIDs(this, 0,
|
||||
"background",
|
||||
"level-name",
|
||||
|
||||
"normal-progress-bar",
|
||||
"practice-progress-bar",
|
||||
"normal-progress-label",
|
||||
"practice-progress-label",
|
||||
"normal-mode-label",
|
||||
"practice-mode-label",
|
||||
|
||||
"center-button-menu",
|
||||
|
||||
"auto-retry-label",
|
||||
"auto-checkpoints-label",
|
||||
"show-progress-bar-label"
|
||||
);
|
||||
|
||||
if (auto menu = this->getChildByID("center-button-menu")) {
|
||||
int start_idx = 0;
|
||||
|
||||
if (menu->getChildrenCount() == 5) {
|
||||
setIDSafe(menu, 0, "edit-button");
|
||||
start_idx = 1;
|
||||
}
|
||||
|
||||
setIDs(menu, start_idx,
|
||||
"practice-button",
|
||||
"play-button",
|
||||
"exit-button"
|
||||
);
|
||||
|
||||
if (menu->getChildrenCount() == 4)
|
||||
setIDSafe(menu, start_idx + 3, "retry-button");
|
||||
}
|
||||
|
||||
// Record toggle on mobile
|
||||
if (auto label = typeinfo_cast<CCLabelBMFont*>(getChild(this, 12))) {
|
||||
setIDSafe(this, 12, "record-label");
|
||||
}
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 1)) {
|
||||
menu->setID("toggle-menu");
|
||||
|
||||
setIDs(menu, 0,
|
||||
"auto-retry-toggle",
|
||||
"auto-checkpoints-toggle",
|
||||
"show-progress-bar-toggle"
|
||||
);
|
||||
|
||||
if (menu->getChildrenCount() == 4)
|
||||
setIDSafe(menu, 3, "record-toggle");
|
||||
}
|
||||
|
||||
|
||||
setIDs(this, this->getChildrenCount() - 4,
|
||||
"music-slider",
|
||||
"sfx-slider",
|
||||
"music-label",
|
||||
"sfx-label"
|
||||
);
|
||||
}
|
||||
|
||||
class $modify(PauseLayer) {
|
||||
void customSetup() {
|
||||
PauseLayer::customSetup();
|
||||
|
||||
NodeIDs::get()->provide(this);
|
||||
}
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
#include <Geode/Modify.hpp>
|
||||
#include <Geode/modify/UILayer.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "AddIDs.hpp"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <Geode/binding/ProfilePage.hpp>
|
||||
#include <Geode/binding/CCContentLayer.hpp>
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/ui/MDTextArea.hpp>
|
||||
#include <Geode/utils/casts.hpp>
|
||||
|
@ -446,6 +447,7 @@ struct MDParser {
|
|||
case MD_BLOCKTYPE::MD_BLOCK_UL:
|
||||
{
|
||||
renderer->popIndent();
|
||||
renderer->breakLine();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -488,6 +490,7 @@ struct MDParser {
|
|||
|
||||
case MD_BLOCKTYPE::MD_BLOCK_LI:
|
||||
{
|
||||
renderer->breakLine();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -228,11 +228,17 @@ SentAsyncWebRequest::Impl::Impl(SentAsyncWebRequest* self, AsyncWebRequest const
|
|||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, utils::fetch::writeBytes);
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_URL, m_url.c_str());
|
||||
// No need to verify SSL, we trust our domains :-)
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
// Github User Agent
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "github_api/1.0");
|
||||
// Track progress
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
|
||||
// Follow redirects
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
// Fail if response code is 4XX or 5XX
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
||||
|
||||
curl_slist* headers = nullptr;
|
||||
for (auto& header : m_httpHeaders) {
|
||||
|
@ -272,6 +278,7 @@ SentAsyncWebRequest::Impl::Impl(SentAsyncWebRequest* self, AsyncWebRequest const
|
|||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &data);
|
||||
auto res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
curl_easy_cleanup(curl);
|
||||
return this->error("Fetch failed: " + std::string(curl_easy_strerror(res)));
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
|
@ -344,14 +351,16 @@ bool SentAsyncWebRequest::Impl::finished() const {
|
|||
void SentAsyncWebRequest::Impl::error(std::string const& error) {
|
||||
auto lock = std::unique_lock(m_statusMutex);
|
||||
m_statusCV.wait(lock, [this]() {
|
||||
return bool(m_paused);
|
||||
return !m_paused;
|
||||
});
|
||||
Loader::get()->queueInGDThread([this, error]() {
|
||||
std::lock_guard _(m_mutex);
|
||||
for (auto& expect : m_expects) {
|
||||
expect(error);
|
||||
{
|
||||
std::lock_guard _(m_mutex);
|
||||
for (auto& expect : m_expects) {
|
||||
expect(error);
|
||||
}
|
||||
}
|
||||
std::lock_guard __(RUNNING_REQUESTS_MUTEX);
|
||||
std::lock_guard _(RUNNING_REQUESTS_MUTEX);
|
||||
RUNNING_REQUESTS.erase(m_id);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue