Browse Source

Merge 1de43bfb49 into 03ff864087

pull/3880/merge
BLUELOVETH 1 day ago
committed by GitHub
parent
commit
69322e96c5
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
9 changed files with 1432 additions and 9 deletions
  1. +35
    -0
      .github/workflows/ios.yml
  2. +123
    -0
      projects/Xcode15/main.c
  3. +446
    -0
      projects/Xcode15/raylib.xcodeproj/project.pbxproj
  4. +8
    -0
      projects/Xcode15/raylib.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  5. +1
    -0
      projects/Xcode15/raylib/.gitignore
  6. +2
    -8
      src/platforms/rcore_android.c
  7. +800
    -0
      src/platforms/rcore_ios.c
  8. +4
    -0
      src/rcore.c
  9. +13
    -1
      src/rlgl.h

+ 35
- 0
.github/workflows/ios.yml View File

@ -0,0 +1,35 @@
name: iOS
on:
workflow_dispatch:
push:
paths:
- 'src/**'
- 'examples/**'
- '.github/workflows/android.yml'
pull_request:
paths:
- 'src/**'
- 'examples/**'
- '.github/workflows/android.yml'
release:
types: [published]
jobs:
build:
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Build Xcode15 project
run: |
cd projects/Xcode15
curl -L https://github.com/raysan5/raylib/files/14743869/libEGL.xcframework.zip --output libEGL.xcframework.zip
curl -L https://github.com/raysan5/raylib/files/14743873/libGLESv2.xcframework.zip --output libGLESv2.xcframework.zip
mkdir -p raylib/Frameworks
unzip -q libEGL.xcframework.zip -d raylib/Frameworks/libEGL.xcframework
unzip -q libGLESv2.xcframework.zip -d raylib/Frameworks/libGLESv2.xcframework
rm libEGL.xcframework.zip
rm libGLESv2.xcframework.zip
xcodebuild -project raylib.xcodeproj -scheme raylib -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' build

+ 123
- 0
projects/Xcode15/main.c View File

