Skip to content

Instantly share code, notes, and snippets.

@lekoder
Created October 5, 2023 14:01
Show Gist options
  • Save lekoder/fd3a0afbbce9f94e13874a45b61dc28f to your computer and use it in GitHub Desktop.
Save lekoder/fd3a0afbbce9f94e13874a45b61dc28f to your computer and use it in GitHub Desktop.

Revisions

  1. lekoder created this gist Oct 5, 2023.
    325 changes: 325 additions & 0 deletions Settings.gd
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,325 @@
    export var viewportResizeStanddown = 0.5
    var viewportResizeCounter = 0.0

    signal settingsChanged()
    signal particlesSettingsChanged()
    signal removeGpuParticles()

    func forbidParticles(time):
    particlesForbiddenCounter = time
    particlesForbidden = true
    emit_signal("removeGpuParticles")

    func scaleWindow(size):
    OS.set_window_size(Vector2(round(size.x), round(size.y)))

    var displaySettingsHash = null
    var keymapHash = null
    var scaleHash = null
    func maximizeWindow():
    match OS.get_name():
    "Windows":
    var pos = OS.get_screen_position()
    var size = OS.get_screen_size() + Vector2(0,1)
    Debug.l("Activating borderless workaround @ %s / %s" % [pos,size])
    OS.window_position = pos
    OS.window_size = size
    requestResize = true
    "OSX":
    Debug.l("Maximizing game window")
    var timer = Tool.makeTimer(workaroundOSXtimeout, self)
    yield(timer, "timeout")
    OS.window_maximized = true
    Debug.l("Window maximized")
    viewportResizeCounter = viewportResizeStanddown
    requestResize = true
    _:
    Debug.l("Maximizing game window")
    OS.window_maximized = true
    requestResize = true

    export var windowMaximizeDelay = 0.5
    var requestWindowMaximize = -1
    var requestWindowMove = -1
    var requestWindowMovePos = Vector2(0,0)

    func getScreenSettingsHash():
    return [cfg.display.fullscreen, cfg.display.windowed, cfg.display.screen, cfg.display.pixelDoubling].hash()

    var settingsHash = 0

    func setFps(fps: int):
    Engine.iterations_per_second = fps
    Physics2DServer.set_collision_iterations(ceil((60.0/float(fps))*16))

    func getFps() -> int:
    return Engine.iterations_per_second

    func sortScreens(a: Rect2, b: Rect2) -> bool:
    if abs(a.position.x) < abs(b.position.x):
    return true
    if abs(a.position.x) > abs(b.position.x):
    return false
    if abs(a.position.y) < abs(b.position.y):
    return true
    if abs(a.position.y) > abs(b.position.y):
    return false
    if a.position.x < b.position.x:
    return true
    if a.position.x > b.position.x:
    return false
    if a.position.y < b.position.y:
    return true
    if a.position.y > b.position.y:
    return false
    return false

    func getSortedScreens():
    var screens = []
    for s in range(OS.get_screen_count()):
    screens.append(Rect2(OS.get_screen_position(s).round(), OS.get_screen_size(s).round()))

    Debug.l("Screens reported by OS: %s" % [screens])
    screens.sort_custom(self, "sortScreens")
    Debug.l("Screens ordered by game: %s" % [screens])
    return screens

    export var workaroundOSXtimeout = 0.5
    export var workaroundOSXnuketime = 2.0
    var applying = false
    func applySettings():
    if applying:
    return
    applying = true
    requestResize = false
    requestWindowMaximize = -1
    var change = false
    var dsh = getScreenSettingsHash()
    setFps(cfg.gameplay.fps)
    Engine.target_fps = cfg.display.fps
    Debug.l("Target FPS: %d, cap: %s" % [cfg.gameplay.fps, cfg.display.fps])

    if dsh != displaySettingsHash:
    change = true
    match OS.get_name():
    "OSX":
    Debug.l("Settings NUKE")
    forbidParticles(workaroundOSXnuketime)
    var timer = Tool.makeTimer(workaroundOSXtimeout, self)
    yield(timer, "timeout")

    displaySettingsHash = dsh
    OS.vsync_enabled = cfg.display.vsync
    if cfg.display.windowed:
    match OS.get_name():
    "OSX":
    if OS.window_fullscreen:
    OS.window_fullscreen = false
    var timer = Tool.makeTimer(workaroundOSXtimeout, self)
    yield(timer, "timeout")
    OS.window_borderless = false
    OS.window_resizable = true
    OS.set_window_always_on_top(false)
    _:
    OS.window_fullscreen = false
    OS.window_borderless = false
    OS.window_resizable = true
    scaleWindow(cfg.display.windowSize)
    requestResize = true
    else:
    var screen = cfg.display.screen
    if screen >= OS.get_screen_count():
    screen = 0
    var screens = getSortedScreens()
    var size = screens[screen].size
    var pos = screens[screen].position
    Debug.l("Moving to %s, size %s, screen %s (display opts: %s)" % [pos, size, screen, cfg.display])
    match OS.get_name():
    "OSX":
    pass
    _:
    OS.window_fullscreen = false
    OS.window_maximized = false
    OS.window_resizable = true
    OS.window_borderless = false
    OS.window_borderless = true
    OS.window_position = pos
    Debug.l("Applying window scale")
    scaleWindow(size)
    if cfg.display.fullscreen:
    Debug.l("Going fullscreen")
    match OS.get_name():
    "OSX":
    Debug.l("Already fullscreen check")
    if !OS.window_fullscreen:
    var timer = Tool.makeTimer(workaroundOSXtimeout, self)
    yield(timer, "timeout")
    if OS.window_borderless:
    OS.window_borderless = false
    Debug.l("Borderless mode disabled")
    Debug.l("Shitty OSX workaround passed")
    viewportResizeCounter = viewportResizeStanddown
    OS.window_fullscreen = true
    Debug.l("Went fullscreen")
    requestResize = true

    else:
    match OS.get_name():
    "OSX":
    if OS.window_fullscreen:
    OS.window_fullscreen = false
    var timer = Tool.makeTimer(workaroundOSXtimeout, self)
    yield(timer, "timeout")

    OS.window_borderless = true
    viewportResizeCounter = viewportResizeStanddown
    requestResize = true
    Debug.l("Requesting deferred move and maximization")
    requestWindowMaximize = windowMaximizeDelay
    requestWindowMove = windowMaximizeDelay / 2
    requestWindowMovePos = pos

    if TranslationServer.get_locale() != cfg.locale.language:
    change = true
    TranslationServer.set_locale(cfg.locale.language)
    AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), muteOverride(cfg.audio.master))
    AudioServer.set_bus_volume_db(AudioServer.get_bus_index("SFX"), muteOverride(cfg.audio.sfx-2))
    AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), muteOverride(cfg.audio.music-2))
    AudioServer.set_bus_volume_db(AudioServer.get_bus_index("ShipBowels"), muteOverride(cfg.audio.ambient))
    var r = cfg.ui.scale
    maxScreenScale = minScreen * r + OS.window_size * (1-r)
    if scaleHash != r:
    scaleHash = r
    change = true
    applyInterfaceScale()

    var h = cfg.input.hash()
    if keymapHash != h:
    keymapHash = h
    change = true
    loadKeymapFromConfig()

    var shs = cfg.hash()
    if shs != settingsHash:
    emit_signal("settingsChanged")
    settingsHash = shs
    emit_signal("tutorialChanged")
    applying = false

    func getViewportSize(viewport = get_viewport()):
    if viewport == get_viewport():
    var newSize = OS.window_size
    #Debug.l("Raw window size: %s, mim: %s" % [newSize,minScreen])
    if newSize.x > 0 and newSize.y > 0:
    var aspect = clamp(OS.window_size.x/OS.window_size.y, 0.25, 8)
    if newSize.x > maxScreenScale.x:
    newSize.x = maxScreenScale.x
    newSize.y = newSize.x / aspect
    if newSize.y > maxScreenScale.y:
    newSize.y = maxScreenScale.y
    newSize.x = newSize.y * aspect

    if newSize.x < minScreen.x:
    newSize.x = minScreen.x
    newSize.y = newSize.x / aspect
    if newSize.y < minScreen.y:
    newSize.y = minScreen.y
    newSize.x = newSize.y * aspect

    if newSize.x < minWindow.x:
    newSize.x = minWindow.x
    if newSize.y < minWindow.y:
    newSize.y = minWindow.y
    newSize.x = round(newSize.x)
    newSize.y = round(newSize.y)
    return newSize
    else:
    return viewport.size

    func getPixelAdjustment():
    var pd = Settings.cfg.display.pixelDoubling
    if pd <= 0:
    pd = 1.0/(1.0-pd)
    return pd

    func applyInterfaceScale():
    var newSize = getViewportSize()
    Debug.l("Viewport size: %s" % newSize)
    var root = get_tree().get_root()
    var currentSize = root.get_size_override()
    if hash(currentSize) != hash(newSize):
    Debug.l("overriding from %s to %s " % [currentSize,newSize])
    root.set_size_override(true, newSize)

    var srs2 = OS.window_size / getPixelAdjustment()
    if srs2 != root.size:
    root.size = srs2
    Debug.l("Size overriden to %s" % [srs2])

    var requestResize = false
    func _on_resize():
    Debug.l("System resize request")
    match OS.get_name():
    "OSX":
    Debug.l("Resize NUKE")
    forbidParticles(workaroundOSXnuketime)
    viewportResizeCounter = viewportResizeStanddown
    requestResize = true
    _:
    doResize()

    func doResize():
    var size = OS.window_size
    Debug.l("Resized interface to %s" % size)
    cfg.display.windowSize = OS.window_size
    var s = OS.window_size
    var r = cfg.ui.scale
    maxScreenScale = minScreen * r + s * (1-r)
    applyInterfaceScale()

    var secondCounter = 0
    var particlesForbidden = false
    var particlesForbiddenCounter = true
    func _process(delta):
    viewportResizeCounter = max(0,viewportResizeCounter-delta)
    if get_tree().paused:
    VisualServer.set_shader_time_scale(0)
    else:
    VisualServer.set_shader_time_scale(Engine.time_scale)
    if requestResize:
    if viewportResizeCounter <= 0:
    viewportResizeCounter = viewportResizeStanddown
    requestResize = false
    doResize()
    if requestWindowMaximize > 0:
    requestWindowMaximize -= delta
    if requestWindowMaximize <= 0:
    maximizeWindow()
    if requestWindowMove > 0:
    requestWindowMove -= delta
    if requestWindowMove <= 0:
    Debug.l("Moving window to requested position: %s" % requestWindowMovePos)
    OS.window_position = requestWindowMovePos
    secondCounter += delta

    if particlesForbidden && particlesForbiddenCounter > 0:
    particlesForbiddenCounter -= delta
    if particlesForbiddenCounter <= 0:
    particlesForbidden = false
    particlesForbiddenCounter = 0
    emit_signal("particlesSettingsChanged")

    if secondCounter > 1.0:
    secondCounter = 0
    if cfg.display.adaptiveFps:
    var real = Performance.get_monitor(Performance.TIME_FPS)
    var current = getFps()
    var target = cfg.gameplay.fps
    var new = clamp(ceil((real+current)/2)+2, 30, target)
    #Debug.l("FPS target: %f real %f current %f new %f" % [target,real, current, new])
    if new != current:
    setFps(new)
    else:
    var new = cfg.gameplay.fps
    if new != getFps():
    setFps(new)