Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rcore] Porting raylib to iOS and implement rcore_ios.c #3880

Open
wants to merge 44 commits into
base: master
Choose a base branch
from

Conversation

blueloveTH
Copy link
Sponsor Contributor

@blueloveTH blueloveTH commented Mar 22, 2024

I would like to take the initial step to add iOS support for raylib.
I am going to add rcore_ios.c and implement an iOS's platform layer.
I will update this pr on my progress.

Current Demo (iPhone 8)

RPReplay_Final1711259172.MP4

Steps

  • Create an empty iOS game project in XCode
  • Compile ANGLE and get libEGL.xcframework and libGLESv2.xcframework
  • Fill rcore_ios.c and compile raylib
  • Link all of the above with an example source file

Functions

  • void PollInputEvents(void)
  • int InitPlatform(void)
  • void ClosePlatform(void)

Prebuilt ANGLE libraries for iOS

Users need to add the following ANGLE libraries into Xcode.
libEGL.xcframework.zip
libGLESv2.xcframework.zip

References

@blueloveTH

This comment was marked as outdated.

@blueloveTH blueloveTH changed the title [rcore] Draft: Try to implement rcore_ios.c [rcore] Porting raylib into iOS and implement rcore_ios.c Mar 23, 2024
@blueloveTH blueloveTH changed the title [rcore] Porting raylib into iOS and implement rcore_ios.c [rcore] Porting raylib to iOS and implement rcore_ios.c Mar 23, 2024
@blueloveTH
Copy link
Sponsor Contributor Author

blueloveTH commented Mar 23, 2024

Hi @raysan5 . I need your help. iOS always use a UIApplicationMain function to start the game. UIApplicationMain is an extern function which is hidden for me. It runs forever.

int main(int argc, char * argv[]) {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}

It seems does not expose detailed control to allow us to achieve the following:

int main() {
  library_init();
  // game init code here
  while(we_have_not_quit_the_game) {
    library_message_loop();
    library_init_render();
    // render stuff
    library_end_render();
    // update game state
  }
  library_shutdown();
}

See https://stackoverflow.com/questions/2187684/how-can-i-remove-uiapplicationmain-from-an-iphone-application.

What we can do is registering render callbacks via CADisplayLink. I cannot find a way to give users full control of the game loop.

I can try a callback-based api like this. However, this requires a minor change of existing raylib projects if they want to run on iOS.

extern void ios_ready();
extern void ios_update();
extern void ios_destroy();

Old project should adapt their main function into this in order to be cross-platform between iOS and other platforms:

#ifndef PLATFORM_IOS
int main(int argc, char** argv){
    // store as global variables if you need
    ios_ready();
    while(!WindowShouldClose()) ios_update();
    ios_destroy();
    return 0;
}
#endif

@blueloveTH

This comment was marked as outdated.

@blueloveTH

This comment was marked as outdated.

@blueloveTH
Copy link
Sponsor Contributor Author

blueloveTH commented Mar 23, 2024

Question: I see there is a feature: InitWindow(0, 0, "title") will set as full screen. How is it achieved?

Should I override CORE.Window.screen.width and CORE.Window.screen.height in InitPlatform with device width and height?

@blueloveTH blueloveTH marked this pull request as ready for review March 24, 2024 05:51
@blueloveTH
Copy link
Sponsor Contributor Author

Now rcore_ios.c has basic functionalities including graphics, audio and touch input. I've marked this PR as ready for review. I will continue to work for more details and wait for raysan5's comment.

@blueloveTH

This comment was marked as outdated.

@blueloveTH
Copy link
Sponsor Contributor Author

Added iOS build workflow to CI.

@raysan5
Copy link
Owner

raysan5 commented Apr 1, 2024

@blueloveTH Excuse my late response and thank you very much for working on this great improvement. iOS platform has been missing from raylib for +10 years and I'm happy to see that some user implemented it.

My main concern is the iOS application approach that completely differs from all the other platforms. All raylib examples work exactly as they are on all the supported platforms and requiring a complete re-design for iOS is not the ideal situation.

Is it possible to use a similar approach to Android one? Embedding the App management inside raylib?

Also note that the provided rcore_ios.c implementation does not follow raylib code conventions. It would be nice to follow them when possible.

- name: Build Xcode15 project
run: |
cd projects/Xcode15
curl -L https://github.com/raysan5/raylib/files/14743869/libEGL.xcframework.zip --output libEGL.xcframework.zip
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are those files located? It looks a bit dodgy... isn't there a better approach?

parser/output/raylib_api.lua Outdated Show resolved Hide resolved
@@ -0,0 +1 @@
Frameworks
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this .gitignore file required? Could't it be avoided?

@@ -815,7 +815,19 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers
#endif

#if defined(GRAPHICS_API_OPENGL_ES3)
#if defined(PLATFORM_IOS)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible I'd prefer to keep rlgl as platform-agnostic as possible, would it be possible to move this configuration to the build system or rcore.c instead of manage it here?

#error "GL_GLEXT_PROTOTYPES required on PLATFORM_IOS"
#endif
#include "libGLESv2/GLES/glext.h"
#include "libGLESv2/GLES2/gl2.h"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why GLES2 and GLES3 are included if only GLES3 is needed?

if(touchs[i] == touch) return i + 1;
}
// clear unused touch pairs before insert
for(int i = 0; i < MAX_TOUCH_POINTS; i++){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raylib adds one space after if, else, for and always aligns brackets.

src/platforms/rcore_ios.c Outdated Show resolved Hide resolved
src/platforms/rcore_ios.c Outdated Show resolved Hide resolved
src/platforms/rcore_ios.c Outdated Show resolved Hide resolved

/* main() */
int main(int argc, char * argv[]) {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine this is the biggest issue with iOS implementation, isn't there another alternative?

@blueloveTH
Copy link
Sponsor Contributor Author

Thanks for your review. I am going to resolve them soon.

@neondeex
Copy link

neondeex commented May 2, 2024

Interesting.. will colaborate soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants