Skip to content
Snippets Groups Projects
Commit 22e90a6a authored by dg's avatar dg
Browse files

Fullscreen & resolution switching fixes

git-svn-id: http://svn.net-core.org/repos/t-engine4@6186 51575b47-30f0-44d4-a5cc-537603b46e54
parent a1b2989e
No related branches found
No related tags found
No related merge requests found
......@@ -366,9 +366,11 @@ end
available_resolutions =
{
["800x600 Windowed"] = {800, 600, false},
["1024x768 Windowed"] = {1024, 768, false},
["1200x1024 Windowed"] = {1200, 1024, false},
["800x600 Windowed"] = {800, 600, false},
["1024x768 Windowed"] = {1024, 768, false},
["1200x1024 Windowed"] = {1200, 1024, false},
["1280x720 Windowed"] = {1280, 720, false},
["1600x900 Windowed"] = {1600, 900, false},
["1600x1200 Windowed"] = {1600, 1200, false},
-- ["800x600 Fullscreen"] = {800, 600, true},
-- ["1024x768 Fullscreen"] = {1024, 768, true},
......@@ -403,55 +405,85 @@ function _M:setResolution(res, force)
end
if not r then return false, "unknown resolution" end
print("Switching resolution to", res, r[1], r[2], r[3])
-- Change the window size
print("setResolution: switching resolution to", res, r[1], r[2], r[3], force and "(forced)")
local old_w, old_h, old_f = self.w, self.h, self.fullscreen
core.display.setWindowSize(r[1], r[2], r[3])
self.w, self.h, self.fullscreen = core.display.size()
-- Don't write self.w/h/fullscreen yet
local new_w, new_h, new_f = core.display.size()
-- Save settings if need be
if self.w ~= old_w or self.h ~= old_h or self.fullscreen ~= old_f then
-- Check if a resolution change actually happened
if new_w ~= old_w or new_h ~= old_h or new_f ~= old_f then
print("setResolution: performing onResolutionChange...\n")
self:onResolutionChange()
self:saveSettings("resolution", ("window.size = %q\n"):format(res))
-- onResolutionChange saves settings...
-- self:saveSettings("resolution", ("window.size = %q\n"):format(res))
else
print("setResolution: resolution change requested from same resolution!\n")
end
end
--- Called when screen resolution changes
function _M:onResolutionChange()
local ow, oh, of = self.w, self.h, self.fullscreen
-- Save old values for a potential revert
if game and not self.change_res_dialog_oldw then
self.change_res_dialog_oldw, self.change_res_dialog_oldh, self.change_res_dialog_oldf = self.w, self.h, self.fullscreen
print("onResolutionChange: saving current resolution for potential revert.")
self.change_res_dialog_oldw, self.change_res_dialog_oldh, self.change_res_dialog_oldf = ow, oh, of
end
local ow, oh, of = self.w, self.h, self.fullscreen
-- Get new resolution and save
self.w, self.h, self.fullscreen = core.display.size()
config.settings.window.size = ("%dx%d%s"):format(self.w, self.h, self.fullscreen and " Fullscreen" or " Windowed")
self:saveSettings("resolution", ("window.size = '%s'\n"):format(config.settings.window.size))
print("[RESOLUTION] changed to ", self.w, self.h, "from", ow, oh)
print("onResolutionChange: resolution changed to ", self.w, self.h, "from", ow, oh)
-- We do not even have a game yet
if not game then return end
if not game then
print("onResolutionChange: no game yet!")
return
end
-- No actual resize
if ow == self.w and oh == self.h then return end
if ow == self.w and oh == self.h then
print("onResolutionChange: no actual resize, no confirm dialog.")
return
end
if self:checkResolutionChange(self.w, self.h, ow, oh) then return end
-- Extra game logic to be updated on a resize
if not self:checkResolutionChange(self.w, self.h, ow, oh) then
print("onResolutionChange: checkResolutionChange returned false, no confirm dialog.")
return
end
-- Do not repop if we just revert back
if self.change_res_dialog and type(self.change_res_dialog) == "string" and self.change_res_dialog == "revert" then return end
if self.change_res_dialog and type(self.change_res_dialog) == "string" and self.change_res_dialog == "revert" then
print("onResolutionChange: Reverting, no popup.")
return
end
-- Unregister old dialog if there was one
if self.change_res_dialog and type(self.change_res_dialog) == "table" then self:unregisterDialog(self.change_res_dialog) end
-- Ask if we want to switch
self.change_res_dialog = require("engine.ui.Dialog"):yesnoPopup("Resolution changed", "Accept the new resolution?", function(ret)
if ret then
if not self.creating_player then self:saveGame() end
util.showMainMenu(false, nil, nil, self.__mod_info.short_name, self.save_name, false)
else
self.change_res_dialog = "revert"
self:setResolution(("%dx%d%s"):format(self.change_res_dialog_oldw, self.change_res_dialog_oldh, self.change_res_dialog_oldf and " Fullscreen" or " Windowed"), true)
self.change_res_dialog = nil
self.change_res_dialog_oldw, self.change_res_dialog_oldh, self.change_res_dialog_oldf = nil, nil, nil
end
end, "Accept", "Revert")
if self.change_res_dialog and type(self.change_res_dialog) == "table" then
print("onResolutionChange: Unregistering dialog")
self:unregisterDialog(self.change_res_dialog)
end
-- Are you sure you want to save these settings? Somewhat obnoxious...
-- self.change_res_dialog = require("engine.ui.Dialog"):yesnoPopup("Resolution changed", "Accept the new resolution?", function(ret)
-- if ret then
-- if not self.creating_player then self:saveGame() end
-- util.showMainMenu(false, nil, nil, self.__mod_info.short_name, self.save_name, false)
-- else
-- self.change_res_dialog = "revert"
-- self:setResolution(("%dx%d%s"):format(self.change_res_dialog_oldw, self.change_res_dialog_oldh, self.change_res_dialog_oldf and " Fullscreen" or " Windowed"), true)
-- self.change_res_dialog = nil
-- self.change_res_dialog_oldw, self.change_res_dialog_oldh, self.change_res_dialog_oldf = nil, nil, nil
-- end
-- end, "Accept", "Revert")
print("onResolutionChange: (Would have) created popup.")
end
--- Checks if we must reload to change resolution
......
......@@ -405,11 +405,10 @@ function _M:resizeIconsHotkeysToolbar()
end
function _M:handleResolutionChange(w, h, ow, oh)
local w, h = core.display.size()
game:setResolution(w.."x"..h, true)
self.no_ui = not self.no_ui
self:toggleUI()
print("minimalist:handleResolutionChange: adjusting UI")
-- what was the point of this recursive call?
-- local w, h = core.display.size()
-- game:setResolution(w.."x"..h, true)
-- Adjust UI
local w2, h2 = math.floor(ow / 2), math.floor(oh / 2)
......@@ -418,8 +417,14 @@ function _M:handleResolutionChange(w, h, ow, oh)
if d.y > h2 then d.y = d.y + h - oh end
end
print("minimalist:handleResolutionChange: toggling UI to refresh")
-- Toggle the UI to refresh the changes
self:toggleUI()
self:toggleUI()
self:boundPlaces()
self:saveSettings()
print("minimalist:handleResolutionChange: saved settings")
return true
end
......
......@@ -1322,6 +1322,23 @@ static int sdl_load_image(lua_State *L)
return 3;
}
static int sdl_load_image_mem(lua_State *L)
{
size_t len;
const char *data = luaL_checklstring(L, 1, &len);
SDL_Surface **s = (SDL_Surface**)lua_newuserdata(L, sizeof(SDL_Surface*));
auxiliar_setclass(L, "sdl{surface}", -1);
*s = IMG_Load_RW(SDL_RWFromConstMem(data, len), TRUE);
if (!*s) return 0;
lua_pushnumber(L, (*s)->w);
lua_pushnumber(L, (*s)->h);
return 3;
}
static int sdl_free_surface(lua_State *L)
{
SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1);
......@@ -2557,6 +2574,7 @@ static const struct luaL_reg displaylib[] =
{"drawStringNewSurface", sdl_surface_drawstring_newsurface},
{"drawStringBlendedNewSurface", sdl_surface_drawstring_newsurface_aa},
{"loadImage", sdl_load_image},
{"loadImageMemory", sdl_load_image_mem},
{"setWindowTitle", sdl_set_window_title},
{"setWindowSize", sdl_set_window_size},
{"setWindowPos", sdl_set_window_pos},
......
......@@ -771,30 +771,90 @@ int resizeWindow(int width, int height)
void do_resize(int w, int h, bool fullscreen)
{
if (!window)
{
window = SDL_CreateWindow("TE4", (start_xpos == -1) ? SDL_WINDOWPOS_CENTERED : start_xpos, (start_ypos == -1) ? SDL_WINDOWPOS_CENTERED : start_ypos, w, h, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | (fullscreen ? SDL_WINDOW_FULLSCREEN : 0));
/* Temporary width, height (since SDL might reject our resize) */
int aw, ah;
int mustPushEvent = 0;
SDL_Event fsEvent;
printf("[DO RESIZE] Requested: %dx%d (%d)\n", w, h, fullscreen);
/* If there is no current window, we have to make one and initialize */
if (!window) {
window = SDL_CreateWindow("TE4",
(start_xpos == -1) ? SDL_WINDOWPOS_CENTERED : start_xpos,
(start_ypos == -1) ? SDL_WINDOWPOS_CENTERED : start_ypos, w, h,
SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
| (fullscreen ? SDL_WINDOW_FULLSCREEN : 0));
if (window==NULL) {
printf("error opening screen: %s\n", SDL_GetError());
exit(1);
}
is_fullscreen = fullscreen;
screen = SDL_GetWindowSurface(window);
maincontext = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, maincontext);
glewInit();
}
else
{
} else {
/* SDL won't allow a fullscreen resolution change in one go. Check. */
if (is_fullscreen) {
/* Drop out of fullscreen so we can change resolution. */
SDL_SetWindowFullscreen(window, SDL_FALSE);
is_fullscreen = 0;
mustPushEvent = 1; /* Actually just a maybe for now, confirmed later */
}
/* Update window size */
SDL_SetWindowSize(window, w, h);
/* Jump [back] into fullscreen if requested */
if (fullscreen) {
if (!SDL_SetWindowFullscreen(window, SDL_TRUE)) {
/* Fullscreen change successful */
is_fullscreen = SDL_TRUE;
} else {
/* Error switching fullscreen mode */
printf("[DO RESIZE] Unable to switch window"
" to fullscreen mode: %s\n", SDL_GetError());
SDL_ClearError();
}
} else if (mustPushEvent) {
/*
* Our changes will get clobbered by an automatic event from
* setWindowFullscreen. Push an event to the event loop to make
* sure these changes are applied after whatever that other event
* throws.
*/
/* Create an event to push */
fsEvent.type = SDL_WINDOWEVENT;
fsEvent.window.timestamp = SDL_GetTicks();
fsEvent.window.windowID = SDL_GetWindowID(window);
// windowId
fsEvent.window.event = SDL_WINDOWEVENT_RESIZED;
fsEvent.window.data1 = w;
fsEvent.window.data2 = h;
/* Push the event, but don't bother waiting */
SDL_PushEvent(&fsEvent);
printf("[DO RESIZE]: pushed fullscreen compensation event\n");
}
/* Finally, update the screen info */
screen = SDL_GetWindowSurface(window);
}
printf("[DO RESIZE] %dx%d (%d)\n", w, h, fullscreen);
is_fullscreen = fullscreen;
SDL_SetWindowFullscreen(window, fullscreen);
SDL_GetWindowSize(window, &w, &h);
/* Check and see if SDL honored our resize request */
SDL_GetWindowSize(window, &aw, &ah);
printf("[DO RESIZE] Got: %dx%d (%d)\n", aw, ah, is_fullscreen);
SDL_GL_MakeCurrent(window, maincontext);
resizeWindow(w, h);
resizeWindow(aw, ah);
}
void boot_lua(int state, bool rebooting, int argc, char *argv[])
......@@ -1087,17 +1147,22 @@ int main(int argc, char *argv[])
switch (event.window.event)
{
case SDL_WINDOWEVENT_RESIZED:
printf("resize %d x %d\n", event.window.data1, event.window.data2);
do_resize(event.window.data1, event.window.data2, is_fullscreen);
/* Note: SDL can't resize a fullscreen window, so don't bother! */
if (!is_fullscreen) {
printf("SDL_WINDOWEVENT_RESIZED: %d x %d\n", event.window.data1, event.window.data2);
do_resize(event.window.data1, event.window.data2, is_fullscreen);
if (current_game != LUA_NOREF)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
lua_pushstring(L, "onResolutionChange");
lua_gettable(L, -2);
lua_remove(L, -2);
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
docall(L, 1, 0);
}
} else {
printf("SDL_WINDOWEVENT_RESIZED: ignored due to fullscreen\n");
if (current_game != LUA_NOREF)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
lua_pushstring(L, "onResolutionChange");
lua_gettable(L, -2);
lua_remove(L, -2);
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
docall(L, 1, 0);
}
break;
case SDL_WINDOWEVENT_MOVED: {
......@@ -1146,22 +1211,33 @@ int main(int argc, char *argv[])
exit_engine = TRUE;
break;
case SDL_USEREVENT:
if (event.user.code == 0 && isActive) {
on_redraw();
SDL_mutexP(renderingLock);
redraw_pending = 0;
SDL_mutexV(renderingLock);
/* TODO: Enumerate user event codes */
switch(event.user.code)
{
case 0:
if (isActive) {
on_redraw();
SDL_mutexP(renderingLock);
redraw_pending = 0;
SDL_mutexV(renderingLock);
}
break;
}
else if (event.user.code == 2 && isActive) {
on_tick();
SDL_mutexP(realtimeLock);
realtime_pending = 0;
SDL_mutexV(realtimeLock);
}
else if (event.user.code == 1) {
case 1:
on_music_stop();
break;
case 2:
if (isActive) {
on_tick();
SDL_mutexP(realtimeLock);
realtime_pending = 0;
SDL_mutexV(realtimeLock);
}
break;
default:
break;
}
break;
default:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment