10 static void savedata_file_write( savedata_file
*file
){
11 savedata_file
*sav
= file
;
12 FILE *fp
= fopen( sav
->path
, "wb" );
14 fwrite( sav
->buf
, sav
->len
, 1, fp
);
16 vg_success( "savedata written to '%s'\n", sav
->path
);
19 vg_error( "Error writing savedata (%s)\n", sav
->path
);
23 static void savedata_group_write( savedata_group
*group
){
24 for( u32 i
=0; i
<group
->file_count
; i
++ ){
25 savedata_file_write( &group
->files
[i
] );
29 static void savedata_file_read( savedata_file
*file
){
30 FILE *fp
= fopen( file
->path
, "rb" );
32 file
->len
= fread( file
->buf
, 1, sizeof(file
->buf
), fp
);
37 vg_warn( "Error reading savedata (%s)\n", file
->path
);
41 static void skaterift_write_addon_alias( vg_msg
*msg
, const char *key
,
43 if( alias
->workshop_id
)
44 vg_msg_wkvu64( msg
, key
, alias
->workshop_id
);
46 vg_msg_wkvstr( msg
, key
, alias
->foldername
);
49 static void skaterift_write_viewslot( vg_msg
*msg
, const char *key
,
50 enum addon_type type
, u16 cache_id
){
51 if( !cache_id
) return;
53 struct addon_cache
*cache
= &addon_system
.cache
[type
];
54 addon_cache_entry
*entry
= vg_pool_item( &cache
->pool
, cache_id
);
55 addon_reg
*reg
= entry
->reg_ptr
;
58 skaterift_write_addon_alias( msg
, key
, ®
->alias
);
61 static void skaterift_read_addon_alias( vg_msg
*msg
, const char *key
,
64 alias
->foldername
[0] = '\0';
65 alias
->workshop_id
= 0;
69 if( vg_msg_getkvcmd( msg
, key
, &kv
) ){
70 if( kv
.code
== k_vg_msg_kvstring
){
71 vg_strncpy( kv
.value
, alias
->foldername
, sizeof(alias
->foldername
),
72 k_strncpy_allow_cutoff
);
75 vg_msg_cast( kv
.value
, kv
.code
, &alias
->workshop_id
, k_vg_msg_u64
);
79 static void skaterift_populate_world_savedata( savedata_file
*file
,
80 enum world_purpose which
){
83 addon_reg
*reg
= world_static
.instance_addons
[ which
];
86 vg_error( "Tried to save unspecified world (reg was null)\n" );
90 skaterift_world_get_save_path( which
, file
->path
);
93 vg_msg_init( &sav
, file
->buf
, sizeof(file
->buf
) );
95 world_instance
*instance
= &world_static
.instances
[which
];
96 world_entity_serialize( instance
, &sav
);
98 vg_msg_frame( &sav
, "player" );
100 vg_msg_wkvnum( &sav
, "position", k_vg_msg_float
|k_vg_msg_32b
, 3,
101 (which
== world_static
.active_instance
)?
103 instance
->player_co
);
105 vg_msg_end_frame( &sav
);
107 file
->len
= sav
.cur
.co
;
110 static void skaterift_populate_main_savedata( savedata_file
*file
){
111 strcpy( file
->path
, str_skaterift_main_save
);
114 vg_msg_init( &sav
, file
->buf
, sizeof(file
->buf
) );
116 vg_msg_frame( &sav
, "player" );
118 skaterift_write_viewslot( &sav
, "board", k_addon_type_board
,
119 localplayer
.board_view_slot
);
120 skaterift_write_viewslot( &sav
, "playermodel", k_addon_type_player
,
121 localplayer
.playermodel_view_slot
);
123 vg_msg_end_frame( &sav
);
125 file
->len
= sav
.cur
.co
;
128 static int skaterift_autosave( int async
){
130 if( !vg_loader_availible() ) return 0;
133 if( world_static
.instances
[k_world_purpose_client
].status
134 == k_world_status_loaded
){
138 vg_linear_clear( vg_async
.buffer
);
139 u32 size
= sizeof(savedata_group
) + sizeof(savedata_file
) * save_files
;
141 savedata_group
*group
;
143 size
= vg_align8( size
);
144 group
= vg_linear_alloc( vg_async
.buffer
, size
);
147 group
= alloca( size
);
149 group
->file_count
= save_files
;
150 skaterift_populate_main_savedata( &group
->files
[0] );
151 skaterift_populate_world_savedata( &group
->files
[1], k_world_purpose_hub
);
153 if( world_static
.instances
[ k_world_purpose_client
].status
154 == k_world_status_loaded
){
155 skaterift_populate_world_savedata( &group
->files
[2],
156 k_world_purpose_client
);
160 vg_loader_start( (void *)savedata_group_write
, group
);
162 savedata_group_write( group
);
167 static void skaterift_autosave_synchronous(void){
168 skaterift_autosave(0);