hero-mark-2/autoloads/scene_manager.gd

105 lines
3.6 KiB
GDScript

## manages current scene and viewport scaling
extends Node
# methods of scaling viewport
enum ScalingMode {
INTEGER, # maintain aspect ratio and scale by whole numbers
ASPECT, # maintain aspect ratio
STRETCH, # stretch to fill screen
}
## method used to scale game viewport
export (ScalingMode) var scaling_mode: int = ScalingMode.INTEGER
# node references #
onready var viewport_container: ViewportContainer = $ViewportContainer
onready var viewport: Viewport = $ViewportContainer/Viewport
var resolution: Vector2
var current_scene: Node setget change_scene
var last_input_gamepad: bool = true
func _input(event: InputEvent) -> void:
if event is InputEventJoypadButton:
last_input_gamepad = true
elif event is InputEventKey:
last_input_gamepad = false
## change the current scene
func change_scene(new_scene: Node) -> void:
# remove current scene if it exists
if current_scene != null:
viewport.remove_child(current_scene)
current_scene.queue_free()
# remove child from parent if it has one
if new_scene.is_inside_tree():
new_scene.get_parent().call_deferred("remove_child", new_scene)
# add new scene to tree
viewport.call_deferred("add_child", new_scene)
current_scene = new_scene
func set_scanlines(type: int) -> void:
yield(get_tree(), "idle_frame")
match type:
Options.ScanlineType.NONE:
viewport_container.material.set_shader_param("enabled", false)
Options.ScanlineType.CRT:
viewport_container.material.set_shader_param("enabled", true)
viewport_container.material.set_shader_param("scanline_opacity", Vector2(0.2, 0.0))
viewport_container.material.set_shader_param("brightness", 1.1)
Options.ScanlineType.LCD:
viewport_container.material.set_shader_param("enabled", true)
viewport_container.material.set_shader_param("scanline_opacity", Vector2(0.2, 0.2))
viewport_container.material.set_shader_param("brightness", 1.2)
func _ready() -> void:
var tree := get_tree()
# capture initial scene
if tree.current_scene != self:
change_scene(tree.current_scene)
tree.current_scene = self
# capture autoloads in the group "viewport_autoload"
for node in tree.get_nodes_in_group("viewport_autoload"):
node.get_parent().call_deferred("remove_child", node)
viewport.call_deferred("add_child", node)
# get design resolution from project settings
var project_resolution := Vector2(
ProjectSettings.get_setting("display/window/size/width"),
ProjectSettings.get_setting("display/window/size/height")
)
viewport.size = project_resolution
resolution = project_resolution
# size container and pivot on center
viewport_container.rect_size = resolution
viewport_container.rect_pivot_offset = resolution / 2.0
# fix viewportcontainer input bug
viewport.set_deferred("handle_input_locally", true)
# connect resized signal
tree.connect("screen_resized", self, "_on_screen_resized")
_on_screen_resized()
func _process(delta: float) -> void:
if Debug.entry == false:
#CRT FILTER
if Input.is_action_just_pressed("crt"):
viewport_container.material.set_shader_param("enabled", not viewport_container.material.get_shader_param("enabled"))
func _on_screen_resized() -> void:
var screen_size := OS.window_size
var scale_delta := screen_size / resolution
match scaling_mode:
ScalingMode.INTEGER:
# find smaller scale difference, floor to integer
var scale = floor(min(scale_delta.x, scale_delta.y))
viewport_container.rect_scale = Vector2(scale, scale)
ScalingMode.ASPECT:
# find smaller scale difference
var scale = min(scale_delta.x, scale_delta.y)
viewport_container.rect_scale = Vector2(scale, scale)
ScalingMode.STRETCH:
# simply use scale difference
viewport_container.rect_scale = scale_delta