I moduleified your code! Could be expanded as a general os utility module. I’ll play with it more too soon.
Edit: actually going to start that process now!
os.lua (4.3 KB)
Added hide/show mouse on Windows for anyone who wanted that, but I would strongly hesitate using this until it’s ironed out a bit more!
Also added window resizing and optional centering. Want your game to have a virtual resolution but to scale to a certain window size on launch and be centered? Now you can… on Windows!
utils/os.lua
local M = {}
local ffi = package.preload.ffi()
-- https://github.com/ffi/ffi/wiki/Types
-- https://github.com/luapower/winapi/blob/master/winapi/window.lua
function M.set_window_size(pos_x, pos_y, width, height)
if(ffi.os == "Windows") then
-- definitions
ffi.cdef([[
typedef unsigned int LONG;
typedef long long LONG_PTR;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
typedef unsigned int UINT;
typedef bool BOOL;
int GetSystemMetrics(int nIndex);
HWND GetActiveWindow();
BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
]])
-- load User32.dll
local user32 = ffi.load("User32")
local HWND_TOP = 0
local SWP_NOMOVE = 0x0002
local SWP_NOZORDER = 0x0004
local SM_CXSCREEN = 0
local SM_CYSCREEN = 1
local ptr = user32.GetActiveWindow()
if pos_x == -1 then
local x_pos = (user32.GetSystemMetrics(SM_CXSCREEN) - width) / 2
local y_pos = (user32.GetSystemMetrics(SM_CYSCREEN) - height) / 2
user32.SetWindowPos(ptr, ptr, x_pos, y_pos, width, height, SWP_NOZORDER)
else
user32.SetWindowPos(ptr, ptr, pos_x, pos_y, width, height, SWP_NOZORDER)
end
end
end
function M.disable_mouse_cursor()
if(ffi.os == "Windows") then
-- definitions
ffi.cdef([[
typedef unsigned int LONG;
typedef long long LONG_PTR;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
typedef bool BOOL;
int ShowCursor(BOOL bShow);
]])
-- load User32.dll
local user32 = ffi.load("User32")
user32.ShowCursor(false)
end
end
function M.enable_mouse_cursor()
if(ffi.os == "Windows") then
-- definitions
ffi.cdef([[
typedef unsigned int LONG;
typedef long long LONG_PTR;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
typedef bool BOOL;
int ShowCursor(BOOL bShow);
]])
-- load User32.dll
local user32 = ffi.load("User32")
user32.ShowCursor(true)
end
end
function M.disable_window_resize()
if(ffi.os == "Windows") then
-- definitions
ffi.cdef([[
typedef unsigned int LONG;
typedef long long LONG_PTR;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
HWND GetActiveWindow();
LONG GetWindowLongPtrA(HWND hWnd, int nIndex);
LONG SetWindowLongPtrA(HWND hWnd, int nIndex, LONG_PTR dwNewLong);
]])
local GWL_STYLE = -16
-- styles from https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx
local WS_SIZEBOX = 0x00040000
-- load User32.dll
local user32 = ffi.load("User32")
local ptr = user32.GetActiveWindow()
local value = user32.GetWindowLongPtrA(ptr, GWL_STYLE)
user32.SetWindowLongPtrA(ptr, GWL_STYLE, bit.band(value, bit.bnot(WS_SIZEBOX)))
end
end
function M.disable_maximize_button()
if(ffi.os == "Windows") then
-- definitions
ffi.cdef([[
typedef unsigned int LONG;
typedef long long LONG_PTR;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
HWND GetActiveWindow();
LONG GetWindowLongPtrA(HWND hWnd, int nIndex);
LONG SetWindowLongPtrA(HWND hWnd, int nIndex, LONG_PTR dwNewLong);
]])
local GWL_STYLE = -16
-- styles from https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx
local WS_MAXIMIZEBOX = 0x00010000
-- load User32.dll
local user32 = ffi.load("User32")
local ptr = user32.GetActiveWindow()
local value = user32.GetWindowLongPtrA(ptr, GWL_STYLE)
user32.SetWindowLongPtrA(ptr, GWL_STYLE, bit.band(value, bit.bnot(WS_MAXIMIZEBOX)))
end
end
function M.disable_minimize_button()
if(ffi.os == "Windows") then
-- definitions
ffi.cdef([[
typedef unsigned int LONG;
typedef long long LONG_PTR;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
HWND GetActiveWindow();
LONG GetWindowLongPtrA(HWND hWnd, int nIndex);
LONG SetWindowLongPtrA(HWND hWnd, int nIndex, LONG_PTR dwNewLong);
]])
local GWL_STYLE = -16
-- styles from https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx
local WS_MINIMIZEBOX = 0x00020000
-- load User32.dll
local user32 = ffi.load("User32")
local ptr = user32.GetActiveWindow()
local value = user32.GetWindowLongPtrA(ptr, GWL_STYLE)
user32.SetWindowLongPtrA(ptr, GWL_STYLE, bit.band(value, bit.bnot(WS_MINIMIZEBOX)))
end
end
return M
Usage
local os_utils = require("utils.os")
function init(self)
os_utils.disable_maximize_button()
os_utils.disable_minimize_button()
os_utils.disable_window_resize()
os_utils.disable_mouse_cursor()
os_utils.enable_mouse_cursor()
os_utils.set_window_size(-1,-1,800,600)
end
I love the codeblocks now being styled like editor 2’s theme!
Here is the source for GLFW2, which is what Defold uses, but we can call the same platform specific apis in the same way.
What would still be better would interacting with GLFW2 directly and let it handle the platform specific stuff.
Defold uses GLFW 2.7 specifically but I don’t know if it’s 2.7.6 https://sourceforge.net/projects/glfw/files/glfw/2.7.6/
If we can get GLFW to work then we’ll get a lot of stuff for free as multiplatform. I’m attempting now but anyone with knowhow should for sure try and get it to work too.
Does Defold actually use GLFW 2.7 or did it fork it?
I was reminded of this thread and that unfortunately the same methods don’t work on Windows otherwise that way would be ideal for using GLFW directly. But then I tested on OSX again to confirm and it seems JIT isn’t being used for Mac engine now so this method wouldn’t work? Otherwise I would have suggested to use GLFW functions directly for OSX and maybe Linux too… anyone confirm?
It’s nice to know some things can work though. Over time I’ll add the things I need.