mirror of
https://github.com/raysan5/raylib.git
synced 2025-09-19 17:58:15 +00:00
Merge branch 'master' into window-visibility
This commit is contained in:
171
src/core.c
171
src/core.c
@@ -175,11 +175,9 @@
|
||||
#include <GLFW/glfw3native.h> // Required for: glfwGetX11Window()
|
||||
#elif defined(__APPLE__)
|
||||
#include <unistd.h> // Required for: usleep()
|
||||
#include <objc/message.h> // Required for: objc_msgsend(), sel_registerName()
|
||||
|
||||
//#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition
|
||||
#define GLFW_EXPOSE_NATIVE_NSGL
|
||||
#include <GLFW/glfw3native.h> // Required for: glfwGetCocoaWindow(), glfwGetNSGLContext()
|
||||
#include <GLFW/glfw3native.h> // Required for: glfwGetCocoaWindow()
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -277,10 +275,6 @@ static bool windowReady = false; // Check if window has been init
|
||||
static bool windowMinimized = false; // Check if window has been minimized
|
||||
static const char *windowTitle = NULL; // Window text title...
|
||||
|
||||
#if defined(__APPLE__)
|
||||
static int windowNeedsUpdating = 2; // Times the Cocoa window needs to be updated initially
|
||||
#endif
|
||||
|
||||
static unsigned int displayWidth, displayHeight;// Display width and height (monitor, device-screen, LCD, ...)
|
||||
static int screenWidth, screenHeight; // Screen width and height (used render area)
|
||||
static int renderWidth, renderHeight; // Framebuffer width and height (render area, including black bars if required)
|
||||
@@ -311,7 +305,7 @@ extern EGLNativeWindowType uwpWindow; // Native EGL window handler for
|
||||
static struct android_app *androidApp; // Android activity
|
||||
static struct android_poll_source *source; // Android events polling source
|
||||
static int ident, events; // Android ALooper_pollAll() variables
|
||||
static const char *internalDataPath; // Android internal data path to write data (/data/data/<package>/files)
|
||||
static const char *internalDataPath = NULL; // Android internal data path to write data (/data/data/<package>/files)
|
||||
|
||||
static bool appEnabled = true; // Used to detec if app is active
|
||||
static bool contextRebindRequired = false; // Used to know context rebind required
|
||||
@@ -332,8 +326,9 @@ static int defaultKeyboardMode; // Used to store default keyboar
|
||||
#endif
|
||||
|
||||
// Mouse states
|
||||
static Vector2 mousePosition; // Mouse position on screen
|
||||
static float mouseScale = 1.0f; // Mouse default scale
|
||||
static Vector2 mousePosition = { 0.0f, 0.0f }; // Mouse position on screen
|
||||
static Vector2 mouseScale = { 1.0f, 1.0f }; // Mouse scaling
|
||||
static Vector2 mouseOffset = { 0.0f, 0.0f }; // Mouse offset
|
||||
static bool cursorHidden = false; // Track if cursor is hidden
|
||||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||
static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen
|
||||
@@ -1485,12 +1480,6 @@ Color Fade(Color color, float alpha)
|
||||
return (Color){color.r, color.g, color.b, (unsigned char)(255.0f*alpha)};
|
||||
}
|
||||
|
||||
// Activate raylib logo at startup (can be done with flags)
|
||||
void ShowLogo(void)
|
||||
{
|
||||
showLogo = true;
|
||||
}
|
||||
|
||||
// Setup window configuration flags (view FLAGS)
|
||||
void SetConfigFlags(unsigned char flags)
|
||||
{
|
||||
@@ -1503,17 +1492,32 @@ void SetConfigFlags(unsigned char flags)
|
||||
// NOTE TraceLog() function is located in [utils.h]
|
||||
|
||||
// Takes a screenshot of current screen (saved a .png)
|
||||
// NOTE: This function could work in any platform but some platforms: PLATFORM_ANDROID and PLATFORM_WEB
|
||||
// have their own internal file-systems, to dowload image to user file-system some additional mechanism is required
|
||||
void TakeScreenshot(const char *fileName)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
unsigned char *imgData = rlReadScreenPixels(renderWidth, renderHeight);
|
||||
|
||||
Image image = { imgData, renderWidth, renderHeight, 1, UNCOMPRESSED_R8G8B8A8 };
|
||||
ExportImage(image, fileName);
|
||||
free(imgData);
|
||||
|
||||
TraceLog(LOG_INFO, "Screenshot taken: %s", fileName);
|
||||
|
||||
char path[512] = { 0 };
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
strcpy(path, internalDataPath);
|
||||
strcat(path, "/");
|
||||
strcat(path, fileName);
|
||||
#else
|
||||
strcpy(path, fileName);
|
||||
#endif
|
||||
|
||||
ExportImage(image, path);
|
||||
free(imgData);
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
// Download file from MEMFS (emscripten memory filesystem)
|
||||
// SaveFileFromMEMFSToDisk() function is defined in raylib/templates/web_shel/shell.html
|
||||
emscripten_run_script(TextFormat("SaveFileFromMEMFSToDisk('%s','%s')", GetFileName(path), GetFileName(path)));
|
||||
#endif
|
||||
|
||||
TraceLog(LOG_INFO, "Screenshot taken: %s", path);
|
||||
}
|
||||
|
||||
// Check if the file exists
|
||||
@@ -1522,11 +1526,10 @@ bool FileExists(const char *fileName)
|
||||
bool result = false;
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (_access(fileName, 0) != -1)
|
||||
if (_access(fileName, 0) != -1) result = true;
|
||||
#else
|
||||
if (access(fileName, F_OK) != -1)
|
||||
if (access(fileName, F_OK) != -1) result = true;
|
||||
#endif
|
||||
result = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1539,7 +1542,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
||||
|
||||
if ((fileExt = strrchr(fileName, '.')) != NULL)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
#if defined(_WIN32)
|
||||
result = true;
|
||||
int extLen = strlen(ext);
|
||||
|
||||
@@ -1555,9 +1558,9 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
||||
}
|
||||
}
|
||||
else result = false;
|
||||
#else
|
||||
#else
|
||||
if (strcmp(fileExt, ext) == 0) result = true;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1759,7 +1762,7 @@ void StorageSaveValue(int position, int value)
|
||||
{
|
||||
FILE *storageFile = NULL;
|
||||
|
||||
char path[128];
|
||||
char path[512] = { 0 };
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
strcpy(path, internalDataPath);
|
||||
strcat(path, "/");
|
||||
@@ -1799,7 +1802,7 @@ int StorageLoadValue(int position)
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
char path[128];
|
||||
char path[512] = { 0 };
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
strcpy(path, internalDataPath);
|
||||
strcat(path, "/");
|
||||
@@ -1844,7 +1847,9 @@ void OpenURL(const char *url)
|
||||
if (strchr(url, '\'') != NULL)
|
||||
{
|
||||
TraceLog(LOG_WARNING, "Provided URL does not seem to be valid.");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
char *cmd = calloc(strlen(url) + 10, sizeof(char));
|
||||
|
||||
#if defined(_WIN32)
|
||||
@@ -2100,7 +2105,7 @@ int GetMouseX(void)
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
return (int)touchPosition[0].x;
|
||||
#else
|
||||
return (int)(mousePosition.x*mouseScale);
|
||||
return (int)((mousePosition.x + mouseOffset.x)*mouseScale.x);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2110,7 +2115,7 @@ int GetMouseY(void)
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
return (int)touchPosition[0].x;
|
||||
#else
|
||||
return (int)(mousePosition.y*mouseScale);
|
||||
return (int)((mousePosition.y + mouseOffset.y)*mouseScale.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2120,27 +2125,32 @@ Vector2 GetMousePosition(void)
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
return GetTouchPosition(0);
|
||||
#else
|
||||
return (Vector2){ mousePosition.x*mouseScale, mousePosition.y*mouseScale };
|
||||
return (Vector2){ (mousePosition.x + mouseOffset.x)*mouseScale.x, (mousePosition.y + mouseOffset.y)*mouseScale.y };
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set mouse position XY
|
||||
void SetMousePosition(Vector2 position)
|
||||
void SetMousePosition(int x, int y)
|
||||
{
|
||||
mousePosition = position;
|
||||
mousePosition = (Vector2){ (float)x, (float)y };
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
// NOTE: emscripten not implemented
|
||||
glfwSetCursorPos(window, position.x, position.y);
|
||||
glfwSetCursorPos(window, mousePosition.x, mousePosition.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set mouse offset
|
||||
// NOTE: Useful when rendering to different size targets
|
||||
void SetMouseOffset(int offsetX, int offsetY)
|
||||
{
|
||||
mouseOffset = (Vector2){ (float)offsetX, (float)offsetY };
|
||||
}
|
||||
|
||||
// Set mouse scaling
|
||||
// NOTE: Useful when rendering to different size targets
|
||||
void SetMouseScale(float scale)
|
||||
void SetMouseScale(float scaleX, float scaleY)
|
||||
{
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
mouseScale = scale;
|
||||
#endif
|
||||
mouseScale = (Vector2){ scaleX, scaleY };
|
||||
}
|
||||
|
||||
// Returns mouse wheel movement Y
|
||||
@@ -2278,8 +2288,8 @@ static bool InitGraphicsDevice(int width, int height)
|
||||
if (configFlags & FLAG_WINDOW_RESIZABLE) glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window
|
||||
else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
||||
|
||||
if (configFlags & FLAG_WINDOW_UNDECORATED) glfwWindowHint(GLFW_DECORATED, GL_FALSE); // Border and buttons on Window
|
||||
else glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Decorated window
|
||||
if (configFlags & FLAG_WINDOW_UNDECORATED) glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); // Border and buttons on Window
|
||||
else glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); // Decorated window
|
||||
// FLAG_WINDOW_TRANSPARENT not supported on HTML5 and not included in any released GLFW version yet
|
||||
#if defined(GLFW_TRANSPARENT_FRAMEBUFFER)
|
||||
if (configFlags & FLAG_WINDOW_TRANSPARENT) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer
|
||||
@@ -2295,21 +2305,28 @@ static bool InitGraphicsDevice(int width, int height)
|
||||
// Check selection OpenGL version
|
||||
if (rlGetVersion() == OPENGL_21)
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // Choose OpenGL major version (just hint)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); // Choose OpenGL minor version (just hint)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // Choose OpenGL major version (just hint)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); // Choose OpenGL minor version (just hint)
|
||||
}
|
||||
else if (rlGetVersion() == OPENGL_33)
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above!
|
||||
// Values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
|
||||
#if defined(__APPLE__)
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // OSX Requires fordward compatibility
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); // OSX Requires fordward compatibility
|
||||
#else
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); // Fordward Compatibility Hint: Only 3.3 and above!
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); // Fordward Compatibility Hint: Only 3.3 and above!
|
||||
#endif
|
||||
//glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); // Request OpenGL DEBUG context
|
||||
//glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context
|
||||
}
|
||||
else if (rlGetVersion() == OPENGL_ES_20) // Request OpenGL ES 2.0 context
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); // Alternative: GLFW_EGL_CONTEXT_API (ANGLE)
|
||||
}
|
||||
|
||||
if (fullscreen)
|
||||
@@ -2402,7 +2419,9 @@ static bool InitGraphicsDevice(int width, int height)
|
||||
|
||||
// Try to disable GPU V-Sync by default, set framerate using SetTargetFPS()
|
||||
// NOTE: V-Sync can be enabled by graphic driver configuration
|
||||
#if !defined(PLATFORM_WEB)
|
||||
glfwSwapInterval(0);
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// Load OpenGL 3.3 extensions
|
||||
@@ -3138,16 +3157,6 @@ static void SwapBuffers(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
glfwSwapBuffers(window);
|
||||
#if __APPLE__
|
||||
// Workaround for missing/erroneous initial rendering on macOS
|
||||
if (windowNeedsUpdating)
|
||||
{
|
||||
// Desugared version of Objective C: [glfwGetNSGLContext(window) update]
|
||||
((id (*)(id, SEL))objc_msgSend)(glfwGetNSGLContext(window), sel_registerName("update"));
|
||||
|
||||
windowNeedsUpdating--;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
||||
@@ -3173,20 +3182,25 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
||||
{
|
||||
if (key == exitKey && action == GLFW_PRESS)
|
||||
{
|
||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
|
||||
// NOTE: Before closing window, while loop must be left!
|
||||
}
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
|
||||
{
|
||||
#if defined(SUPPORT_GIF_RECORDING)
|
||||
#if defined(SUPPORT_GIF_RECORDING)
|
||||
if (mods == GLFW_MOD_CONTROL)
|
||||
{
|
||||
if (gifRecording)
|
||||
{
|
||||
GifEnd();
|
||||
gifRecording = false;
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
// Download file from MEMFS (emscripten memory filesystem)
|
||||
// SaveFileFromMEMFSToDisk() function is defined in raylib/templates/web_shel/shell.html
|
||||
emscripten_run_script(TextFormat("SaveFileFromMEMFSToDisk('%s','%s')", TextFormat("screenrec%03i.gif", screenshotCounter - 1), TextFormat("screenrec%03i.gif", screenshotCounter - 1)));
|
||||
#endif
|
||||
|
||||
TraceLog(LOG_INFO, "End animated GIF recording");
|
||||
}
|
||||
@@ -3194,25 +3208,32 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
||||
{
|
||||
gifRecording = true;
|
||||
gifFramesCounter = 0;
|
||||
|
||||
char path[512] = { 0 };
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
strcpy(path, internalDataPath);
|
||||
strcat(path, TextFormat("/screenrec%03i.gif", screenshotCounter));
|
||||
#else
|
||||
strcpy(path, TextFormat("/screenrec%03i.gif", screenshotCounter));
|
||||
#endif
|
||||
|
||||
// NOTE: delay represents the time between frames in the gif, if we capture a gif frame every
|
||||
// 10 game frames and each frame trakes 16.6ms (60fps), delay between gif frames should be ~16.6*10.
|
||||
GifBegin(FormatText("screenrec%03i.gif", screenshotCounter), screenWidth, screenHeight, (int)(GetFrameTime()*10.0f), 8, false);
|
||||
GifBegin(path, screenWidth, screenHeight, (int)(GetFrameTime()*10.0f), 8, false);
|
||||
screenshotCounter++;
|
||||
|
||||
TraceLog(LOG_INFO, "Begin animated GIF recording: %s", FormatText("screenrec%03i.gif", screenshotCounter));
|
||||
TraceLog(LOG_INFO, "Begin animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter));
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // SUPPORT_GIF_RECORDING
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
#endif // SUPPORT_GIF_RECORDING
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
{
|
||||
TakeScreenshot(FormatText("screenshot%03i.png", screenshotCounter));
|
||||
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
||||
screenshotCounter++;
|
||||
}
|
||||
#endif // SUPPORT_SCREEN_CAPTURE
|
||||
#endif // SUPPORT_SCREEN_CAPTURE
|
||||
}
|
||||
#endif // PLATFORM_DESKTOP
|
||||
else
|
||||
{
|
||||
currentKeyState[key] = action;
|
||||
@@ -3394,11 +3415,11 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
||||
// Init hi-res timer
|
||||
InitTimer();
|
||||
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
// NOTE: External function (defined in module: text)
|
||||
LoadDefaultFont();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// TODO: GPU assets reload in case of lost focus (lost context)
|
||||
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
||||
@@ -4246,10 +4267,10 @@ static void *EventThread(void *arg)
|
||||
|
||||
// Screen confinement
|
||||
if (mousePosition.x < 0) mousePosition.x = 0;
|
||||
if (mousePosition.x > screenWidth/mouseScale) mousePosition.x = screenWidth/mouseScale;
|
||||
if (mousePosition.x > screenWidth/mouseScale.x) mousePosition.x = screenWidth/mouseScale.x;
|
||||
|
||||
if (mousePosition.y < 0) mousePosition.y = 0;
|
||||
if (mousePosition.y > screenHeight/mouseScale) mousePosition.y = screenHeight/mouseScale;
|
||||
if (mousePosition.y > screenHeight/mouseScale.y) mousePosition.y = screenHeight/mouseScale.y;
|
||||
|
||||
// Gesture update
|
||||
if (GestureNeedsUpdate)
|
||||
@@ -4475,7 +4496,7 @@ static void LogoAnimation(void)
|
||||
|
||||
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
|
||||
|
||||
DrawText(SubText("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
|
||||
DrawText(TextSubtext("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
|
Reference in New Issue
Block a user