6 #include "vg/vg_loader.h"
10 static const char *str_skaterift_main_save
= "save.bkv";
11 static f64 last_autosave
;
13 void savedata_file_write( savedata_file
*file
)
15 savedata_file
*sav
= file
;
16 FILE *fp
= fopen( sav
->path
, "wb" );
18 fwrite( sav
->buf
, sav
->len
, 1, fp
);
20 vg_success( "savedata written to '%s'\n", sav
->path
);
23 vg_error( "Error writing savedata (%s)\n", sav
->path
);
27 void savedata_group_write( savedata_group
*group
)
29 for( u32 i
=0; i
<group
->file_count
; i
++ ){
30 savedata_file_write( &group
->files
[i
] );
34 void savedata_file_read( savedata_file
*file
)
36 FILE *fp
= fopen( file
->path
, "rb" );
38 file
->len
= fread( file
->buf
, 1, sizeof(file
->buf
), fp
);
43 vg_warn( "Error reading savedata (%s)\n", file
->path
);
47 static void skaterift_write_addon_alias( vg_msg
*msg
, const char *key
,
49 if( alias
->workshop_id
)
50 vg_msg_wkvnum( msg
, key
, k_vg_msg_u64
, 1, &alias
->workshop_id
);
52 vg_msg_wkvstr( msg
, key
, alias
->foldername
);
55 static void skaterift_write_viewslot( vg_msg
*msg
, const char *key
,
56 enum addon_type type
, u16 cache_id
){
57 if( !cache_id
) return;
59 struct addon_cache
*cache
= &addon_system
.cache
[type
];
60 addon_cache_entry
*entry
= vg_pool_item( &cache
->pool
, cache_id
);
61 addon_reg
*reg
= entry
->reg_ptr
;
64 skaterift_write_addon_alias( msg
, key
, ®
->alias
);
67 void skaterift_read_addon_alias( vg_msg
*msg
, const char *key
,
71 alias
->foldername
[0] = '\0';
72 alias
->workshop_id
= 0;
76 if( vg_msg_getkvcmd( msg
, key
, &kv
) ){
77 if( kv
.code
== k_vg_msg_kvstring
){
78 vg_strncpy( kv
.value
, alias
->foldername
, sizeof(alias
->foldername
),
79 k_strncpy_allow_cutoff
);
82 vg_msg_cast( kv
.value
, kv
.code
, &alias
->workshop_id
, k_vg_msg_u64
);
86 static void skaterift_populate_world_savedata( savedata_file
*file
,
87 enum world_purpose which
){
90 addon_reg
*reg
= world_static
.instance_addons
[ which
];
93 vg_error( "Tried to save unspecified world (reg was null)\n" );
97 skaterift_world_get_save_path( which
, file
->path
);
100 vg_msg_init( &sav
, file
->buf
, sizeof(file
->buf
) );
102 world_instance
*instance
= &world_static
.instances
[which
];
103 world_entity_serialize( instance
, &sav
);
105 vg_msg_frame( &sav
, "player" );
107 vg_msg_wkvnum( &sav
, "position", k_vg_msg_float
|k_vg_msg_32b
, 3,
108 (which
== world_static
.active_instance
)?
110 instance
->player_co
);
112 vg_msg_end_frame( &sav
);
114 file
->len
= sav
.cur
.co
;
117 static void skaterift_populate_main_savedata( savedata_file
*file
)
119 strcpy( file
->path
, str_skaterift_main_save
);
122 vg_msg_init( &sav
, file
->buf
, sizeof(file
->buf
) );
123 vg_msg_wkvnum( &sav
, "ach", k_vg_msg_u32
, 1, &skaterift
.achievements
);
125 vg_msg_frame( &sav
, "player" );
127 skaterift_write_viewslot( &sav
, "board", k_addon_type_board
,
128 localplayer
.board_view_slot
);
129 skaterift_write_viewslot( &sav
, "playermodel", k_addon_type_player
,
130 localplayer
.playermodel_view_slot
);
132 vg_msg_end_frame( &sav
);
134 file
->len
= sav
.cur
.co
;
137 void skaterift_read_main_savedata( savedata_file
*file
)
139 strcpy( file
->path
, str_skaterift_main_save
);
140 savedata_file_read( file
);
143 int skaterift_autosave( int async
)
146 if( !vg_loader_availible() ) return 0;
149 if( world_static
.instances
[k_world_purpose_client
].status
150 == k_world_status_loaded
){
154 vg_linear_clear( vg_async
.buffer
);
155 u32 size
= sizeof(savedata_group
) + sizeof(savedata_file
) * save_files
;
157 savedata_group
*group
;
159 size
= vg_align8( size
);
160 group
= vg_linear_alloc( vg_async
.buffer
, size
);
163 group
= alloca( size
);
165 group
->file_count
= save_files
;
166 skaterift_populate_main_savedata( &group
->files
[0] );
167 skaterift_populate_world_savedata( &group
->files
[1], k_world_purpose_hub
);
169 if( world_static
.instances
[ k_world_purpose_client
].status
170 == k_world_status_loaded
){
171 skaterift_populate_world_savedata( &group
->files
[2],
172 k_world_purpose_client
);
176 vg_loader_start( (void *)savedata_group_write
, group
);
178 savedata_group_write( group
);
183 void skaterift_autosave_synchronous(void)
185 skaterift_autosave(0);
188 void skaterift_autosave_update(void)
190 if( vg
.time
- last_autosave
> 20.0 ){
191 if( skaterift_autosave(1) ){
192 last_autosave
= vg
.time
;