mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-12 21:14:41 -04:00
Merge branch 'main' into bi-additions
This commit is contained in:
commit
4c8c0ae7b5
32 changed files with 685 additions and 262 deletions
.github/workflows
.gitignoreCMakeLists.txtVERSIONbindings
codegen/src
installer/mac
loader
include/Geode/ui
launcher/mac
resources
src
cocos2d-ext
hooks
ids
platform
ui
internal
nodes
test/members
15
.github/workflows/build.yml
vendored
15
.github/workflows/build.yml
vendored
|
@ -112,6 +112,19 @@ jobs:
|
|||
with:
|
||||
name: geode-v${{ env.VERSION_TRIM }}-${{ matrix.config.os_identifier }}
|
||||
path: ./out
|
||||
|
||||
- name: Package MacOS
|
||||
run: |
|
||||
cp -R ./bin/nightly/resources ./out/resources
|
||||
./installer/mac/package.sh ./out ./out/geode-installer-v${{ env.VERSION_TRIM }}-${{ matrix.config.os_identifier }}.pkg
|
||||
if: matrix.config.os_identifier == 'mac'
|
||||
|
||||
- name: Publish MacOS Installer
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: geode-installer-v${{ env.VERSION_TRIM }}-${{ matrix.config.os_identifier }}
|
||||
path: ./out/geode-installer-v${{ env.VERSION_TRIM }}-${{ matrix.config.os_identifier }}.pkg
|
||||
if: matrix.config.os_identifier == 'mac'
|
||||
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -145,7 +158,7 @@ jobs:
|
|||
dest: geode-nightly-win.zip
|
||||
|
||||
- name: Update release
|
||||
uses: IsaacShelton/update-existing-release@v1.3.1
|
||||
uses: IsaacShelton/update-existing-release@v1.3.2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: ./geode-nightly-mac.zip ./geode-nightly-win.zip
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -54,6 +54,7 @@ loader/resources/version
|
|||
loader/resources/blanks/rename.js
|
||||
loader/resources/changelog.md
|
||||
fods-catgirl-hideout.txt
|
||||
test-docs.bat
|
||||
|
||||
# krita files too because alk is funny
|
||||
**/*.kra
|
||||
|
|
|
@ -122,6 +122,10 @@ file(GLOB CODEGEN_DEPENDS CONFIGURE_DEPENDS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/codegen/src/*.hpp
|
||||
)
|
||||
|
||||
if (NOT GEODE_BINDINGS_PATH)
|
||||
set(GEODE_BINDINGS_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bindings)
|
||||
endif()
|
||||
|
||||
file(GLOB CODEGEN_OUTPUTS CONFIGURE_DEPENDS
|
||||
${GEODE_CODEGEN_PATH}/Geode/binding/*.hpp
|
||||
)
|
||||
|
@ -129,7 +133,7 @@ file(GLOB CODEGEN_OUTPUTS CONFIGURE_DEPENDS
|
|||
add_custom_command(
|
||||
DEPENDS ${CODEGEN_DEPENDS}
|
||||
DEPENDS CodegenProject
|
||||
COMMAND ${GEODE_CODEGEN_BINARY_OUT}/Codegen ${GEODE_TARGET_PLATFORM} bindings ${GEODE_CODEGEN_PATH}
|
||||
COMMAND ${GEODE_CODEGEN_BINARY_OUT}/Codegen ${GEODE_TARGET_PLATFORM} ${GEODE_BINDINGS_PATH} ${GEODE_CODEGEN_PATH}
|
||||
COMMAND echo codegen > ${GEODE_CODEGEN_PATH}/.stamp
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Run Codegen"
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
1.0.0
|
||||
1.0.0
|
|
@ -737,6 +737,7 @@ class cocos2d::CCRenderTexture {
|
|||
static cocos2d::CCRenderTexture* create(int, int, cocos2d::CCTexture2DPixelFormat) = mac 0x35c720;
|
||||
auto newCCImage(bool) = mac 0x35d7d0;
|
||||
auto saveToFile(char const*) = mac 0x35dab0;
|
||||
auto beginWithClear(float r, float g, float b, float a) = mac 0x35d010;
|
||||
}
|
||||
|
||||
class cocos2d::CCRepeat {
|
||||
|
|
|
@ -1020,11 +1020,13 @@ class CustomSongWidget : cocos2d::CCNode, MusicDownloadDelegate, FLAlertLayerPro
|
|||
class CustomizeObjectLayer : FLAlertLayer, TextInputDelegate, HSVWidgetPopupDelegate, ColorSelectDelegate, ColorSetupDelegate {
|
||||
void onNextColorChannel(cocos2d::CCObject* sender) = win 0x56c80;
|
||||
void onSelectColor(cocos2d::CCObject* sender) = win 0x577b0;
|
||||
void onSelectMode(cocos2d::CCObject* sender) = mac 0xdf820, win 0x56db0;
|
||||
int getActiveMode(bool unknown) = win 0x57210;
|
||||
void onClose(cocos2d::CCObject*) = mac 0xdf660, win 0x57ac0;
|
||||
void updateSelected(int channelID) = win 0x57850;
|
||||
bool init(GameObject* target, cocos2d::CCArray* targets) = mac 0xdd560, win 0x53e00;
|
||||
void onHSV(cocos2d::CCObject* sender) = win 0x567c0;
|
||||
void toggleVisible() = mac 0xe1140, win 0x56fb0;
|
||||
virtual void hsvPopupClosed(HSVWidgetPopup* popup, cocos2d::ccHSVValue value) = win 0x56990;
|
||||
inline CustomizeObjectLayer() {}
|
||||
~CustomizeObjectLayer() = win 0x53c30;
|
||||
|
@ -1032,10 +1034,10 @@ class CustomizeObjectLayer : FLAlertLayer, TextInputDelegate, HSVWidgetPopupDele
|
|||
GameObject* m_targetObject;
|
||||
cocos2d::CCArray* m_targetObjects;
|
||||
cocos2d::CCArray* m_colorButtons;
|
||||
cocos2d::CCArray* m_colorNodes;
|
||||
cocos2d::CCArray* m_textInputNodes;
|
||||
cocos2d::CCArray* m_colorTabNodes;
|
||||
cocos2d::CCArray* m_textTabNodes;
|
||||
PAD = win 0x4;
|
||||
cocos2d::CCArray* m_detailColorButtons;
|
||||
cocos2d::CCArray* m_detailTabNodes;
|
||||
int m_selectedMode;
|
||||
int m_customColorChannel;
|
||||
bool m_unk0x200;
|
||||
|
@ -1964,8 +1966,8 @@ class GJBaseGameLayer : cocos2d::CCLayer, TriggerEffectDelegate {
|
|||
int m_activeEnterEffect;
|
||||
bool m_activeDualTouch;
|
||||
int m_attemptClickCount;
|
||||
int m_lastVisibleSection;
|
||||
int m_firstVisibleSection;
|
||||
int m_lastVisibleSection;
|
||||
bool m_objectsAreDisabled;
|
||||
bool m_blending;
|
||||
PAD = mac 0x8, win 0x8;
|
||||
|
@ -2094,7 +2096,7 @@ class GJEffectManager : cocos2d::CCNode {
|
|||
}
|
||||
|
||||
virtual bool init() = mac 0x180230, win 0x11c1b0;
|
||||
void activeColorForIndex(int) = mac 0x180cb0, win 0x11c6e0;
|
||||
cocos2d::_ccColor3B activeColorForIndex(int) = mac 0x180cb0, win 0x11c6e0;
|
||||
void activeOpacityForIndex(int) = mac 0x180e10;
|
||||
void addAllInheritedColorActions(cocos2d::CCArray*) = mac 0x1817a0;
|
||||
void addGroupPulseEffect(PulseEffectAction*) = mac 0x184c10;
|
||||
|
@ -2124,7 +2126,7 @@ class GJEffectManager : cocos2d::CCNode {
|
|||
const cocos2d::_ccColor3B& getColorSprite(int) = mac 0x180d00, win 0x11ce20;
|
||||
void getCurrentStateString() = mac 0x1867e0, win 0x11fac0;
|
||||
void getLoadedMoveOffset() = mac 0x184390;
|
||||
void getMixedColor(cocos2d::_ccColor3B, cocos2d::_ccColor3B, float) = mac 0x185d30;
|
||||
static cocos2d::_ccColor3B getMixedColor(cocos2d::_ccColor3B, cocos2d::_ccColor3B, float) = mac 0x185d30, win 0x11f610;
|
||||
uint8_t getOpacityActionForGroup(int) = mac 0x1845b0;
|
||||
gd::string getSaveString() = mac 0x185e90;
|
||||
void handleObjectCollision(bool, int, int) = mac 0x1828f0, win 0x11d2a0;
|
||||
|
@ -2260,7 +2262,7 @@ class GJGameLevel : cocos2d::CCNode {
|
|||
void getNormalPercent() = mac 0x2b8b20;
|
||||
void levelWasAltered() = mac 0x2db530, win 0xbd550;
|
||||
void savePercentage(int, bool, int, int, bool) = mac 0x2db700;
|
||||
void dataLoaded(DS_Dictionary* dict) = mac 0x2922f0, win 0xbded0, ios 0x6fca4;
|
||||
void dataLoaded(DS_Dictionary* dict) = mac 0x2dc0e0, win 0xbded0, ios 0x6fca4;
|
||||
GJDifficulty getAverageDifficulty() = win 0xbd9b0;
|
||||
gd::string getUnpackedLevelDescription() = win 0xbf890;
|
||||
gd::string lengthKeyToString(int key) = win 0xbd910;
|
||||
|
@ -2314,7 +2316,7 @@ class GJGameLevel : cocos2d::CCNode {
|
|||
int m_chk;
|
||||
bool m_isChkValid;
|
||||
bool m_isCompletionLegitimate;
|
||||
geode::SeedValueVSR m_normalPercent;
|
||||
geode::SeedValueVRS m_normalPercent;
|
||||
geode::SeedValueRSV m_orbCompletion;
|
||||
geode::SeedValueRSV m_newNormalPercent2;
|
||||
int m_practicePercent;
|
||||
|
@ -2589,7 +2591,7 @@ class GJSearchObject : cocos2d::CCNode {
|
|||
}
|
||||
|
||||
static GJSearchObject* create(SearchType nID) = win 0xc2b90;
|
||||
static GJSearchObject* create(SearchType nID, gd::string str) = win 0xc2c80;
|
||||
static GJSearchObject* create(SearchType nID, gd::string str) = win 0xc2c80, mac 0x2df310;
|
||||
static GJSearchObject* createFromKey(const char* key) = win 0xC2760;
|
||||
const char* getKey() = win 0xC30A0;
|
||||
const char* getNextPageKey() = win 0xC31F0;
|
||||
|
@ -3222,14 +3224,15 @@ class GameObject : CCSpritePlus {
|
|||
void addToTempOffset(float, float) = mac 0x335700;
|
||||
void calculateOrientedBox() = mac 0x342b20, win 0xef1a0;
|
||||
void canChangeCustomColor() = mac 0x342db0;
|
||||
void colorForMode(int, bool) = mac 0x343460;
|
||||
cocos2d::_ccColor3B& colorForMode(int, bool) = mac 0x343460, win 0xef8d0;
|
||||
float groupOpacityMod() = win 0xebda0;
|
||||
void commonSetup() = mac 0x2f5570, win 0xcfac0;
|
||||
void copyGroups(GameObject*) = mac 0x33ae30, win 0xeb9d0;
|
||||
static GameObject* createWithFrame(const char*) = mac 0x2f5490, win 0xcf8f0;
|
||||
static GameObject* createWithKey(int) = mac 0x2f4ce0, win 0xcf4f0;
|
||||
void destroyObject() = mac 0x336a00;
|
||||
void determineSlopeDirection() = mac 0x33a9e0, win 0xeb670;
|
||||
void getActiveColorForMode(int, bool) = mac 0x343860, win 0xefb10;
|
||||
cocos2d::_ccColor3B& getActiveColorForMode(int, bool) = mac 0x343860, win 0xefb10;
|
||||
void getBallFrame(int) = mac 0x341bf0;
|
||||
cocos2d::CCPoint getBoxOffset() = mac 0x3353d0, win 0xef350;
|
||||
const cocos2d::_ccColor3B& getColorIndex() = mac 0x343b90;
|
||||
|
@ -3363,7 +3366,7 @@ class GameObject : CCSpritePlus {
|
|||
bool m_unknownVisibility347;
|
||||
cocos2d::CCSprite* m_baseSprite;
|
||||
cocos2d::CCSprite* m_detailSprite;
|
||||
PAD = mac 0x4, win 0x4;
|
||||
bool m_unk2e8;
|
||||
float m_objectRadius;
|
||||
bool m_isRotatedSide;
|
||||
float m_unk2F4;
|
||||
|
@ -3391,7 +3394,10 @@ class GameObject : CCSpritePlus {
|
|||
int m_targetColorID;
|
||||
float m_scale;
|
||||
int m_objectID;
|
||||
int m_unknown3c8;
|
||||
bool m_unk364;
|
||||
bool m_unk365;
|
||||
bool m_unk366;
|
||||
bool m_ignoreFade;
|
||||
bool m_unk368;
|
||||
bool m_unk369;
|
||||
bool m_unk36A;
|
||||
|
@ -3401,10 +3407,10 @@ class GameObject : CCSpritePlus {
|
|||
int m_defaultZOrder;
|
||||
bool m_useSecondSheet;
|
||||
bool m_isPortal;
|
||||
bool m_lockColourAsChild;
|
||||
bool m_customAudioScale;
|
||||
int m_minAudioScale;
|
||||
int m_maxAudioScale;
|
||||
bool m_lockColourAsChild;
|
||||
float m_minAudioScale;
|
||||
float m_maxAudioScale;
|
||||
bool m_unkParticleSystem2;
|
||||
int m_secretCoinID;
|
||||
int m_unkUnusedSaveStringKey53;
|
||||
|
@ -3420,7 +3426,7 @@ class GameObject : CCSpritePlus {
|
|||
float m_realOpacity;
|
||||
GJSpriteColor* m_baseColor;
|
||||
GJSpriteColor* m_detailColor;
|
||||
int m_unknown420;
|
||||
bool m_unk3b0;
|
||||
ZLayer m_defaultZLayer;
|
||||
ZLayer m_zLayer;
|
||||
int m_gameZOrder;
|
||||
|
@ -3480,7 +3486,7 @@ class GameRateDelegate {}
|
|||
class GameSoundManager : cocos2d::CCNode {
|
||||
void disableMetering() = mac 0x362d80, win 0x257D0;
|
||||
void enableMetering() = mac 0x362d00, win 0x256F0;
|
||||
void getMeteringValue() = mac 0x362db0, win 0x258f0;
|
||||
float getMeteringValue() = mac 0x362db0, win 0x258f0;
|
||||
void playBackgroundMusic(gd::string, bool, bool) = mac 0x362070, win 0x252B0;
|
||||
void playEffect(gd::string, float, float, float) = mac 0x3623d0, win 0x25450;
|
||||
void stopBackgroundMusic() = mac 0x362130, win 0x253A0;
|
||||
|
@ -3712,8 +3718,7 @@ class LevelBrowserLayer : cocos2d::CCLayer, LevelManagerDelegate, FLAlertLayerPr
|
|||
void updateLevelsLabel() = win 0x15c350;
|
||||
static LevelBrowserLayer* create(GJSearchObject* search) = mac 0x251210, win 0x159fa0, ios 0x2d0a00;
|
||||
|
||||
PAD = win 0x4;
|
||||
int m_unk0;
|
||||
PAD = win 0x4, mac 0x8;
|
||||
TextArea* m_noInternet;
|
||||
GJListLayer* m_list;
|
||||
CCMenuItemSpriteExtra* m_rightArrow;
|
||||
|
@ -3975,14 +3980,14 @@ class LevelInfoLayer : cocos2d::CCLayer, LevelDownloadDelegate, LevelUpdateDeleg
|
|||
void setupProgressBars() = win 0x177fc0;
|
||||
void downloadLevel() = win 0x177d90;
|
||||
|
||||
PAD = win 0x4;
|
||||
PAD = win 0x4, mac 0x8;
|
||||
cocos2d::CCMenu* m_playBtnMenu;
|
||||
GJGameLevel* m_level;
|
||||
cocos2d::CCArray* m_unknown;
|
||||
CCMenuItemSpriteExtra* m_likeBtn;
|
||||
CCMenuItemSpriteExtra* m_starRateBtn;
|
||||
CCMenuItemSpriteExtra* m_demonRateBtn;
|
||||
PAD = win 0x4;
|
||||
PAD = win 0x4, mac 0x8;
|
||||
CCMenuItemToggler* m_toggler;
|
||||
cocos2d::CCLabelBMFont* m_label0;
|
||||
cocos2d::CCLabelBMFont* m_label1;
|
||||
|
@ -3991,7 +3996,7 @@ class LevelInfoLayer : cocos2d::CCLayer, LevelDownloadDelegate, LevelUpdateDeleg
|
|||
cocos2d::CCLabelBMFont* m_label4;
|
||||
cocos2d::CCLabelBMFont* m_label5;
|
||||
CCMenuItemSpriteExtra* m_cloneBtn;
|
||||
PAD = win 0x4;
|
||||
PAD = win 0x4, mac 0x8;
|
||||
}
|
||||
|
||||
class LevelLeaderboard : FLAlertLayer {
|
||||
|
@ -4005,7 +4010,11 @@ class LevelLeaderboard : FLAlertLayer {
|
|||
LevelLeaderboardType m_type;
|
||||
}
|
||||
|
||||
class LevelManagerDelegate {}
|
||||
class LevelManagerDelegate {
|
||||
virtual void loadLevelsFailed(char const*) {}
|
||||
virtual void loadLevelsFinished(cocos2d::CCArray *,char const*) {}
|
||||
virtual void setupPageInfo(std::string,char const*) {}
|
||||
}
|
||||
|
||||
class LevelPage {
|
||||
PAD = win 0x124;
|
||||
|
@ -4206,7 +4215,7 @@ class LocalLevelManager : GManager {
|
|||
|
||||
cocos2d::CCDictionary* getAllLevelsInDict() = mac 0x35e3d0, win 0x18d7c0;
|
||||
|
||||
PAD = mac 0x10, win 0x1C;
|
||||
PAD = mac 0x4, win 0x1C;
|
||||
cocos2d::CCDictionary* m_loadData;
|
||||
cocos2d::CCDictionary* m_levelData;
|
||||
cocos2d::CCArray* m_localLevels;
|
||||
|
@ -4650,7 +4659,7 @@ class PlayLayer : GJBaseGameLayer, CCCircleWaveDelegate, CurrencyRewardDelegate,
|
|||
bool unk350;
|
||||
cocos2d::CCArray* unk354;
|
||||
cocos2d::CCArray* unk358;
|
||||
cocos2d::CCArray* unk35C;
|
||||
cocos2d::CCArray* m_objectsToUpdate;
|
||||
cocos2d::CCArray* unk360;
|
||||
bool m_isMute;
|
||||
bool unk365;
|
||||
|
@ -4713,14 +4722,14 @@ class PlayLayer : GJBaseGameLayer, CCCircleWaveDelegate, CurrencyRewardDelegate,
|
|||
bool unk42C;
|
||||
bool m_isPlayer2Frozen;
|
||||
gd::string m_previousRecords;
|
||||
void* unknown6a8;
|
||||
double unknown6a8;
|
||||
double m_time;
|
||||
int unknown6b8;
|
||||
int unknown6bc;
|
||||
bool unk460;
|
||||
bool m_isAudioMeteringSupported;
|
||||
cocos2d::CCDictionary* unk464;
|
||||
gd::map<short, bool> unk468;
|
||||
gd::map<short, bool> m_hasColors;
|
||||
bool m_collisionDisabled;
|
||||
bool unknown701;
|
||||
GameObject* m_latestVehicle;
|
||||
|
@ -4957,8 +4966,8 @@ class PlayerObject : GameObject, AnimatedSpriteDelegate {
|
|||
PAD = mac 0x30, win 0x1c;
|
||||
bool m_unk4B0;
|
||||
cocos2d::CCSprite* m_unk4B4;
|
||||
int m_unk4B8;
|
||||
int m_unk4BC;
|
||||
int m_collidedGroundObjectUniqueID;
|
||||
int m_collidedCeilObjectUniqueID;
|
||||
PAD = mac 0x14, win 0x14;
|
||||
bool m_unk4D4;
|
||||
cocos2d::CCArray* m_particleSystems;
|
||||
|
@ -5047,7 +5056,7 @@ class PlayerObject : GameObject, AnimatedSpriteDelegate {
|
|||
bool m_isRobot;
|
||||
bool m_isSpider;
|
||||
bool m_isUpsideDown;
|
||||
bool m_unk63F;
|
||||
bool m_isDead;
|
||||
bool m_isOnGround;
|
||||
bool m_isDashing;
|
||||
float m_vehicleSize;
|
||||
|
@ -5069,7 +5078,8 @@ class PlayerObject : GameObject, AnimatedSpriteDelegate {
|
|||
bool m_unk684;
|
||||
bool m_unk685;
|
||||
double m_unk688;
|
||||
PAD = win 0x8;
|
||||
PAD = win 0x4;
|
||||
float m_meteringValue;
|
||||
float m_groundHeight;
|
||||
float m_unk69C;
|
||||
PAD = win 0x4;
|
||||
|
|
|
@ -122,65 +122,67 @@ std::string generateAddressHeader(Root& root) {
|
|||
}
|
||||
}
|
||||
|
||||
output += format_strings::declare_metadata_begin;
|
||||
// TODO: this eats too much of compile time make it opt in maybe
|
||||
|
||||
for (auto& c : root.classes) {
|
||||
for (auto& field : c.fields) {
|
||||
std::string address_str;
|
||||
// output += format_strings::declare_metadata_begin;
|
||||
|
||||
auto fn = field.get_as<FunctionBindField>();
|
||||
// for (auto& c : root.classes) {
|
||||
// for (auto& field : c.fields) {
|
||||
// std::string address_str;
|
||||
|
||||
if (!fn) {
|
||||
continue;
|
||||
}
|
||||
// auto fn = field.get_as<FunctionBindField>();
|
||||
|
||||
if (codegen::getStatus(field) == BindStatus::Binded) {
|
||||
address_str = fmt::format(
|
||||
"addresser::get{}Virtual(Resolve<{}>::func(&{}::{}))",
|
||||
str_if("Non", !fn->beginning.is_virtual),
|
||||
codegen::getParameterTypes(fn->beginning),
|
||||
field.parent,
|
||||
fn->beginning.name
|
||||
);
|
||||
}
|
||||
else if (codegen::getStatus(field) == BindStatus::NeedsBinding) {
|
||||
address_str = fmt::format("base::get() + 0x{:x}", codegen::platformNumber(fn->binds));
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
// if (!fn) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
char const* used_declare_format;
|
||||
// if (codegen::getStatus(field) == BindStatus::Binded) {
|
||||
// address_str = fmt::format(
|
||||
// "addresser::get{}Virtual(Resolve<{}>::func(&{}::{}))",
|
||||
// str_if("Non", !fn->beginning.is_virtual),
|
||||
// codegen::getParameterTypes(fn->beginning),
|
||||
// field.parent,
|
||||
// fn->beginning.name
|
||||
// );
|
||||
// }
|
||||
// else if (codegen::getStatus(field) == BindStatus::NeedsBinding) {
|
||||
// address_str = fmt::format("base::get() + 0x{:x}", codegen::platformNumber(fn->binds));
|
||||
// }
|
||||
// else {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
switch (fn->beginning.type) {
|
||||
case FunctionType::Normal:
|
||||
used_declare_format = format_strings::declare_metadata;
|
||||
break;
|
||||
case FunctionType::Ctor:
|
||||
case FunctionType::Dtor:
|
||||
used_declare_format = format_strings::declare_metadata_structor;
|
||||
break;
|
||||
}
|
||||
// char const* used_declare_format;
|
||||
|
||||
if (fn->beginning.is_static)
|
||||
used_declare_format = format_strings::declare_metadata_static;
|
||||
// switch (fn->beginning.type) {
|
||||
// case FunctionType::Normal:
|
||||
// used_declare_format = format_strings::declare_metadata;
|
||||
// break;
|
||||
// case FunctionType::Ctor:
|
||||
// case FunctionType::Dtor:
|
||||
// used_declare_format = format_strings::declare_metadata_structor;
|
||||
// break;
|
||||
// }
|
||||
|
||||
output += fmt::format(
|
||||
used_declare_format,
|
||||
fmt::arg("address", address_str),
|
||||
fmt::arg("class_name", c.name),
|
||||
fmt::arg("const", str_if(" const ", fn->beginning.is_const)),
|
||||
fmt::arg("convention", codegen::getModifyConventionName(field)),
|
||||
fmt::arg("return", bank.getReturn(fn->beginning, c.name)),
|
||||
fmt::arg("parameters", codegen::getParameters(fn->beginning)),
|
||||
fmt::arg("parameter_types", codegen::getParameterTypes(fn->beginning)),
|
||||
fmt::arg("arguments", codegen::getParameterNames(fn->beginning)),
|
||||
fmt::arg("parameter_comma", str_if(", ", !fn->beginning.args.empty())),
|
||||
fmt::arg("index", field.field_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
// if (fn->beginning.is_static)
|
||||
// used_declare_format = format_strings::declare_metadata_static;
|
||||
|
||||
output += format_strings::declare_metadata_end;
|
||||
// output += fmt::format(
|
||||
// used_declare_format,
|
||||
// fmt::arg("address", address_str),
|
||||
// fmt::arg("class_name", c.name),
|
||||
// fmt::arg("const", str_if(" const ", fn->beginning.is_const)),
|
||||
// fmt::arg("convention", codegen::getModifyConventionName(field)),
|
||||
// fmt::arg("return", bank.getReturn(fn->beginning, c.name)),
|
||||
// fmt::arg("parameters", codegen::getParameters(fn->beginning)),
|
||||
// fmt::arg("parameter_types", codegen::getParameterTypes(fn->beginning)),
|
||||
// fmt::arg("arguments", codegen::getParameterNames(fn->beginning)),
|
||||
// fmt::arg("parameter_comma", str_if(", ", !fn->beginning.args.empty())),
|
||||
// fmt::arg("index", field.field_id)
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// output += format_strings::declare_metadata_end;
|
||||
return output;
|
||||
}
|
||||
|
|
67
installer/mac/Scripts/postinstall
Executable file
67
installer/mac/Scripts/postinstall
Executable file
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env osascript
|
||||
|
||||
|
||||
set tmpPath to POSIX path of "/tmp/"
|
||||
set binPath to POSIX path of (tmpPath & "geode-install/")
|
||||
|
||||
on ExitWithMessage(message)
|
||||
display dialog message
|
||||
do shell script "rm -rf " & binPath
|
||||
error number -128
|
||||
end ExitWithMessage
|
||||
|
||||
try
|
||||
set gdPath to (the POSIX path of (choose file with prompt "Please choose the Geometry Dash application to install Geode to:" of type {"app"}))
|
||||
on error
|
||||
ExitWithMessage ("Prompt cancelled.")
|
||||
end try
|
||||
|
||||
set execPath to (gdPath & "Contents/MacOS/Geometry Dash")
|
||||
set frameworkPath to POSIX path of (gdPath & "Contents/Frameworks/")
|
||||
set fmodPath to "libfmod.dylib"
|
||||
set fmodOriginalPath to "libfmod-original.dylib"
|
||||
set geodePath to "Geode.dylib"
|
||||
set bootstrapperPath to "GeodeBootstrapper.dylib"
|
||||
set resourcesPath to "resources/"
|
||||
set newGeodePath to "Contents/geode/"
|
||||
set newResourcesPath to (newGeodePath & "resources/geode.loader/")
|
||||
|
||||
try
|
||||
tell application "System Events"
|
||||
if not exists file execPath then
|
||||
ExitWithMessage ("Not a valid Geometry Dash installation (executable missing): " & gdPath)
|
||||
end if
|
||||
|
||||
if not exists file (frameworkPath & fmodPath) then
|
||||
ExitWithMessage ("Not a valid Geometry Dash installation (fmod missing): " & gdPath)
|
||||
end if
|
||||
end tell
|
||||
on error
|
||||
ExitWithMessage ("Not a valid Geometry Dash installation: " & gdPath)
|
||||
end try
|
||||
|
||||
try
|
||||
do shell script "mv -n " & (frameworkPath & fmodPath) & " " & (frameworkPath & fmodOriginalPath)
|
||||
on error
|
||||
ExitWithMessage ("Moving original fmod failed: " & (frameworkPath & fmodPath))
|
||||
end try
|
||||
|
||||
try
|
||||
do shell script "mv " & (binPath & geodePath) & " " & (frameworkPath & geodePath)
|
||||
do shell script "mv " & (binPath & bootstrapperPath) & " " & (frameworkPath & bootstrapperPath)
|
||||
do shell script "mv " & (binPath & fmodPath) & " " & (frameworkPath & fmodPath)
|
||||
do shell script "INSTALLER_USER=$(stat -f '%Su' $HOME) && sudo chown -R $INSTALLER_USER " & frameworkPath
|
||||
on error
|
||||
ExitWithMessage ("Moving libraries failed: " & frameworkPath)
|
||||
end try
|
||||
|
||||
try
|
||||
do shell script "mkdir -p " & (gdPath & newResourcesPath)
|
||||
do shell script "mv " & (binPath & resourcesPath) & "* " & (gdPath & newResourcesPath)
|
||||
do shell script "INSTALLER_USER=$(stat -f '%Su' $HOME) && sudo chown -R $INSTALLER_USER " & (gdPath & newGeodePath)
|
||||
on error
|
||||
ExitWithMessage ("Moving resources failed: " & (gdPath & newResourcesPath))
|
||||
end try
|
||||
|
||||
|
||||
do shell script "rm -rf " & binPath
|
3
installer/mac/package.sh
Executable file
3
installer/mac/package.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
pkgbuild --root "$1" --identifier com.geode-sdk.geode --scripts "installer/mac/Scripts" --install-location "/tmp/geode-install" $2
|
|
@ -53,7 +53,7 @@ namespace geode {
|
|||
template<class T, class N>
|
||||
concept InheritsEnterLayer = std::is_base_of_v<EnterLayerEvent<N>, T>;
|
||||
|
||||
template<class N, InheritsEnterLayer<N> T>
|
||||
template<class N, InheritsEnterLayer<N> T = EnterLayerEvent<N>>
|
||||
class EnterLayerFilter : public EventFilter<EnterLayerEvent<N>> {
|
||||
public:
|
||||
using Callback = void(T*);
|
||||
|
|
|
@ -33,8 +33,7 @@ namespace geode {
|
|||
m_buttonMenu->setZOrder(100);
|
||||
m_mainLayer->addChild(m_buttonMenu);
|
||||
|
||||
cocos2d::CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
|
||||
this->registerWithTouchDispatcher();
|
||||
this->setTouchEnabled(true);
|
||||
|
||||
auto closeSpr = cocos2d::CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png");
|
||||
closeSpr->setScale(.8f);
|
||||
|
|
|
@ -51,8 +51,7 @@ namespace geode {
|
|||
|
||||
this->updateLabel();
|
||||
|
||||
cocos2d::CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
|
||||
this->registerWithTouchDispatcher();
|
||||
this->setTouchEnabled(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,77 +1,4 @@
|
|||
#include <ghc/filesystem.hpp>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
void displayError(std::string alertMessage) {
|
||||
CFStringRef cfTitle = CFStringCreateWithCString(NULL, "Geode Bootstrapper", kCFStringEncodingUTF8);
|
||||
CFStringRef cfMessage = CFStringCreateWithCString(NULL, alertMessage.c_str(), kCFStringEncodingUTF8);
|
||||
|
||||
CFUserNotificationDisplayNotice(0, kCFUserNotificationCautionAlertLevel, NULL, NULL, NULL, cfTitle, cfMessage, NULL);
|
||||
}
|
||||
|
||||
void loadGeode() {
|
||||
auto dylib = dlopen("Geode.dylib", RTLD_NOW);
|
||||
if (!dylib) {
|
||||
displayError(std::string("Couldn't load Geode: ") + dlerror());
|
||||
return;
|
||||
}
|
||||
auto trigger = dlsym(dylib, "dynamicTrigger");
|
||||
if (!trigger) {
|
||||
displayError(std::string("Couldn't start Geode: ") + dlerror());
|
||||
return;
|
||||
}
|
||||
reinterpret_cast<void(*)()>(trigger)();
|
||||
return;
|
||||
}
|
||||
|
||||
extern "C" void fake();
|
||||
__attribute__((constructor)) void _entry() {
|
||||
std::array<char, PATH_MAX> gddir;
|
||||
|
||||
uint32_t out = PATH_MAX;
|
||||
_NSGetExecutablePath(gddir.data(), &out);
|
||||
|
||||
ghc::filesystem::path gdpath = gddir.data();
|
||||
auto workingDir = gdpath.parent_path().parent_path();
|
||||
|
||||
auto updatesDir = workingDir / "geode" / "update";
|
||||
auto libDir = workingDir / "Frameworks";
|
||||
auto resourcesDir = workingDir / "geode" / "resources";
|
||||
|
||||
auto error = std::error_code();
|
||||
|
||||
if (ghc::filesystem::exists(updatesDir / "Geode.dylib", error) && !error) {
|
||||
ghc::filesystem::rename(
|
||||
updatesDir / "Geode.dylib",
|
||||
libDir / "Geode.dylib", error
|
||||
);
|
||||
if (error) {
|
||||
displayError(std::string("Couldn't update Geode: ") + error.message());
|
||||
return loadGeode();
|
||||
}
|
||||
}
|
||||
|
||||
if (ghc::filesystem::exists(updatesDir / "resources", error) && !error) {
|
||||
ghc::filesystem::remove_all(resourcesDir / "geode.loader", error);
|
||||
|
||||
if (error) {
|
||||
displayError(std::string("Couldn't update Geode resources: ") + error.message());
|
||||
return loadGeode();
|
||||
}
|
||||
|
||||
ghc::filesystem::rename(
|
||||
updatesDir / "resources",
|
||||
resourcesDir / "geode.loader", error
|
||||
);
|
||||
|
||||
if (error) {
|
||||
displayError(std::string("Couldn't update Geode resources: ") + error.message());
|
||||
return loadGeode();
|
||||
}
|
||||
}
|
||||
|
||||
return loadGeode();
|
||||
fake();
|
||||
}
|
|
@ -10,4 +10,13 @@ set_target_properties(Bootstrapper PROPERTIES
|
|||
RUNTIME_OUTPUT_DIRECTORY "${GEODE_BIN_PATH}/nightly"
|
||||
)
|
||||
|
||||
target_link_libraries(Bootstrapper PRIVATE "-framework CoreFoundation" ghc_filesystem)
|
||||
target_link_libraries(Bootstrapper PRIVATE)
|
||||
|
||||
add_library(FakeGeode SHARED FakeGeode.cpp)
|
||||
target_compile_features(FakeGeode PUBLIC cxx_std_17)
|
||||
set_target_properties(FakeGeode PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "Geode"
|
||||
)
|
||||
|
||||
target_link_libraries(Bootstrapper PRIVATE geode-loader)
|
||||
|
|
1
loader/launcher/mac/FakeGeode.cpp
Normal file
1
loader/launcher/mac/FakeGeode.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
extern "C" void fake() {}
|
0
loader/launcher/mac/Updater.cpp
Normal file
0
loader/launcher/mac/Updater.cpp
Normal file
|
@ -70,6 +70,12 @@
|
|||
"default": true,
|
||||
"name": "Auto-Update Mods",
|
||||
"description": "Automatically update <cp>mods</c> on startup"
|
||||
},
|
||||
"disable-last-crashed-popup": {
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"name": "Disable Crash Popup",
|
||||
"description": "Disables the popup at startup asking if you'd like to send a bug report; intended for developers"
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
|
|
|
@ -221,9 +221,6 @@ static AxisPosition nodeAxis(CCNode* node, Axis axis, float scale) {
|
|||
if (auto toggle = typeinfo_cast<CCMenuItemToggler*>(node)) {
|
||||
scaledSize = toggle->m_offButton->getScaledContentSize();
|
||||
}
|
||||
if (auto spacer = typeinfo_cast<SpacerNode*>(node)) {
|
||||
scaledSize = CCSizeZero;
|
||||
}
|
||||
auto anchor = node->getAnchorPoint();
|
||||
if (axis == Axis::Row) {
|
||||
return AxisPosition {
|
||||
|
@ -492,6 +489,13 @@ void AxisLayout::tryFitLayout(
|
|||
float crossScaleDownFactor = 0.f;
|
||||
float crossSquishFactor = 0.f;
|
||||
|
||||
// make spacers have zero size so they don't affect spacing calculations
|
||||
for (auto& node : CCArrayExt<CCNode>(nodes)) {
|
||||
if (auto spacer = typeinfo_cast<SpacerNode*>(node)) {
|
||||
spacer->setContentSize(CCSizeZero);
|
||||
}
|
||||
}
|
||||
|
||||
// fit everything into rows while possible
|
||||
size_t ix = 0;
|
||||
auto newNodes = nodes->shallowCopy();
|
||||
|
|
|
@ -139,7 +139,11 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
|
||||
// show crash info
|
||||
static bool shownLastCrash = false;
|
||||
if (Loader::get()->didLastLaunchCrash() && !shownLastCrash) {
|
||||
if (
|
||||
Loader::get()->didLastLaunchCrash() &&
|
||||
!shownLastCrash &&
|
||||
!Mod::get()->template getSettingValue<bool>("disable-last-crashed-popup")
|
||||
) {
|
||||
shownLastCrash = true;
|
||||
auto popup = createQuickPopup(
|
||||
"Crashed",
|
||||
|
@ -198,12 +202,7 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
}
|
||||
|
||||
void onMissingTextures(CCObject*) {
|
||||
static bool shownInfoPopup = false;
|
||||
if (shownInfoPopup) {
|
||||
return this->onGeode(nullptr);
|
||||
}
|
||||
shownInfoPopup = true;
|
||||
|
||||
|
||||
#ifdef GEODE_IS_DESKTOP
|
||||
|
||||
try {
|
||||
|
@ -218,7 +217,7 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
"and <cy>unzip its contents</c> into <cb>geode/update/resources</c>.\n"
|
||||
"Afterwards, <cg>restart the game</c>.\n"
|
||||
"You may also continue without installing resources, but be aware that "
|
||||
"the game <cr>will crash</c>.",
|
||||
"you won't be able to open <cr>the Geode menu</c>.",
|
||||
"Dismiss", "Open Github",
|
||||
[](auto, bool btn2) {
|
||||
if (btn2) {
|
||||
|
|
|
@ -35,7 +35,9 @@ void setIDs(CCNode* node, int startIndex, Args... args) {
|
|||
static void switchToMenu(CCNode* node, CCMenu* menu) {
|
||||
if (!node || !menu) return;
|
||||
|
||||
auto worldPos = node->getParent()->convertToWorldSpace(node->getPosition());
|
||||
auto worldPos = node->getParent() ?
|
||||
node->getParent()->convertToWorldSpace(node->getPosition()) :
|
||||
node->getPosition();
|
||||
|
||||
node->retain();
|
||||
node->removeFromParent();
|
||||
|
|
321
loader/src/ids/CustomizeObjectLayer.cpp
Normal file
321
loader/src/ids/CustomizeObjectLayer.cpp
Normal file
|
@ -0,0 +1,321 @@
|
|||
#include "AddIDs.hpp"
|
||||
|
||||
#include <Geode/modify/CustomizeObjectLayer.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
$register_ids(CustomizeObjectLayer) {
|
||||
auto winSize = CCDirector::get()->getWinSize();
|
||||
|
||||
setIDs(
|
||||
m_mainLayer, 0,
|
||||
"alert-bg",
|
||||
"title-label",
|
||||
"button-menu",
|
||||
"selected-channel-label",
|
||||
"channel-input-bg",
|
||||
"channel-input",
|
||||
"text-input-bg",
|
||||
"text-input",
|
||||
"glow-label"
|
||||
);
|
||||
|
||||
m_buttonMenu->setID("ok-menu");
|
||||
|
||||
setIDs(
|
||||
m_buttonMenu,
|
||||
0,
|
||||
"ok-button",
|
||||
"info-button",
|
||||
|
||||
"base-tab-button",
|
||||
"detail-tab-button",
|
||||
"base-hsv-button",
|
||||
"detail-hsv-button",
|
||||
"text-tab-button",
|
||||
|
||||
"player-color-1-button",
|
||||
"player-color-2-button",
|
||||
"light-bg-button",
|
||||
"default-button",
|
||||
"channel-1-button",
|
||||
"channel-2-button",
|
||||
"channel-3-button",
|
||||
"channel-4-button",
|
||||
"channel-5-button",
|
||||
"channel-6-button",
|
||||
"channel-7-button",
|
||||
"channel-8-button",
|
||||
"channel-9-button",
|
||||
"channel-custom-button",
|
||||
|
||||
"select-channel-up-button",
|
||||
"select-channel-down-button",
|
||||
"select-channel-button",
|
||||
|
||||
"split-text-button",
|
||||
"clear-text-button",
|
||||
|
||||
"next-free-button",
|
||||
|
||||
"copy-button",
|
||||
"paste-button",
|
||||
|
||||
"browse-button",
|
||||
|
||||
"glow-toggle"
|
||||
);
|
||||
|
||||
auto tabsLayout = RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Center)
|
||||
->setCrossAxisAlignment(AxisAlignment::Center);
|
||||
tabsLayout->ignoreInvisibleChildren(true);
|
||||
auto tabsMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"tabs-menu",
|
||||
tabsLayout,
|
||||
m_buttonMenu->getChildByID("base-tab-button"),
|
||||
m_buttonMenu->getChildByID("detail-tab-button"),
|
||||
SpacerNode::create(),
|
||||
m_buttonMenu->getChildByID("text-tab-button")
|
||||
);
|
||||
tabsMenu->setContentSize({ 360.f, 50.f });
|
||||
tabsMenu->setPositionX(winSize.width / 2);
|
||||
tabsMenu->updateLayout();
|
||||
|
||||
auto specialChannelsMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"special-channels-menu",
|
||||
RowLayout::create()
|
||||
->setCrossAxisOverflow(false)
|
||||
->setGrowCrossAxis(true)
|
||||
->setAxisAlignment(AxisAlignment::Center)
|
||||
->setCrossAxisAlignment(AxisAlignment::Center)
|
||||
->setGap(14.f),
|
||||
m_buttonMenu->getChildByID("player-color-1-button"),
|
||||
m_buttonMenu->getChildByID("player-color-2-button"),
|
||||
m_buttonMenu->getChildByID("light-bg-button"),
|
||||
m_buttonMenu->getChildByID("default-button")
|
||||
);
|
||||
specialChannelsMenu->setContentSize({ 350.f, 50.f });
|
||||
specialChannelsMenu->setPositionX(winSize.width / 2);
|
||||
specialChannelsMenu->updateLayout();
|
||||
|
||||
auto channelsMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"channels-menu",
|
||||
RowLayout::create()
|
||||
->setCrossAxisOverflow(false)
|
||||
->setGrowCrossAxis(true)
|
||||
->setAxisAlignment(AxisAlignment::Center)
|
||||
->setCrossAxisAlignment(AxisAlignment::Center)
|
||||
->setGap(20.f),
|
||||
m_buttonMenu->getChildByID("channel-1-button"),
|
||||
m_buttonMenu->getChildByID("channel-2-button"),
|
||||
m_buttonMenu->getChildByID("channel-3-button"),
|
||||
m_buttonMenu->getChildByID("channel-4-button"),
|
||||
m_buttonMenu->getChildByID("channel-5-button"),
|
||||
m_buttonMenu->getChildByID("channel-6-button"),
|
||||
m_buttonMenu->getChildByID("channel-7-button"),
|
||||
m_buttonMenu->getChildByID("channel-8-button"),
|
||||
m_buttonMenu->getChildByID("channel-9-button"),
|
||||
m_buttonMenu->getChildByID("channel-custom-button")
|
||||
);
|
||||
channelsMenu->setContentSize({ 350.f, 100.f });
|
||||
channelsMenu->setPosition(winSize.width / 2, winSize.height / 2 - 25.f);
|
||||
channelsMenu->updateLayout();
|
||||
|
||||
auto selectedChannelMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"selected-channel-menu",
|
||||
nullptr,
|
||||
m_buttonMenu->getChildByID("select-channel-button"),
|
||||
m_mainLayer->getChildByID("selected-channel-label")
|
||||
);
|
||||
selectedChannelMenu->setContentSize({ 120.f, 40.f });
|
||||
selectedChannelMenu->setPosition(
|
||||
winSize.width / 2 + 110.f,
|
||||
winSize.height / 2 - 90.f
|
||||
);
|
||||
if (auto label = selectedChannelMenu->getChildByID("selected-channel-label")) {
|
||||
label->setPosition(75.f, 20.f);
|
||||
}
|
||||
if (auto button = selectedChannelMenu->getChildByID("select-channel-button")) {
|
||||
button->setPosition(100.f, 20.f);
|
||||
}
|
||||
|
||||
auto togglesMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"toggles-menu",
|
||||
nullptr,
|
||||
m_mainLayer->getChildByID("glow-label"),
|
||||
m_buttonMenu->getChildByID("glow-toggle")
|
||||
);
|
||||
togglesMenu->setContentSize({ 75.f, 120.f });
|
||||
togglesMenu->setPosition(55.f, 90.f);
|
||||
if (auto label = togglesMenu->getChildByID("glow-label")) {
|
||||
label->setPosition(57.f, 20.f);
|
||||
}
|
||||
if (auto toggle = togglesMenu->getChildByID("glow-toggle")) {
|
||||
toggle->setPosition(57.f, 5.f);
|
||||
}
|
||||
|
||||
auto baseHSVMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"base-hsv-menu",
|
||||
RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Start),
|
||||
m_buttonMenu->getChildByID("base-hsv-button")
|
||||
);
|
||||
baseHSVMenu->setContentSize({ 80.f, 60.f });
|
||||
baseHSVMenu->setPositionX(winSize.width / 2 - 132.5f);
|
||||
baseHSVMenu->updateLayout();
|
||||
|
||||
auto detailHSVMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"detail-hsv-menu",
|
||||
RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Start),
|
||||
m_buttonMenu->getChildByID("detail-hsv-button")
|
||||
);
|
||||
detailHSVMenu->setContentSize({ 80.f, 60.f });
|
||||
detailHSVMenu->setPositionX(baseHSVMenu->getPositionX());
|
||||
detailHSVMenu->updateLayout();
|
||||
|
||||
auto nextFreeMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"next-free-menu",
|
||||
RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Start),
|
||||
m_buttonMenu->getChildByID("next-free-button")
|
||||
);
|
||||
nextFreeMenu->setContentSize({ 120.f, 60.f });
|
||||
nextFreeMenu->setPositionX(winSize.width / 2 - 110.f);
|
||||
nextFreeMenu->updateLayout();
|
||||
|
||||
auto textActionsMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"text-actions-menu",
|
||||
RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::End)
|
||||
->setAxisReverse(true),
|
||||
m_buttonMenu->getChildByID("split-text-button")
|
||||
);
|
||||
textActionsMenu->setContentSize({ 120.f, 60.f });
|
||||
textActionsMenu->setPositionX(winSize.width / 2 + 110.f);
|
||||
textActionsMenu->updateLayout();
|
||||
|
||||
auto clearTextMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"clear-text-menu",
|
||||
nullptr,
|
||||
m_buttonMenu->getChildByID("clear-text-button")
|
||||
);
|
||||
|
||||
auto infoMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"info-menu",
|
||||
RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::End)
|
||||
->setAxisReverse(true),
|
||||
m_buttonMenu->getChildByID("info-button")
|
||||
);
|
||||
infoMenu->setContentSize({ 80.f, 60.f });
|
||||
infoMenu->setPosition(winSize.width / 2 + 132.5f, baseHSVMenu->getPositionY());
|
||||
infoMenu->updateLayout();
|
||||
|
||||
auto browseMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"browse-menu",
|
||||
ColumnLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Start)
|
||||
->setAxisReverse(true),
|
||||
m_buttonMenu->getChildByID("browse-button")
|
||||
);
|
||||
browseMenu->setContentSize({ 100.f, 140.f });
|
||||
browseMenu->setPositionY(winSize.height / 2 - 70.f);
|
||||
browseMenu->updateLayout();
|
||||
|
||||
auto copyPasteMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"copy-paste-menu",
|
||||
ColumnLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::End)
|
||||
->setAxisReverse(true),
|
||||
m_buttonMenu->getChildByID("copy-button"),
|
||||
m_buttonMenu->getChildByID("paste-button")
|
||||
);
|
||||
copyPasteMenu->setContentSize({ 100.f, 140.f });
|
||||
copyPasteMenu->setPositionY(winSize.height / 2 + 100.f);
|
||||
copyPasteMenu->updateLayout();
|
||||
|
||||
auto selectChannelMenu = detachAndCreateMenu(
|
||||
m_mainLayer,
|
||||
"select-channel-menu",
|
||||
nullptr,
|
||||
m_mainLayer->getChildByID("channel-input-bg"),
|
||||
m_mainLayer->getChildByID("channel-input"),
|
||||
m_buttonMenu->getChildByID("select-channel-up-button"),
|
||||
m_buttonMenu->getChildByID("select-channel-down-button")
|
||||
);
|
||||
selectChannelMenu->setContentSize({ 60.f, 140.f });
|
||||
if (auto bg = selectChannelMenu->getChildByID("channel-input-bg")) {
|
||||
bg->setPosition({ 30.f, 70.f });
|
||||
}
|
||||
if (auto input = selectChannelMenu->getChildByID("channel-input")) {
|
||||
input->setPosition({ 30.f, 70.f });
|
||||
}
|
||||
if (auto btn = selectChannelMenu->getChildByID("select-channel-up-button")) {
|
||||
btn->setPosition({ 30.f, 110.f });
|
||||
}
|
||||
if (auto btn = selectChannelMenu->getChildByID("select-channel-down-button")) {
|
||||
btn->setPosition({ 30.f, 30.f });
|
||||
}
|
||||
}
|
||||
|
||||
struct CustomizeObjectLayerIDs : Modify<CustomizeObjectLayerIDs, CustomizeObjectLayer> {
|
||||
static void onModify(auto& self) {
|
||||
if (!self.setHookPriority("CustomizeObjectLayer::init", GEODE_ID_PRIORITY)) {
|
||||
log::warn("Failed to set CustomizeObjectLayer::init hook priority, node IDs may not work properly");
|
||||
}
|
||||
}
|
||||
|
||||
void toggleMenuIf(const char* id, int mode) {
|
||||
if (auto menu = m_mainLayer->getChildByID(id)) {
|
||||
menu->setVisible(m_selectedMode == mode);
|
||||
}
|
||||
}
|
||||
|
||||
void toggleMenuIfNot(const char* id, int mode) {
|
||||
if (auto menu = m_mainLayer->getChildByID(id)) {
|
||||
menu->setVisible(m_selectedMode != mode);
|
||||
}
|
||||
}
|
||||
|
||||
void toggleVisible() {
|
||||
CustomizeObjectLayer::toggleVisible();
|
||||
// have to manually toggle menu visibility to allow touches being correctly passed
|
||||
this->toggleMenuIf("base-hsv-menu", 1);
|
||||
this->toggleMenuIf("detail-hsv-menu", 2);
|
||||
this->toggleMenuIf("text-actions-menu", 3);
|
||||
this->toggleMenuIf("clear-text-menu", 3);
|
||||
this->toggleMenuIfNot("next-free-menu", 3);
|
||||
this->toggleMenuIfNot("toggles-menu", 3);
|
||||
this->toggleMenuIfNot("channels-menu", 3);
|
||||
this->toggleMenuIfNot("special-channels-menu", 3);
|
||||
this->toggleMenuIfNot("selected-channel-menu", 3);
|
||||
this->toggleMenuIfNot("browse-menu", 3);
|
||||
this->toggleMenuIfNot("copy-paste-menu", 3);
|
||||
this->toggleMenuIfNot("select-channel-menu", 3);
|
||||
}
|
||||
|
||||
bool init(GameObject* obj, CCArray* objs) {
|
||||
if (!CustomizeObjectLayer::init(obj, objs))
|
||||
return false;
|
||||
|
||||
NodeIDs::get()->provide(this);
|
||||
this->toggleVisible();
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
|
@ -5,6 +5,7 @@ using namespace geode::prelude;
|
|||
|
||||
#if defined(GEODE_IS_MACOS)
|
||||
|
||||
#include "mac/main.mm"
|
||||
#include "mac/crashlog.mm"
|
||||
#include "mac/FileWatcher.mm"
|
||||
#include "mac/util.mm"
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
#include <Geode/DefaultInclude.hpp>
|
||||
|
||||
#if defined(GEODE_IS_MACOS)
|
||||
|
||||
#include "../load.hpp"
|
||||
#include <dlfcn.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <thread>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
std::length_error::~length_error() _NOEXCEPT {} // do not ask...
|
||||
|
||||
// camila has an old ass macos and this function turned
|
||||
// from dynamic to static thats why she needs to define it
|
||||
// this is what old versions does to a silly girl
|
||||
|
||||
void dynamicEntry() {
|
||||
auto dylib = dlopen("GeodeBootstrapper.dylib", RTLD_NOLOAD);
|
||||
dlclose(dylib);
|
||||
|
||||
auto workingDir = dirs::getGameDir();
|
||||
auto libDir = workingDir / "Frameworks";
|
||||
auto updatesDir = workingDir / "geode" / "update";
|
||||
|
||||
auto error = std::error_code();
|
||||
|
||||
if (ghc::filesystem::exists(updatesDir / "GeodeBootstrapper.dylib", error) && !error) {
|
||||
ghc::filesystem::rename(
|
||||
updatesDir / "GeodeBootstrapper.dylib", libDir / "GeodeBootstrapper.dylib", error
|
||||
);
|
||||
if (error) return;
|
||||
}
|
||||
|
||||
geodeEntry(nullptr);
|
||||
}
|
||||
|
||||
extern "C" __attribute__((visibility("default"))) void dynamicTrigger() {
|
||||
std::thread(&dynamicEntry).detach();
|
||||
}
|
||||
|
||||
// remove when we can figure out how to not remove it
|
||||
auto dynamicTriggerRef = &dynamicTrigger;
|
||||
|
||||
#endif
|
66
loader/src/platform/mac/main.mm
Normal file
66
loader/src/platform/mac/main.mm
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include <Geode/DefaultInclude.hpp>
|
||||
|
||||
#if defined(GEODE_IS_MACOS)
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include "../load.hpp"
|
||||
#include <dlfcn.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <unistd.h>
|
||||
#include <tulip/TulipHook.hpp>
|
||||
#include <array>
|
||||
|
||||
#include <thread>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
std::length_error::~length_error() _NOEXCEPT {} // do not ask...
|
||||
|
||||
// camila has an old ass macos and this function turned
|
||||
// from dynamic to static thats why she needs to define it
|
||||
// this is what old versions does to a silly girl
|
||||
|
||||
extern "C" void fake() {}
|
||||
|
||||
void applicationDidFinishLaunchingHook(void* self, SEL sel, NSNotification* notification) {
|
||||
// updateGeode();
|
||||
|
||||
std::array<uint8_t, 6> patchBytes = {
|
||||
0x55,
|
||||
0x48, 0x89, 0xe5,
|
||||
0x41, 0x57
|
||||
};
|
||||
|
||||
auto res = tulip::hook::writeMemory((void*)(base::get() + 0x69a0), patchBytes.data(), 6);
|
||||
if (!res)
|
||||
return;
|
||||
|
||||
int exitCode = geodeEntry(nullptr);
|
||||
if (exitCode != 0)
|
||||
return;
|
||||
|
||||
return reinterpret_cast<void(*)(void*, SEL, NSNotification*)>(geode::base::get() + 0x69a0)(self, sel, notification);
|
||||
}
|
||||
|
||||
|
||||
bool loadGeode() {
|
||||
auto detourAddr = reinterpret_cast<uintptr_t>(&applicationDidFinishLaunchingHook) - geode::base::get() - 0x69a5;
|
||||
auto detourAddrPtr = reinterpret_cast<uint8_t*>(&detourAddr);
|
||||
|
||||
std::array<uint8_t, 5> patchBytes = {
|
||||
0xe9, detourAddrPtr[0], detourAddrPtr[1], detourAddrPtr[2], detourAddrPtr[3]
|
||||
};
|
||||
|
||||
auto res = tulip::hook::writeMemory((void*)(base::get() + 0x69a0), patchBytes.data(), 5);
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void _entry() {
|
||||
if (!loadGeode())
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -75,25 +75,14 @@ void utils::web::openLinkInBrowser(std::string const& url) {
|
|||
|
||||
@implementation FileDialog
|
||||
+(Result<std::vector<ghc::filesystem::path>>) filePickerWithMode:(file::PickMode)mode options:(file::FilePickOptions const&)options multiple:(bool)mult {
|
||||
NSOpenPanel* panel = [NSOpenPanel openPanel];
|
||||
NSSavePanel* panel;
|
||||
if (mode == file::PickMode::SaveFile)
|
||||
panel = [NSSavePanel savePanel];
|
||||
else
|
||||
panel = [NSOpenPanel openPanel];
|
||||
|
||||
// allowed files
|
||||
NSMutableArray* allowed = [NSMutableArray array];
|
||||
[panel setCanCreateDirectories: TRUE];
|
||||
|
||||
for (auto& f : options.filters) {
|
||||
for (auto& i : f.files) {
|
||||
auto nsstr = [NSString stringWithUTF8String: i.c_str()];
|
||||
|
||||
if (![allowed containsObject: nsstr])
|
||||
[allowed addObject: nsstr];
|
||||
}
|
||||
}
|
||||
|
||||
if (options.filters.size())
|
||||
[panel setAllowedFileTypes: allowed];
|
||||
|
||||
// multiple
|
||||
[panel setAllowsMultipleSelection: mult];
|
||||
|
||||
// default path
|
||||
if (options.defaultPath) {
|
||||
|
@ -102,8 +91,36 @@ void utils::web::openLinkInBrowser(std::string const& url) {
|
|||
}
|
||||
|
||||
// other
|
||||
[panel setCanChooseDirectories: NO];
|
||||
[panel setCanChooseFiles: YES];
|
||||
if (mode != file::PickMode::SaveFile) {
|
||||
auto openPanel = (NSOpenPanel*)panel;
|
||||
|
||||
if (mode == file::PickMode::OpenFile){
|
||||
[openPanel setCanChooseDirectories: NO];
|
||||
[openPanel setCanChooseFiles: YES];
|
||||
}
|
||||
else {
|
||||
[openPanel setCanChooseDirectories: YES];
|
||||
[openPanel setCanChooseFiles: NO];
|
||||
}
|
||||
|
||||
[openPanel setAllowsMultipleSelection: mult];
|
||||
|
||||
// allowed files
|
||||
// TODO: allowed files using the NSOpenSavePanelDelegate xd
|
||||
// NSMutableArray* allowed = [NSMutableArray array];
|
||||
|
||||
// for (auto& f : options.filters) {
|
||||
// for (auto& i : f.files) {
|
||||
// auto nsstr = [NSString stringWithUTF8String: i.c_str()];
|
||||
|
||||
// if (![allowed containsObject: nsstr])
|
||||
// [allowed addObject: nsstr];
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (options.filters.size())
|
||||
// [panel setAllowedFileTypes: allowed];
|
||||
}
|
||||
|
||||
// run thing
|
||||
|
||||
|
@ -111,11 +128,16 @@ void utils::web::openLinkInBrowser(std::string const& url) {
|
|||
|
||||
if (result == NSModalResponseOK) {
|
||||
std::vector<ghc::filesystem::path> fileURLs;
|
||||
|
||||
for (NSURL* i in panel.URLs) {
|
||||
fileURLs.push_back(std::string(i.path.UTF8String));
|
||||
if (mode == file::PickMode::SaveFile) {
|
||||
fileURLs.push_back(std::string([[[panel URL] path] UTF8String]));
|
||||
}
|
||||
else {
|
||||
auto openPanel = (NSOpenPanel*)panel;
|
||||
|
||||
for (NSURL* i in openPanel.URLs) {
|
||||
fileURLs.push_back(std::string(i.path.UTF8String));
|
||||
}
|
||||
}
|
||||
return Ok(fileURLs);
|
||||
} else {
|
||||
return Err("File picker cancelled");
|
||||
|
@ -143,10 +165,11 @@ Result<std::vector<ghc::filesystem::path>> utils::file::pickFiles(
|
|||
}
|
||||
|
||||
CCPoint cocos::getMousePos() {
|
||||
auto frame = NSApp.mainWindow.frame;
|
||||
auto scaleFactor = CCPoint(CCDirector::get()->getWinSize()) / ccp(frame.size.width, frame.size.height);
|
||||
auto windowFrame = NSApp.mainWindow.frame;
|
||||
auto viewFrame = NSApp.mainWindow.contentView.frame;
|
||||
auto scaleFactor = CCPoint(CCDirector::get()->getWinSize()) / ccp(viewFrame.size.width, viewFrame.size.height);
|
||||
auto mouse = [NSEvent mouseLocation];
|
||||
return ccp(mouse.x - frame.origin.x, mouse.y - frame.origin.y) * scaleFactor;
|
||||
return ccp(mouse.x - windowFrame.origin.x, mouse.y - windowFrame.origin.y) * scaleFactor;
|
||||
}
|
||||
|
||||
ghc::filesystem::path dirs::getGameDir() {
|
||||
|
|
|
@ -91,8 +91,7 @@ bool ModInfoPopup::init(ModInfo const& info, ModListLayer* list) {
|
|||
versionLabel->setColor({0, 255, 0});
|
||||
m_mainLayer->addChild(versionLabel);
|
||||
|
||||
CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
|
||||
this->registerWithTouchDispatcher();
|
||||
this->setTouchEnabled(true);
|
||||
|
||||
m_detailsArea = MDTextArea::create(
|
||||
(info.details() ? info.details().value() : "### No description provided."),
|
||||
|
|
|
@ -107,8 +107,7 @@ protected:
|
|||
);
|
||||
m_menu->addChild(m_resetBtn);
|
||||
|
||||
CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
|
||||
m_menu->registerWithTouchDispatcher();
|
||||
m_menu->setTouchEnabled(true);
|
||||
|
||||
if (!this->setup(setting, width)) return false;
|
||||
|
||||
|
|
|
@ -25,9 +25,7 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
|||
|
||||
auto layer = ScrollLayer::create(layerSize);
|
||||
layer->setPosition(winSize / 2 - layerSize / 2);
|
||||
|
||||
CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
|
||||
layer->registerWithTouchDispatcher();
|
||||
layer->setTouchEnabled(true);
|
||||
|
||||
float totalHeight = .0f;
|
||||
std::vector<CCNode*> rendered;
|
||||
|
|
|
@ -128,8 +128,7 @@ bool MDTextArea::init(std::string const& str, CCSize const& size) {
|
|||
m_content->setZOrder(2);
|
||||
m_scrollLayer->m_contentLayer->addChild(m_content);
|
||||
|
||||
CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
|
||||
m_scrollLayer->registerWithTouchDispatcher();
|
||||
m_scrollLayer->setTouchEnabled(true);
|
||||
|
||||
this->addChild(m_scrollLayer);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ using namespace geode::prelude;
|
|||
constexpr auto NOTIFICATION_FADEIN = .3f;
|
||||
constexpr auto NOTIFICATION_FADEOUT = 1.f;
|
||||
|
||||
Ref<CCArray> Notification::s_queue = CCArray::create();
|
||||
Ref<CCArray> Notification::s_queue = nullptr;
|
||||
|
||||
bool Notification::init(std::string const& text, CCSprite* icon, float time) {
|
||||
if (!CCNodeRGBA::init()) return false;
|
||||
|
@ -55,6 +55,9 @@ void Notification::updateLayout() {
|
|||
|
||||
void Notification::showNextNotification() {
|
||||
m_showing = false;
|
||||
if (!s_queue) {
|
||||
s_queue = CCArray::create();
|
||||
}
|
||||
SceneManager::get()->forget(this);
|
||||
// remove self from front of queue
|
||||
s_queue->removeFirstObject();
|
||||
|
@ -156,6 +159,9 @@ void Notification::waitAndHide() {
|
|||
}
|
||||
|
||||
void Notification::show() {
|
||||
if (!s_queue) {
|
||||
s_queue = CCArray::create();
|
||||
}
|
||||
if (!m_showing) {
|
||||
if (!s_queue->containsObject(this)) {
|
||||
s_queue->addObject(this);
|
||||
|
|
|
@ -177,7 +177,7 @@ bool Scrollbar::init(CCScrollLayerExt* target) {
|
|||
this->addChild(m_track);
|
||||
this->addChild(m_thumb);
|
||||
|
||||
this->registerWithTouchDispatcher();
|
||||
this->setTouchEnabled(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -64,4 +64,15 @@ GEODE_MEMBER_CHECK(SetupPulsePopup, m_pulseMode, 0x38c);
|
|||
// ColorSelectPopup
|
||||
GEODE_MEMBER_CHECK(ColorSelectPopup, m_copyColor, 0x372);
|
||||
|
||||
// LevelInfoLayer
|
||||
GEODE_MEMBER_CHECK(LevelInfoLayer, m_level, 0x1c0);
|
||||
|
||||
// LevelBrowserLayer
|
||||
GEODE_MEMBER_CHECK(LevelBrowserLayer, m_leftArrow, 0x1a8);
|
||||
GEODE_MEMBER_CHECK(LevelBrowserLayer, m_searchObject, 0x1d8);
|
||||
GEODE_MEMBER_CHECK(LevelBrowserLayer, m_itemCount, 0x208);
|
||||
|
||||
// LocalLevelManager
|
||||
GEODE_MEMBER_CHECK(LocalLevelManager, m_localLevels, 0x140);
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue