diff --git a/include/libretro.h b/include/libretro.h index cff6206..8255ddf 100644 --- a/include/libretro.h +++ b/include/libretro.h @@ -1047,6 +1047,10 @@ typedef int (RETRO_CALLCONV *retro_vfs_close_t)(struct retro_vfs_file_handle *st * Introduced in VFS API v1 */ typedef int64_t (RETRO_CALLCONV *retro_vfs_size_t)(struct retro_vfs_file_handle *stream); +/* Truncate file to specified size. Returns 0 on success or -1 on error + * Introduced in VFS API v2 */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_truncate_t)(struct retro_vfs_file_handle *stream, int64_t length); + /* Get the current read / write position for the file. Returns - 1 for error. * Introduced in VFS API v1 */ typedef int64_t (RETRO_CALLCONV *retro_vfs_tell_t)(struct retro_vfs_file_handle *stream); @@ -1088,6 +1092,7 @@ struct retro_vfs_interface retro_vfs_flush_t flush; retro_vfs_remove_t remove; retro_vfs_rename_t rename; + retro_vfs_truncate_t truncate; }; struct retro_vfs_interface_info diff --git a/include/streams/file_stream.h b/include/streams/file_stream.h index e10c6b3..d5c0ab0 100644 --- a/include/streams/file_stream.h +++ b/include/streams/file_stream.h @@ -49,6 +49,8 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info); int64_t filestream_get_size(RFILE *stream); +int64_t filestream_truncate(RFILE *stream, int64_t length); + /** * filestream_open: * @path : path to file diff --git a/include/vfs/vfs_implementation.h b/include/vfs/vfs_implementation.h index 047b170..5a1e5c3 100644 --- a/include/vfs/vfs_implementation.h +++ b/include/vfs/vfs_implementation.h @@ -46,6 +46,8 @@ int retro_vfs_file_error_impl(libretro_vfs_implementation_file *stream); int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream); +int64_t retro_vfs_file_truncate_impl(libretro_vfs_implementation_file *stream, int64_t length); + int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream); int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset, int seek_position); diff --git a/streams/file_stream.c b/streams/file_stream.c index 06b587b..680a809 100644 --- a/streams/file_stream.c +++ b/streams/file_stream.c @@ -41,6 +41,7 @@ static retro_vfs_get_path_t filestream_get_path_cb = NULL; static retro_vfs_open_t filestream_open_cb = NULL; static retro_vfs_close_t filestream_close_cb = NULL; static retro_vfs_size_t filestream_size_cb = NULL; +static retro_vfs_truncate_t filestream_truncate_cb = NULL; static retro_vfs_tell_t filestream_tell_cb = NULL; static retro_vfs_seek_t filestream_seek_cb = NULL; static retro_vfs_read_t filestream_read_cb = NULL; @@ -67,6 +68,7 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info) filestream_close_cb = NULL; filestream_tell_cb = NULL; filestream_size_cb = NULL; + filestream_truncate_cb = NULL; filestream_seek_cb = NULL; filestream_read_cb = NULL; filestream_write_cb = NULL; @@ -84,6 +86,7 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info) filestream_open_cb = vfs_iface->open; filestream_close_cb = vfs_iface->close; filestream_size_cb = vfs_iface->size; + filestream_truncate_cb = vfs_iface->truncate; filestream_tell_cb = vfs_iface->tell; filestream_seek_cb = vfs_iface->seek; filestream_read_cb = vfs_iface->read; @@ -127,6 +130,21 @@ int64_t filestream_get_size(RFILE *stream) return output; } +int64_t filestream_truncate(RFILE *stream, int64_t length) +{ + int64_t output; + + if (filestream_truncate_cb != NULL) + output = filestream_truncate_cb(stream->hfile, length); + else + output = retro_vfs_file_truncate_impl((libretro_vfs_implementation_file*)stream->hfile, length); + + if (output == vfs_error_return_value) + stream->error_flag = true; + + return output; +} + /** * filestream_open: * @path : path to file diff --git a/vfs/vfs_implementation.c b/vfs/vfs_implementation.c index ff8100f..36bd57a 100644 --- a/vfs/vfs_implementation.c +++ b/vfs/vfs_implementation.c @@ -380,6 +380,22 @@ int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream) return stream->size; } +int64_t retro_vfs_file_truncate_impl(libretro_vfs_implementation_file *stream, int64_t length) +{ + if (!stream) + return -1; + +#ifdef _WIN32 + if(_chsize(_fileno(stream->fp), length) != 0) + return -1; +#else + if(ftruncate(fileno(stream->fp), length) != 0) + return -1; +#endif + + return 0; +} + int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream) { if (!stream)