Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/desktop/backends/glfw2.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "input_recording.h"
#include "desktop/platformdefs.h"
#include "gettime.h"
#include "runner_mouse.h"

static Runner *g_runner;

Expand Down Expand Up @@ -221,9 +222,20 @@ void platformExit(void) {
glfwTerminate();
}

static void platformSetCursor(int32_t cursorType) {
// GLFW2 only supports showing/hiding
if (cursorType == GML_CR_NONE) {
glfwDisable(GLFW_MOUSE_CURSOR);
} else {
glfwEnable(GLFW_MOUSE_CURSOR);
}
}

void platformInitFunctions(Runner *runner) {
g_runner = runner;
runner->windowHasFocus = platformGetWindowFocus;
runner->setCursor = platformSetCursor;
runner->currentCursor = GML_CR_DEFAULT;
#ifdef ENABLE_SW_RENDERER
if (gfx == SOFTWARE)
glfwSetWindowSizeCallback(resizeCallback);
Expand Down
32 changes: 32 additions & 0 deletions src/desktop/backends/glfw3.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "input_recording.h"
#include "desktop/platformdefs.h"
#include "gettime.h"
#include "runner_mouse.h"

static GLFWwindow *window;
static Runner *g_runner;
Expand Down Expand Up @@ -252,9 +253,40 @@ void platformExit(void) {
glfwTerminate();
}

static void platformSetCursor(int32_t cursorType) {
if (cursorType == GML_CR_NONE) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
return;
}
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);

int glfwShape;
switch (cursorType) {
case GML_CR_CROSS: glfwShape = GLFW_CROSSHAIR_CURSOR; break;
case GML_CR_BEAM: glfwShape = GLFW_IBEAM_CURSOR; break;
case GML_CR_SIZE_NS: glfwShape = GLFW_VRESIZE_CURSOR; break;
case GML_CR_SIZE_WE: glfwShape = GLFW_HRESIZE_CURSOR; break;
case GML_CR_DRAG: glfwShape = GLFW_HAND_CURSOR; break;
case GML_CR_HANDPOINT: glfwShape = GLFW_HAND_CURSOR; break;
#if (GLFW_VERSION_MINOR >= 4)
case GML_CR_SIZE_ALL: glfwShape = GLFW_RESIZE_ALL_CURSOR; break;
case GML_CR_SIZE_NWSE: glfwShape = GLFW_RESIZE_NWSE_CURSOR; break;
case GML_CR_SIZE_NESW: glfwShape = GLFW_RESIZE_NESW_CURSOR; break;
#endif
default: glfwShape = GLFW_ARROW_CURSOR; break;
}

GLFWcursor* cursor = glfwCreateStandardCursor(glfwShape);
if (cursor) {
glfwSetCursor(window, cursor);
}
}