@ -0,0 +1,123 @@
/*******************************************************************************************
*
* raylib [core] example - Input Gestures Detection
*
* Example originally created with raylib 1.4, last time updated with raylib 4.2
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2016-2024 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#ifndef RL_IOS_NO_EXAMPLE
#include "raylib.h"
int MAX_GESTURE_STRINGS = 20;
int screenWidth = 0;
int screenHeight = 0;
Vector2 touchPosition;
Rectangle touchArea;
int gesturesCount = 0;
char gestureStrings[100][32];
int currentGesture = GESTURE_NONE;
int lastGesture = GESTURE_NONE;
void ios_ready(){
InitWindow(0, 0, "raylib [core] example - input gestures");
screenWidth = GetScreenWidth();
screenHeight = GetScreenHeight();
touchPosition = (Vector2){ 0, 0 };
touchArea = (Rectangle){ 220, 10, screenWidth - 230.0f, screenHeight - 20.0f };
//SetGesturesEnabled(0b0000000000001001); // Enable only some gestures to be detected
SetTargetFPS(60);
MAX_GESTURE_STRINGS = (screenHeight - 50) / 20;
}
static void add_gesture(const char* title){
if (gesturesCount >= MAX_GESTURE_STRINGS)
{
for (int i = 0; i < MAX_GESTURE_STRINGS; i++) TextCopy(gestureStrings[i], "\0");
gesturesCount = 0;
}
TextCopy(gestureStrings[gesturesCount], title);
gesturesCount++;
}
void ios_update()
{
lastGesture = currentGesture;
currentGesture = GetGestureDetected();
touchPosition = GetTouchPosition(0);
if(IsMouseButtonPressed(0)) add_gesture("MouseButtonPressed");
if(IsMouseButtonReleased(0)) add_gesture("MouseButtonReleased");
if (CheckCollisionPointRec(touchPosition, touchArea) && (currentGesture != GESTURE_NONE))
{
if (currentGesture != lastGesture)
{
// Store gesture string
switch (currentGesture)
{
case GESTURE_TAP: add_gesture( "GESTURE TAP"); break;
case GESTURE_DOUBLETAP: add_gesture( "GESTURE DOUBLETAP"); break;
case GESTURE_HOLD: add_gesture( "GESTURE HOLD"); break;
case GESTURE_DRAG: add_gesture( "GESTURE DRAG"); break;
case GESTURE_SWIPE_RIGHT: add_gesture( "GESTURE SWIPE RIGHT"); break;
case GESTURE_SWIPE_LEFT: add_gesture( "GESTURE SWIPE LEFT"); break;
case GESTURE_SWIPE_UP: add_gesture( "GESTURE SWIPE UP"); break;
case GESTURE_SWIPE_DOWN: add_gesture( "GESTURE SWIPE DOWN"); break;
case GESTURE_PINCH_IN: add_gesture( "GESTURE PINCH IN"); break;
case GESTURE_PINCH_OUT: add_gesture( "GESTURE PINCH OUT"); break;
default: break;
}
}
}
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawRectangleRec(touchArea, GRAY);
DrawRectangle(225, 15, screenWidth - 240, screenHeight - 30, RAYWHITE);
DrawText("GESTURES TEST AREA", screenWidth - 270, screenHeight - 40, 20, Fade(GRAY, 0.5f));
for (int i = 0; i < gesturesCount; i++)
{
if (i % 2 == 0){
DrawRectangle(10, 30 + 20*i, 200, 20, Fade(LIGHTGRAY, 0.5f));
}else{
DrawRectangle(10, 30 + 20*i, 200, 20, Fade(LIGHTGRAY, 0.3f));
}
if (i < gesturesCount - 1){
DrawText(gestureStrings[i], 35, 36 + 20*i, 10, DARKGRAY);
}else{
DrawText(gestureStrings[i], 35, 36 + 20*i, 10, MAROON);
}
}
DrawRectangleLines(10, 29, 200, screenHeight - 50, GRAY);
DrawText(
TextFormat("TOUCH COUNT: %d", GetTouchPointCount()),
50, 15, 10, GRAY
);
for(int i=0; i < GetTouchPointCount(); i++){
DrawCircleV(GetTouchPosition(i), 30, MAROON);
}
EndDrawing();
}
void ios_destroy(){
CloseWindow(); // Close window and OpenGL context
}
#endif

+ 446
- 0
projects/Xcode15/raylib.xcodeproj/project.pbxproj View File

@ -0,0 +1,446 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
1BF3FCDE2BAF1C1800D3B043 /* libEGL.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B16D9042BAEDC41001FD5E0 /* libEGL.xcframework */; };
1BF3FCDF2BAF1C1800D3B043 /* libEGL.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1B16D9042BAEDC41001FD5E0 /* libEGL.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1BF3FCE02BAF1C1800D3B043 /* libGLESv2.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B16D9032BAEDC41001FD5E0 /* libGLESv2.xcframework */; };
1BF3FCE12BAF1C1800D3B043 /* libGLESv2.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1B16D9032BAEDC41001FD5E0 /* libGLESv2.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1BF3FCE62BAF1C3000D3B043 /* AVFAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1BF3FCE42BAF1C3000D3B043 /* AVFAudio.framework */; };
1BF3FCE72BAF1C3000D3B043 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1BF3FCE52BAF1C3000D3B043 /* AVFoundation.framework */; };
1BF3FCE92BAF1C3800D3B043 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1BF3FCE82BAF1C3800D3B043 /* Foundation.framework */; };
1BF3FCF12BAF1D3300D3B043 /* raudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BF3FCEA2BAF1D3300D3B043 /* raudio.c */; };
1BF3FCF22BAF1D3300D3B043 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BF3FCEB2BAF1D3300D3B043 /* utils.c */; };
1BF3FCF32BAF1D3300D3B043 /* rshapes.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BF3FCEC2BAF1D3300D3B043 /* rshapes.c */; };
1BF3FCF42BAF1D3300D3B043 /* rtextures.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BF3FCED2BAF1D3300D3B043 /* rtextures.c */; };
1BF3FCF52BAF1D3300D3B043 /* rcore.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BF3FCEE2BAF1D3300D3B043 /* rcore.c */; };
1BF3FCF62BAF1D3300D3B043 /* rtext.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BF3FCEF2BAF1D3300D3B043 /* rtext.c */; };
1BF3FCF72BAF1D3300D3B043 /* rmodels.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BF3FCF02BAF1D3300D3B043 /* rmodels.c */; };
1BF3FCFD2BAF2CFD00D3B043 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BF3FCFC2BAF2CFD00D3B043 /* main.c */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
1BF3FCE22BAF1C1900D3B043 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
1BF3FCE12BAF1C1800D3B043 /* libGLESv2.xcframework in Embed Frameworks */,
1BF3FCDF2BAF1C1800D3B043 /* libEGL.xcframework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1B16D9032BAEDC41001FD5E0 /* libGLESv2.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = libGLESv2.xcframework; sourceTree = "<group>"; };
1B16D9042BAEDC41001FD5E0 /* libEGL.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = libEGL.xcframework; sourceTree = "<group>"; };
1BF3FCC32BAF1BC900D3B043 /* raylib.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = raylib.app; sourceTree = BUILT_PRODUCTS_DIR; };
1BF3FCE42BAF1C3000D3B043 /* AVFAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFAudio.framework; path = System/Library/Frameworks/AVFAudio.framework; sourceTree = SDKROOT; };
1BF3FCE52BAF1C3000D3B043 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
1BF3FCE82BAF1C3800D3B043 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1BF3FCEA2BAF1D3300D3B043 /* raudio.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; name = raudio.c; path = ../../../src/raudio.c; sourceTree = "<group>"; };
1BF3FCEB2BAF1D3300D3B043 /* utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = utils.c; path = ../../../src/utils.c; sourceTree = "<group>"; };
1BF3FCEC2BAF1D3300D3B043 /* rshapes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rshapes.c; path = ../../../src/rshapes.c; sourceTree = "<group>"; };
1BF3FCED2BAF1D3300D3B043 /* rtextures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rtextures.c; path = ../../../src/rtextures.c; sourceTree = "<group>"; };
1BF3FCEE2BAF1D3300D3B043 /* rcore.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; name = rcore.c; path = ../../../src/rcore.c; sourceTree = "<group>"; };
1BF3FCEF2BAF1D3300D3B043 /* rtext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rtext.c; path = ../../../src/rtext.c; sourceTree = "<group>"; };
1BF3FCF02BAF1D3300D3B043 /* rmodels.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rmodels.c; path = ../../../src/rmodels.c; sourceTree = "<group>"; };
1BF3FCFC2BAF2CFD00D3B043 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1BF3FCC02BAF1BC900D3B043 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1BF3FCE92BAF1C3800D3B043 /* Foundation.framework in Frameworks */,
1BF3FCE72BAF1C3000D3B043 /* AVFoundation.framework in Frameworks */,
1BF3FCE62BAF1C3000D3B043 /* AVFAudio.framework in Frameworks */,
1BF3FCE02BAF1C1800D3B043 /* libGLESv2.xcframework in Frameworks */,
1BF3FCDE2BAF1C1800D3B043 /* libEGL.xcframework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1B16D8EE2BAEDBEA001FD5E0 = {
isa = PBXGroup;
children = (
1BF3FCFC2BAF2CFD00D3B043 /* main.c */,
1BF3FCC42BAF1BC900D3B043 /* raylib */,
1B16D8F92BAEDBEA001FD5E0 /* Products */,
1BF3FCE32BAF1C3000D3B043 /* Frameworks */,
);
sourceTree = "<group>";
};
1B16D8F92BAEDBEA001FD5E0 /* Products */ = {
isa = PBXGroup;
children = (
1BF3FCC32BAF1BC900D3B043 /* raylib.app */,
);
name = Products;
sourceTree = "<group>";
};
1B16D9022BAEDC1C001FD5E0 /* Frameworks */ = {
isa = PBXGroup;
children = (
1B16D9042BAEDC41001FD5E0 /* libEGL.xcframework */,
1B16D9032BAEDC41001FD5E0 /* libGLESv2.xcframework */,
);
path = Frameworks;
sourceTree = "<group>";
};
1BF3FCC42BAF1BC900D3B043 /* raylib */ = {
isa = PBXGroup;
children = (
1BF3FCEA2BAF1D3300D3B043 /* raudio.c */,
1BF3FCEE2BAF1D3300D3B043 /* rcore.c */,
1BF3FCF02BAF1D3300D3B043 /* rmodels.c */,
1BF3FCEC2BAF1D3300D3B043 /* rshapes.c */,
1BF3FCEF2BAF1D3300D3B043 /* rtext.c */,
1BF3FCED2BAF1D3300D3B043 /* rtextures.c */,
1BF3FCEB2BAF1D3300D3B043 /* utils.c */,
1B16D9022BAEDC1C001FD5E0 /* Frameworks */,
);
path = raylib;
sourceTree = "<group>";
};
1BF3FCE32BAF1C3000D3B043 /* Frameworks */ = {
isa = PBXGroup;
children = (
1BF3FCE82BAF1C3800D3B043 /* Foundation.framework */,
1BF3FCE42BAF1C3000D3B043 /* AVFAudio.framework */,
1BF3FCE52BAF1C3000D3B043 /* AVFoundation.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
1BF3FCC22BAF1BC900D3B043 /* raylib */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1BF3FCDB2BAF1BCB00D3B043 /* Build configuration list for PBXNativeTarget "raylib" */;
buildPhases = (
1BF3FCBF2BAF1BC900D3B043 /* Sources */,
1BF3FCC02BAF1BC900D3B043 /* Frameworks */,
1BF3FCC12BAF1BC900D3B043 /* Resources */,
1BF3FCE22BAF1C1900D3B043 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = raylib;
productName = raylib;
productReference = 1BF3FCC32BAF1BC900D3B043 /* raylib.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
1B16D8EF2BAEDBEA001FD5E0 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastUpgradeCheck = 1520;
TargetAttributes = {
1BF3FCC22BAF1BC900D3B043 = {
CreatedOnToolsVersion = 15.2;
};
};
};
buildConfigurationList = 1B16D8F22BAEDBEA001FD5E0 /* Build configuration list for PBXProject "raylib" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 1B16D8EE2BAEDBEA001FD5E0;
productRefGroup = 1B16D8F92BAEDBEA001FD5E0 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
1BF3FCC22BAF1BC900D3B043 /* raylib */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
1BF3FCC12BAF1BC900D3B043 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1BF3FCBF2BAF1BC900D3B043 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1BF3FCF32BAF1D3300D3B043 /* rshapes.c in Sources */,
1BF3FCF12BAF1D3300D3B043 /* raudio.c in Sources */,
1BF3FCF42BAF1D3300D3B043 /* rtextures.c in Sources */,
1BF3FCF62BAF1D3300D3B043 /* rtext.c in Sources */,
1BF3FCF52BAF1D3300D3B043 /* rcore.c in Sources */,
1BF3FCFD2BAF2CFD00D3B043 /* main.c in Sources */,
1BF3FCF22BAF1D3300D3B043 /* utils.c in Sources */,
1BF3FCF72BAF1D3300D3B043 /* rmodels.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1B16D8FD2BAEDBEA001FD5E0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = NO;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = c17;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
1B16D8FE2BAEDBEA001FD5E0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = NO;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = c17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
1BF3FCDC2BAF1BCB00D3B043 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_WARN_COMMA = NO;
CLANG_WARN_STRICT_PROTOTYPES = NO;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = A7A93GC9AY;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
GRAPHICS_API_OPENGL_ES3,
PLATFORM_IOS,
GL_GLEXT_PROTOTYPES,
);
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GENERATE_INFOPLIST_FILE = YES;
HEADER_SEARCH_PATHS = "";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = "";
INFOPLIST_KEY_UIRequiredDeviceCapabilities = metal;
INFOPLIST_KEY_UIRequiresFullScreen = YES;
INFOPLIST_KEY_UIStatusBarHidden = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)";
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = "-lc++";
PRODUCT_BUNDLE_IDENTIFIER = com.example.raylib;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = ../../src;
};
name = Debug;
};
1BF3FCDD2BAF1BCB00D3B043 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_WARN_COMMA = NO;
CLANG_WARN_STRICT_PROTOTYPES = NO;
CLANG_WARN_UNREACHABLE_CODE = NO;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = A7A93GC9AY;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_PREPROCESSOR_DEFINITIONS = (
GRAPHICS_API_OPENGL_ES3,
PLATFORM_IOS,
GL_GLEXT_PROTOTYPES,
);
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GENERATE_INFOPLIST_FILE = YES;
HEADER_SEARCH_PATHS = "";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = "";
INFOPLIST_KEY_UIRequiredDeviceCapabilities = metal;
INFOPLIST_KEY_UIRequiresFullScreen = YES;
INFOPLIST_KEY_UIStatusBarHidden = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)";
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = "-lc++";
PRODUCT_BUNDLE_IDENTIFIER = com.example.raylib;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = ../../src;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1B16D8F22BAEDBEA001FD5E0 /* Build configuration list for PBXProject "raylib" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1B16D8FD2BAEDBEA001FD5E0 /* Debug */,
1B16D8FE2BAEDBEA001FD5E0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1BF3FCDB2BAF1BCB00D3B043 /* Build configuration list for PBXNativeTarget "raylib" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1BF3FCDC2BAF1BCB00D3B043 /* Debug */,
1BF3FCDD2BAF1BCB00D3B043 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 1B16D8EF2BAEDBEA001FD5E0 /* Project object */;
}

+ 8
- 0
projects/Xcode15/raylib.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

+ 1
- 0
projects/Xcode15/raylib/.gitignore View File

@ -0,0 +1 @@
Frameworks

+ 2
- 8
src/platforms/rcore_android.c View File

@ -427,36 +427,31 @@ void *GetWindowHandle(void)
// Get number of monitors // Get number of monitors
int GetMonitorCount(void) int GetMonitorCount(void)
{ {
TRACELOG(LOG_WARNING, "GetMonitorCount() not implemented on target platform");
return 1; return 1;
} }
// Get number of monitors // Get number of monitors
int GetCurrentMonitor(void) int GetCurrentMonitor(void)
{ {
TRACELOG(LOG_WARNING, "GetCurrentMonitor() not implemented on target platform");
return 0; return 0;
} }
// Get selected monitor position // Get selected monitor position
Vector2 GetMonitorPosition(int monitor) Vector2 GetMonitorPosition(int monitor)
{ {
TRACELOG(LOG_WARNING, "GetMonitorPosition() not implemented on target platform");
return (Vector2){ 0, 0 }; return (Vector2){ 0, 0 };
} }
// Get selected monitor width (currently used by monitor) // Get selected monitor width (currently used by monitor)
int GetMonitorWidth(int monitor) int GetMonitorWidth(int monitor)
{ {
TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform");
return 0;
return CORE.Window.screen.width;
} }
// Get selected monitor height (currently used by monitor) // Get selected monitor height (currently used by monitor)
int GetMonitorHeight(int monitor) int GetMonitorHeight(int monitor)
{ {
TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform");
return 0;
return CORE.Window.screen.height;
} }
// Get selected monitor physical width in millimetres // Get selected monitor physical width in millimetres
@ -497,7 +492,6 @@ Vector2 GetWindowPosition(void)
// Get window scale DPI factor for current monitor // Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void) Vector2 GetWindowScaleDPI(void)
{ {
TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
return (Vector2){ 1.0f, 1.0f }; return (Vector2){ 1.0f, 1.0f };
} }

+ 800
- 0
src/platforms/rcore_ios.c View File

@ -0,0 +1,800 @@
/**********************************************************************************************
*
* rcore_ios - Functions to manage window, graphics device and touch inputs
*
* PLATFORM: IOS
* - iOS (arm64)
*
* LIMITATIONS:
* - No keyboard input support
* - No gamepad input support
*
* POSSIBLE IMPROVEMENTS:
* - Improvement 01
* - Improvement 02
*
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used-
*
* DEPENDENCIES:
* - ANGLE for iOS
* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs)
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) and contributors
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#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 <UIKit/UIKit.h>
/* GameViewController */
@interface GameViewController : UIViewController
- (void)update;
@end
/* AppDelegate */
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct {
GameViewController *viewController; // Root view controller
// Display data
EGLDisplay device; // Native display device (physical screen connection)
EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
EGLContext context; // Graphic context, mode in which drawing can be done
EGLConfig config; // Graphic config
} PlatformData;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
extern CoreData CORE; // Global CORE state context
static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
static int MapPointId(UITouch *touch){
static UITouch* touchs[MAX_TOUCH_POINTS] = { 0 };
for(int i = 0; i < MAX_TOUCH_POINTS; i++){
if(touchs[i] == touch) return i + 1;
}
// clear unused touch pairs before insert
for(int i = 0; i < MAX_TOUCH_POINTS; i++){
if(touchs[i] == NULL) continue;
bool found = false;
for(int j = 0; j < MAX_TOUCH_POINTS; j++){
if(CORE.Input.Touch.pointId[j] == i + 1){
found = true;
break;
}
}
if(!found) touchs[i] = NULL;
}
for(int i = 0; i < MAX_TOUCH_POINTS; i++){
if(touchs[i] == NULL){
touchs[i] = touch;
return i + 1;
}
}
TRACELOG(LOG_ERROR, "Touch point id overflow. This may be a bug!");
return 0;
}
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
// Check if application should close
bool WindowShouldClose(void)
{
if (CORE.Window.ready) return CORE.Window.shouldClose;
else return true;
}
// Toggle fullscreen mode
void ToggleFullscreen(void)
{
TRACELOG(LOG_WARNING, "ToggleFullscreen() not available on target platform");
}
// Toggle borderless windowed mode
void ToggleBorderlessWindowed(void)
{
TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform");
}
// Set window state: maximized, if resizable
void MaximizeWindow(void)
{
TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform");
}
// Set window state: minimized
void MinimizeWindow(void)
{
TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform");
}
// Set window state: not minimized/maximized
void RestoreWindow(void)
{
TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform");
}
// Set window configuration state using flags
void SetWindowState(unsigned int flags)
{
TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform");
}
// Clear window configuration state flags
void ClearWindowState(unsigned int flags)
{
TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform");
}
// Set icon for window
void SetWindowIcon(Image image)
{
TRACELOG(LOG_WARNING, "SetWindowIcon() not available on target platform");
}
// Set icon for window
void SetWindowIcons(Image *images, int count)
{
TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform");
}
// Set title for window
void SetWindowTitle(const char *title)
{
CORE.Window.title = title;
}
// Set window position on screen (windowed mode)
void SetWindowPosition(int x, int y)
{
TRACELOG(LOG_WARNING, "SetWindowPosition() not available on target platform");
}
// Set monitor for the current window
void SetWindowMonitor(int monitor)
{
TRACELOG(LOG_WARNING, "SetWindowMonitor() not available on target platform");
}
// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE)
void SetWindowMinSize(int width, int height)
{
CORE.Window.screenMin.width = width;
CORE.Window.screenMin.height = height;
}
// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE)
void SetWindowMaxSize(int width, int height)
{
CORE.Window.screenMax.width = width;
CORE.Window.screenMax.height = height;
}
// Set window dimensions
void SetWindowSize(int width, int height)
{
TRACELOG(LOG_WARNING, "SetWindowSize() not available on target platform");
}
// Set window opacity, value opacity is between 0.0 and 1.0
void SetWindowOpacity(float opacity)
{
TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform");
}
// Set window focused
void SetWindowFocused(void)
{
TRACELOG(LOG_WARNING, "SetWindowFocused() not available on target platform");
}
// Get native window handle
void *GetWindowHandle(void)
{
TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform");
return NULL;
}
// Get number of monitors
int GetMonitorCount(void)
{
return 1;
}
// Get current monitor id
int GetCurrentMonitor(void)
{
return 0;
}
// Get selected monitor position
Vector2 GetMonitorPosition(int monitor)
{
return (Vector2){ 0, 0 };
}
// Get selected monitor width (currently used by monitor)
int GetMonitorWidth(int monitor)
{
return CORE.Window.screen.width;
}
// Get selected monitor height (currently used by monitor)
int GetMonitorHeight(int monitor)
{
return CORE.Window.screen.height;
}
// Get selected monitor physical width in millimetres
int GetMonitorPhysicalWidth(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() not implemented on target platform");
return 0;
}
// Get selected monitor physical height in millimetres
int GetMonitorPhysicalHeight(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() not implemented on target platform");
return 0;
}
// Get selected monitor refresh rate
int GetMonitorRefreshRate(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorRefreshRate() not implemented on target platform");
return 0;
}
// Get the human-readable, UTF-8 encoded name of the selected monitor
const char *GetMonitorName(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorName() not implemented on target platform");
return "";
}
// Get window position XY on monitor
Vector2 GetWindowPosition(void)
{
TRACELOG(LOG_WARNING, "GetWindowPosition() not implemented on target platform");
return (Vector2){ 0, 0 };
}
// Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void)
{
CGFloat scale = [[UIScreen mainScreen] scale];
return (Vector2){ scale, scale };
}
// Set clipboard text content
void SetClipboardText(const char *text)
{
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = [NSString stringWithUTF8String:text];
}
// Get clipboard text content
const char *GetClipboardText(void)
{
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
NSString *clipboard = pasteboard.string;
return clipboard.UTF8String;
}
// Show mouse cursor
void ShowCursor(void)
{
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
void HideCursor(void)
{
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
void EnableCursor(void)
{
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
CORE.Input.Mouse.cursorHidden = false;
}
// Disables cursor (lock cursor)
void DisableCursor(void)
{
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
CORE.Input.Mouse.cursorHidden = true;
}
// Swap back buffer with front buffer (screen drawing)
void SwapScreenBuffer(void)
{
eglSwapBuffers(platform.device, platform.surface);
}
//----------------------------------------------------------------------------------
// Module Functions Definition: Misc
//----------------------------------------------------------------------------------
// Get elapsed time measure in seconds since InitTimer()
double GetTime(void)
{
double time = 0.0;
struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
return time;
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if you control the URL given.
// A user could craft a malicious string performing another action.
// Only call this function yourself not with user input or make sure to check the string yourself.
// Ref: https://github.com/raysan5/raylib/issues/686
void OpenURL(const char *url)
{
NSURL *nsurl = [NSURL URLWithString:[NSString stringWithUTF8String:url]];
[[UIApplication sharedApplication] openURL:nsurl options:@{} completionHandler:nil];
}
//----------------------------------------------------------------------------------
// Module Functions Definition: Inputs
//----------------------------------------------------------------------------------
// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform");
return 0;
}
// Set gamepad vibration
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
{
TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");
}
// Set mouse position XY
void SetMousePosition(int x, int y)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
// Set mouse cursor
void SetMouseCursor(int cursor)
{
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
}
// Register all input events
void PollInputEvents(void)
{
#if defined(SUPPORT_GESTURES_SYSTEM)
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
UpdateGestures();
#endif
// Reset keys/chars pressed registered
CORE.Input.Keyboard.keyPressedQueueCount = 0;
CORE.Input.Keyboard.charPressedQueueCount = 0;
// Reset key repeats
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
// Reset last gamepad button/axis registered state
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
//CORE.Input.Gamepad.axisCount = 0;
// Register previous touch states
for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
// Reset touch positions
// TODO: It resets on target platform the mouse position and not filled again until a move-event,
// so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed!
//for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };
// Register previous keys states
// NOTE: Android supports up to 260 keys
for (int i = 0; i < 260; i++)
{
CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
}
// Poll input events for iOS
// https://developer.apple.com/documentation/uikit/touches_presses_and_gestures
}
//----------------------------------------------------------------------------------
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
// Initialize platform: graphics, inputs and more
int InitPlatform(void)
{
CORE.Window.fullscreen = true;
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
EGLint samples = 0;
EGLint sampleBuffer = 0;
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
{
samples = 4;
sampleBuffer = 1;
TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4");
}
const EGLint framebufferAttribs[] =
{
EGL_RENDERABLE_TYPE, (rlGetVersion() == RL_OPENGL_ES_30)? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT, // Type of context support
EGL_RED_SIZE, 8, // RED color bit depth (alternative: 5)
EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6)
EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5)
//EGL_TRANSPARENT_TYPE, EGL_NONE, // Request transparent framebuffer (EGL_TRANSPARENT_RGB does not work on RPI)
EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!)
//EGL_STENCIL_SIZE, 8, // Stencil buffer size
EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA
EGL_SAMPLES, samples, // 4x Antialiasing if activated (Free on MALI GPUs)
EGL_NONE
};
const EGLint contextAttribs[] =
{
EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE
};
EGLint numConfigs = 0;
// Get an EGL device connection
platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (platform.device == EGL_NO_DISPLAY)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
// Initialize the EGL device connection
if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)
{
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
// Get an appropriate EGL framebuffer configuration
eglChooseConfig(platform.device, framebufferAttribs, &platform.config, 1, &numConfigs);
// Set rendering API
eglBindAPI(EGL_OPENGL_ES_API);
// Create an EGL rendering context
platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs);
if (platform.context == EGL_NO_CONTEXT)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
return false;
}
// Create an EGL window surface
EGLint displayFormat = 0;
// EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry()
// As soon as we picked a EGLConfig, we can safely reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID
eglGetConfigAttrib(platform.device, platform.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
// eglCreateWindowSurface(platform.device, platform.config, platform.app->window, NULL);
// bridged cast rootViewController.view.layer; to void*
void* native_window = (__bridge void*)platform.viewController.view.layer;
platform.surface = eglCreateWindowSurface(platform.device, platform.config, native_window, NULL);
// There must be at least one frame displayed before the buffers are swapped
//eglSwapInterval(platform.device, 1);
if (eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context) == EGL_FALSE)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
return false;
}
else
{
CORE.Window.display.width = [[UIScreen mainScreen] nativeBounds].size.width;
CORE.Window.display.height = [[UIScreen mainScreen] nativeBounds].size.height;
if(CORE.Window.screen.width == 0){
CORE.Window.screen.width = [[UIScreen mainScreen] bounds].size.width;
}
if(CORE.Window.screen.height == 0){
CORE.Window.screen.height = [[UIScreen mainScreen] bounds].size.height;
}
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height;
TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");
TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
TRACELOG(LOG_INFO, " > Render size: %i x %i", GetRenderWidth(), GetRenderHeight());
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
TRACELOG(LOG_INFO, " > EGL: %s", eglQueryString(platform.device, EGL_VERSION));
}
//----------------------------------------------------------------------------
// Load OpenGL extensions
// NOTE: GL procedures address loader is required to load extensions
rlLoadExtensions(eglGetProcAddress);
CORE.Window.ready = true;
//----------------------------------------------------------------------------
// Initialize OpenGL context (states and resources)
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
// Setup default viewport
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
InitTimer();
CORE.Storage.basePath = GetWorkingDirectory();
TRACELOG(LOG_INFO, "PLATFORM: IOS: Initialized successfully");
return true;
}
// Close platform
void ClosePlatform(void)
{
// TODO: De-initialize graphics, inputs and more
// Close surface, context and display
if (platform.device != EGL_NO_DISPLAY)
{
eglMakeCurrent(platform.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (platform.surface != EGL_NO_SURFACE)
{
eglDestroySurface(platform.device, platform.surface);
platform.surface = EGL_NO_SURFACE;
}
if (platform.context != EGL_NO_CONTEXT)
{
eglDestroyContext(platform.device, platform.context);
platform.context = EGL_NO_CONTEXT;
}
eglTerminate(platform.device);
platform.device = EGL_NO_DISPLAY;
}
}
@implementation GameViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// self.modalPresentationCapturesStatusBarAppearance = true;
platform.viewController = self;
self.view.multipleTouchEnabled = true;
self.view.contentScaleFactor = [[UIScreen mainScreen] scale];
}
- (bool)prefersStatusBarHidden
{
return true;
}
- (void)update
{
ios_update();
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// In iOS 17, Messages allows you to interactively resize iMessage apps with a vertical pan gesture. Messages handles any conflicts between resize gestures and your custom gestures. If your app uses manual touch handling, override those methods in your apps UIView. You can either change your manual touch handling code to use a gesture recognizer instead, or your UIView can override gestureRecognizerShouldBegin: and return NO when your iMessage app doesnt own the gesture.
return false;
}
static void SyncAllTouches(UIEvent* event)
{
CORE.Input.Touch.pointCount = (int)event.allTouches.count;
int i = 0;
for (UITouch *touch in event.allTouches)
{
CGPoint location = [touch locationInView:platform.viewController.view];
CORE.Input.Touch.position[i] = (Vector2){ location.x, location.y };
CORE.Input.Touch.pointId[i] = MapPointId(touch);
i++;
if(i >= MAX_TOUCH_POINTS) break;
}
// TODO: Normalize CORE.Input.Touch.position[i] for CORE.Window.screen.width and CORE.Window.screen.height
}
static int IndexOf(int needle, int *haystack, int size)
{
for (int i = 0; i < size; i++) if(haystack[i] == needle) return i;
return -1;
}
static void SendGestureEvent(NSSet<UITouch *> * touches, int action)
{
#if defined(SUPPORT_GESTURES_SYSTEM)
GestureEvent gestureEvent = { 0 };
gestureEvent.pointCount = CORE.Input.Touch.pointCount;
// Register touch actions
gestureEvent.touchAction = action;
for (int i = 0; (i < gestureEvent.pointCount) && (i < MAX_TOUCH_POINTS); i++)
{
gestureEvent.pointId[i] = CORE.Input.Touch.pointId[i];
gestureEvent.position[i] = CORE.Input.Touch.position[i];
gestureEvent.position[i].x /= (float)GetScreenWidth();
gestureEvent.position[i].y /= (float)GetScreenHeight();
}
// Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent);
#endif
if(action == TOUCH_ACTION_UP){
// One of the touchpoints is released, remove it from touch point arrays
for (UITouch *touch in touches)
{
int size = CORE.Input.Touch.pointCount;
if(size > MAX_TOUCH_POINTS) size = MAX_TOUCH_POINTS;
int i = IndexOf(MapPointId(touch), CORE.Input.Touch.pointId, size);
if(i >= 0){
// remove i-th touch point
for (int j = i; j < size - 1; j++)
{
CORE.Input.Touch.pointId[j] = CORE.Input.Touch.pointId[j + 1];
CORE.Input.Touch.position[j] = CORE.Input.Touch.position[j + 1];
}
CORE.Input.Touch.pointCount--;
}else{
TRACELOG(LOG_WARNING, "Touch point not found. This may be a bug!");
}
}
}
if (CORE.Input.Touch.pointCount > 0) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1;
else CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
if(action == TOUCH_ACTION_MOVE){
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}else{
CORE.Input.Mouse.previousPosition = CORE.Input.Touch.position[0];
}
// Map touch[0] as mouse input for convenience
CORE.Input.Mouse.currentPosition = CORE.Input.Touch.position[0];
CORE.Input.Mouse.currentWheelMove = (Vector2){ 0.0f, 0.0f };
}
// touch callbacks
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
SyncAllTouches(event);
SendGestureEvent(touches, TOUCH_ACTION_DOWN);
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
SyncAllTouches(event);
SendGestureEvent(touches, TOUCH_ACTION_UP);
// post sync needed
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
SyncAllTouches(event);
SendGestureEvent(touches, TOUCH_ACTION_MOVE);
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
SyncAllTouches(event);
SendGestureEvent(touches, TOUCH_ACTION_CANCEL);
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[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;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 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.
CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationWillTerminate:(UIApplication *)application {
ios_destroy();
if (platform.device != EGL_NO_DISPLAY)
{
// the user does not call CloseWindow() before exiting
TRACELOG(LOG_ERROR, "DISPLAY: CloseWindow() should be called before terminating the application");
}
// If 'platform.device' is already set to 'EGL_NO_DISPLAY'
// this means that the user has already called 'CloseWindow()'
}
@end
/* main() */
int main(int argc, char * argv[]) {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
// EOF

+ 4
- 0
src/rcore.c View File

@ -555,6 +555,8 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
#include "platforms/rcore_drm.c" #include "platforms/rcore_drm.c"
#elif defined(PLATFORM_ANDROID) #elif defined(PLATFORM_ANDROID)
#include "platforms/rcore_android.c" #include "platforms/rcore_android.c"
#elif defined(PLATFORM_IOS)
#include "platforms/rcore_ios.c"
#else #else
// TODO: Include your custom platform backend! // TODO: Include your custom platform backend!
// i.e software rendering backend or console backend! // i.e software rendering backend or console backend!
@ -626,6 +628,8 @@ void InitWindow(int width, int height, const char *title)
TRACELOG(LOG_INFO, "Platform backend: NATIVE DRM"); TRACELOG(LOG_INFO, "Platform backend: NATIVE DRM");
#elif defined(PLATFORM_ANDROID) #elif defined(PLATFORM_ANDROID)
TRACELOG(LOG_INFO, "Platform backend: ANDROID"); TRACELOG(LOG_INFO, "Platform backend: ANDROID");
#elif defined(PLATFORM_IOS)
TRACELOG(LOG_INFO, "Platform backend: IOS");
#else #else
// TODO: Include your custom platform backend! // TODO: Include your custom platform backend!
// i.e software rendering backend or console backend! // i.e software rendering backend or console backend!

+ 13
- 1
src/rlgl.h View File

@ -861,7 +861,19 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers #include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES3)
#if defined(PLATFORM_IOS)
// These required macros should be defined in Xcode
#ifndef GRAPHICS_API_OPENGL_ES3
#error "GRAPHICS_API_OPENGL_ES3 required on PLATFORM_IOS"
#endif
#ifndef GL_GLEXT_PROTOTYPES
#error "GL_GLEXT_PROTOTYPES 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
#include "libGLESv2/GLES3/gl3.h"
#elif defined(GRAPHICS_API_OPENGL_ES3)
#include <GLES3/gl3.h> // OpenGL ES 3.0 library #include <GLES3/gl3.h> // OpenGL ES 3.0 library
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library

Loading…
Cancel
Save