From d1ffab40cc58d213dfeab7faa67152603ac705bd Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 24 Mar 2024 01:01:30 +0800 Subject: [PATCH] the first working version --- projects/Xcode15/main.c | 207 +++++++++--------- .../Xcode15/raylib.xcodeproj/project.pbxproj | 9 + src/platforms/rcore_ios.c | 39 +++- src/rcore.c | 2 +- src/rlgl.h | 9 +- 5 files changed, 149 insertions(+), 117 deletions(-) diff --git a/projects/Xcode15/main.c b/projects/Xcode15/main.c index c603fd0c3..ee07d156b 100644 --- a/projects/Xcode15/main.c +++ b/projects/Xcode15/main.c @@ -20,126 +20,120 @@ //------------------------------------------------------------------------------------------ typedef enum GameScreen { LOGO = 0, TITLE, GAMEPLAY, ENDING } GameScreen; -//------------------------------------------------------------------------------------ -// Program main entry point -//------------------------------------------------------------------------------------ -int ios_main(int argc, char * argv[]) -{ +const int screenWidth = 800; +const int screenHeight = 450; +GameScreen currentScreen = LOGO; +int framesCounter = 0; // Useful to count frames + +void ios_ready(){ // Initialization //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [core] example - basic screen manager"); - GameScreen currentScreen = LOGO; - // TODO: Initialize all required variables and load all required data here! - - int framesCounter = 0; // Useful to count frames - SetTargetFPS(60); // Set desired framerate (frames-per-second) //-------------------------------------------------------------------------------------- +} - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + +void ios_update() +{ + // Update + //---------------------------------------------------------------------------------- + switch(currentScreen) { - // Update - //---------------------------------------------------------------------------------- - switch(currentScreen) + case LOGO: { - case LOGO: + // TODO: Update LOGO screen variables here! + framesCounter++; // Count frames + + // Wait for 2 seconds (120 frames) before jumping to TITLE screen + if (framesCounter > 120) { - // TODO: Update LOGO screen variables here! - - framesCounter++; // Count frames - - // Wait for 2 seconds (120 frames) before jumping to TITLE screen - if (framesCounter > 120) - { - currentScreen = TITLE; - } - } break; - case TITLE: - { - // TODO: Update TITLE screen variables here! - - // Press enter to change to GAMEPLAY screen - if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP)) - { - currentScreen = GAMEPLAY; - } - } break; - case GAMEPLAY: - { - // TODO: Update GAMEPLAY screen variables here! - - // Press enter to change to ENDING screen - if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP)) - { - currentScreen = ENDING; - } - } break; - case ENDING: - { - // TODO: Update ENDING screen variables here! - - // Press enter to return to TITLE screen - if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP)) - { - currentScreen = TITLE; - } - } break; - default: break; - } - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - switch(currentScreen) - { - case LOGO: - { - // TODO: Draw LOGO screen here! - DrawText("LOGO SCREEN", 20, 20, 40, LIGHTGRAY); - DrawText("WAIT for 2 SECONDS...", 290, 220, 20, GRAY); - - } break; - case TITLE: - { - // TODO: Draw TITLE screen here! - DrawRectangle(0, 0, screenWidth, screenHeight, GREEN); - DrawText("TITLE SCREEN", 20, 20, 40, DARKGREEN); - DrawText("PRESS ENTER or TAP to JUMP to GAMEPLAY SCREEN", 120, 220, 20, DARKGREEN); - - } break; - case GAMEPLAY: - { - // TODO: Draw GAMEPLAY screen here! - DrawRectangle(0, 0, screenWidth, screenHeight, PURPLE); - DrawText("GAMEPLAY SCREEN", 20, 20, 40, MAROON); - DrawText("PRESS ENTER or TAP to JUMP to ENDING SCREEN", 130, 220, 20, MAROON); - - } break; - case ENDING: - { - // TODO: Draw ENDING screen here! - DrawRectangle(0, 0, screenWidth, screenHeight, BLUE); - DrawText("ENDING SCREEN", 20, 20, 40, DARKBLUE); - DrawText("PRESS ENTER or TAP to RETURN to TITLE SCREEN", 120, 220, 20, DARKBLUE); - - } break; - default: break; + currentScreen = TITLE; } - - EndDrawing(); - //---------------------------------------------------------------------------------- + } break; + case TITLE: + { + // TODO: Update TITLE screen variables here! + + // Press enter to change to GAMEPLAY screen + if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP)) + { + currentScreen = GAMEPLAY; + } + } break; + case GAMEPLAY: + { + // TODO: Update GAMEPLAY screen variables here! + + // Press enter to change to ENDING screen + if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP)) + { + currentScreen = ENDING; + } + } break; + case ENDING: + { + // TODO: Update ENDING screen variables here! + + // Press enter to return to TITLE screen + if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP)) + { + currentScreen = TITLE; + } + } break; + default: break; } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + switch(currentScreen) + { + case LOGO: + { + // TODO: Draw LOGO screen here! + DrawText("LOGO SCREEN", 20, 20, 40, LIGHTGRAY); + DrawText("WAIT for 2 SECONDS...", 290, 220, 20, GRAY); + + } break; + case TITLE: + { + // TODO: Draw TITLE screen here! + DrawRectangle(0, 0, screenWidth, screenHeight, GREEN); + DrawText("TITLE SCREEN", 20, 20, 40, DARKGREEN); + DrawText("PRESS ENTER or TAP to JUMP to GAMEPLAY SCREEN", 120, 220, 20, DARKGREEN); + + } break; + case GAMEPLAY: + { + // TODO: Draw GAMEPLAY screen here! + DrawRectangle(0, 0, screenWidth, screenHeight, PURPLE); + DrawText("GAMEPLAY SCREEN", 20, 20, 40, MAROON); + DrawText("PRESS ENTER or TAP to JUMP to ENDING SCREEN", 130, 220, 20, MAROON); + + } break; + case ENDING: + { + // TODO: Draw ENDING screen here! + DrawRectangle(0, 0, screenWidth, screenHeight, BLUE); + DrawText("ENDING SCREEN", 20, 20, 40, DARKBLUE); + DrawText("PRESS ENTER or TAP to RETURN to TITLE SCREEN", 120, 220, 20, DARKBLUE); + + } break; + default: break; + } + + EndDrawing(); + //---------------------------------------------------------------------------------- +} +void ios_destroy(){ // De-Initialization //-------------------------------------------------------------------------------------- @@ -148,5 +142,4 @@ int ios_main(int argc, char * argv[]) CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- - return 0; } diff --git a/projects/Xcode15/raylib.xcodeproj/project.pbxproj b/projects/Xcode15/raylib.xcodeproj/project.pbxproj index 191082c84..7f6a8a0d6 100644 --- a/projects/Xcode15/raylib.xcodeproj/project.pbxproj +++ b/projects/Xcode15/raylib.xcodeproj/project.pbxproj @@ -341,6 +341,11 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = A7A93GC9AY; GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + GRAPHICS_API_OPENGL_ES2, + PLATFORM_IOS, + ); GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_UNINITIALIZED_AUTOS = YES; GENERATE_INFOPLIST_FILE = YES; @@ -379,6 +384,10 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = A7A93GC9AY; GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_PREPROCESSOR_DEFINITIONS = ( + GRAPHICS_API_OPENGL_ES2, + PLATFORM_IOS, + ); GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_UNINITIALIZED_AUTOS = YES; GENERATE_INFOPLIST_FILE = YES; diff --git a/src/platforms/rcore_ios.c b/src/platforms/rcore_ios.c index 9dfbba5d2..ef3aceb4b 100644 --- a/src/platforms/rcore_ios.c +++ b/src/platforms/rcore_ios.c @@ -49,10 +49,17 @@ // TODO: Include the platform specific libraries #include "libEGL/libEGL.h" +// iOS only supports callbacks +// We are not able to give users full control of the game loop +extern void ios_ready(); +extern void ios_update(); +extern void ios_destroy(); + #import /* GameViewController */ @interface GameViewController : UIViewController +- (void)update; @end /* AppDelegate */ @@ -476,10 +483,17 @@ int InitPlatform(void) EGL_NONE }; +// const EGLint contextAttribs[] = +// { +// EGL_CONTEXT_CLIENT_VERSION, 2, +// EGL_NONE +// }; + const EGLint contextAttribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE + EGL_CONTEXT_MAJOR_VERSION, 2, + EGL_CONTEXT_MINOR_VERSION, 0, + EGL_NONE, }; EGLint numConfigs = 0; @@ -590,7 +604,7 @@ int InitPlatform(void) CORE.Storage.basePath = GetWorkingDirectory(); //---------------------------------------------------------------------------- - TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully"); + TRACELOG(LOG_INFO, "PLATFORM: IOS: Initialized successfully"); return 0; } @@ -632,6 +646,11 @@ void ClosePlatform(void) platform.viewController = self; } +- (void)update +{ + ios_update(); +} + - (bool)prefersStatusBarHidden { return true; @@ -644,10 +663,14 @@ void ClosePlatform(void) - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - NSLog(@"bounds: %@", NSStringFromCGRect([UIScreen mainScreen].bounds)); self.window.backgroundColor = [UIColor redColor]; self.window.rootViewController = [[GameViewController alloc] init]; [self.window makeKeyAndVisible]; + + ios_ready(); + + CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self.window.rootViewController selector:@selector(update)]; + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; return YES; } @@ -668,11 +691,11 @@ void ClosePlatform(void) // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } -@end +- (void)applicationWillTerminate:(UIApplication *)application { + ios_destroy(); +} -// To allow easier porting to android, we allow the user to define a -// main function which we call from android_main, defined by ourselves -extern int ios_main(int argc, char *argv[]); +@end /* main() */ int main(int argc, char * argv[]) { diff --git a/src/rcore.c b/src/rcore.c index 4da6f5472..ca184849a 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -502,7 +502,7 @@ const char *TextFormat(const char *text, ...); // Formatting of tex #include "platforms/rcore_drm.c" #elif defined(PLATFORM_ANDROID) #include "platforms/rcore_android.c" -#elif defined(PLATFORM_IOS) || defined(PLATFORM_IOSSIMULATOR) +#elif defined(PLATFORM_IOS) #include "platforms/rcore_ios.c" #else // TODO: Include your custom platform backend! diff --git a/src/rlgl.h b/src/rlgl.h index 0f7840259..b13c595f1 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -815,7 +815,14 @@ 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) + #ifndef GRAPHICS_API_OPENGL_ES2 + #error "GRAPHICS_API_OPENGL_ES2 required on PLATFORM_IOS" + #endif + #include "libGLESv2/GLES/glext.h" + #include "libGLESv2/GLES2/gl2.h" + #include "libGLESv2/GLES2/gl2ext.h" // OpenGL ES 2.0 extensions library +#elif defined(GRAPHICS_API_OPENGL_ES3) #include // OpenGL ES 3.0 library #define GL_GLEXT_PROTOTYPES #include // OpenGL ES 2.0 extensions library