void platformInitFunctions(Runner *runner) {
g_runner = runner;
runner->windowHasFocus = platformGetWindowFocus;
runner->setCursor = platformSetCursor;
runner->currentCursor = GML_CR_DEFAULT;
#ifdef ENABLE_SW_RENDERER
if (gfx == SOFTWARE)
glfwSetWindowSizeCallback(window, resizeCallback);
Expand Down
8 changes: 8 additions & 0 deletions src/desktop/backends/sdl1.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifndef SDL_BUTTON_WHEELDOWN
#define SDL_BUTTON_WHEELDOWN 5
#endif
#include "runner_mouse.h"

static Runner *g_runner;
static int32_t fbWidth, fbHeight;
Expand Down Expand Up @@ -101,9 +102,16 @@ void platformExit(void) {
SDL_Quit();
}

static void platformSetCursor(int32_t cursorType) {
// SDL1.2 only supports showing/hiding
SDL_ShowCursor(cursorType == GML_CR_NONE ? SDL_DISABLE : SDL_ENABLE);
}

void platformInitFunctions(Runner *runner) {
g_runner = runner;
runner->windowHasFocus = platformGetWindowFocus;
runner->setCursor = platformSetCursor;
runner->currentCursor = GML_CR_DEFAULT;
}

#ifdef ENABLE_SW_RENDERER
Expand Down
32 changes: 32 additions & 0 deletions src/desktop/backends/sdl2.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "input_recording.h"
#include "desktop/platformdefs.h"
#include "gettime.h"
#include "runner_mouse.h"

static Runner *g_runner;
static SDL_Surface* scr;
Expand Down Expand Up @@ -159,9 +160,40 @@ void platformExit(void) {
SDL_Quit();
}

static void platformSetCursor(int32_t cursorType) {
if (cursorType == GML_CR_NONE) {
SDL_ShowCursor(SDL_DISABLE);
return;
}
SDL_ShowCursor(SDL_ENABLE);

SDL_SystemCursor sdlCursor;
switch (cursorType) {
case GML_CR_CROSS: sdlCursor = SDL_SYSTEM_CURSOR_CROSSHAIR; break;
case GML_CR_BEAM: sdlCursor = SDL_SYSTEM_CURSOR_IBEAM; break;
case GML_CR_SIZE_NESW: sdlCursor = SDL_SYSTEM_CURSOR_SIZENESW; break;
case GML_CR_SIZE_NS: sdlCursor = SDL_SYSTEM_CURSOR_SIZENS; break;
case GML_CR_SIZE_NWSE: sdlCursor = SDL_SYSTEM_CURSOR_SIZENWSE; break;
case GML_CR_SIZE_WE: sdlCursor = SDL_SYSTEM_CURSOR_SIZEWE; break;
case GML_CR_HOURGLASS: sdlCursor = SDL_SYSTEM_CURSOR_WAIT; break;
case GML_CR_DRAG: sdlCursor = SDL_SYSTEM_CURSOR_HAND; break;
case GML_CR_APPSTART: sdlCursor = SDL_SYSTEM_CURSOR_WAITARROW; break;
case GML_CR_HANDPOINT: sdlCursor = SDL_SYSTEM_CURSOR_HAND; break;
case GML_CR_SIZE_ALL: sdlCursor = SDL_SYSTEM_CURSOR_SIZEALL; break;
default: sdlCursor = SDL_SYSTEM_CURSOR_ARROW; break;
}

SDL_Cursor* cursor = SDL_CreateSystemCursor(sdlCursor);
if (cursor) {
SDL_SetCursor(cursor);
}
}

void platformInitFunctions(Runner *runner) {
g_runner = runner;
runner->windowHasFocus = platformGetWindowFocus;
runner->setCursor = platformSetCursor;
runner->currentCursor = GML_CR_DEFAULT;
}

#ifdef ENABLE_SW_RENDERER
Expand Down
33 changes: 33 additions & 0 deletions src/desktop/backends/sdl3.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
#include <SDL3/SDL_events.h>
#include <SDL3/SDL.h>
#include <SDL3/SDL_video.h>
#include <SDL3/SDL_mouse.h>

#include "common.h"
#include "input_recording.h"
#include "desktop/platformdefs.h"
#include "gettime.h"
#include <ctype.h>
#include "runner_mouse.h"

static Runner *g_runner;
static int32_t fbWidth, fbHeight;
Expand Down Expand Up @@ -147,9 +149,40 @@ void platformExit(void) {
SDL_Quit();
}

static void platformSetCursor(int32_t cursorType) {
if (cursorType == GML_CR_NONE) {
SDL_HideCursor();
return;
}
SDL_ShowCursor();

SDL_SystemCursor sdlCursor;
switch (cursorType) {
case GML_CR_CROSS: sdlCursor = SDL_SYSTEM_CURSOR_CROSSHAIR; break;
case GML_CR_BEAM: sdlCursor = SDL_SYSTEM_CURSOR_TEXT; break;
case GML_CR_SIZE_NESW: sdlCursor = SDL_SYSTEM_CURSOR_NESW_RESIZE; break;
case GML_CR_SIZE_NS: sdlCursor = SDL_SYSTEM_CURSOR_NS_RESIZE; break;
case GML_CR_SIZE_NWSE: sdlCursor = SDL_SYSTEM_CURSOR_NWSE_RESIZE; break;
case GML_CR_SIZE_WE: sdlCursor = SDL_SYSTEM_CURSOR_EW_RESIZE; break;
case GML_CR_HOURGLASS: sdlCursor = SDL_SYSTEM_CURSOR_WAIT; break;
case GML_CR_DRAG: sdlCursor = SDL_SYSTEM_CURSOR_POINTER; break;
case GML_CR_APPSTART: sdlCursor = SDL_SYSTEM_CURSOR_PROGRESS; break;
case GML_CR_HANDPOINT: sdlCursor = SDL_SYSTEM_CURSOR_POINTER; break;
case GML_CR_SIZE_ALL: sdlCursor = SDL_SYSTEM_CURSOR_MOVE; break;
default: sdlCursor = SDL_SYSTEM_CURSOR_DEFAULT; break;
}

SDL_Cursor* cursor = SDL_CreateSystemCursor(sdlCursor);
if (cursor) {
SDL_SetCursor(cursor);
}
}

void platformInitFunctions(Runner *runner) {
g_runner = runner;
runner->windowHasFocus = platformGetWindowFocus;
runner->setCursor = platformSetCursor;
runner->currentCursor = GML_CR_DEFAULT;
}

#ifdef ENABLE_SW_RENDERER
Expand Down
2 changes: 2 additions & 0 deletions src/runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ struct Runner {
bool (*getWindowSize)(int32_t* outW, int32_t* outH);
void (*setWindowSize)(int32_t width, int32_t height);
bool (*windowHasFocus)(void);
void (*setCursor)(int32_t cursorType);
int32_t currentCursor; // last value passed to window_set_cursor
TileLayerMapEntry* tileLayerMap; // stb_ds hashmap: depth -> tile layer state
RuntimeLayer* runtimeLayers; // stb_ds array, index-parallel to currentRoom->layers for parsed entries; dynamic entries appended
uint32_t nextLayerId; // counter for IDs of layers/elements created at runtime
Expand Down
17 changes: 17 additions & 0 deletions src/runner_mouse.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@

#define GML_MOUSE_BUTTON_COUNT 5

// Cursor constants
#define GML_CR_SIZE_ALL -22
#define GML_CR_HANDPOINT -21
#define GML_CR_APPSTART -19
#define GML_CR_DRAG -12
#define GML_CR_HOURGLASS -11
#define GML_CR_UPARROW -10
#define GML_CR_SIZE_WE -9
#define GML_CR_SIZE_NWSE -8
#define GML_CR_SIZE_NS -7
#define GML_CR_SIZE_NESW -6
#define GML_CR_BEAM -4
#define GML_CR_CROSS -3
#define GML_CR_ARROW -2
#define GML_CR_NONE -1
#define GML_CR_DEFAULT 0

typedef struct RunnerMouseState {
// Cursor cached in app-surface (FBO) pixel space
double screenX, screenY;
Expand Down
20 changes: 20 additions & 0 deletions src/vm_builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -7257,6 +7257,24 @@ static RValue builtin_window_has_focus(VMContext* ctx, MAYBE_UNUSED RValue* args
return RValue_makeBool(true);
}

static RValue builtin_window_set_cursor(VMContext* ctx, RValue* args, int32_t argCount) {
if (argCount < 1) return RValue_makeUndefined();
Runner* runner = ctx->runner;
if (runner == nullptr) return RValue_makeUndefined();
int32_t cursorType = RValue_toInt32(args[0]);
runner->currentCursor = cursorType;
if (runner->setCursor != nullptr) {
runner->setCursor(cursorType);
}
return RValue_makeUndefined();
}

static RValue builtin_window_get_cursor(VMContext* ctx, MAYBE_UNUSED RValue* args, MAYBE_UNUSED int32_t argCount) {
Runner* runner = ctx->runner;
if (runner == nullptr) return RValue_makeReal(0);
return RValue_makeReal(runner->currentCursor);
}

// ===[ Game State Functions ]===
static RValue builtin_game_restart(VMContext* ctx, MAYBE_UNUSED RValue* args, MAYBE_UNUSED int32_t argCount) {
ctx->runner->pendingRoom = ROOM_RESTARTGAME;
Expand Down Expand Up @@ -15108,6 +15126,8 @@ void VMBuiltins_registerAll(VMContext* ctx) {
VM_registerBuiltin(ctx, "window_set_size", builtin_window_set_size);
VM_registerBuiltin(ctx, "window_center", builtin_window_center);
VM_registerBuiltin(ctx, "window_has_focus", builtin_window_has_focus);
VM_registerBuiltin(ctx, "window_set_cursor", builtin_window_set_cursor);
VM_registerBuiltin(ctx, "window_get_cursor", builtin_window_get_cursor);

// Game
VM_registerBuiltin(ctx, "game_restart", builtin_game_restart);
Expand Down
Loading