1009e61285e8cc1367a55e4d4ac09e849a85fa1a
8 #include "vg/vg_loader.h"
11 static void savedata_file_write( savedata_file
*file
){
12 savedata_file
*sav
= file
;
13 FILE *fp
= fopen( sav
->path
, "wb" );
15 fwrite( sav
->buf
, sav
->len
, 1, fp
);
17 vg_success( "savedata written to '%s'\n", sav
->path
);
20 vg_error( "Error writing savedata (%s)\n", sav
->path
);
24 static void savedata_group_write( savedata_group
*group
){
25 for( u32 i
=0; i
<group
->file_count
; i
++ ){
26 savedata_file_write( &group
->files
[i
] );
30 static void savedata_file_read( savedata_file
*file
){
31 FILE *fp
= fopen( file
->path
, "rb" );
33 file
->len
= fread( file
->buf
, 1, sizeof(file
->buf
), fp
);
38 vg_warn( "Error reading savedata (%s)\n", file
->path
);
42 static void skaterift_write_addon_alias( vg_msg
*msg
, const char *key
,
44 if( alias
->workshop_id
)
45 vg_msg_wkvnum( msg
, key
, k_vg_msg_u64
, 1, &alias
->workshop_id
);
47 vg_msg_wkvstr( msg
, key
, alias
->foldername
);
50 static void skaterift_write_viewslot( vg_msg
*msg
, const char *key
,
51 enum addon_type type
, u16 cache_id
){
52 if( !cache_id
) return;
54 struct addon_cache
*cache
= &addon_system
.cache
[type
];
55 addon_cache_entry
*entry
= vg_pool_item( &cache
->pool
, cache_id
);
56 addon_reg
*reg
= entry
->reg_ptr
;
59 skaterift_write_addon_alias( msg
, key
, ®
->alias
);
62 static void skaterift_read_addon_alias( vg_msg
*msg
, const char *key
,
65 alias
->foldername
[0] = '\0';
66 alias
->workshop_id
= 0;
70 if( vg_msg_getkvcmd( msg
, key
, &kv
) ){
71 if( kv
.code
== k_vg_msg_kvstring
){
72 vg_strncpy( kv
.value
, alias
->foldername
, sizeof(alias
->foldername
),
73 k_strncpy_allow_cutoff
);
76 vg_msg_cast( kv
.value
, kv
.code
, &alias
->workshop_id
, k_vg_msg_u64
);
80 static void skaterift_populate_world_savedata( savedata_file
*file
,
81 enum world_purpose which
){
84 addon_reg
*reg
= world_static
.instance_addons
[ which
];
87 vg_error( "Tried to save unspecified world (reg was null)\n" );
91 skaterift_world_get_save_path( which
, file
->path
);
94 vg_msg_init( &sav
, file
->buf
, sizeof(file
->buf
) );
96 world_instance
*instance
= &world_static
.instances
[which
];
97 world_entity_serialize( instance
, &sav
);
99 vg_msg_frame( &sav
, "player" );
101 vg_msg_wkvnum( &sav
, "position", k_vg_msg_float
|k_vg_msg_32b
, 3,
102 (which
== world_static
.active_instance
)?
104 instance
->player_co
);
106 vg_msg_end_frame( &sav
);
108 file
->len
= sav
.cur
.co
;
111 static void skaterift_populate_main_savedata( savedata_file
*file
){
112 strcpy( file
->path
, str_skaterift_main_save
);
115 vg_msg_init( &sav
, file
->buf
, sizeof(file
->buf
) );
116 vg_msg_wkvnum( &sav
, "ach", k_vg_msg_u32
, 1, &skaterift
.achievements
);
118 vg_msg_frame( &sav
, "player" );
120 skaterift_write_viewslot( &sav
, "board", k_addon_type_board
,
121 localplayer
.board_view_slot
);
122 skaterift_write_viewslot( &sav
, "playermodel", k_addon_type_player
,
123 localplayer
.playermodel_view_slot
);
125 vg_msg_end_frame( &sav
);
127 file
->len
= sav
.cur
.co
;
130 static int skaterift_autosave( int async
){
132 if( !vg_loader_availible() ) return 0;
135 if( world_static
.instances
[k_world_purpose_client
].status
136 == k_world_status_loaded
){
140 vg_linear_clear( vg_async
.buffer
);
141 u32 size
= sizeof(savedata_group
) + sizeof(savedata_file
) * save_files
;
143 savedata_group
*group
;
145 size
= vg_align8( size
);
146 group
= vg_linear_alloc( vg_async
.buffer
, size
);
149 group
= alloca( size
);
151 group
->file_count
= save_files
;
152 skaterift_populate_main_savedata( &group
->files
[0] );
153 skaterift_populate_world_savedata( &group
->files
[1], k_world_purpose_hub
);
155 if( world_static
.instances
[ k_world_purpose_client
].status
156 == k_world_status_loaded
){
157 skaterift_populate_world_savedata( &group
->files
[2],
158 k_world_purpose_client
);
162 vg_loader_start( (void *)savedata_group_write
, group
);
164 savedata_group_write( group
);
169 static void skaterift_autosave_synchronous(void){
170 skaterift_autosave(0);