105 lines
3.6 KiB
GDScript
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
|