commit
e23da390bc
|
|
@ -81,6 +81,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| rayed-bqn | **auto** | [BQN](https://mlochbaum.github.io/BQN/) | MIT | https://github.com/Brian-ED/rayed-bqn |
|
||||
| rayjs | 4.6-dev | [QuickJS](https://bellard.org/quickjs/) | MIT | https://github.com/mode777/rayjs |
|
||||
| raylib-raku | **auto** | [Raku](https://www.raku.org/) | Artistic License 2.0 | https://github.com/vushu/raylib-raku |
|
||||
| Raylib.lean | 4.5 | [Lean4](https://lean-lang.org/) | BSD-3-Clause | https://github.com/KislyjKisel/Raylib.lean |
|
||||
|
||||
### Utility Wrapers
|
||||
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's pardigm.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const std = @import("std");
|
||||
const raylib = @import("src/build.zig");
|
||||
|
||||
// This has been tested to work with zig master branch as of commit 87de821 or May 14 2023
|
||||
// This has been tested to work with zig 0.11.0 (67709b6, Aug 4 2023)
|
||||
pub fn build(b: *std.Build) void {
|
||||
raylib.build(b);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
// This has been tested to work with zig master branch as of commit 87de821 or May 14 2023
|
||||
// This has been tested to work with zig 0.11.0 (67709b6, Aug 4 2023)
|
||||
fn add_module(comptime module: []const u8, b: *std.Build, target: std.zig.CrossTarget, optimize: std.builtin.OptimizeMode) !*std.Build.Step {
|
||||
if (target.getOsTag() == .emscripten) {
|
||||
@panic("Emscripten building via Zig unsupported");
|
||||
|
|
@ -11,7 +11,7 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: std.zig.CrossT
|
|||
const dir = try std.fs.cwd().openIterableDir(module, .{});
|
||||
var iter = dir.iterate();
|
||||
while (try iter.next()) |entry| {
|
||||
if (entry.kind != .File) continue;
|
||||
if (entry.kind != .file) continue;
|
||||
const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue;
|
||||
const name = entry.name[0..extension_idx];
|
||||
const path = try std.fs.path.join(b.allocator, &.{ module, entry.name });
|
||||
|
|
@ -24,26 +24,26 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: std.zig.CrossT
|
|||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.addCSourceFile(path, &[_][]const u8{});
|
||||
exe.addCSourceFile(.{ .file = .{ .path = path }, .flags = &.{} });
|
||||
exe.linkLibC();
|
||||
exe.addObjectFile(switch (target.getOsTag()) {
|
||||
.windows => "../src/zig-out/lib/raylib.lib",
|
||||
.linux => "../src/zig-out/lib/libraylib.a",
|
||||
.macos => "../src/zig-out/lib/libraylib.a",
|
||||
.emscripten => "../src/zig-out/lib/libraylib.a",
|
||||
.windows => .{ .path = "../zig-out/lib/raylib.lib" },
|
||||
.linux => .{ .path = "../zig-out/lib/libraylib.a" },
|
||||
.macos => .{ .path = "../zig-out/lib/libraylib.a" },
|
||||
.emscripten => .{ .path = "../zig-out/lib/libraylib.a" },
|
||||
else => @panic("Unsupported OS"),
|
||||
});
|
||||
|
||||
exe.addIncludePath("../src");
|
||||
exe.addIncludePath("../src/external");
|
||||
exe.addIncludePath("../src/external/glfw/include");
|
||||
exe.addIncludePath(.{ .path = "../src" });
|
||||
exe.addIncludePath(.{ .path = "../src/external" });
|
||||
exe.addIncludePath(.{ .path = "../src/external/glfw/include" });
|
||||
|
||||
switch (target.getOsTag()) {
|
||||
.windows => {
|
||||
exe.linkSystemLibrary("winmm");
|
||||
exe.linkSystemLibrary("gdi32");
|
||||
exe.linkSystemLibrary("opengl32");
|
||||
exe.addIncludePath("external/glfw/deps/mingw");
|
||||
exe.addIncludePath(.{ .path = "external/glfw/deps/mingw" });
|
||||
|
||||
exe.defineCMacro("PLATFORM_DESKTOP", null);
|
||||
},
|
||||
|
|
@ -71,11 +71,15 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: std.zig.CrossT
|
|||
},
|
||||
}
|
||||
|
||||
b.installArtifact(exe);
|
||||
var run = b.addRunArtifact(exe);
|
||||
run.cwd = module;
|
||||
b.step(name, name).dependOn(&run.step);
|
||||
all.dependOn(&exe.step);
|
||||
const install_cmd = b.addInstallArtifact(exe, .{});
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.step.dependOn(&install_cmd.step);
|
||||
|
||||
const run_step = b.step(name, name);
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
all.dependOn(&install_cmd.step);
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const std = @import("std");
|
||||
|
||||
// This has been tested to work with zig master branch as of commit 87de821 or May 14 2023
|
||||
// This has been tested to work with zig 0.11.0 (67709b6, Aug 4 2023)
|
||||
pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.builtin.OptimizeMode, options: Options) *std.Build.CompileStep {
|
||||
const raylib_flags = &[_][]const u8{
|
||||
"-std=gnu99",
|
||||
|
|
|
|||
2634
src/external/stb_image_resize.h
vendored
2634
src/external/stb_image_resize.h
vendored
File diff suppressed because it is too large
Load Diff
10303
src/external/stb_image_resize2.h
vendored
Normal file
10303
src/external/stb_image_resize2.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -981,14 +981,14 @@ void UnloadSoundAlias(Sound alias)
|
|||
}
|
||||
|
||||
// Update sound buffer with new data
|
||||
void UpdateSound(Sound sound, const void *data, int sampleCount)
|
||||
void UpdateSound(Sound sound, const void *data, int frameCount)
|
||||
{
|
||||
if (sound.stream.buffer != NULL)
|
||||
{
|
||||
StopAudioBuffer(sound.stream.buffer);
|
||||
|
||||
// TODO: May want to lock/unlock this since this data buffer is read at mixing time
|
||||
memcpy(sound.stream.buffer->data, data, sampleCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.formatIn, sound.stream.buffer->converter.channelsIn));
|
||||
memcpy(sound.stream.buffer->data, data, frameCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.formatIn, sound.stream.buffer->converter.channelsIn));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
67
src/rcore.c
67
src/rcore.c
|
|
@ -322,18 +322,15 @@ const char *TextFormat(const char *text, ...); // Formatting of text with
|
|||
//void InitWindow(int width, int height, const char *title)
|
||||
//void CloseWindow(void)
|
||||
//bool WindowShouldClose(void)
|
||||
//bool IsWindowHidden(void)
|
||||
//bool IsWindowMinimized(void)
|
||||
//bool IsWindowMaximized(void)
|
||||
//bool IsWindowFocused(void)
|
||||
//bool IsWindowResized(void)
|
||||
//void ToggleFullscreen(void)
|
||||
//void ToggleBorderlessWindowed(void)
|
||||
//void MaximizeWindow(void)
|
||||
//void MinimizeWindow(void)
|
||||
//void RestoreWindow(void)
|
||||
//void ToggleBorderlessWindowed(void)
|
||||
|
||||
//void SetWindowState(unsigned int flags)
|
||||
//void ClearWindowState(unsigned int flags)
|
||||
|
||||
//void SetWindowIcon(Image image)
|
||||
//void SetWindowIcons(Image *images, int count)
|
||||
//void SetWindowTitle(const char *title)
|
||||
|
|
@ -345,25 +342,27 @@ const char *TextFormat(const char *text, ...); // Formatting of text with
|
|||
//void SetWindowOpacity(float opacity)
|
||||
//void SetWindowFocused(void)
|
||||
//void *GetWindowHandle(void)
|
||||
//Vector2 GetWindowPosition(void)
|
||||
//Vector2 GetWindowScaleDPI(void)
|
||||
|
||||
//int GetMonitorCount(void)
|
||||
//int GetCurrentMonitor(void)
|
||||
//Vector2 GetMonitorPosition(int monitor)
|
||||
//int GetMonitorWidth(int monitor)
|
||||
//int GetMonitorHeight(int monitor)
|
||||
//int GetMonitorPhysicalWidth(int monitor)
|
||||
//int GetMonitorPhysicalHeight(int monitor)
|
||||
//int GetMonitorRefreshRate(int monitor)
|
||||
//Vector2 GetMonitorPosition(int monitor)
|
||||
//const char *GetMonitorName(int monitor)
|
||||
//Vector2 GetWindowPosition(void)
|
||||
//Vector2 GetWindowScaleDPI(void)
|
||||
|
||||
//void SetClipboardText(const char *text)
|
||||
//const char *GetClipboardText(void)
|
||||
|
||||
//void ShowCursor(void)
|
||||
//void HideCursor(void)
|
||||
//void EnableCursor(void)
|
||||
//void DisableCursor(void)
|
||||
|
||||
|
||||
// Check if window has been initialized successfully
|
||||
bool IsWindowReady(void)
|
||||
{
|
||||
|
|
@ -376,6 +375,36 @@ bool IsWindowFullscreen(void)
|
|||
return CORE.Window.fullscreen;
|
||||
}
|
||||
|
||||
// Check if window is currently hidden
|
||||
bool IsWindowHidden(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0);
|
||||
}
|
||||
|
||||
// Check if window has been minimized
|
||||
bool IsWindowMinimized(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0);
|
||||
}
|
||||
|
||||
// Check if window has been maximized
|
||||
bool IsWindowMaximized(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0);
|
||||
}
|
||||
|
||||
// Check if window has the focus
|
||||
bool IsWindowFocused(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) == 0);
|
||||
}
|
||||
|
||||
// Check if window has been resizedLastFrame
|
||||
bool IsWindowResized(void)
|
||||
{
|
||||
return CORE.Window.resizedLastFrame;
|
||||
}
|
||||
|
||||
// Check if one specific window flag is enabled
|
||||
bool IsWindowState(unsigned int flag)
|
||||
{
|
||||
|
|
@ -394,13 +423,13 @@ int GetScreenHeight(void)
|
|||
return CORE.Window.screen.height;
|
||||
}
|
||||
|
||||
// Get current render width which is equal to screen width * dpi scale
|
||||
// Get current render width which is equal to screen width*dpi scale
|
||||
int GetRenderWidth(void)
|
||||
{
|
||||
return CORE.Window.render.width;
|
||||
}
|
||||
|
||||
// Get current screen height which is equal to screen height * dpi scale
|
||||
// Get current screen height which is equal to screen height*dpi scale
|
||||
int GetRenderHeight(void)
|
||||
{
|
||||
return CORE.Window.render.height;
|
||||
|
|
@ -2331,15 +2360,15 @@ int GetTouchPointCount(void)
|
|||
//----------------------------------------------------------------------------------
|
||||
|
||||
// NOTE: Functions with a platform-specific implementation on rcore_<platform>.c
|
||||
//static bool InitGraphicsDevice(int width, int height)
|
||||
//static bool InitPlatform(void)
|
||||
|
||||
// Initialize hi-resolution timer
|
||||
void InitTimer(void)
|
||||
{
|
||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
||||
// High resolutions can also prevent the CPU power management system from entering power-saving modes.
|
||||
// Setting a higher resolution does not improve the accuracy of the high-resolution performance counter.
|
||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
||||
// High resolutions can also prevent the CPU power management system from entering power-saving modes.
|
||||
// Setting a higher resolution does not improve the accuracy of the high-resolution performance counter.
|
||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||
timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms)
|
||||
#endif
|
||||
|
|
@ -2783,7 +2812,7 @@ static void RecordAutomationEvent(unsigned int frame)
|
|||
// INPUT_GAMEPAD_CONNECT
|
||||
/*
|
||||
if ((CORE.Input.Gamepad.currentState[gamepad] != CORE.Input.Gamepad.previousState[gamepad]) &&
|
||||
(CORE.Input.Gamepad.currentState[gamepad] == true)) // Check if changed to ready
|
||||
(CORE.Input.Gamepad.currentState[gamepad])) // Check if changed to ready
|
||||
{
|
||||
// TODO: Save gamepad connect event
|
||||
}
|
||||
|
|
@ -2792,7 +2821,7 @@ static void RecordAutomationEvent(unsigned int frame)
|
|||
// INPUT_GAMEPAD_DISCONNECT
|
||||
/*
|
||||
if ((CORE.Input.Gamepad.currentState[gamepad] != CORE.Input.Gamepad.previousState[gamepad]) &&
|
||||
(CORE.Input.Gamepad.currentState[gamepad] == false)) // Check if changed to not-ready
|
||||
(!CORE.Input.Gamepad.currentState[gamepad])) // Check if changed to not-ready
|
||||
{
|
||||
// TODO: Save gamepad disconnect event
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
static void ClosePlatform(void); // Close platform
|
||||
|
||||
static void AndroidCommandCallback(struct android_app *app, int32_t cmd); // Process Android activity lifecycle commands
|
||||
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs
|
||||
|
|
@ -172,81 +173,23 @@ void InitWindow(int width, int height, const char *title)
|
|||
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||
#endif
|
||||
|
||||
// NOTE: Keep internal pointer to input title string (no copy)
|
||||
// Initialize window data
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||
|
||||
// Initialize global input state
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input));
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
|
||||
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
||||
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
||||
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
CORE.Window.currentFbo.width = width;
|
||||
CORE.Window.currentFbo.height = height;
|
||||
|
||||
// Platform specific init window
|
||||
// Initialize platform
|
||||
//--------------------------------------------------------------
|
||||
// Set desired windows flags before initializing anything
|
||||
ANativeActivity_setWindowFlags(platform.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
|
||||
|
||||
int orientation = AConfiguration_getOrientation(platform.app->config);
|
||||
|
||||
if (orientation == ACONFIGURATION_ORIENTATION_PORT) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as portrait");
|
||||
else if (orientation == ACONFIGURATION_ORIENTATION_LAND) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as landscape");
|
||||
|
||||
// TODO: Automatic orientation doesn't seem to work
|
||||
if (width <= height)
|
||||
{
|
||||
AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_PORT);
|
||||
TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to portrait");
|
||||
}
|
||||
else
|
||||
{
|
||||
AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_LAND);
|
||||
TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to landscape");
|
||||
}
|
||||
|
||||
//AConfiguration_getDensity(platform.app->config);
|
||||
//AConfiguration_getKeyboard(platform.app->config);
|
||||
//AConfiguration_getScreenSize(platform.app->config);
|
||||
//AConfiguration_getScreenLong(platform.app->config);
|
||||
|
||||
// Initialize App command system
|
||||
// NOTE: On APP_CMD_INIT_WINDOW -> InitGraphicsDevice(), InitTimer(), LoadFontDefault()...
|
||||
platform.app->onAppCmd = AndroidCommandCallback;
|
||||
|
||||
// Initialize input events system
|
||||
platform.app->onInputEvent = AndroidInputCallback;
|
||||
|
||||
// Initialize assets manager
|
||||
InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath);
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = platform.app->activity->internalDataPath;
|
||||
|
||||
TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Application initialized successfully");
|
||||
|
||||
// Android ALooper_pollAll() variables
|
||||
int pollResult = 0;
|
||||
int pollEvents = 0;
|
||||
|
||||
// Wait for window to be initialized (display and context)
|
||||
while (!CORE.Window.ready)
|
||||
{
|
||||
// Process events loop
|
||||
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&platform.source)) >= 0)
|
||||
{
|
||||
// Process this event
|
||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||
|
||||
// NOTE: Never close window, native activity is controlled by the system!
|
||||
//if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
|
||||
}
|
||||
}
|
||||
InitPlatform();
|
||||
//--------------------------------------------------------------
|
||||
}
|
||||
|
||||
|
|
@ -272,28 +215,9 @@ void CloseWindow(void)
|
|||
timeEndPeriod(1); // Restore time period
|
||||
#endif
|
||||
|
||||
// Platform specific close window
|
||||
// De-initialize platform
|
||||
//--------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
ClosePlatform();
|
||||
//--------------------------------------------------------------
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
|
|
@ -311,36 +235,6 @@ bool WindowShouldClose(void)
|
|||
else return true;
|
||||
}
|
||||
|
||||
// Check if window is currently hidden
|
||||
bool IsWindowHidden(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has been minimized
|
||||
bool IsWindowMinimized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has been maximized
|
||||
bool IsWindowMaximized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has the focus
|
||||
bool IsWindowFocused(void)
|
||||
{
|
||||
return platform.appEnabled;
|
||||
}
|
||||
|
||||
// Check if window has been resizedLastFrame
|
||||
bool IsWindowResized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Toggle fullscreen mode
|
||||
void ToggleFullscreen(void)
|
||||
{
|
||||
|
|
@ -713,25 +607,108 @@ void PollInputEvents(void)
|
|||
// Module Internal Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Initialize platform: graphics, inputs and more
|
||||
static int InitPlatform(void)
|
||||
{
|
||||
CORE.Window.currentFbo.width = CORE.Window.screen.width;
|
||||
CORE.Window.currentFbo.height = CORE.Window.screen.height;
|
||||
|
||||
// Set desired windows flags before initializing anything
|
||||
ANativeActivity_setWindowFlags(platform.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
|
||||
|
||||
int orientation = AConfiguration_getOrientation(platform.app->config);
|
||||
|
||||
if (orientation == ACONFIGURATION_ORIENTATION_PORT) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as portrait");
|
||||
else if (orientation == ACONFIGURATION_ORIENTATION_LAND) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as landscape");
|
||||
|
||||
// TODO: Automatic orientation doesn't seem to work
|
||||
if (CORE.Window.screen.width <= CORE.Window.screen.height)
|
||||
{
|
||||
AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_PORT);
|
||||
TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to portrait");
|
||||
}
|
||||
else
|
||||
{
|
||||
AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_LAND);
|
||||
TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to landscape");
|
||||
}
|
||||
|
||||
//AConfiguration_getDensity(platform.app->config);
|
||||
//AConfiguration_getKeyboard(platform.app->config);
|
||||
//AConfiguration_getScreenSize(platform.app->config);
|
||||
//AConfiguration_getScreenLong(platform.app->config);
|
||||
|
||||
// Initialize App command system
|
||||
// NOTE: On APP_CMD_INIT_WINDOW -> InitGraphicsDevice(), InitTimer(), LoadFontDefault()...
|
||||
platform.app->onAppCmd = AndroidCommandCallback;
|
||||
|
||||
// Initialize input events system
|
||||
platform.app->onInputEvent = AndroidInputCallback;
|
||||
|
||||
// Initialize assets manager
|
||||
InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath);
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = platform.app->activity->internalDataPath;
|
||||
|
||||
// Set some default window flags
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
|
||||
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
|
||||
|
||||
TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Application initialized successfully");
|
||||
|
||||
// Android ALooper_pollAll() variables
|
||||
int pollResult = 0;
|
||||
int pollEvents = 0;
|
||||
|
||||
// Wait for window to be initialized (display and context)
|
||||
while (!CORE.Window.ready)
|
||||
{
|
||||
// Process events loop
|
||||
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&platform.source)) >= 0)
|
||||
{
|
||||
// Process this event
|
||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||
|
||||
// NOTE: Never close window, native activity is controlled by the system!
|
||||
//if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close platform
|
||||
static void ClosePlatform(void)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize display device and framebuffer
|
||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
||||
// If width or height are 0, default display size will be used for framebuffer size
|
||||
// NOTE: returns false in case graphic device could not be created
|
||||
static bool InitGraphicsDevice(int width, int height)
|
||||
static bool InitGraphicsDevice(void)
|
||||
{
|
||||
CORE.Window.screen.width = width; // User desired width
|
||||
CORE.Window.screen.height = height; // User desired height
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
|
||||
// Set the screen minimum and maximum default values to 0
|
||||
CORE.Window.screenMin.width = 0;
|
||||
CORE.Window.screenMin.height = 0;
|
||||
CORE.Window.screenMax.width = 0;
|
||||
CORE.Window.screenMax.height = 0;
|
||||
|
||||
// NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
|
||||
// ...in top-down or left-right to match display aspect ratio (no weird scaling)
|
||||
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
|
|
@ -771,7 +748,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.device == EGL_NO_DISPLAY)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialize the EGL device connection
|
||||
|
|
@ -779,7 +756,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
// 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;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get an appropriate EGL framebuffer configuration
|
||||
|
|
@ -793,7 +770,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.context == EGL_NO_CONTEXT)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create an EGL window surface
|
||||
|
|
@ -822,7 +799,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
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;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -842,19 +819,11 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(eglGetProcAddress);
|
||||
|
||||
// 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);
|
||||
|
||||
CORE.Window.ready = true;
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ANDROID: Process activity lifecycle commands
|
||||
|
|
@ -897,25 +866,50 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
CORE.Window.display.height = ANativeWindow_getHeight(platform.app->window);
|
||||
|
||||
// Initialize graphics device (display device and OpenGL context)
|
||||
InitGraphicsDevice(CORE.Window.screen.width, CORE.Window.screen.height);
|
||||
InitGraphicsDevice();
|
||||
|
||||
// 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);
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize random seed
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
// WARNING: External function: Module required: rtext
|
||||
LoadFontDefault();
|
||||
Rectangle rec = GetFontDefault().recs[95];
|
||||
// NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
|
||||
#if defined(SUPPORT_MODULE_RSHAPES)
|
||||
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); // WARNING: Module required: rshapes
|
||||
// Set font white rectangle for shapes drawing, so shapes and text can be batched together
|
||||
// WARNING: rshapes module is required, if not available, default internal white rectangle is used
|
||||
Rectangle rec = GetFontDefault().recs[95];
|
||||
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
|
||||
{
|
||||
// NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering
|
||||
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 });
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding
|
||||
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if defined(SUPPORT_MODULE_RSHAPES)
|
||||
// Set default texture and rectangle to be used for shapes drawing
|
||||
// NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
|
||||
Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
||||
SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
// TODO: GPU assets reload in case of lost focus (lost context)
|
||||
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
||||
/*
|
||||
|
|
@ -936,12 +930,14 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
case APP_CMD_GAINED_FOCUS:
|
||||
{
|
||||
platform.appEnabled = true;
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED;
|
||||
//ResumeMusicStream();
|
||||
} break;
|
||||
case APP_CMD_PAUSE: break;
|
||||
case APP_CMD_LOST_FOCUS:
|
||||
{
|
||||
platform.appEnabled = false;
|
||||
CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED;
|
||||
//PauseMusicStream();
|
||||
} break;
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
|
|
@ -1173,6 +1169,8 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
{
|
||||
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
|
||||
|
|
@ -1199,6 +1197,16 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
if (CORE.Input.Touch.pointCount > 0) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1;
|
||||
else CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
|
||||
|
||||
// Stores the previous position of touch[0] only while it's active to calculate the delta.
|
||||
if (flags == AMOTION_EVENT_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 };
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* rcore_desktop - Functions to manage window, graphics device and inputs
|
||||
*
|
||||
* PLATFORM: DESKTOP
|
||||
* PLATFORM: DESKTOP: GLFW
|
||||
* - Windows (Win32, Win64)
|
||||
* - Linux (X11/Wayland desktop mode)
|
||||
* - FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop)
|
||||
|
|
@ -111,7 +111,8 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
static void ClosePlatform(void); // Close platform
|
||||
|
||||
// Error callback event
|
||||
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
||||
|
|
@ -176,33 +177,31 @@ void InitWindow(int width, int height, const char *title)
|
|||
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||
#endif
|
||||
|
||||
// NOTE: Keep internal pointer to input title string (no copy)
|
||||
// Initialize window data
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||
|
||||
// Initialize global input state
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE structure to 0
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
|
||||
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
||||
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
||||
|
||||
// Initialize graphics device
|
||||
// NOTE: returns true if window and graphic device has been initialized successfully
|
||||
CORE.Window.ready = InitGraphicsDevice(width, height);
|
||||
// Initialize platform
|
||||
//--------------------------------------------------------------
|
||||
InitPlatform();
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
|
||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
|
||||
// Initialize rlgl default data (buffers and shaders)
|
||||
// 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);
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
// Setup default viewport
|
||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
|
@ -246,6 +245,9 @@ void InitWindow(int width, int height, const char *title)
|
|||
CORE.Time.frameCounter = 0;
|
||||
#endif
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP: Application initialized successfully");
|
||||
}
|
||||
|
||||
|
|
@ -267,14 +269,9 @@ void CloseWindow(void)
|
|||
|
||||
rlglClose(); // De-init rlgl
|
||||
|
||||
// Platform specific close window
|
||||
// De-initialize platform
|
||||
//--------------------------------------------------------------
|
||||
glfwDestroyWindow(platform.handle);
|
||||
glfwTerminate();
|
||||
|
||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||
timeEndPeriod(1); // Restore time period
|
||||
#endif
|
||||
ClosePlatform();
|
||||
//--------------------------------------------------------------
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
|
|
@ -304,36 +301,6 @@ bool WindowShouldClose(void)
|
|||
else return true;
|
||||
}
|
||||
|
||||
// Check if window is currently hidden
|
||||
bool IsWindowHidden(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0);
|
||||
}
|
||||
|
||||
// Check if window has been minimized
|
||||
bool IsWindowMinimized(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0);
|
||||
}
|
||||
|
||||
// Check if window has been maximized
|
||||
bool IsWindowMaximized(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0);
|
||||
}
|
||||
|
||||
// Check if window has the focus
|
||||
bool IsWindowFocused(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) == 0);
|
||||
}
|
||||
|
||||
// Check if window has been resizedLastFrame
|
||||
bool IsWindowResized(void)
|
||||
{
|
||||
return CORE.Window.resizedLastFrame;
|
||||
}
|
||||
|
||||
// Toggle fullscreen mode
|
||||
void ToggleFullscreen(void)
|
||||
{
|
||||
|
|
@ -1389,25 +1356,9 @@ void PollInputEvents(void)
|
|||
// Module Internal Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Initialize display device and framebuffer
|
||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
||||
// If width or height are 0, default display size will be used for framebuffer size
|
||||
// NOTE: returns false in case graphic device could not be created
|
||||
static bool InitGraphicsDevice(int width, int height)
|
||||
// Initialize platform: graphics, inputs and more
|
||||
static int InitPlatform(void)
|
||||
{
|
||||
CORE.Window.screen.width = width; // User desired width
|
||||
CORE.Window.screen.height = height; // User desired height
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
|
||||
// Set the screen minimum and maximum default values to 0
|
||||
CORE.Window.screenMin.width = 0;
|
||||
CORE.Window.screenMin.height = 0;
|
||||
CORE.Window.screenMax.width = 0;
|
||||
CORE.Window.screenMax.height = 0;
|
||||
|
||||
// NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
|
||||
// ...in top-down or left-right to match display aspect ratio (no weird scaling)
|
||||
|
||||
glfwSetErrorCallback(ErrorCallback);
|
||||
/*
|
||||
// TODO: Setup GLFW custom allocators to match raylib ones
|
||||
|
|
@ -1420,15 +1371,13 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
|
||||
glfwInitAllocator(&allocator);
|
||||
*/
|
||||
|
||||
#if defined(__APPLE__)
|
||||
glfwInitHint(GLFW_COCOA_CHDIR_RESOURCES, GLFW_FALSE);
|
||||
#endif
|
||||
|
||||
if (!glfwInit())
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW");
|
||||
return false;
|
||||
}
|
||||
// Initialize GLFW internal global state
|
||||
int result = glfwInit();
|
||||
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
|
||||
|
||||
glfwDefaultWindowHints(); // Set default windows hints
|
||||
//glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
|
||||
|
|
@ -1550,7 +1499,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!monitor)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
|
||||
|
|
@ -1639,7 +1588,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
glfwTerminate();
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set window callback events
|
||||
|
|
@ -1705,22 +1654,37 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
|
||||
rlLoadExtensions(glfwGetProcAddress);
|
||||
|
||||
// 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);
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
|
||||
return true;
|
||||
CORE.Window.ready = true; // TODO: Proper validation on windows/context creation
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
|
||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Close platform
|
||||
static void ClosePlatform(void)
|
||||
{
|
||||
glfwDestroyWindow(platform.handle);
|
||||
glfwTerminate();
|
||||
|
||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||
timeEndPeriod(1); // Restore time period
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// GLFW3 Error Callback, runs on GLFW3 error
|
||||
static void ErrorCallback(int error, const char *description)
|
||||
{
|
||||
|
|
@ -1988,7 +1952,7 @@ static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffs
|
|||
// GLFW3 CursorEnter Callback, when cursor enters the window
|
||||
static void CursorEnterCallback(GLFWwindow *window, int enter)
|
||||
{
|
||||
if (enter == true) CORE.Input.Mouse.cursorOnScreen = true;
|
||||
if (enter) CORE.Input.Mouse.cursorOnScreen = true;
|
||||
else CORE.Input.Mouse.cursorOnScreen = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
370
src/rcore_drm.c
370
src/rcore_drm.c
|
|
@ -140,21 +140,22 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
static void ClosePlatform(void); // Close platform
|
||||
|
||||
static void InitKeyboard(void); // Initialize raw keyboard system
|
||||
static void RestoreKeyboard(void); // Restore keyboard system
|
||||
static void InitKeyboard(void); // Initialize raw keyboard system
|
||||
static void RestoreKeyboard(void); // Restore keyboard system
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
static void ProcessKeyboard(void); // Process keyboard events
|
||||
static void ProcessKeyboard(void); // Process keyboard events
|
||||
#endif
|
||||
|
||||
static void InitEvdevInput(void); // Initialize evdev inputs
|
||||
static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
|
||||
static void PollKeyboardEvents(void); // Process evdev keyboard events
|
||||
static void *EventThread(void *arg); // Input device events reading thread
|
||||
static void InitEvdevInput(void); // Initialize evdev inputs
|
||||
static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
|
||||
static void PollKeyboardEvents(void); // Process evdev keyboard events
|
||||
static void *EventThread(void *arg); // Input device events reading thread
|
||||
|
||||
static void InitGamepad(void); // Initialize raw gamepad input
|
||||
static void *GamepadThread(void *arg); // Mouse reading thread
|
||||
static void InitGamepad(void); // Initialize raw gamepad input
|
||||
static void *GamepadThread(void *arg); // Mouse reading thread
|
||||
|
||||
static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list
|
||||
static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list
|
||||
|
|
@ -204,33 +205,31 @@ void InitWindow(int width, int height, const char *title)
|
|||
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||
#endif
|
||||
|
||||
// NOTE: Keep internal pointer to input title string (no copy)
|
||||
// Initialize window data
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||
|
||||
// Initialize global input state
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input));
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
|
||||
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
||||
CORE.Input.Mouse.scale = (Vector2){1.0f, 1.0f};
|
||||
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
||||
|
||||
// Initialize graphics device (display device and OpenGL context)
|
||||
// NOTE: returns true if window and graphic device has been initialized successfully
|
||||
CORE.Window.ready = InitGraphicsDevice(width, height);
|
||||
// Initialize platform
|
||||
//--------------------------------------------------------------
|
||||
InitPlatform();
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
|
||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);
|
||||
// Initialize rlgl default data (buffers and shaders)
|
||||
// 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);
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
// Setup default viewport
|
||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
|
@ -274,13 +273,8 @@ void InitWindow(int width, int height, const char *title)
|
|||
CORE.Time.frameCounter = 0;
|
||||
#endif
|
||||
|
||||
// Platform specific init window
|
||||
//--------------------------------------------------------------
|
||||
// Initialize raw input system
|
||||
InitEvdevInput(); // Evdev inputs initialization
|
||||
InitGamepad(); // Gamepad init
|
||||
InitKeyboard(); // Keyboard init (stdin)
|
||||
//--------------------------------------------------------------
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
TRACELOG(LOG_INFO, "PLATFORM: DRM: Application initialized successfully");
|
||||
}
|
||||
|
|
@ -307,93 +301,9 @@ void CloseWindow(void)
|
|||
timeEndPeriod(1); // Restore time period
|
||||
#endif
|
||||
|
||||
// Platform specific close window
|
||||
// De-initialize platform
|
||||
//--------------------------------------------------------------
|
||||
if (platform.prevFB)
|
||||
{
|
||||
drmModeRmFB(platform.fd, platform.prevFB);
|
||||
platform.prevFB = 0;
|
||||
}
|
||||
|
||||
if (platform.prevBO)
|
||||
{
|
||||
gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
platform.prevBO = NULL;
|
||||
}
|
||||
|
||||
if (platform.gbmSurface)
|
||||
{
|
||||
gbm_surface_destroy(platform.gbmSurface);
|
||||
platform.gbmSurface = NULL;
|
||||
}
|
||||
|
||||
if (platform.gbmDevice)
|
||||
{
|
||||
gbm_device_destroy(platform.gbmDevice);
|
||||
platform.gbmDevice = NULL;
|
||||
}
|
||||
|
||||
if (platform.crtc)
|
||||
{
|
||||
if (platform.connector)
|
||||
{
|
||||
drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, platform.crtc->buffer_id,
|
||||
platform.crtc->x, platform.crtc->y, &platform.connector->connector_id, 1, &platform.crtc->mode);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
platform.connector = NULL;
|
||||
}
|
||||
|
||||
drmModeFreeCrtc(platform.crtc);
|
||||
platform.crtc = NULL;
|
||||
}
|
||||
|
||||
if (platform.fd != -1)
|
||||
{
|
||||
close(platform.fd);
|
||||
platform.fd = -1;
|
||||
}
|
||||
|
||||
// Close surface, context and display
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// Wait for mouse and gamepad threads to finish before closing
|
||||
// NOTE: Those threads should already have finished at this point
|
||||
// because they are controlled by CORE.Window.shouldClose variable
|
||||
|
||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||
|
||||
// Close the evdev keyboard
|
||||
if (platform.keyboardFd != -1)
|
||||
{
|
||||
close(platform.keyboardFd);
|
||||
platform.keyboardFd = -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
{
|
||||
if (platform.eventWorker[i].threadId)
|
||||
{
|
||||
pthread_join(platform.eventWorker[i].threadId, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL);
|
||||
ClosePlatform();
|
||||
//--------------------------------------------------------------
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
|
|
@ -412,36 +322,6 @@ bool WindowShouldClose(void)
|
|||
else return true;
|
||||
}
|
||||
|
||||
// Check if window is currently hidden
|
||||
bool IsWindowHidden(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has been minimized
|
||||
bool IsWindowMinimized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has been maximized
|
||||
bool IsWindowMaximized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has the focus
|
||||
bool IsWindowFocused(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if window has been resizedLastFrame
|
||||
bool IsWindowResized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Toggle fullscreen mode
|
||||
void ToggleFullscreen(void)
|
||||
{
|
||||
|
|
@ -830,28 +710,9 @@ void PollInputEvents(void)
|
|||
// Module Internal Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Initialize display device and framebuffer
|
||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
||||
// If width or height are 0, default display size will be used for framebuffer size
|
||||
// NOTE: returns false in case graphic device could not be created
|
||||
static bool InitGraphicsDevice(int width, int height)
|
||||
// Initialize platform: graphics, inputs and more
|
||||
static int InitPlatform(void)
|
||||
{
|
||||
CORE.Window.screen.width = width; // User desired width
|
||||
CORE.Window.screen.height = height; // User desired height
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
|
||||
// Set the window minimum and maximum default values to 0
|
||||
CORE.Window.screenMin.width = 0;
|
||||
CORE.Window.screenMin.height = 0;
|
||||
CORE.Window.screenMax.width = 0;
|
||||
CORE.Window.screenMax.height = 0;
|
||||
|
||||
// NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
|
||||
// ...in top-down or left-right to match display aspect ratio (no weird scaling)
|
||||
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
platform.fd = -1;
|
||||
platform.connector = NULL;
|
||||
platform.modeIndex = -1;
|
||||
|
|
@ -861,6 +722,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
platform.prevBO = NULL;
|
||||
platform.prevFB = 0;
|
||||
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
|
||||
platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
|
||||
#else
|
||||
|
|
@ -883,14 +747,14 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.fd == -1)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
drmModeRes *res = drmModeGetResources(platform.fd);
|
||||
if (!res)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors);
|
||||
|
|
@ -919,7 +783,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
||||
|
|
@ -927,7 +791,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id);
|
||||
|
|
@ -936,7 +800,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If InitWindow should use the current mode find it in the connector's mode list
|
||||
|
|
@ -951,7 +815,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CORE.Window.screen.width = CORE.Window.display.width;
|
||||
|
|
@ -979,7 +843,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;
|
||||
|
|
@ -1004,7 +868,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!platform.gbmDevice)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
platform.gbmSurface = gbm_surface_create(platform.gbmDevice, platform.connector->modes[platform.modeIndex].hdisplay,
|
||||
|
|
@ -1012,7 +876,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!platform.gbmSurface)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
EGLint samples = 0;
|
||||
|
|
@ -1052,7 +916,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.device == EGL_NO_DISPLAY)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialize the EGL device connection
|
||||
|
|
@ -1060,13 +924,13 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
// 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;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs))
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError());
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: EGL configs available: %d", numConfigs);
|
||||
|
|
@ -1075,7 +939,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!configs)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get memory for EGL configs");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
EGLint matchingNumConfigs = 0;
|
||||
|
|
@ -1083,7 +947,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());
|
||||
free(configs);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: EGL matching configs available: %d", matchingNumConfigs);
|
||||
|
|
@ -1113,7 +977,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!found)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable EGL config");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set rendering API
|
||||
|
|
@ -1124,7 +988,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.context == EGL_NO_CONTEXT)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create an EGL window surface
|
||||
|
|
@ -1133,7 +997,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (EGL_NO_SURFACE == platform.surface)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// At this point we need to manage render size vs screen size
|
||||
|
|
@ -1149,7 +1013,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
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;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1169,19 +1033,125 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(eglGetProcAddress);
|
||||
|
||||
// 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);
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
|
||||
return true;
|
||||
CORE.Window.ready = true; // TODO: Proper validation on windows/context creation
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
|
||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);
|
||||
|
||||
// Set some default window flags
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
|
||||
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
|
||||
// Initialize raw input system
|
||||
InitEvdevInput(); // Evdev inputs initialization
|
||||
InitGamepad(); // Gamepad init
|
||||
InitKeyboard(); // Keyboard init (stdin)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Close platform
|
||||
static void ClosePlatform(void)
|
||||
{
|
||||
if (platform.prevFB)
|
||||
{
|
||||
drmModeRmFB(platform.fd, platform.prevFB);
|
||||
platform.prevFB = 0;
|
||||
}
|
||||
|
||||
if (platform.prevBO)
|
||||
{
|
||||
gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
platform.prevBO = NULL;
|
||||
}
|
||||
|
||||
if (platform.gbmSurface)
|
||||
{
|
||||
gbm_surface_destroy(platform.gbmSurface);
|
||||
platform.gbmSurface = NULL;
|
||||
}
|
||||
|
||||
if (platform.gbmDevice)
|
||||
{
|
||||
gbm_device_destroy(platform.gbmDevice);
|
||||
platform.gbmDevice = NULL;
|
||||
}
|
||||
|
||||
if (platform.crtc)
|
||||
{
|
||||
if (platform.connector)
|
||||
{
|
||||
drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, platform.crtc->buffer_id,
|
||||
platform.crtc->x, platform.crtc->y, &platform.connector->connector_id, 1, &platform.crtc->mode);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
platform.connector = NULL;
|
||||
}
|
||||
|
||||
drmModeFreeCrtc(platform.crtc);
|
||||
platform.crtc = NULL;
|
||||
}
|
||||
|
||||
if (platform.fd != -1)
|
||||
{
|
||||
close(platform.fd);
|
||||
platform.fd = -1;
|
||||
}
|
||||
|
||||
// Close surface, context and display
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// Wait for mouse and gamepad threads to finish before closing
|
||||
// NOTE: Those threads should already have finished at this point
|
||||
// because they are controlled by CORE.Window.shouldClose variable
|
||||
|
||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||
|
||||
// Close the evdev keyboard
|
||||
if (platform.keyboardFd != -1)
|
||||
{
|
||||
close(platform.keyboardFd);
|
||||
platform.keyboardFd = -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
{
|
||||
if (platform.eventWorker[i].threadId)
|
||||
{
|
||||
pthread_join(platform.eventWorker[i].threadId, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL);
|
||||
}
|
||||
|
||||
|
||||
// Initialize Keyboard system (using standard input)
|
||||
static void InitKeyboard(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
static bool InitGraphicsDevice(void); // Initialize graphics device
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
|
|
@ -128,8 +129,11 @@ void InitWindow(int width, int height, const char *title)
|
|||
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
||||
|
||||
CORE.Window.eventWaiting = false;
|
||||
|
||||
|
||||
// TODO: Platform specific init window
|
||||
//--------------------------------------------------------------
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
CORE.Window.currentFbo.width = width;
|
||||
|
|
@ -139,17 +143,15 @@ void InitWindow(int width, int height, const char *title)
|
|||
// NOTE: returns true if window and graphic device has been initialized successfully
|
||||
CORE.Window.ready = InitGraphicsDevice(width, height);
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
// 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);
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
// Setup default viewport
|
||||
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
|
@ -193,10 +195,8 @@ void InitWindow(int width, int height, const char *title)
|
|||
CORE.Time.frameCounter = 0;
|
||||
#endif
|
||||
|
||||
// TODO: Platform specific init window
|
||||
//--------------------------------------------------------------
|
||||
// ...
|
||||
//--------------------------------------------------------------
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Application initialized successfully");
|
||||
}
|
||||
|
|
@ -239,36 +239,6 @@ bool WindowShouldClose(void)
|
|||
else return true;
|
||||
}
|
||||
|
||||
// Check if window is currently hidden
|
||||
bool IsWindowHidden(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has been minimized
|
||||
bool IsWindowMinimized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has been maximized
|
||||
bool IsWindowMaximized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has the focus
|
||||
bool IsWindowFocused(void)
|
||||
{
|
||||
return platform.appEnabled;
|
||||
}
|
||||
|
||||
// Check if window has been resizedLastFrame
|
||||
bool IsWindowResized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Toggle fullscreen mode
|
||||
void ToggleFullscreen(void)
|
||||
{
|
||||
|
|
@ -627,25 +597,9 @@ void PollInputEvents(void)
|
|||
// Module Internal Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Initialize display device and framebuffer
|
||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
||||
// If width or height are 0, default display size will be used for framebuffer size
|
||||
// NOTE: returns false in case graphic device could not be created
|
||||
static bool InitGraphicsDevice(int width, int height)
|
||||
// Initialize platform: graphics, inputs and more
|
||||
static int InitPlatform(void)
|
||||
{
|
||||
CORE.Window.screen.width = width; // User desired width
|
||||
CORE.Window.screen.height = height; // User desired height
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
|
||||
// Set the screen minimum and maximum default values to 0
|
||||
CORE.Window.screenMin.width = 0;
|
||||
CORE.Window.screenMin.height = 0;
|
||||
CORE.Window.screenMax.width = 0;
|
||||
CORE.Window.screenMax.height = 0;
|
||||
|
||||
// NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
|
||||
// ...in top-down or left-right to match display aspect ratio (no weird scaling)
|
||||
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
|
|
@ -707,7 +661,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.context == EGL_NO_CONTEXT)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create an EGL window surface
|
||||
|
|
@ -736,7 +690,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
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;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -756,19 +710,24 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(eglGetProcAddress);
|
||||
|
||||
// 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);
|
||||
|
||||
CORE.Window.ready = true;
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
|
||||
|
||||
return true;
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Close platform
|
||||
static void ClosePlatform(void)
|
||||
{
|
||||
// TODO: De-initialize graphics, inputs and more
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
|||
261
src/rcore_web.c
261
src/rcore_web.c
|
|
@ -87,17 +87,18 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
static void ClosePlatform(void); // Close platform
|
||||
|
||||
// Error callback event
|
||||
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
||||
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
||||
|
||||
// Window callbacks events
|
||||
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
||||
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||
static void WindowMaximizeCallback(GLFWwindow *window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
|
||||
static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
|
||||
static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window
|
||||
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
||||
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||
static void WindowMaximizeCallback(GLFWwindow *window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
|
||||
static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
|
||||
static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window
|
||||
|
||||
// Input callbacks events
|
||||
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
|
||||
|
|
@ -107,11 +108,12 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y);
|
|||
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
|
||||
static void CursorEnterCallback(GLFWwindow *window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
|
||||
|
||||
// Emscripten callback events
|
||||
// Emscripten window callback events
|
||||
static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData);
|
||||
static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const EmscriptenUiEvent *event, void *userData);
|
||||
static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData);
|
||||
|
||||
// Emscripten input callback events
|
||||
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
|
||||
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
|
||||
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData);
|
||||
|
|
@ -160,33 +162,32 @@ void InitWindow(int width, int height, const char *title)
|
|||
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||
#endif
|
||||
|
||||
// NOTE: Keep internal pointer to input title string (no copy)
|
||||
// Initialize window data
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||
|
||||
// Initialize global input state
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input));
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
|
||||
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
||||
CORE.Input.Mouse.scale = (Vector2){1.0f, 1.0f};
|
||||
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
||||
|
||||
// Initialize graphics device (display device and OpenGL context)
|
||||
// NOTE: returns true if window and graphic device has been initialized successfully
|
||||
CORE.Window.ready = InitGraphicsDevice(width, height);
|
||||
// Initialize platform
|
||||
//--------------------------------------------------------------
|
||||
InitPlatform();
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
|
||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
|
||||
// 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);
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
// Setup default viewport
|
||||
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
|
@ -230,37 +231,8 @@ void InitWindow(int width, int height, const char *title)
|
|||
CORE.Time.frameCounter = 0;
|
||||
#endif
|
||||
|
||||
// Platform specific init window
|
||||
//--------------------------------------------------------------
|
||||
// Setup callback functions for the DOM events
|
||||
emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback);
|
||||
|
||||
// WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review
|
||||
// Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas)
|
||||
// emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
|
||||
// Check Resize event (note this is done on the window since most browsers don't support this on #canvas)
|
||||
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
|
||||
|
||||
// Trigger this once to get initial window sizing
|
||||
EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL);
|
||||
|
||||
// Support keyboard events -> Not used, GLFW.JS takes care of that
|
||||
// emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
|
||||
// emscripten_set_keydown_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
|
||||
|
||||
// Support mouse events
|
||||
emscripten_set_click_callback("#canvas", NULL, 1, EmscriptenMouseCallback);
|
||||
|
||||
// Support touch events
|
||||
emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
|
||||
emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
|
||||
emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
|
||||
emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
|
||||
|
||||
// Support gamepad events (not provided by GLFW3 on emscripten)
|
||||
emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenGamepadCallback);
|
||||
emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback);
|
||||
//--------------------------------------------------------------
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
TRACELOG(LOG_INFO, "PLATFORM: WEB: Application initialized successfully");
|
||||
}
|
||||
|
|
@ -283,10 +255,9 @@ void CloseWindow(void)
|
|||
|
||||
rlglClose(); // De-init rlgl
|
||||
|
||||
// Platform specific close window
|
||||
// De-initialize platform
|
||||
//--------------------------------------------------------------
|
||||
glfwDestroyWindow(platform.handle);
|
||||
glfwTerminate();
|
||||
ClosePlatform();
|
||||
//--------------------------------------------------------------
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
|
|
@ -309,36 +280,6 @@ bool WindowShouldClose(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check if window is currently hidden
|
||||
bool IsWindowHidden(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has been minimized
|
||||
bool IsWindowMinimized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has been maximized
|
||||
bool IsWindowMaximized(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if window has the focus
|
||||
bool IsWindowFocused(void)
|
||||
{
|
||||
return ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) == 0);
|
||||
}
|
||||
|
||||
// Check if window has been resizedLastFrame
|
||||
bool IsWindowResized(void)
|
||||
{
|
||||
return CORE.Window.resizedLastFrame;
|
||||
}
|
||||
|
||||
// Toggle fullscreen mode
|
||||
void ToggleFullscreen(void)
|
||||
{
|
||||
|
|
@ -718,7 +659,34 @@ void SetMousePosition(int x, int y)
|
|||
// Set mouse cursor
|
||||
void SetMouseCursor(int cursor)
|
||||
{
|
||||
TRACELOG(LOG_INFO, "SetMouseCursor not implemented in rcore_web.c");
|
||||
const char *cursorName;
|
||||
switch (cursor)
|
||||
{
|
||||
case MOUSE_CURSOR_IBEAM: cursorName = "text"; break;
|
||||
case MOUSE_CURSOR_CROSSHAIR: cursorName = "crosshair"; break;
|
||||
case MOUSE_CURSOR_POINTING_HAND: cursorName = "pointer"; break;
|
||||
case MOUSE_CURSOR_RESIZE_EW: cursorName = "ew-resize"; break;
|
||||
case MOUSE_CURSOR_RESIZE_NS: cursorName = "ns-resize"; break;
|
||||
case MOUSE_CURSOR_RESIZE_NWSE: cursorName = "nwse-resize"; break;
|
||||
case MOUSE_CURSOR_RESIZE_NESW: cursorName = "nesw-resize"; break;
|
||||
case MOUSE_CURSOR_RESIZE_ALL: cursorName = "move"; break;
|
||||
case MOUSE_CURSOR_NOT_ALLOWED: cursorName = "not-allowed"; break;
|
||||
|
||||
case MOUSE_CURSOR_ARROW: // can't find a name specifically for arrow cursor
|
||||
case MOUSE_CURSOR_DEFAULT:
|
||||
{
|
||||
cursorName = "default";
|
||||
} break;
|
||||
|
||||
default:
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "Cursor value out of bound (%d). Setting to default", cursor);
|
||||
cursorName = "default";
|
||||
} break;
|
||||
}
|
||||
|
||||
// Set the cursor element on the CSS
|
||||
EM_ASM({document.body.style.cursor = UTF8ToString($0);}, cursorName);
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
|
|
@ -842,43 +810,14 @@ void PollInputEvents(void)
|
|||
// Module Internal Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Initialize display device and framebuffer
|
||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
||||
// If width or height are 0, default display size will be used for framebuffer size
|
||||
// NOTE: returns false in case graphic device could not be created
|
||||
static bool InitGraphicsDevice(int width, int height)
|
||||
// Initialize platform: graphics, inputs and more
|
||||
static int InitPlatform(void)
|
||||
{
|
||||
CORE.Window.screen.width = width; // User desired width
|
||||
CORE.Window.screen.height = height; // User desired height
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
|
||||
// Set the screen minimum and maximum default values to 0
|
||||
CORE.Window.screenMin.width = 0;
|
||||
CORE.Window.screenMin.height = 0;
|
||||
CORE.Window.screenMax.width = 0;
|
||||
CORE.Window.screenMax.height = 0;
|
||||
|
||||
// NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
|
||||
// ...in top-down or left-right to match display aspect ratio (no weird scaling)
|
||||
|
||||
glfwSetErrorCallback(ErrorCallback);
|
||||
/*
|
||||
// TODO: Setup GLFW custom allocators to match raylib ones
|
||||
const GLFWallocator allocator = {
|
||||
.allocate = MemAlloc,
|
||||
.deallocate = MemFree,
|
||||
.reallocate = MemRealloc,
|
||||
.user = NULL
|
||||
};
|
||||
|
||||
glfwInitAllocator(&allocator);
|
||||
*/
|
||||
|
||||
if (!glfwInit())
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW");
|
||||
return false;
|
||||
}
|
||||
// Initialize GLFW internal global state
|
||||
int result = glfwInit();
|
||||
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
|
||||
|
||||
glfwDefaultWindowHints(); // Set default windows hints
|
||||
// glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
|
||||
|
|
@ -1044,7 +983,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
glfwTerminate();
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// WARNING: glfwCreateWindow() title doesn't work with emscripten
|
||||
|
|
@ -1066,6 +1005,12 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
|
||||
glfwMakeContextCurrent(platform.handle);
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(glfwGetProcAddress);
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
|
||||
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
|
||||
// NOTE: V-Sync can be enabled by graphic driver configuration, it doesn't need
|
||||
// to be activated on web platforms since VSync is enforced there.
|
||||
|
|
@ -1084,21 +1029,55 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
|
||||
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(glfwGetProcAddress);
|
||||
CORE.Window.ready = true; // TODO: Proper validation on windows/context creation
|
||||
|
||||
// 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);
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
|
||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
|
||||
|
||||
// Setup default viewport
|
||||
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
|
||||
return true;
|
||||
// Setup callback functions for the DOM events
|
||||
emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback);
|
||||
|
||||
// WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review
|
||||
// Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas)
|
||||
// emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
|
||||
// Check Resize event (note this is done on the window since most browsers don't support this on #canvas)
|
||||
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
|
||||
|
||||
// Trigger this once to get initial window sizing
|
||||
EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL);
|
||||
|
||||
// Support keyboard events -> Not used, GLFW.JS takes care of that
|
||||
// emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
|
||||
// emscripten_set_keydown_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
|
||||
|
||||
// Support mouse events
|
||||
emscripten_set_click_callback("#canvas", NULL, 1, EmscriptenMouseCallback);
|
||||
|
||||
// Support touch events
|
||||
emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
|
||||
emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
|
||||
emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
|
||||
emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
|
||||
|
||||
// Support gamepad events (not provided by GLFW3 on emscripten)
|
||||
emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenGamepadCallback);
|
||||
emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Close platform
|
||||
static void ClosePlatform(void)
|
||||
{
|
||||
glfwDestroyWindow(platform.handle);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
// GLFW3 Error Callback, runs on GLFW3 error
|
||||
|
|
@ -1147,7 +1126,7 @@ static void WindowIconifyCallback(GLFWwindow *window, int iconified)
|
|||
// GLFW3 Window Maximize Callback, runs when window is maximized
|
||||
static void WindowMaximizeCallback(GLFWwindow *window, int maximized)
|
||||
{
|
||||
|
||||
// TODO.
|
||||
}
|
||||
|
||||
// GLFW3 WindowFocus Callback, runs when window get/lose focus
|
||||
|
|
@ -1185,7 +1164,6 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// GLFW3 Keyboard Callback, runs on key pressed
|
||||
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
|
|
@ -1364,11 +1342,10 @@ static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffs
|
|||
// GLFW3 CursorEnter Callback, when cursor enters the window
|
||||
static void CursorEnterCallback(GLFWwindow *window, int enter)
|
||||
{
|
||||
if (enter == true) CORE.Input.Mouse.cursorOnScreen = true;
|
||||
if (enter) CORE.Input.Mouse.cursorOnScreen = true;
|
||||
else CORE.Input.Mouse.cursorOnScreen = false;
|
||||
}
|
||||
|
||||
|
||||
// Register fullscreen change events
|
||||
static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@
|
|||
#define STBIR_MALLOC(size,c) ((void)(c), RL_MALLOC(size))
|
||||
#define STBIR_FREE(ptr,c) ((void)(c), RL_FREE(ptr))
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include "external/stb_image_resize.h" // Required for: stbir_resize_uint8() [ImageResize()]
|
||||
#include "external/stb_image_resize2.h" // Required for: stbir_resize_uint8_linear() [ImageResize()]
|
||||
|
||||
#if defined(SUPPORT_FILEFORMAT_SVG)
|
||||
#define NANOSVG_IMPLEMENTATION // Expands implementation
|
||||
|
|
@ -1624,10 +1624,10 @@ void ImageResize(Image *image, int newWidth, int newHeight)
|
|||
|
||||
switch (image->format)
|
||||
{
|
||||
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: stbir_resize_uint8((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, 1); break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: stbir_resize_uint8((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, 2); break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: stbir_resize_uint8((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, 3); break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: stbir_resize_uint8((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, 4); break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: stbir_resize_uint8_linear((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, (stbir_pixel_layout)1); break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: stbir_resize_uint8_linear((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, (stbir_pixel_layout)2); break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: stbir_resize_uint8_linear((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, (stbir_pixel_layout)3); break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: stbir_resize_uint8_linear((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, (stbir_pixel_layout)4); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
|
@ -1643,7 +1643,7 @@ void ImageResize(Image *image, int newWidth, int newHeight)
|
|||
Color *output = (Color *)RL_MALLOC(newWidth*newHeight*sizeof(Color));
|
||||
|
||||
// NOTE: Color data is cast to (unsigned char *), there shouldn't been any problem...
|
||||
stbir_resize_uint8((unsigned char *)pixels, image->width, image->height, 0, (unsigned char *)output, newWidth, newHeight, 0, 4);
|
||||
stbir_resize_uint8_linear((unsigned char *)pixels, image->width, image->height, 0, (unsigned char *)output, newWidth, newHeight, 0, (stbir_pixel_layout)4);
|
||||
|
||||
int format = image->format;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user