Fix save serialization
This commit is contained in:
parent
724f48a62e
commit
36d025e18c
|
@ -47,7 +47,27 @@ func get_struct(buffer: StreamPeer, struct_name: String) -> Dictionary:
|
|||
return {}
|
||||
return struct_types[struct_name].get_value(buffer, [0, 0])
|
||||
|
||||
func get_save_slot(sram: File, slot_id: int):
|
||||
func put_struct(buffer: StreamPeer, struct_name: String, data: Dictionary):
|
||||
if not (struct_name in struct_types):
|
||||
print_debug('Attempted to put undeclared struct: "%s"' % struct_name)
|
||||
return
|
||||
struct_types[struct_name].put_value(buffer, data, [0, 0])
|
||||
|
||||
func deserialize_save_slot(bytes: PoolByteArray) -> Dictionary:
|
||||
var buffer = StreamPeerBuffer.new()
|
||||
buffer.data_array = bytes
|
||||
return struct_types['Save_slot'].get_value(buffer, [0, 0])
|
||||
|
||||
func serialize_save_slot(data: Dictionary) -> PoolByteArray:
|
||||
var buffer = StreamPeerBuffer.new()
|
||||
struct_types['Save_slot'].put_value(buffer, data, [0, 0])
|
||||
var padding := PoolByteArray()
|
||||
padding.resize(0x100)
|
||||
padding.fill(0)
|
||||
buffer.put_data(padding)
|
||||
return buffer.data_array
|
||||
|
||||
func get_save_slot(sram: File, slot_id: int) -> StreamPeerBuffer:
|
||||
var buffer := StreamPeerBuffer.new()
|
||||
sram.seek(0x700 * slot_id)
|
||||
buffer.set_data_array(sram.get_buffer(0x700))
|
||||
|
|
|
@ -78,7 +78,7 @@ class UBits extends StructType:
|
|||
return value
|
||||
|
||||
func put_value(buffer: StreamPeer, value, leftover_bits: Array):
|
||||
leftover_bits[1] |= value << bits
|
||||
leftover_bits[1] |= value << leftover_bits[0]
|
||||
leftover_bits[0] += bits
|
||||
while leftover_bits[0] >= 8:
|
||||
buffer.put_8(leftover_bits[1] & 0xFF)
|
||||
|
|
|
@ -2,6 +2,15 @@ extends Control
|
|||
|
||||
var dir_user := Directory.new()
|
||||
const P_TESTDATA := 'user://test_data/'
|
||||
# Shared state between tests
|
||||
var save_slot_buffers = []
|
||||
var save_slot_dicts = []
|
||||
|
||||
func test(label, input):
|
||||
if input:
|
||||
print('SUCCESS: ' + label)
|
||||
else:
|
||||
print('FAILURE: ' + label)
|
||||
|
||||
func load_snes_savefile(filename: String = 'res://test.srm'):
|
||||
var save_file := File.new()
|
||||
|
@ -11,17 +20,14 @@ func load_snes_savefile(filename: String = 'res://test.srm'):
|
|||
var error:
|
||||
print_debug('Failed to open test.srm for reading: %d' % error)
|
||||
return
|
||||
var save_slots = []
|
||||
var save_slot_dicts = []
|
||||
for i in 4:
|
||||
save_slots.append(SaveLoader.get_save_slot(save_file, i))
|
||||
save_slot_dicts.append(SaveLoader.get_struct(save_slots[i], 'Save_slot'))
|
||||
self.save_slot_buffers.append(SaveLoader.get_save_slot(save_file, i))
|
||||
self.save_slot_dicts.append(SaveLoader.deserialize_save_slot(self.save_slot_buffers[i].data_array))
|
||||
print('Loaded test save file')
|
||||
return save_slot_dicts
|
||||
|
||||
func generate_known_good_results():
|
||||
var save_slot_dicts = load_snes_savefile()
|
||||
if not save_slot_dicts:
|
||||
load_snes_savefile()
|
||||
if not self.save_slot_dicts:
|
||||
return
|
||||
match dir_user.make_dir_recursive(P_TESTDATA):
|
||||
OK:
|
||||
|
@ -30,7 +36,7 @@ func generate_known_good_results():
|
|||
print_debug('Failed to create "%s" with error code %d' % [P_TESTDATA, error])
|
||||
return
|
||||
var filename := P_TESTDATA + 'test.srm.json'
|
||||
match Common.save_json(filename, save_slot_dicts):
|
||||
match Common.save_json(filename, self.save_slot_dicts):
|
||||
OK:
|
||||
pass
|
||||
var error:
|
||||
|
@ -38,8 +44,8 @@ func generate_known_good_results():
|
|||
return
|
||||
|
||||
func test_save_loading() -> bool:
|
||||
var save_slot_dicts = load_snes_savefile()
|
||||
if not save_slot_dicts:
|
||||
load_snes_savefile()
|
||||
if not self.save_slot_dicts:
|
||||
print_debug('Failed to load test savefile')
|
||||
return false
|
||||
var filename := P_TESTDATA + 'test.srm.json'
|
||||
|
@ -47,7 +53,7 @@ func test_save_loading() -> bool:
|
|||
match typeof(known_good):
|
||||
TYPE_ARRAY:
|
||||
print_debug('Comparing known savefile results')
|
||||
return Common.are_arrays_equal(save_slot_dicts, known_good)
|
||||
return Common.are_arrays_equal(self.save_slot_dicts, known_good)
|
||||
TYPE_DICTIONARY:
|
||||
print_debug('Known savefile results "%s" is a dict instead of an array. Did we change formats?' % filename)
|
||||
return false
|
||||
|
@ -55,6 +61,24 @@ func test_save_loading() -> bool:
|
|||
print_debug('Failed to load known savefile results "%s"' % filename)
|
||||
return false
|
||||
|
||||
func test_save_serialization() -> bool:
|
||||
if not self.save_slot_dicts:
|
||||
print_debug('test savefile not loaded')
|
||||
return false
|
||||
for i in 4:
|
||||
var bytes = SaveLoader.serialize_save_slot(self.save_slot_dicts[i])
|
||||
if bytes != self.save_slot_buffers[i].data_array:
|
||||
print_debug('Slot %d failed to serialize correctly, rescanning' % i)
|
||||
for j in 0x700:
|
||||
var b1: int = bytes[j]
|
||||
var b2: int = self.save_slot_buffers[i].data_array[j]
|
||||
if b1 != b2:
|
||||
print_debug('Mismatch occurs at byte %d: %d vs %d' % [j, b1, b2])
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
|
@ -64,5 +88,6 @@ func _ready() -> void:
|
|||
var error:
|
||||
print_debug('Failed to open user directory')
|
||||
# generate_known_good_results() # Uncomment this to get your sample on first run
|
||||
print(test_save_loading())
|
||||
test('SNES save file loaded to array of dictionaries', test_save_loading())
|
||||
test('SNES save file slots serialized from dictionaries', test_save_serialization())
|
||||
get_tree().quit()
|
||||
|
|
Loading…
Reference in New Issue