ChocolateBird/scripts/loaders/common.gd

159 lines
5.2 KiB
GDScript3
Raw Normal View History

2023-07-28 15:57:21 +09:30
extends Node
2023-08-02 20:18:29 +09:30
var base_resolution: Vector2 = Vector2(ProjectSettings.get_setting('display/window/size/width'), ProjectSettings.get_setting('display/window/size/height')) # Vector2(640, 360)
var shrink_timer := Timer.new()
static func load_json(filename: String): # Valid JSON will return Array or Dictionary. int error code for anything else.
2023-07-28 15:57:21 +09:30
var file := File.new()
match file.open(filename, File.READ):
OK:
var result = JSON.parse(file.get_as_text())
match result.error:
OK:
return result.result
var error:
print_debug(result.error_string)
print_debug(result.error_line)
return error
var error:
return error
static func _to_json(data, current_indent: int = 0) -> String:
match typeof(data):
TYPE_RAW_ARRAY: # XX: add more as required
return str(data)
TYPE_ARRAY:
var contents := PoolStringArray()
for value in data:
contents.append(_to_json(value, current_indent + 1))
return '[' + ', '.join(contents) + ']\n'
TYPE_DICTIONARY:
var contents := PoolStringArray()
for k in data:
contents.append('"%s": %s' % [k, _to_json(data[k], current_indent + 1)])
return '{' + ', '.join(contents) + '}\n'
_:
return JSON.print(data)
static func save_json(filename: String, data) -> int: # Returns error code but Error is not usable as return signature
# Oh cool, 3.6.beta2's json serialization is borked on PoolByteArray and PoolVector2Array
# print(JSON.print([PoolByteArray([0,1]), PoolIntArray([0,1]), PoolRealArray([0,1]), PoolVector2Array([Vector2.ONE, Vector2.LEFT]), PoolStringArray(['hello', 'world'])]))
# ["[0, 1]",[0,1],[0,1],"[(1, 1), (-1, 0)]",["hello","world"]]
var file := File.new()
var error := file.open(filename, File.WRITE)
if error != OK:
return error
# file.store_line(to_json(data))
# file.store_line(JSON.print(data))
file.store_line(_to_json(data, 0))
return OK
static func genericize_type(type: int) -> int:
match type:
TYPE_RAW_ARRAY, TYPE_INT_ARRAY, TYPE_REAL_ARRAY, TYPE_STRING_ARRAY:
return TYPE_ARRAY
TYPE_INT:
return TYPE_REAL
_:
return type
static func are_values_equal(v1, v2, fuzzy_types: bool = true) -> bool:
var t1 := typeof(v1)
var t2 := typeof(v2)
if fuzzy_types:
t1 = genericize_type(t1)
t2 = genericize_type(t2)
if t1 != t2:
print_debug('Type mismatch: %s vs %s' % [t1, t2])
return false
match t1:
TYPE_ARRAY:
return are_arrays_equal(v1, v2, fuzzy_types)
TYPE_DICTIONARY:
return are_dictionaries_equal(v1, v2, fuzzy_types)
_:
return v1 == v2
static func are_dictionaries_equal(d1: Dictionary, d2: Dictionary, fuzzy_types: bool = true) -> bool:
if len(d1) != len(d2):
print_debug('Array lengths not equal: %s vs %s' % [len(d1), len(d2)])
return false
for k in d1:
if not (k in d2):
print_debug('d1 has key "%s" that d2 does not' % k)
return false
if not are_values_equal(d1[k], d2[k], fuzzy_types):
print_debug('d1["%s"] != d2["%s"]' % [k, k])
print_debug(d1[k])
print_debug(d2[k])
return false
return true
static func are_arrays_equal(a1: Array, a2: Array, fuzzy_types: bool = true) -> bool:
var l1 := len(a1)
if l1 != len(a2):
print_debug('Array lengths not equal: %s vs %s' % [l1, len(a2)])
return false
for i in l1:
if not are_values_equal(a1[i], a2[i], fuzzy_types):
print_debug('a1[%d] != a2[%d]' % [i, i])
print_debug(a1[i])
print_debug(a2[i])
return false
return true
2023-07-31 23:33:05 +09:30
static func load_tsv(filename: String, delimiter: String = '\t') -> Dictionary:
var file := File.new()
var error := file.open(filename, File.READ)
if error == OK:
var headers := file.get_csv_line(delimiter)
var n := headers.size()
var output = {}
while file.get_position() < file.get_len():
var line := file.get_csv_line(delimiter)
var entry := {}
for i in range(1, n):
if line.size() > i:
var token := line[i]
entry[headers[i]] = token
if token.begins_with('0x'):
var hex := token.hex_to_int()
if hex > 0:
entry[headers[i]] = hex
output[line[0]] = entry
return output
print_debug(error)
return {}
var SNES_PSX_addresses := load_tsv('res://data/SNES_PSX_addresses.tsv')
func shrink_to_integer():
var size := OS.get_window_size()
var scale_vec := size / base_resolution
var scale_f := max(min(scale_vec.x, scale_vec.y), 1)
var scale := int(scale_f)
2023-08-02 20:18:29 +09:30
var new_window_size := base_resolution*scale
if OS.get_window_size() != new_window_size: # avoid retriggering this event forever
OS.set_window_size(new_window_size)
print('resized to scale %d %s' % [scale, new_window_size])
func update_window_scale():
if OS.window_size < base_resolution*2:
OS.window_size = base_resolution*2
var size := OS.get_window_size()
var scale_vec := size / base_resolution
var scale_f := max(min(scale_vec.x, scale_vec.y), 1)
var scale := int(scale_f)
if ProjectSettings.get_setting('display/window/size/snap_to_integer'):
# OS.window_size = base_resolution*scale
shrink_timer.paused = false
shrink_timer.start(1)
get_tree().set_screen_stretch(SceneTree.STRETCH_MODE_VIEWPORT, SceneTree.STRETCH_ASPECT_KEEP, base_resolution*scale, scale)
func _ready():
shrink_timer.connect('timeout', self, 'shrink_to_integer')
2023-08-02 20:18:29 +09:30
shrink_timer.one_shot = true
add_child(shrink_timer)
get_tree().connect('screen_resized', self, 'update_window_scale')
OS.set_min_window_size(base_resolution*2)