Add Doxygen-styled comments to parts of the libretro API (#15641)

* Touch up the documentation for a few environment calls

* Touch up more comments

* Update docs for more environment calls

* Add doc comments for more environment calls

* Change various @returns to indicate that the environment call is available

- Some environment calls might be recognized but ignored (e.g. when fast-forwarding during netplay)

* Note some deprecated symbols

* Touch up the docs for RETRO_ENVIRONMENT_SET_MESSAGE

* Touch up the docs for RETRO_ENVIRONMENT_SET_PIXEL_FORMAT

* Add more doc comments

* (libretro) Add more doxygen documentation for the libretro API

* (libretro) Add doxygen comments for the callbacks

* Document retro_init and retro_deinit

* Add comments for retro_log-related symbols

* Add a comment

* Clean up some camera-related comments

* Clean up frame time-related callbacks

* Correct some information about major callbacks

* Clarify some parameter info

* Fix incorrect info about retro_set_environment

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* (libretro) Add doxygen docs on RETRO_THROTTLE

* Touch up the docs for RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK

* Touch up the docs for some macros

* Touch up the docs for some more environment calls

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Tidy up the doc comments for clamping.h

- It was a low-hanging fruit

* Define some sections for constants

- Doxygen will group all contained symbols on one page

* Fix a duplicate @see

* Polish up the docs for the rumble interface

* Polish up the docs for RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Document INLINE

* Clean up some tags

* Touch up the docs for the sensor interface

* Add docs for RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK

* Update docs for RETRO_ENVIRONMENT_GET_INPUT_BITMASKS and accompanying names

* Update some group definitions

* Spiff up the docs for retro_dirent.h

* Document dylib.h

* Document base64.h

* Document crc32.h

* Touch up the docs for audio conversion functions

* Clean up some Doxygen tags

* Refine the docs for RETRO_ENVIRONMENT_GET_PERF_INTERFACE

* Fix incorrect infor in dylib.h

* Touch up the docs for RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE

* Revise the docs for RETRO_ENVIRONMENT_SET_GEOMETRY

* Revise the docs for RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE

* Revise a function's doc

* Touch up most of the rthreads docs

* Touch up the retro_timers.h docs

* Revise the subsystem docs

* Fix some incorrect @see's

* Touch up the docs for RETRO_ENVIRONMENT_GET_LED_INTERFACE

* Give the RETRO_ENVIRONMENT_GET_SAVESTATE_CONTEXT docs a makeover

* Slight cleanup to the microphone docs

* Slight cleanup to the device power docs

* Touch up serialization quirk docs

* Give the MIDI docs a haircut

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Freshen up rtime's docs

* Improve the docs and accompanying definitions for RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE

- Revise the text of the documentation
- Introduce an enum that defines the flags (it's still an int, so ABI compatibility will be fine)
- Move the documentation for each bit to its corresponding enum

* Shine the shoes of RETRO_ENVIRONMENT_GET_INPUT_MAX_USERS's docs

* Freshen up the docs for fifo_queue.h

* Document most of task_queue.h

* Put retro_dirent's symbols in a group

* Finish documenting task_queue.h

* Document some compatibility headers

* Document read_stdin

* Document file_stream_transforms.h

* Document the VFS API

- Not the wrappers, just the plain API itself

* (Docs) Add doxygen notes about RETRO_DEVICE_*

* Fix some line breaks

* Revise RETRO_DEVICE docs

* Document strl.h

* Update the features_cpu.h docs

* Rewrite the docs for file_stream.h

* Update the docs for retro_endianness.h

* Update the docs for retro_miscellaneous.h

* Document the RETRO_VFS_SEEK_POSITION constants

* Finish documenting rthreads.h

* Document network_stream.h

* Put the RETRO_MEMORY defines in a defgroup

* Move a doc comment in retro_common.h to file scope

* Revise the docs for RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, and accompanying symbols

* Fix the @param/in/out order in libretro.h's @param declarations

* Tidy up the docs for RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION

* Spiff up the docs for RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER

* Fix some tags

* Polish up RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE's docs

* libretro: Add header doxygen

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Clean up the docs for RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY

* Clean up the docs for RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE

* Touch up some comment syntax for RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE

* Fix some inaccuracies

* Re-add the license statement for libretro.h

* Touch up the docs for RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2

* Touch up docs for RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY

* Touch up docs for some options-related symbols

* Fix some syntax that was preventing most doc files from being generated

* Express retro_core_option_definition docs in terms of retro_core_option_v2_definition

* Finalize some core option-related docs

* Fix some incorrect info about achievements

* Polish up the docs for RETRO_ENVIRONMENT_SET_MEMORY_MAPS

* Polish up the docs for RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION

* Add a notice for `RETRO_ENVIRONMENT_GET_LOG_INTERFACE`

* Update the disk control interface docs

* Add a sentence to a doc comment

* Update a comment

* Remove an irrelevant @todo

* Touch up the docs for `retro_message_target`

* Touch up the docs for `retro_message_type`

* Touch up the docs for `RETRO_ENVIRONMENT_SET_MESSAGE_EXT`

* Touch up the docs for `RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK`

* Touch up the docs for `RETRO_ENVIRONMENT_SET_MINIMUM_AUDIO_LATENCY`

* Revise a comment

* Revise the docs for `RETRO_ENVIRONMENT_SET_VARIABLE`

* Add a `@see`

* Clean up the `RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE` docs

* Update the Doxyfile

* libretro: Add three more environment callback doxygen docs

* doxygen: Remove @example reference

---------

Co-authored-by: Rob Loach <robloach@gmail.com>
This commit is contained in:
Jesse Talavera 2024-03-09 20:24:01 -05:00 committed by GitHub
parent a417f74476
commit b7ddac2431
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 8039 additions and 3080 deletions

469
Doxyfile
View file

@ -1,4 +1,4 @@
# Doxyfile 1.8.14
# Doxyfile 1.9.1
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@ -17,10 +17,10 @@
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See
# This tag specifies the encoding used for all characters in the configuration
# file that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
# The default value is: UTF-8.
@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = "RetroArch"
PROJECT_NAME = RetroArch
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY =
OUTPUT_DIRECTORY = docs
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@ -93,6 +93,14 @@ ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
@ -187,7 +195,17 @@ SHORT_NAMES = YES
# description.)
# The default value is: NO.
JAVADOC_AUTOBRIEF = NO
JAVADOC_AUTOBRIEF = YES
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
# such as
# /***************
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
# Javadoc-style will behave just like regular comments and it will not be
# interpreted by doxygen.
# The default value is: NO.
JAVADOC_BANNER = NO
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
@ -209,6 +227,14 @@ QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
# By default Python docstrings are displayed as preformatted text and doxygen's
# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
# doxygen's special commands can be used and the contents of the docstring
# documentation blocks is shown as doxygen documentation.
# The default value is: YES.
PYTHON_DOCSTRING = YES
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
# documentation from any documented member that it re-implements.
# The default value is: YES.
@ -238,14 +264,12 @@ TAB_SIZE = 4
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
ALIASES = "setby{1}=@par Set by^^The \1."
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
@ -253,7 +277,7 @@ TCL_SUBST =
# members will be omitted, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored
@ -275,28 +299,40 @@ OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
# sources only. Doxygen will then generate output that is more tailored for that
# language. For instance, namespaces will be presented as modules, types will be
# separated into more groups, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_SLICE = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
# Fortran. In the later case the parser tries to guess whether the code is fixed
# or free formatted code, this is the default for Fortran type files), VHDL. For
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files). For instance to make doxygen treat .inc files
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
# use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen.
# the files are not read by doxygen. When specifying no_extension you should add
# * to the FILE_PATTERNS.
#
# Note see also the list of default file extension mappings.
EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See http://daringfireball.net/projects/markdown/ for details.
# documentation. See https://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
@ -308,7 +344,7 @@ MARKDOWN_SUPPORT = YES
# to that level are automatically included in the table of contents, even if
# they do not have an id attribute.
# Note: This feature currently applies only to Markdown headings.
# Minimum value: 0, maximum value: 99, default value: 0.
# Minimum value: 0, maximum value: 99, default value: 5.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
TOC_INCLUDE_HEADINGS = 0
@ -398,7 +434,7 @@ INLINE_GROUPED_CLASSES = NO
# Man pages) or section (for LaTeX and RTF).
# The default value is: NO.
INLINE_SIMPLE_STRUCTS = NO
INLINE_SIMPLE_STRUCTS = YES
# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
# enum is documented as struct, union, or enum with the name of the typedef. So
@ -424,6 +460,19 @@ TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
# during processing. When set to 0 doxygen will based this on the number of
# cores available in the system. You can set it explicitly to a value larger
# than 0 to get more control over the balance between CPU load and processing
# speed. At this moment only the input processing can be done using multiple
# threads. Since this is still an experimental feature the default is set to 1,
# which efficively disables parallel processing. Please report any issues you
# encounter. Generating dot graphs in parallel is controlled by the
# DOT_NUM_THREADS setting.
# Minimum value: 0, maximum value: 32, default value: 1.
NUM_PROC_THREADS = 16
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@ -442,7 +491,13 @@ EXTRACT_ALL = YES
# be included in the documentation.
# The default value is: NO.
EXTRACT_PRIVATE = YES
EXTRACT_PRIVATE = NO
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
# methods of a class will be included in the documentation.
# The default value is: NO.
EXTRACT_PRIV_VIRTUAL = NO
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.
@ -481,6 +536,13 @@ EXTRACT_LOCAL_METHODS = YES
EXTRACT_ANON_NSPACES = NO
# If this flag is set to YES, the name of an unnamed parameter in a declaration
# will be determined by the corresponding definition. By default unnamed
# parameters remain unnamed in the output.
# The default value is: YES.
RESOLVE_UNNAMED_PARAMS = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
# undocumented members inside documented classes or files. If set to NO these
# members will be included in the various overviews, but no documentation
@ -498,8 +560,8 @@ HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# (class|struct|union) declarations. If set to NO, these declarations will be
# included in the documentation.
# declarations. If set to NO, these declarations will be included in the
# documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
@ -518,11 +580,18 @@ HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
# able to match the capabilities of the underlying filesystem. In case the
# filesystem is case sensitive (i.e. it supports files in the same directory
# whose names only differ in casing), the option must be set to YES to properly
# deal with such files in case they appear in the input. For filesystems that
# are not case sensitive the option should be be set to NO to properly deal with
# output files written for symbols that only differ in casing, such as for two
# classes, one named CLASS and the other named Class, and to also support
# references to files without having to specify the exact matching casing. On
# Windows (including Cygwin) and MacOS, users should typically set this option
# to NO, whereas on Linux or other Unix flavors it should typically be set to
# YES.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
@ -532,7 +601,7 @@ CASE_SENSE_NAMES = YES
# scope will be hidden.
# The default value is: NO.
HIDE_SCOPE_NAMES = NO
HIDE_SCOPE_NAMES = YES
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
# append additional text to a page's title, such as Class Reference. If set to
@ -571,7 +640,7 @@ INLINE_INFO = YES
# name. If set to NO, the members will appear in declaration order.
# The default value is: YES.
SORT_MEMBER_DOCS = YES
SORT_MEMBER_DOCS = NO
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
# descriptions of file, namespace and class members alphabetically by member
@ -754,13 +823,17 @@ WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation.
# parameter documentation, but not about the absence of documentation. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
# at the end of the doxygen process doxygen will return with a non-zero status.
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# The default value is: NO.
WARN_AS_ERROR = NO
@ -791,13 +864,13 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT =
INPUT = libretro-common
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
# possible encodings.
# documentation (see:
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
# The default value is: UTF-8.
INPUT_ENCODING = UTF-8
@ -810,56 +883,17 @@ INPUT_ENCODING = UTF-8
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# read by doxygen.
#
# Note the list of default checked file patterns might differ from the list of
# default file extension mappings.
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
# *.ucf, *.qsf and *.ice.
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.idl \
*.ddl \
*.odl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.cs \
*.d \
*.php \
*.php4 \
*.php5 \
*.phtml \
*.inc \
*.m \
*.markdown \
*.md \
*.mm \
*.dox \
*.py \
*.pyw \
*.f90 \
*.f95 \
*.f03 \
*.f08 \
*.f \
*.for \
*.tcl \
*.vhd \
*.vhdl \
*.ucf \
*.qsf
FILE_PATTERNS = *.h
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
@ -890,7 +924,11 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS =
EXCLUDE_PATTERNS = */libretro-common/rthreads/* \
*/libretro-common/formats/* \
*/libretro-common/crt/* \
*/libretro-common/samples/* \
*/libretro-common/include/glsym/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@ -901,7 +939,9 @@ EXCLUDE_PATTERNS =
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
EXCLUDE_SYMBOLS =
EXCLUDE_SYMBOLS = bool \
void \
const
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
# that contain example code fragments that are included (see the \include
@ -1012,7 +1052,7 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# function all documented functions referencing it will be listed.
# entity all documented functions referencing it will be listed.
# The default value is: NO.
REFERENCED_BY_RELATION = NO
@ -1049,7 +1089,7 @@ SOURCE_TOOLTIPS = YES
#
# To use it do the following:
# - Install the latest version of global
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
@ -1071,6 +1111,44 @@ USE_HTAGS = NO
VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser (see:
# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
# performance. This can be particularly helpful with template rich C++ code for
# which doxygen's built-in parser lacks the necessary type information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to
# YES then doxygen will add the directory of each input to the include path.
# The default value is: YES.
CLANG_ADD_INC_PATHS = YES
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
# the include paths will already be set by doxygen for the files and directories
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
# If clang assisted parsing is enabled you can provide the clang parser with the
# path to the directory containing a file called compile_commands.json. This
# file is the compilation database (see:
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
# options used when the source files were built. This is equivalent to
# specifying the -p option to a clang tool, such as clang-check. These options
# will then be passed to the parser. Any options specified with CLANG_OPTIONS
# will be added as well.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
@ -1082,20 +1160,14 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
# while generating the index headers.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
IGNORE_PREFIX =
IGNORE_PREFIX = retro_ \
RETRO_
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
@ -1227,9 +1299,9 @@ HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via Javascript. If disabled, the navigation index will
# are dynamically created via JavaScript. If disabled, the navigation index will
# consists of multiple levels of tabs that are statically embedded in every HTML
# page. Disable this option to support browsers that do not have Javascript,
# page. Disable this option to support browsers that do not have JavaScript,
# like the Qt help browser.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
@ -1259,13 +1331,14 @@ HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see: https://developer.apple.com/tools/xcode/), introduced with
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# environment (see:
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
# create a documentation set, doxygen will generate a Makefile in the HTML
# output directory. Running make will produce the docset in that directory and
# running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
# genXcode/_index.html for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@ -1304,8 +1377,8 @@ DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
# (see:
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
@ -1335,7 +1408,7 @@ CHM_FILE =
HHC_LOCATION =
# The GENERATE_CHI flag controls if a separate .chi index file is generated
# (YES) or that it should be included in the master .chm file (NO).
# (YES) or that it should be included in the main .chm file (NO).
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
@ -1380,7 +1453,8 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace).
# (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@ -1388,7 +1462,8 @@ QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders).
# Folders (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@ -1396,28 +1471,30 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes).
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
# The QHG_LOCATION tag can be used to specify the location of Qt's
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
# generated .qhp file.
# The QHG_LOCATION tag can be used to specify the location (absolute path
# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
# run qhelpgenerator on the generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHG_LOCATION =
@ -1468,7 +1545,7 @@ DISABLE_INDEX = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO
GENERATE_TREEVIEW = YES
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
@ -1494,6 +1571,17 @@ TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
# the HTML output. These images will generally look nicer at scaled resolutions.
# Possible values are: png (the default) and svg (looks nicer but requires the
# pdf2svg or inkscape tool).
# The default value is: png.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FORMULA_FORMAT = png
# Use this tag to change the font size of LaTeX formulas included as images in
# the HTML documentation. When you change the font size after a successful
# doxygen run you need to manually remove any form_*.png images from the HTML
@ -1514,8 +1602,14 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details.
FORMULA_MACROFILE =
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# https://www.mathjax.org) which uses client side Javascript for the rendering
# https://www.mathjax.org) which uses client side JavaScript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
@ -1527,7 +1621,7 @@ USE_MATHJAX = NO
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
# http://docs.mathjax.org/en/latest/output.html) for more details.
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# The default value is: HTML-CSS.
@ -1543,7 +1637,7 @@ MATHJAX_FORMAT = HTML-CSS
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/.
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/
@ -1557,7 +1651,8 @@ MATHJAX_EXTENSIONS =
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
# (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
@ -1585,7 +1680,7 @@ MATHJAX_CODEFILE =
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There
# implemented using a web server instead of a web client using JavaScript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
# setting. When disabled, doxygen will generate a PHP script for searching and
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
@ -1604,7 +1699,8 @@ SERVER_BASED_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: https://xapian.org/).
# Xapian (see:
# https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@ -1617,8 +1713,9 @@ EXTERNAL_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: https://xapian.org/). See the section "External Indexing and
# Searching" for details.
# Xapian (see:
# https://xapian.org/). See the section "External Indexing and Searching" for
# details.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHENGINE_URL =
@ -1669,21 +1766,35 @@ LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked.
#
# Note that when enabling USE_PDFLATEX this option is only used for generating
# bitmaps for formulas in the HTML output, but not in the Makefile that is
# written to the output directory.
# The default file is: latex.
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
# chosen this is overwritten by pdflatex. For specific output languages the
# default can have been set differently, this depends on the implementation of
# the output language.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
# index for LaTeX.
# Note: This tag is used in the Makefile / make.bat.
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
# (.tex).
# The default file is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
MAKEINDEX_CMD_NAME = makeindex
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
# generate index for LaTeX. In case there is no backslash (\) as first character
# it will be automatically added in the LaTeX code.
# Note: This tag is used in the generated output file (.tex).
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
# The default value is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_MAKEINDEX_CMD = makeindex
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some
# trees in general.
@ -1768,9 +1879,11 @@ LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
# the PDF file directly from the LaTeX files. Set this option to YES, to get a
# higher quality PDF documentation.
# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
# files. Set this option to YES, to get a higher quality PDF documentation.
#
# See also section LATEX_CMD_NAME for selecting the engine.
# The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@ -1818,6 +1931,14 @@ LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the
# LATEX_OUTPUT directory will be used.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@ -1857,9 +1978,9 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
# file, i.e. a series of assignments. You only have to provide replacements,
# missing definitions are set to their default value.
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# configuration file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
#
# See also section "Doxygen usage" for information on how to generate the
# default style sheet that doxygen normally uses.
@ -1868,8 +1989,8 @@ RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's config file. A template extensions file can be generated
# using doxygen -e rtf extensionFile.
# similar to doxygen's configuration file. A template extensions file can be
# generated using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
@ -1955,6 +2076,13 @@ XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
# namespace members in file scope as well, matching the HTML output.
# The default value is: NO.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
@ -1994,6 +2122,10 @@ DOCBOOK_PROGRAMLISTING = NO
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to Sqlite3 output
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
@ -2089,7 +2221,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED =
PREDEFINED = DOXYGEN
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@ -2156,12 +2288,6 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of 'which perl').
# The default file (with absolute path) is: /usr/bin/perl.
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
@ -2173,16 +2299,7 @@ PERL_PATH = /usr/bin/perl
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
CLASS_DIAGRAMS = NO
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
@ -2202,9 +2319,9 @@ HIDE_UNDOC_RELATIONS = YES
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: NO.
# The default value is: YES.
HAVE_DOT = YES
HAVE_DOT = NO
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
@ -2281,10 +2398,32 @@ UML_LOOK = NO
# but if the number exceeds 15, the total amount of fields shown is limited to
# 10.
# Minimum value: 0, maximum value: 100, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
# This tag requires that the tag UML_LOOK is set to YES.
UML_LIMIT_NUM_FIELDS = 10
# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
# tag is set to YES, doxygen will add type and arguments for attributes and
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
# will not generate fields with class member information in the UML graphs. The
# class diagrams will look similar to the default class diagrams but using UML
# notation for the relationships.
# Possible values are: NO, YES and NONE.
# The default value is: NO.
# This tag requires that the tag UML_LOOK is set to YES.
DOT_UML_DETAILS = NO
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
# to display on a single line. If the actual line length exceeds this threshold
# significantly it will wrapped across multiple lines. Some heuristics are apply
# to avoid ugly line breaks.
# Minimum value: 0, maximum value: 1000, default value: 17.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_WRAP_THRESHOLD = 17
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
# collaboration graphs will show the relations between templates and their
# instances.
@ -2358,7 +2497,9 @@ DIRECTORY_GRAPH = YES
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
# png:gdiplus:gdiplus.
# The default value is: png.
@ -2474,9 +2615,11 @@ DOT_MULTI_TARGETS = YES
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
# files that are used to generate the various graphs.
#
# Note: This setting is not only used for dot files but also for msc and
# plantuml temporary files.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_CLEANUP = YES

View file

@ -150,13 +150,6 @@ static int ra_clock_gettime(int clk_ik, struct timespec *t)
#include <string.h>
/**
* cpu_features_get_perf_counter:
*
* Gets performance counter.
*
* @return Performance counter.
**/
retro_perf_tick_t cpu_features_get_perf_counter(void)
{
retro_perf_tick_t time_ticks = 0;
@ -218,13 +211,6 @@ retro_perf_tick_t cpu_features_get_perf_counter(void)
return time_ticks;
}
/**
* cpu_features_get_time_usec:
*
* Gets time in microseconds.
*
* @return Time in microseconds.
**/
retro_time_t cpu_features_get_time_usec(void)
{
#if defined(_WIN32)
@ -503,13 +489,6 @@ static void cpulist_read_from(CpuList* list, const char* filename)
#endif
/**
* cpu_features_get_core_amount:
*
* Gets the amount of available CPU cores.
*
* @return Amount of CPU cores available.
**/
unsigned cpu_features_get_core_amount(void)
{
#if defined(_WIN32) && !defined(_XBOX)
@ -609,13 +588,6 @@ unsigned cpu_features_get_core_amount(void)
#define VENDOR_INTEL_c 0x6c65746e
#define VENDOR_INTEL_d 0x49656e69
/**
* cpu_features_get:
*
* Gets CPU features..
*
* @return Bitmask of all CPU features available.
**/
uint64_t cpu_features_get(void)
{
uint64_t cpu = 0;

View file

@ -31,22 +31,28 @@ RETRO_BEGIN_DECLS
#include <stddef.h>
/**
* convert_float_to_s16:
* @out : output buffer
* @in : input buffer
* @samples : size of samples to be converted
* Converts an array of floating-point audio samples
* to signed integer 16-bit audio samples,
* possibly using SIMD intrinsics.
*
* Converts floating point
* to signed integer 16-bit.
* @param out The buffer that will be used to store the converted samples.
* @param in The buffer containing the samples to convert.
* Any number of channels is supported.
* @param samples The length of \c in in samples, \em not bytes or frames.
* \c out must be as large as <tt>sizeof(int16_t) * samples</tt>.
* @see convert_s16_to_float
**/
void convert_float_to_s16(int16_t *out,
const float *in, size_t samples);
/**
* convert_float_to_s16_init_simd:
* Initializes any prerequisites for
* using SIMD implementations of \c convert_float_to_s16.
*
* Sets up function pointers for conversion
* functions based on CPU features.
* If SIMD intrinsics are not available or no initialization is required,
* this function does nothing.
*
* @see convert_float_to_s16
**/
void convert_float_to_s16_init_simd(void);

View file

@ -30,23 +30,30 @@
RETRO_BEGIN_DECLS
/**
* convert_s16_to_float:
* @out : output buffer
* @in : input buffer
* @samples : size of samples to be converted
* @gain : gain applied (.e.g. audio volume)
* Converts an array of signed integer 16-bit audio samples
* to floating-point format,
* possibly using SIMD intrinsics.
*
* Converts from signed integer 16-bit
* to floating point.
* @param out The buffer that will be used to store the converted samples.
* @param in The buffer containing the samples to convert.
* Any number of channels is supported.
* @param samples The length of \c in in samples, \em not bytes or frames.
* \c out must be as large as <tt>sizeof(float) * samples</tt>.
* @param gain The gain (audio volume) to apply to the samples.
* Pass a value of 1.0 to not apply any gain.
* @see convert_float_to_s16
**/
void convert_s16_to_float(float *out,
const int16_t *in, size_t samples, float gain);
/**
* convert_s16_to_float_init_simd:
* Initializes any prerequisites for
* using SIMD implementations of \c convert_s16_to_float.
*
* Sets up function pointers for conversion
* functions based on CPU features.
* If SIMD intrinsics are not available or no initialization is required,
* this function does nothing.
*
* @see convert_s16_to_float
**/
void convert_s16_to_float_init_simd(void);

View file

@ -27,14 +27,13 @@
#include <retro_inline.h>
/**
* clamp_float:
* @val : initial value
* @lower : lower limit that value should be clamped against
* @upper : upper limit that value should be clamped against
* Clamps a floating-point value to the specified range.
*
* Clamps a floating point value.
* @param val The value to clamp.
* @param lower The minimum possible value.
* @param upper The maximum possible value.
*
* Returns: a clamped value of initial float value @val.
* @returns \c val clamped to between \c lower and \c upper (inclusive).
*/
static INLINE float clamp_float(float val, float lower, float upper)
{
@ -46,12 +45,10 @@ static INLINE float clamp_float(float val, float lower, float upper)
}
/**
* clamp_8bit:
* @val : initial value
* Clamps an integer to fit in 8 bits.
*
* Clamps an unsigned 8-bit value.
*
* Returns: a clamped value of initial unsigned 8-bit value @val.
* @param val The value to clamp.
* @return \c val clamped to between 0 and 255 (inclusive).
*/
static INLINE uint8_t clamp_8bit(int val)
{

View file

@ -25,6 +25,11 @@
#define FNM_NOMATCH 1
/**
* Portable implementation of \c fnmatch(3),
* except \c flags is not implemented.
* @see https://man7.org/linux/man-pages/man3/fnmatch.3.html
*/
int rl_fnmatch(const char *pattern, const char *string, int flags);
#endif

View file

@ -27,9 +27,17 @@
#include "../../../config.h"
#endif
/* Custom implementation of the GNU getopt_long for portability.
* Not designed to be fully compatible, but compatible with
* the features RetroArch uses. */
/**
* @file getopt.h
*
* Portable reimplementation of a subset of libc's \c getopt_long.
* Not designed to be fully compatible,
* but it's enough for RetroArch's purposes.
*
* If \c getopt_long is available (as determined by \c HAVE_GETOPT_LONG), it will be used instead.
*
* @see https://man7.org/linux/man-pages/man3/getopt.3.html
*/
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>

View file

@ -47,7 +47,20 @@ struct ifaddrs
#include <sys/cdefs.h>
/**
* Portable reimplementation of \c getifaddrs().
* The original function will be used if it's available.
*
* @see https://man7.org/linux/man-pages/man3/getifaddrs.3.html
*/
extern int getifaddrs(struct ifaddrs **ifap);
/**
* Portable reimplementation of \c freeifaddrs().
* The original function will be used if it's available.
*
* @see https://man7.org/linux/man-pages/man3/getifaddrs.3.html
*/
extern void freeifaddrs(struct ifaddrs *ifa);
#endif

View file

@ -38,7 +38,13 @@
RETRO_BEGIN_DECLS
/* Count Leading Zero, unsigned 16bit input value */
/**
* Counts the leading zero bits in a \c uint16_t.
* Uses compiler intrinsics if available, or a standard C implementation if not.
*
* @param val Value to count leading zeroes in.
* @return Number of leading zeroes in \c val.
*/
static INLINE unsigned compat_clz_u16(uint16_t val)
{
#if defined(__GNUC__)
@ -56,7 +62,13 @@ static INLINE unsigned compat_clz_u16(uint16_t val)
#endif
}
/* Count Trailing Zero */
/**
* Counts the trailing zero bits in a \c uint16_t.
* Uses compiler intrinsics if available, or a standard C implementation if not.
*
* @param val Value to count trailing zeroes in.
* @return Number of trailing zeroes in \c val.
*/
static INLINE int compat_ctz(unsigned x)
{
#if defined(__GNUC__) && !defined(RARCH_CONSOLE)

View file

@ -25,31 +25,64 @@
#include <retro_common_api.h>
/**
* @file posix_string.h
*
* Portable reimplementations of various string functions
* that are normally provided by libc or POSIX.
*/
#ifdef _MSC_VER
#include <compat/msvc.h>
#endif
RETRO_BEGIN_DECLS
#ifdef _WIN32
#if defined(_WIN32) || defined(DOXYGEN)
#undef strtok_r
#define strtok_r(str, delim, saveptr) retro_strtok_r__(str, delim, saveptr)
/**
* Portable reimplementation of \c strtok_r().
* The original function will be used if it's available.
*
* @see https://man7.org/linux/man-pages/man3/strtok.3.html
*/
char *strtok_r(char *str, const char *delim, char **saveptr);
#endif
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(DOXYGEN)
#undef strcasecmp
#undef strdup
#define strcasecmp(a, b) retro_strcasecmp__(a, b)
#define strdup(orig) retro_strdup__(orig)
/**
* Portable reimplementation of \c strcasecmp().
* The original function will be used if it's available.
*
* @see https://man7.org/linux/man-pages/man3/strcasecmp.3.html
*/
int strcasecmp(const char *a, const char *b);
/**
* Portable reimplementation of \c strdup().
* The original function will be used if it's available.
*
* @see https://man7.org/linux/man-pages/man3/strdup.3.html
*/
char *strdup(const char *orig);
/* isblank is available since MSVC 2013 */
#if _MSC_VER < 1800
#undef isblank
#define isblank(c) retro_isblank__(c)
/**
* Portable reimplementation of \c isblank().
* The original function will be used if it's available.
*
* @see https://en.cppreference.com/w/c/string/byte/isblank
*/
int isblank(int c);
#endif

View file

@ -39,6 +39,14 @@ RETRO_BEGIN_DECLS
* since we prefer to use the actual name. */
#define strcasestr(haystack, needle) strcasestr_retro__(haystack, needle)
/**
* Portable reimplementation of \c strcasestr(3).
* If the original function is available
* (as determined by the presence of \c HAVE_STRCASESTR),
* it will be used instead.
*
* @see https://man7.org/linux/man-pages/man3/strstr.3.html
*/
char *strcasestr(const char *haystack, const char *needle);
RETRO_END_DECLS

View file

@ -23,6 +23,15 @@
#ifndef __LIBRETRO_SDK_COMPAT_STRL_H
#define __LIBRETRO_SDK_COMPAT_STRL_H
/**
* @file strl.h
*
* Portable implementation of \c strlcpy(3) and \c strlcat(3).
* If these functions are available on the target platform,
* then the originals should be imported instead.
*
* @see https://linux.die.net/man/3/strlcpy
*/
#include <string.h>
#include <stddef.h>
@ -47,11 +56,29 @@ RETRO_BEGIN_DECLS
#define strlcat(dst, src, size) strlcat_retro__(dst, src, size)
/**
* @brief Portable implementation of \c strlcpy(3).
* @see https://linux.die.net/man/3/strlcpy
*/
size_t strlcpy(char *dest, const char *source, size_t size);
/**
* @brief Portable implementation of \c strlcat(3).
* @see https://linux.die.net/man/3/strlcpy
*/
size_t strlcat(char *dest, const char *source, size_t size);
#endif
/**
* A version of \c strndup(3) that guarantees the result will be null-terminated.
*
* @param s The string to duplicate.
* @param n The maximum number of characters to copy from \c s.
* The result will allocate one more byte than this value.
* @return Pointer to the cloned string.
* Must be freed with \c free().
*/
char *strldup(const char *s, size_t n);
RETRO_END_DECLS

View file

@ -39,30 +39,79 @@
RETRO_BEGIN_DECLS
/**
* Opaque handle to a dynamic library.
* @see dylib_load
*/
typedef void *dylib_t;
/**
* Opaque handle to a function exposed by a dynamic library.
*
* Should be cast to a known function pointer type before being used.
* @see dylib_proc
*/
typedef void (*function_t)(void);
#ifdef NEED_DYNAMIC
/**
* dylib_load:
* @path : Path to libretro core library.
* Loads a dynamic library in a platform-independent manner.
*
* Platform independent dylib loading.
* @param path Path to the library to load.
* May be either a complete path or a filename without an extension.
* If not a complete path, the operating system will search for a library by this name;
* details will depend on the platform.
* @note The returned library must be freed with \c dylib_close
* before the core or frontend exits.
*
* @return Library handle on success, otherwise NULL.
* @return Handle to the loaded library, or \c NULL on failure.
* Upon failure, \c dylib_error may be used
* to retrieve a string describing the error.
* @see dylib_close
* @see dylib_error
* @see dylib_proc
**/
dylib_t dylib_load(const char *path);
/**
* dylib_close:
* @lib : Library handle.
* Frees the resources associated with a dynamic library.
*
* Frees library handle.
* Any function pointers obtained from the library may become invalid,
* depending on whether the operating system manages reference counts to dynamic libraries.
*
* If there was an error closing the library,
* it will be reported by \c dylib_error.
*
* @param lib Handle to the library to close.
* Behavior is undefined if \c NULL.
**/
void dylib_close(dylib_t lib);
/**
* Returns a string describing the most recent error that occurred
* within the other \c dylib functions.
*
* @return Pointer to the most recent error string,
* \c or NULL if there was no error.
* @warning The returned string is only valid
* until the next call to a \c dylib function.
* Additionally, the string is managed by the library
* and should not be modified or freed by the caller.
*/
char *dylib_error(void);
/**
* Returns a pointer to a function exposed by a dynamic library.
*
* @param lib The library to get a function pointer from.
* @param proc The name of the function to get a pointer to.
* @return Pointer to the requested function,
* or \c NULL if there was an error.
* This must be cast to the correct function pointer type before being used.
* @warning The returned pointer is only valid for the lifetime of \c lib.
* Once \c lib is closed, all function pointers returned from it will be invalidated;
* using them is undefined behavior.
*/
function_t dylib_proc(dylib_t lib, const char *proc);
#endif

View file

@ -8,7 +8,29 @@
RETRO_BEGIN_DECLS
/**
* Encodes binary data into a \c NULL-terminated base64 string.
*
* @param binaryData The data to encode.
* Behavior is undefined if \c NULL.
* @param len The length of the data to encode.
* @param flen Pointer to the length of the returned string.
* @return Pointer to the base64-encoded string, or \c NULL on failure.
* The returned string is owned by the caller and must be released with \c free().
* @see unbase64
*/
char* base64(const void* binaryData, int len, int *flen);
/**
* Decodes a base64-encoded string into binary data.
*
* @param ascii The base64 string to decode, in ASCII format.
* @param len Length of the string to decode.
* @param flen Pointer to the length of the returned data.
* @return The decoded binary data, or \c NULL on failure.
* The returned buffer is owned by the caller and must be released with \c free().
* @see base64
*/
unsigned char* unbase64(const char* ascii, int len, int *flen);
RETRO_END_DECLS

View file

@ -30,6 +30,14 @@
RETRO_BEGIN_DECLS
/**
* Computes a buffer's CRC32 checksum.
*
* @param crc The initial CRC32 value.
* @param buf The buffer to calculate the CRC32 checksum of.
* @param len The length of the data in \c buf.
* @return The CRC32 checksum of the given buffer.
*/
uint32_t encoding_crc32(uint32_t crc, const uint8_t *buf, size_t len);
RETRO_END_DECLS

View file

@ -32,42 +32,62 @@
RETRO_BEGIN_DECLS
/**
* cpu_features_get_perf_counter:
* Gets the time in ticks since some unspecified epoch.
* The notion of a "tick" varies per platform.
*
* Gets performance counter.
* The epoch may change between devices or across reboots.
*
* @return Performance counter.
**/
* Suitable for use as a default implementation of \c retro_perf_callback::get_perf_counter,
* (or as a fallback by the core),
* although a frontend may provide its own implementation.
*
* @return The current time, in ticks.
* @see retro_perf_callback::get_perf_counter
*/
retro_perf_tick_t cpu_features_get_perf_counter(void);
/**
* cpu_features_get_time_usec:
* Gets the time in microseconds since some unspecified epoch.
*
* Gets time in microseconds, from an undefined epoch.
* The epoch may change between computers or across reboots.
* The epoch may change between devices or across reboots.
*
* @return Time in microseconds
**/
* Suitable for use as a default implementation of \c retro_perf_callback::get_time_usec,
* (or as a fallback by the core),
* although a frontend may provide its own implementation.
*
* @return The current time, in microseconds.
* @see retro_perf_callback::get_time_usec
*/
retro_time_t cpu_features_get_time_usec(void);
/**
* cpu_features_get:
* Returns the available features (mostly SIMD extensions)
* supported by this CPU.
*
* Gets CPU features.
* Suitable for use as a default implementation of \c retro_perf_callback::get_time_usec,
* (or as a fallback by the core),
* although a frontend may provide its own implementation.
*
* @return Bitmask of all CPU features available.
**/
* @see RETRO_SIMD
* @see retro_perf_callback::get_cpu_features
*/
uint64_t cpu_features_get(void);
/**
* cpu_features_get_core_amount:
*
* Gets the amount of available CPU cores.
*
* @return Amount of CPU cores available.
**/
* @return The number of CPU cores available,
* or 1 if the number of cores could not be determined.
*/
unsigned cpu_features_get_core_amount(void);
/**
* Returns the name of the CPU model.
*
* @param[out] name Pointer to a buffer to store the name.
* Will be \c NULL-terminated.
* If \c NULL, this value will not be modified.
* @param len The amount of space available in \c name.
*/
void cpu_features_get_model_name(char *name, int len);
RETRO_END_DECLS

File diff suppressed because it is too large Load diff

View file

@ -33,14 +33,39 @@
RETRO_BEGIN_DECLS
/**
* Returns the available data in \c buffer for reading.
*
* @param buffer <tt>fifo_buffer_t *</tt>. The FIFO queue to check.
* @return The number of bytes available for reading from \c buffer.
*/
#define FIFO_READ_AVAIL(buffer) (((buffer)->end + (((buffer)->end < (buffer)->first) ? (buffer)->size : 0)) - (buffer)->first)
/**
* Returns the available space in \c buffer for writing.
*
* @param buffer <tt>fifo_buffer_t *</tt>. The FIFO queue to check.
* @return The number of bytes that \c buffer can accept.
*/
#define FIFO_WRITE_AVAIL(buffer) (((buffer)->size - 1) - (((buffer)->end + (((buffer)->end < (buffer)->first) ? (buffer)->size : 0)) - (buffer)->first))
/**
* Returns the available data in \c buffer for reading.
*
* @param buffer \c fifo_buffer_t. The FIFO queue to check.
* @return The number of bytes available for reading from \c buffer.
*/
#define FIFO_READ_AVAIL_NONPTR(buffer) (((buffer).end + (((buffer).end < (buffer).first) ? (buffer).size : 0)) - (buffer).first)
/**
* Returns the available space in \c buffer for writing.
*
* @param buffer \c fifo_buffer_t. The FIFO queue to check.
* @return The number of bytes that \c buffer can accept.
*/
#define FIFO_WRITE_AVAIL_NONPTR(buffer) (((buffer).size - 1) - (((buffer).end + (((buffer).end < (buffer).first) ? (buffer).size : 0)) - (buffer).first))
/** @copydoc fifo_buffer_t */
struct fifo_buffer
{
uint8_t *buffer;
@ -49,24 +74,94 @@ struct fifo_buffer
size_t end;
};
/**
* A bounded FIFO byte queue implemented as a ring buffer.
*
* Useful for communication between threads,
* although the caller is responsible for synchronization.
*/
typedef struct fifo_buffer fifo_buffer_t;
/**
* Creates a new FIFO queue with \c size bytes of memory.
* Must be freed with \c fifo_free.
*
* @param size The size of the FIFO queue, in bytes.
* @return The new queue if successful, \c NULL otherwise.
* @see fifo_initialize
*/
fifo_buffer_t *fifo_new(size_t size);
/**
* Initializes an existing FIFO queue with \c size bytes of memory.
*
* Suitable for use with \c fifo_buffer_t instances
* of static or automatic lifetime.
* Must be freed with \c fifo_deinitialize.
*
* @param buf Pointer to the FIFO queue to initialize.
* May be static or automatic.
* @param size The size of the FIFO queue, in bytes.
* @return \c true if \c buf was initialized with the requested memory,
* \c false if \c buf is \c NULL or there was an error.
*/
bool fifo_initialize(fifo_buffer_t *buf, size_t size);
/**
* Resets the bounds of \c buffer,
* effectively clearing it.
*
* No memory will actually be freed,
* but the contents of \c buffer will be overwritten
* with the next call to \c fifo_write.
* @param buffer The FIFO queue to clear.
* Behavior is undefined if \c NULL.
*/
static INLINE void fifo_clear(fifo_buffer_t *buffer)
{
buffer->first = 0;
buffer->end = 0;
}
/**
* Writes \c size bytes to the given queue.
*
* @param buffer The FIFO queue to write to.
* @param in_buf The buffer to read bytes from.
* @param size The length of \c in_buf, in bytes.
*/
void fifo_write(fifo_buffer_t *buffer, const void *in_buf, size_t size);
/**
* Reads \c size bytes from the given queue.
*
* @param buffer The FIFO queue to read from.
* @param in_buf The buffer to store the read bytes in.
* @param size The length of \c in_buf, in bytes.
* @post Upon return, \c buffer will have up to \c size more bytes of space available for writing.
*/
void fifo_read(fifo_buffer_t *buffer, void *in_buf, size_t size);
/**
* Releases \c buffer and its contents.
*
* @param buffer The FIFO queue to free.
* If \c NULL, this function will do nothing.
* Behavior is undefined if \c buffer was previously freed.
* @see fifo_deinitialize
*/
void fifo_free(fifo_buffer_t *buffer);
/**
* Deallocates the contents of \c buffer,
* but not \c buffer itself.
*
* Suitable for use with static or automatic \c fifo_buffer_t instances.
*
* @param buffer The buffer to deinitialize.
* @return \c false if \c buffer is \c NULL, \c true otherwise.
* @see fifo_free
*/
bool fifo_deinitialize(fifo_buffer_t *buffer);

View file

@ -36,10 +36,12 @@ RETRO_BEGIN_DECLS
enum task_type
{
/** A regular task. The vast majority of tasks will use this type. */
TASK_TYPE_NONE,
/* Only one blocking task can exist in the queue at a time.
* Attempts to add a new one while another is running is
* ignored.
/**
* Only one blocking task can exist in the queue at a time.
* Attempts to add a new one while another is running will fail.
*/
TASK_TYPE_BLOCKING
};
@ -52,21 +54,38 @@ enum task_style
};
typedef struct retro_task retro_task_t;
/** @copydoc retro_task::callback */
typedef void (*retro_task_callback_t)(retro_task_t *task,
void *task_data,
void *user_data, const char *error);
/** @copydoc retro_task::handler */
typedef void (*retro_task_handler_t)(retro_task_t *task);
/** @copydoc task_finder_data::func */
typedef bool (*retro_task_finder_t)(retro_task_t *task,
void *userdata);
/**
* Displays a message output by a task.
*/
typedef void (*retro_task_queue_msg_t)(retro_task_t *task,
const char *msg,
unsigned prio, unsigned duration, bool flush);
/** @copydoc task_retriever_data::func */
typedef bool (*retro_task_retriever_t)(retro_task_t *task, void *data);
/**
* Called by \c task_queue_wait after each task executes
* (i.e. once per pass over the queue).
* @param data Arbitrary data.
* The function should cast this to a known type.
* @return \c true if \c task_queue_wait should continue waiting,
* \c false if it should return early.
* @see task_queue_wait
*/
typedef bool (*retro_task_condition_fn_t)(void *data);
typedef struct
@ -74,195 +93,652 @@ typedef struct
char *source_file;
} decompress_task_data_t;
/**
* A unit of work executed by the task system,
* spread across one or more frames.
*
* Some fields are set by the caller,
* others are set by the task system.
*/
struct retro_task
{
/* when the task should run (0 for as soon as possible) */
/**
* The time (in microseconds) when the task should start running,
* or 0 if it should start as soon as possible.
* The exact time this task starts will depend on when the queue is next updated.
* Set by the caller.
* @note This is a point in time, not a duration.
* It is not affected by a frontend's time manipulation (pausing, fast-forward, etc.).
* @see cpu_features_get_time_usec
*/
retro_time_t when;
/**
* The main body of work for a task.
* Should be as fast as possible,
* as it will be called with each task queue update
* (usually once per frame).
* Must not be \c NULL.
*
* @param task The task that this handler is associated with.
* Can be used to configure or query the task.
* Will never be \c NULL.
* @see task_queue_check
*/
retro_task_handler_t handler;
/* always called from the main loop */
/**
* Called when this task finishes;
* executed during the next task queue update
* after \c finished is set to \c true.
* May be \c NULL, in which case this function is skipped.
*
* @param task The task that is being cleaned up.
* Will never be \c NULL.
* @param task_data \c task's \c task_data field.
* @param user_data \c task's \c user_data field.
* @param error \c task's \c error field.
* @see task_queue_check
* @see retro_task_callback_t
*/
retro_task_callback_t callback;
/* task cleanup handler to free allocated resources, will
* be called immediately after running the main callback */
/**
* Called when this task finishes immediately after \c callback is run.
* Used to clean up any resources or state owned by the task.
* May be \c NULL, in which case this function is skipped.
*
* @param task The task that is being cleaned up.
* Will never be \c NULL.
*/
retro_task_handler_t cleanup;
/* created by the handler, destroyed by the user */
/**
* Pointer to arbitrary data, intended for "returning" an object from the task
* (although it can be used for any purpose).
* If owned by the task, it should be cleaned up within \c cleanup.
* Not modified or freed by the task queue.
*/
void *task_data;
/* owned by the user */
/**
* Pointer to arbitrary data, intended for passing parameters to the task.
* If owned by the task, it should be cleaned up within \c cleanup.
* Not modified or freed by the task queue.
*/
void *user_data;
/* created and destroyed by the code related to the handler */
/**
* Pointer to arbitrary data, intended for state that exists for the task's lifetime.
* If owned by the task, it should be cleaned up within \c cleanup.
* Not modified or freed by the task queue.
*/
void *state;
/* created by task handler; destroyed by main loop
* (after calling the callback) */
/**
* Human-readable details about an error that occurred while running the task.
* Should be created and assigned within \c handler if there was an error.
* Will be cleaned up by the task queue with \c free() upon this task's completion.
* @see task_set_error
*/
char *error;
/**
* Called to update a task's \c progress,
* or to update some view layer (e.g. an on-screen display)
* about the task's progress.
*
* Skipped if \c NULL or if \c mute is set.
*
* @param task The task whose progress is being updated or reported.
* @see progress
*/
void (*progress_cb)(retro_task_t*);
/* handler can modify but will be
* free()d automatically if non-NULL. */
/**
* Human-readable description of this task.
* May be \c NULL,
* but if not then it will be disposed of by the task system with \c free()
* upon this task's completion.
* Can be modified or replaced at any time.
* @see strdup
*/
char *title;
/* frontend userdata
* (e.g. associate a sticky notification to a task) */
/**
* Pointer to arbitrary data, intended for use by a frontend
* (for example, to associate a sticky notification with a task).
*
* This should be cleaned up within \c cleanup if necessary.
* Cores may use this for any purpose.
*/
void *frontend_userdata;
/* don't touch this. */
/**
* @private Pointer to the next task in the queue.
* Do not touch this; it is managed by the task system.
*/
retro_task_t *next;
/* -1 = unmetered/indeterminate, 0-100 = current progress percentage */
/**
* Indicates the current progress of the task.
*
* -1 means the task is indefinite or not measured,
* 0-100 is a percentage of the task's completion.
*
* Set by the caller.
*
* @see progress_cb
*/
int8_t progress;
/* task identifier */
/**
* A unique identifier assigned to a task when it's created.
* Set by the task system.
*/
uint32_t ident;
/**
* The type of task this is.
* Set by the caller.
*/
enum task_type type;
enum task_style style;
/* if set to true, frontend will
use an alternative look for the
task progress display */
/**
* If \c true, the frontend should use some alternative means
* of displaying this task's progress or messages.
* Not used within cores.
*/
bool alternative_look;
/* set to true by the handler to signal
* the task has finished executing. */
/**
* Set to \c true by \c handler to indicate that this task has finished.
* At this point the task queue will call \c callback and \c cleanup,
* then deallocate the task.
*/
bool finished;
/* set to true by the task system
* to signal the task *must* end. */
/**
* Set to true by the task queue to signal that this task \em must end.
* \c handler should check to see if this is set,
* aborting or completing its work as soon as possible afterward.
* \c callback and \c cleanup will still be called as normal.
*
* @see task_queue_reset
*/
bool cancelled;
/* if true no OSD messages will be displayed. */
/**
* If set, the task queue will not call \c progress_cb
* and will not display any messages from this task.
*/
bool mute;
};
/**
* Parameters for \c task_queue_find.
*
* @see task_queue_find
*/
typedef struct task_finder_data
{
/**
* Predicate to call for each task.
* Must not be \c NULL.
*
* @param task The task to query.
* @param userdata \c userdata from this struct.
* @return \c true if this task matches the search criteria,
* at which point \c task_queue_find will stop searching and return \c true.
*/
retro_task_finder_t func;
/**
* Pointer to arbitrary data.
* Passed directly to \c func.
* May be \c NULL.
*/
void *userdata;
} task_finder_data_t;
/**
* Contains the result of a call to \c task_retriever_data::func.
* Implemented as an intrusive singly-linked list.
*/
typedef struct task_retriever_info
{
/**
* The next item in the result list,
* or \c NULL if this is the last one.
*/
struct task_retriever_info *next;
/**
* Arbitrary data returned by \c func.
* Can be anything, but should be a simple \c struct
* so that it can be freed by \c task_queue_retriever_info_free.
*/
void *data;
} task_retriever_info_t;
/**
* Parameters for \c task_queue_retrieve.
*
* @see task_queue_retrieve
*/
typedef struct task_retriever_data
{
/**
* Contains the result of each call to \c func that returned \c true.
* Should be initialized to \c NULL.
* Will remain \c NULL after \c task_queue_retrieve if no tasks matched.
* Must be freed by \c task_queue_retriever_info_free.
* @see task_queue_retriever_info_free
*/
task_retriever_info_t *list;
/**
* The handler to compare against.
* Only tasks with this handler will be considered for retrieval.
* Must not be \c NULL.
*/
retro_task_handler_t handler;
/**
* The predicate that determines if the given task will be retrieved.
* Must not be \c NULL.
*
* @param task[in] The task to query.
* @param data[out] Arbitrary data that the retriever should return.
* Allocated by the task queue based on \c element_size.
* @return \c true if \c data should be appended to \c list.
*/
retro_task_retriever_t func;
/**
* The size of the output that \c func may write to.
* Must not be zero.
*/
size_t element_size;
} task_retriever_data_t;
/**
* Returns the next item in the result list.
* Here's a usage example, assuming that \c results is used to store strings:
*
* @code{.c}
* void print_results(task_retriever_info_t *results)
* {
* char* text = NULL;
* task_retriever_info_t *current = results;
* while (text = task_queue_retriever_info_next(&current))
* {
* printf("%s\n", text);
* }
* }
* @endcode
*
* @param link Pointer to the first element in the result list.
* Must not be \c NULL.
* @return The next item in the result list.
*/
void *task_queue_retriever_info_next(task_retriever_info_t **link);
/**
* Frees the result of a call to \c task_queue_retrieve.
* @param list The result list to free.
* May be \c NULL, in which case this function does nothing.
* The list, its nodes, and its elements will all be freed.
*
* If the list's elements must be cleaned up with anything besides \c free,
* then the caller must do that itself before invoking this function.
*/
void task_queue_retriever_info_free(task_retriever_info_t *list);
/**
* Signals a task to end without waiting for
* it to complete. */
* Cancels the provided task.
* The task should finish its work as soon as possible afterward.
*
* @param task The task to cancel.
* @see task_set_cancelled
*/
void task_queue_cancel_task(void *task);
/**
* Sets \c task::finished to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param finished Whether the task should be considered finished.
* @see retro_task::finished
*/
void task_set_finished(retro_task_t *task, bool finished);
/**
* Sets \c task::mute to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param mute Whether the task should be considered muted.
* @see retro_task::mute
*/
void task_set_mute(retro_task_t *task, bool mute);
/**
* Sets \c task::error to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param error The error message to set.
* @see retro_task::error
* @warning This does not free the existing error message.
* The caller must do that itself.
*/
void task_set_error(retro_task_t *task, char *error);
/**
* Sets \c task::progress to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param progress The progress value to set.
* @see retro_task::progress
*/
void task_set_progress(retro_task_t *task, int8_t progress);
/**
* Sets \c task::title to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param title The title to set.
* @see retro_task::title
* @see task_free_title
* @warning This does not free the existing title.
* The caller must do that itself.
*/
void task_set_title(retro_task_t *task, char *title);
/**
* Sets \c task::data to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param data The data to set.
* @see retro_task::data
*/
void task_set_data(retro_task_t *task, void *data);
/**
* Sets \c task::cancelled to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param cancelled Whether the task should be considered cancelled.
* @see retro_task::cancelled
*/
void task_set_cancelled(retro_task_t *task, bool cancelled);
/**
* Frees the \c task's title, if any.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* @see task_set_title
*/
void task_free_title(retro_task_t *task);
/**
* Returns \c task::cancelled.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::cancelled.
* @see retro_task::cancelled
*/
bool task_get_cancelled(retro_task_t *task);
/**
* Returns \c task::finished.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::finished.
* @see retro_task::finished
*/
bool task_get_finished(retro_task_t *task);
/**
* Returns \c task::mute.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::mute.
* @see retro_task::mute
*/
bool task_get_mute(retro_task_t *task);
/**
* Returns \c task::error.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::error.
* @see retro_task::error
*/
char* task_get_error(retro_task_t *task);
/**
* Returns \c task::progress.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::progress.
* @see retro_task::progress
*/
int8_t task_get_progress(retro_task_t *task);
/**
* Returns \c task::title.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::title.
* @see retro_task::title
*/
char* task_get_title(retro_task_t *task);
/**
* Returns \c task::data.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::data.
* @see retro_task::data
*/
void* task_get_data(retro_task_t *task);
/**
* Returns whether the task queue is running
* on the same thread that called \c task_queue_init.
*
* @return \c true if the caller is running
* on the same thread that called \c task_queue_init.
*/
bool task_is_on_main_thread(void);
/**
* Ensures that the task queue is in threaded mode.
*
* Next time \c retro_task_queue_check is called,
* the task queue will be recreated with threading enabled.
* Existing tasks will continue to run on the new thread.
*/
void task_queue_set_threaded(void);
/**
* Ensures that the task queue is not in threaded mode.
*
* Next time \c retro_task_queue_check is called,
* the task queue will be recreated with threading disabled.
* Existing tasks will continue to run on whichever thread updates the queue.
*
* @see task_queue_set_threaded
* @see task_queue_is_threaded
*/
void task_queue_unset_threaded(void);
/**
* Returns whether the task queue is running in threaded mode.
*
* @return \c true if the task queue is running its tasks on a separate thread.
*/
bool task_queue_is_threaded(void);
/**
* Calls func for every running task
* until it returns true.
* Returns a task or NULL if not found.
* Calls the function given in \c find_data for each task
* until it returns \c true for one of them,
* or until all tasks have been searched.
*
* @param find_data Parameters for the search.
* Behavior is undefined if \c NULL.
* @return \c true if \c find_data::func returned \c true for any task.
* @see task_finder_data_t
*/
bool task_queue_find(task_finder_data_t *find_data);
/**
* Calls func for every running task when handler
* parameter matches task handler, allowing the
* list parameter to be filled with user-defined
* data.
* Retrieves arbitrary data from every task
* whose handler matches \c data::handler.
*
* @param data[in, out] Parameters for retrieving data from the task queue,
* including the results themselves.
* Behavior is undefined if \c NULL.
* @see task_retriever_data_t
*/
void task_queue_retrieve(task_retriever_data_t *data);
/* Checks for finished tasks
* Takes the finished tasks, if any,
* and runs their callbacks.
* This must only be called from the main thread. */
/**
* Runs each task.
* If a task is finished or cancelled,
* its callback and cleanup handler will be called.
* Afterwards, the task will be deallocated.
* If used in a core, generally called in \c retro_run
* and just before \c task_queue_deinit.
* @warning This must only be called from the main thread.
*/
void task_queue_check(void);
/* Pushes a task
* The task will start as soon as possible.
* If a second blocking task is attempted, false will be returned
* and the task will be ignored. */
/**
* Schedules a task to start running.
* If \c task::when is 0, it will start as soon as possible.
*
* Tasks with the same \c task::when value
* will be executed in the order they were scheduled.
*
* @param task The task to schedule.
* @return \c true unless \c task's type is \c TASK_TYPE_BLOCKING
* and there's already a blocking task in the queue.
*/
bool task_queue_push(retro_task_t *task);
/* Blocks until all non-scheduled tasks have finished.
* Will return early if cond is not NULL
* and cond(data) returns false.
* This must only be called from the main thread. */
/**
* Block until all active (i.e. current time > \c task::when) tasks have finished,
* or until the given function returns \c false.
* If a scheduled task's \c when is passed while within this function,
* it will start executing.
*
* Must only be called from the main thread.
*
* @param cond Function to call after all tasks in the queue have executed
* (i.e. once per pass over the task queue).
* May be \c NULL, in which case the task queue will wait unconditionally.
* @param data Pointer to arbitrary data, passed directly into \c cond.
* May be \c NULL.
* @see retro_task_condition_fn_t
* @see task_queue_deinit
* @see task_queue_reset
* @warning Passing \c NULL to \c cond is strongly discouraged.
* If you use tasks that run indefinitely
* (e.g. for the lifetime of the core),
* you will need a way to stop these tasks externally;
* otherwise, you risk the frontend and core freezing.
*/
void task_queue_wait(retro_task_condition_fn_t cond, void* data);
/* Sends a signal to terminate all the tasks.
/**
* Marks all tasks in the queue as cancelled.
*
* This won't terminate the tasks immediately.
* They will finish as soon as possible.
* The tasks won't immediately be terminated;
* each task may finish its work,
* but must do so as quickly as possible.
*
* This must only be called from the main thread. */
* Must only be called from the main thread.
*
* @see task_queue_wait
* @see task_queue_deinit
* @see task_set_finished
* @see task_get_cancelled
*/
void task_queue_reset(void);
/* Deinitializes the task system.
* This deinitializes the task system.
* The tasks that are running at
* the moment will stay on hold */
/**
* Deinitializes the task system.
*
* Outstanding tasks will not be cleaned up;
* if the intent is to finish the core or frontend's work,
* then all tasks must be finished before calling this function.
* May be safely called multiple times in a row,
* but only from the main thread.
* @see task_queue_wait
* @see task_queue_reset
*/
void task_queue_deinit(void);
/* Initializes the task system.
* This initializes the task system
* and chooses an appropriate
* implementation according to the settings.
/**
* Initializes the task system with the provided parameters.
* Must be called before any other task_queue_* function,
* and must only be called from the main thread.
*
* This must only be called from the main thread. */
* @param threaded \c true if tasks should run on a separate thread,
* \c false if they should remain on the calling thread.
* All tasks run in sequence on a single thread.
* If you want to scale a task to multiple threads,
* you must do so within the task itself.
* @param msg_push The task system will call this function to output messages.
* If \c NULL, no messages will be output.
* @note Calling this function while the task system is already initialized
* will reinitialize it with the new parameters,
* but it will not reset the task queue;
* all existing tasks will continue to run
* when the queue is updated.
* @see task_queue_deinit
* @see retro_task_queue_msg_t
*/
void task_queue_init(bool threaded, retro_task_queue_msg_t msg_push);
/* Allocates and inits a new retro_task_t */
/**
* Allocates and initializes a new task.
* Deallocated by the task queue after it finishes executing.
*
* @returns Pointer to a newly allocated task,
* or \c NULL if allocation fails.
*/
retro_task_t *task_init(void);
RETRO_END_DECLS

View file

@ -23,12 +23,12 @@
#ifndef _LIBRETRO_COMMON_RETRO_COMMON_H
#define _LIBRETRO_COMMON_RETRO_COMMON_H
/*
This file is designed to normalize the libretro-common compiling environment.
It is not to be used in public API headers, as they should be designed as leanly as possible.
Nonetheless.. in the meantime, if you do something like use ssize_t, which is not fully portable,
in a public API, you may need this.
*/
/*!
* @internal This file is designed to normalize the libretro-common compiling environment.
* It is not to be used in public API headers, as they should be designed as leanly as possible.
* Nonetheless.. in the meantime, if you do something like use ssize_t, which is not fully portable,
* in a public API, you may need this.
*/
/* conditional compilation is handled inside here */
#include <compat/msvc.h>

View file

@ -28,50 +28,142 @@
#include <boolean.h>
/** @defgroup dirent Directory Entries
* @{
*/
RETRO_BEGIN_DECLS
/**
* The minimum VFS version (as defined in \c retro_vfs_interface_info::required_interface_version)
* required by the \c dirent functions.
* If no acceptable VFS interface is provided,
* all dirent functions will fall back to libretro-common's implementations.
* @see retro_vfs_interface_info
*/
#define DIRENT_REQUIRED_VFS_VERSION 3
/**
* Installs a frontend-provided VFS interface for the dirent functions to use
* instead of libretro-common's built-in implementations.
*
* @param vfs_info The VFS interface returned by the frontend.
* The dirent functions will fall back to libretro-common's implementations
* if \c vfs_info::required_interface_version is too low.
* @see retro_vfs_interface_info
* @see RETRO_ENVIRONMENT_GET_VFS_INTERFACE
*/
void dirent_vfs_init(const struct retro_vfs_interface_info* vfs_info);
/**
* Opaque handle to a directory entry (aka "dirent").
* It may name a file, directory, or other filesystem object.
* @see retro_opendir
*/
typedef struct RDIR RDIR;
/**
* Opens a directory for reading.
*
* retro_opendir:
* @name : path to the directory to open.
*
* Opens a directory for reading. Tidy up with retro_closedir.
*
* Returns: RDIR pointer on success, NULL if name is not a
* valid directory, null itself or the empty string.
* @param name Path to a directory to open.
* @return An \c RDIR representing the given directory if successful.
* Returns \c NULL if \c name is \c NULL, the empty string, or does not name a directory.
* @note The returned \c RDIR must be closed with \c retro_closedir.
* @see retro_opendir_include_hidden
* @see retro_closedir
*/
struct RDIR *retro_opendir(const char *name);
/**
* @copybrief retro_opendir
*
* @param name Path to the directory to open.
* @param include_hidden Whether to include hidden files and directories
* when iterating over this directory with \c retro_readdir.
* Platforms and filesystems have different notions of "hidden" files.
* Setting this to \c false will not prevent this function from opening \c name.
* @return An \c RDIR representing the given directory if successful.
* Returns \c NULL if \c name is \c NULL, the empty string, or does not name a directory.
* @note The returned \c RDIR must be closed with \c retro_closedir.
* @see retro_opendir
* @see retro_closedir
*/
struct RDIR *retro_opendir_include_hidden(const char *name, bool include_hidden);
/**
* Reads the next entry in the given directory.
*
* Here's a usage example that prints the names of all files in the current directory:
* @code
* struct RDIR *rdir = retro_opendir(".");
* if (rdir)
* {
* while (retro_readdir(rdir))
* {
* const char *name = retro_dirent_get_name(rdir);
* printf("%s\n", name);
* }
* retro_closedir(rdir);
* rdir = NULL;
* }
* @endcode
*
* @param rdir The directory to iterate over.
* Behavior is undefined if \c NULL.
* @return \c true if the next entry was read successfully,
* \c false if there are no more entries to read or if there was an error.
* @note This may include "." and ".." on Unix-like platforms.
* @see retro_dirent_get_name
* @see retro_dirent_is_dir
*/
int retro_readdir(struct RDIR *rdir);
/* Deprecated, returns false, left for compatibility */
/**
* @deprecated Left for compatibility.
* @param rdir Ignored.
* @return \c false.
*/
bool retro_dirent_error(struct RDIR *rdir);
/**
* Gets the name of the dirent's current file or directory.
*
* @param rdir The dirent to get the name of.
* Behavior is undefined if \c NULL.
* @return The name of the directory entry (file, directory, etc.) that the dirent points to.
* Will return \c NULL if there was an error,
* \c retro_readdir has not been called on \c rdir,
* or if there are no more entries to read.
* @note This returns only a name, not a full path.
* @warning The returned string is managed by the VFS implementation
* and must not be modified or freed by the caller.
* @warning The returned string is only valid until the next call to \c retro_readdir.
* @see retro_readdir
*/
const char *retro_dirent_get_name(struct RDIR *rdir);
/**
* Checks if the given \c RDIR's current dirent names a directory.
*
* retro_dirent_is_dir:
* @rdir : pointer to the directory entry.
* @unused : deprecated, included for compatibility reasons, pass NULL
*
* Is the directory listing entry a directory?
*
* Returns: true if directory listing entry is
* a directory, false if not.
* @param rdir The directory entry to check.
* Behavior is undefined if \c NULL.
* @param unused Ignored for compatibility reasons. Pass \c NULL.
* @return \c true if \c rdir refers to a directory, otherwise \c false.
* @see retro_readdir
*/
bool retro_dirent_is_dir(struct RDIR *rdir, const char *unused);
/**
* Closes an opened \c RDIR that was returned by \c retro_opendir.
*
* @param rdir The directory entry to close.
* If \c NULL, this function does nothing.
* @see retro_vfs_closedir_t
*/
void retro_closedir(struct RDIR *rdir);
RETRO_END_DECLS
/** @} */
#endif

View file

@ -31,12 +31,22 @@
#define SWAP16 _byteswap_ushort
#define SWAP32 _byteswap_ulong
#else
/**
* Swaps the byte order of a 16-bit unsigned integer.
* @param x The integer to byteswap.
* @return \c with its two bytes swapped.
*/
static INLINE uint16_t SWAP16(uint16_t x)
{
return ((x & 0x00ff) << 8) |
((x & 0xff00) >> 8);
}
/**
* Swaps the byte order of a 32-bit unsigned integer.
* @param x The integer to byteswap.
* @return \c with its bytes swapped.
*/
static INLINE uint32_t SWAP32(uint32_t x)
{
return ((x & 0x000000ff) << 24) |
@ -61,6 +71,11 @@ static INLINE uint64_t SWAP64(uint64_t val)
| ((val & 0xff00000000000000) >> 56);
}
#else
/**
* Swaps the byte order of a 64-bit unsigned integer.
* @param x The integer to byteswap.
* @return \c with its bytes swapped.
*/
static INLINE uint64_t SWAP64(uint64_t val)
{
return ((val & 0x00000000000000ffULL) << 56)
@ -124,25 +139,20 @@ static INLINE uint64_t SWAP64(uint64_t val)
/**
* is_little_endian:
* Checks if the current CPU is little-endian.
*
* Checks if the system is little endian or big-endian.
*
* Returns: greater than 0 if little-endian,
* otherwise big-endian.
**/
* @return \c true on little-endian CPUs,
* \c false on big-endian CPUs.
*/
#define is_little_endian() RETRO_IS_LITTLE_ENDIAN
/**
* swap_if_big64:
* @val : unsigned 64-bit value
* Byte-swaps an unsigned 64-bit integer on big-endian CPUs.
*
* Byteswap unsigned 64-bit value if system is big-endian.
*
* Returns: Byteswapped value in case system is big-endian,
* otherwise returns same value.
**/
* @param val The value to byteswap if necessary.
* @return \c val byteswapped on big-endian CPUs,
* \c val unchanged on little-endian CPUs.
*/
#if RETRO_IS_BIG_ENDIAN
#define swap_if_big64(val) (SWAP64(val))
#elif RETRO_IS_LITTLE_ENDIAN
@ -150,15 +160,12 @@ static INLINE uint64_t SWAP64(uint64_t val)
#endif
/**
* swap_if_big32:
* @val : unsigned 32-bit value
* Byte-swaps an unsigned 32-bit integer on big-endian CPUs.
*
* Byteswap unsigned 32-bit value if system is big-endian.
*
* Returns: Byteswapped value in case system is big-endian,
* otherwise returns same value.
**/
* @param val The value to byteswap if necessary.
* @return \c val byteswapped on big-endian CPUs,
* \c val unchanged on little-endian CPUs.
*/
#if RETRO_IS_BIG_ENDIAN
#define swap_if_big32(val) (SWAP32(val))
#elif RETRO_IS_LITTLE_ENDIAN
@ -166,15 +173,12 @@ static INLINE uint64_t SWAP64(uint64_t val)
#endif
/**
* swap_if_little64:
* @val : unsigned 64-bit value
* Byte-swaps an unsigned 64-bit integer on little-endian CPUs.
*
* Byteswap unsigned 64-bit value if system is little-endian.
*
* Returns: Byteswapped value in case system is little-endian,
* otherwise returns same value.
**/
* @param val The value to byteswap if necessary.
* @return \c val byteswapped on little-endian CPUs,
* \c val unchanged on big-endian CPUs.
*/
#if RETRO_IS_BIG_ENDIAN
#define swap_if_little64(val) (val)
#elif RETRO_IS_LITTLE_ENDIAN
@ -182,15 +186,12 @@ static INLINE uint64_t SWAP64(uint64_t val)
#endif
/**
* swap_if_little32:
* @val : unsigned 32-bit value
* Byte-swaps an unsigned 32-bit integer on little-endian CPUs.
*
* Byteswap unsigned 32-bit value if system is little-endian.
*
* Returns: Byteswapped value in case system is little-endian,
* otherwise returns same value.
**/
* @param val The value to byteswap if necessary.
* @return \c val byteswapped on little-endian CPUs,
* \c val unchanged on big-endian CPUs.
*/
#if RETRO_IS_BIG_ENDIAN
#define swap_if_little32(val) (val)
#elif RETRO_IS_LITTLE_ENDIAN
@ -198,15 +199,12 @@ static INLINE uint64_t SWAP64(uint64_t val)
#endif
/**
* swap_if_big16:
* @val : unsigned 16-bit value
* Byte-swaps an unsigned 16-bit integer on big-endian systems.
*
* Byteswap unsigned 16-bit value if system is big-endian.
*
* Returns: Byteswapped value in case system is big-endian,
* otherwise returns same value.
**/
* @param val The value to byteswap if necessary.
* @return \c val byteswapped on big-endian systems,
* \c val unchanged on little-endian systems.
*/
#if RETRO_IS_BIG_ENDIAN
#define swap_if_big16(val) (SWAP16(val))
#elif RETRO_IS_LITTLE_ENDIAN
@ -214,15 +212,12 @@ static INLINE uint64_t SWAP64(uint64_t val)
#endif
/**
* swap_if_little16:
* @val : unsigned 16-bit value
* Byte-swaps an unsigned 16-bit integer on little-endian systems.
*
* Byteswap unsigned 16-bit value if system is little-endian.
*
* Returns: Byteswapped value in case system is little-endian,
* otherwise returns same value.
**/
* @param val The value to byteswap if necessary.
* @return \c val byteswapped on little-endian systems,
* \c val unchanged on big-endian systems.
*/
#if RETRO_IS_BIG_ENDIAN
#define swap_if_little16(val) (val)
#elif RETRO_IS_LITTLE_ENDIAN
@ -230,167 +225,143 @@ static INLINE uint64_t SWAP64(uint64_t val)
#endif
/**
* store32be:
* @addr : pointer to unsigned 32-bit buffer
* @data : unsigned 32-bit value to write
* Stores a 32-bit integer in at the given address, in big-endian order.
*
* Write data to address. Endian-safe. Byteswaps the data
* first if necessary before storing it.
**/
* @param addr The address to store the value at.
* Behavior is undefined if \c NULL or not aligned to a 32-bit boundary.
* @param data The value to store in \c addr.
* Will be byteswapped if on a little-endian CPU.
*/
static INLINE void store32be(uint32_t *addr, uint32_t data)
{
*addr = swap_if_little32(data);
}
/**
* load32be:
* @addr : pointer to unsigned 32-bit buffer
* Loads a 32-bit integer order from the given address, in big-endian order.
*
* Load value from address. Endian-safe.
*
* Returns: value from address, byte-swapped if necessary.
**/
* @param addr The address to load the value from.
* Behavior is undefined if \c NULL or not aligned to a 32-bit boundary.
* @return The value at \c addr, byteswapped if on a little-endian CPU.
*/
static INLINE uint32_t load32be(const uint32_t *addr)
{
return swap_if_little32(*addr);
}
/**
* retro_cpu_to_le16:
* @val : unsigned 16-bit value
* Converts the given unsigned 16-bit integer to little-endian order if necessary.
*
* Convert unsigned 16-bit value from system to little-endian.
*
* Returns: Little-endian representation of val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a big-endian CPU,
* unchanged otherwise.
*/
#define retro_cpu_to_le16(val) swap_if_big16(val)
/**
* retro_cpu_to_le32:
* @val : unsigned 32-bit value
* Converts the given unsigned 32-bit integer to little-endian order if necessary.
*
* Convert unsigned 32-bit value from system to little-endian.
*
* Returns: Little-endian representation of val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a big-endian CPU,
* unchanged otherwise.
*/
#define retro_cpu_to_le32(val) swap_if_big32(val)
/**
* retro_cpu_to_le64:
* @val : unsigned 64-bit value
* Converts the given unsigned 64-bit integer to little-endian order if necessary.
*
* Convert unsigned 64-bit value from system to little-endian.
*
* Returns: Little-endian representation of val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a big-endian CPU,
* unchanged otherwise.
*/
#define retro_cpu_to_le64(val) swap_if_big64(val)
/**
* retro_le_to_cpu16:
* @val : unsigned 16-bit value
* Converts the given unsigned 16-bit integer to host-native order if necessary.
*
* Convert unsigned 16-bit value from little-endian to native.
*
* Returns: Native representation of little-endian val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a big-endian CPU,
* unchanged otherwise.
*/
#define retro_le_to_cpu16(val) swap_if_big16(val)
/**
* retro_le_to_cpu32:
* @val : unsigned 32-bit value
* Converts the given unsigned 32-bit integer to host-native order if necessary.
*
* Convert unsigned 32-bit value from little-endian to native.
*
* Returns: Native representation of little-endian val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a big-endian CPU,
* unchanged otherwise.
*/
#define retro_le_to_cpu32(val) swap_if_big32(val)
/**
* retro_le_to_cpu16:
* @val : unsigned 64-bit value
* Converts the given unsigned 64-bit integer to host-native order if necessary.
*
* Convert unsigned 64-bit value from little-endian to native.
*
* Returns: Native representation of little-endian val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a big-endian CPU,
* unchanged otherwise.
*/
#define retro_le_to_cpu64(val) swap_if_big64(val)
/**
* retro_cpu_to_be16:
* @val : unsigned 16-bit value
* Converts the given unsigned 16-bit integer to big-endian order if necessary.
*
* Convert unsigned 16-bit value from system to big-endian.
*
* Returns: Big-endian representation of val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a little-endian CPU,
* unchanged otherwise.
*/
#define retro_cpu_to_be16(val) swap_if_little16(val)
/**
* retro_cpu_to_be32:
* @val : unsigned 32-bit value
* Converts the given unsigned 32-bit integer to big-endian order if necessary.
*
* Convert unsigned 32-bit value from system to big-endian.
*
* Returns: Big-endian representation of val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a little-endian CPU,
* unchanged otherwise.
*/
#define retro_cpu_to_be32(val) swap_if_little32(val)
/**
* retro_cpu_to_be64:
* @val : unsigned 64-bit value
* Converts the given unsigned 64-bit integer to big-endian order if necessary.
*
* Convert unsigned 64-bit value from system to big-endian.
*
* Returns: Big-endian representation of val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a little-endian CPU,
* unchanged otherwise.
*/
#define retro_cpu_to_be64(val) swap_if_little64(val)
/**
* retro_be_to_cpu16:
* @val : unsigned 16-bit value
* Converts the given unsigned 16-bit integer from big-endian to host-native order if necessary.
*
* Convert unsigned 16-bit value from big-endian to native.
*
* Returns: Native representation of big-endian val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a little-endian CPU,
* unchanged otherwise.
*/
#define retro_be_to_cpu16(val) swap_if_little16(val)
/**
* retro_be_to_cpu32:
* @val : unsigned 32-bit value
* Converts the given unsigned 32-bit integer from big-endian to host-native order if necessary.
*
* Convert unsigned 32-bit value from big-endian to native.
*
* Returns: Native representation of big-endian val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a little-endian CPU,
* unchanged otherwise.
*/
#define retro_be_to_cpu32(val) swap_if_little32(val)
/**
* retro_be_to_cpu64:
* @val : unsigned 64-bit value
* Converts the given unsigned 64-bit integer from big-endian to host-native order if necessary.
*
* Convert unsigned 64-bit value from big-endian to native.
*
* Returns: Native representation of big-endian val.
**/
* @param val The value to convert if necessary.
* @return \c val byteswapped if on a little-endian CPU,
* unchanged otherwise.
*/
#define retro_be_to_cpu64(val) swap_if_little64(val)
#ifdef __GNUC__
/* This attribute means that the same memory may be referred through
pointers to different size of the object (aliasing). E.g. that u8 *
and u32 * may actually be pointing to the same object. */
/**
* This attribute indicates that pointers to this type may alias
* to pointers of any other type, similar to \c void* or \c char*.
*/
#define MAY_ALIAS __attribute__((__may_alias__))
#else
#define MAY_ALIAS
@ -411,8 +382,22 @@ struct retro_unaligned_uint64_s
} MAY_ALIAS;
#pragma pack(pop)
/**
* A wrapper around a \c uint16_t that allows unaligned access
* where supported by the compiler.
*/
typedef struct retro_unaligned_uint16_s retro_unaligned_uint16_t;
/**
* A wrapper around a \c uint32_t that allows unaligned access
* where supported by the compiler.
*/
typedef struct retro_unaligned_uint32_s retro_unaligned_uint32_t;
/**
* A wrapper around a \c uint64_t that allows unaligned access
* where supported by the compiler.
*/
typedef struct retro_unaligned_uint64_s retro_unaligned_uint64_t;
/* L-value references to unaligned pointers. */
@ -421,157 +406,175 @@ typedef struct retro_unaligned_uint64_s retro_unaligned_uint64_t;
#define retro_unaligned64(p) (((retro_unaligned_uint64_t *)p)->val)
/**
* retro_get_unaligned_16be:
* @addr : pointer to unsigned 16-bit value
* Reads a 16-bit unsigned integer from the given address
* and converts it from big-endian to host-native order (if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert unsigned unaligned 16-bit value from big-endian to native.
*
* Returns: Native representation of big-endian val.
**/
* @param addr The address of the integer to read.
* Does not need to be divisible by 2
* the way a \c uint16_t* usually would be.
* @return The first two bytes of \c addr as a 16-bit unsigned integer,
* byteswapped from big-endian to host-native order if necessary.
*/
static INLINE uint16_t retro_get_unaligned_16be(void *addr) {
return retro_be_to_cpu16(retro_unaligned16(addr));
}
/**
* retro_get_unaligned_32be:
* @addr : pointer to unsigned 32-bit value
* Reads a 32-bit unsigned integer from the given address
* and converts it from big-endian to host-native order (if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert unsigned unaligned 32-bit value from big-endian to native.
*
* Returns: Native representation of big-endian val.
**/
* @param addr The address of the integer to read.
* Does not need to be divisible by 4
* the way a \c uint32_t* usually would be.
* @return The first four bytes of \c addr as a 32-bit unsigned integer,
* byteswapped from big-endian to host-native order if necessary.
*/
static INLINE uint32_t retro_get_unaligned_32be(void *addr) {
return retro_be_to_cpu32(retro_unaligned32(addr));
}
/**
* retro_get_unaligned_64be:
* @addr : pointer to unsigned 64-bit value
* Reads a 64-bit unsigned integer from the given address
* and converts it from big-endian to host-native order (if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert unsigned unaligned 64-bit value from big-endian to native.
*
* Returns: Native representation of big-endian val.
**/
* @param addr The address of the integer to read.
* Does not need to be divisible by 8
* the way a \c uint64_t* usually would be.
* @return The first eight bytes of \c addr as a 64-bit unsigned integer,
* byteswapped from big-endian to host-native order if necessary.
*/
static INLINE uint64_t retro_get_unaligned_64be(void *addr) {
return retro_be_to_cpu64(retro_unaligned64(addr));
}
/**
* retro_get_unaligned_16le:
* @addr : pointer to unsigned 16-bit value
* Reads a 16-bit unsigned integer from the given address
* and converts it from little-endian to host-native order (if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert unsigned unaligned 16-bit value from little-endian to native.
*
* Returns: Native representation of little-endian val.
**/
* @param addr The address of the integer to read.
* Does not need to be divisible by 2
* the way a \c uint16_t* usually would be.
* @return The first two bytes of \c addr as a 16-bit unsigned integer,
* byteswapped from little-endian to host-native order if necessary.
*/
static INLINE uint16_t retro_get_unaligned_16le(void *addr) {
return retro_le_to_cpu16(retro_unaligned16(addr));
}
/**
* retro_get_unaligned_32le:
* @addr : pointer to unsigned 32-bit value
* Reads a 32-bit unsigned integer from the given address
* and converts it from little-endian to host-native order (if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert unsigned unaligned 32-bit value from little-endian to native.
*
* Returns: Native representation of little-endian val.
**/
* @param addr The address of the integer to read.
* Does not need to be divisible by 4
* the way a \c uint32_t* usually would be.
* @return The first four bytes of \c addr as a 32-bit unsigned integer,
* byteswapped from little-endian to host-native order if necessary.
*/
static INLINE uint32_t retro_get_unaligned_32le(void *addr) {
return retro_le_to_cpu32(retro_unaligned32(addr));
}
/**
* retro_get_unaligned_64le:
* @addr : pointer to unsigned 64-bit value
* Reads a 64-bit unsigned integer from the given address
* and converts it from little-endian to host-native order (if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert unsigned unaligned 64-bit value from little-endian to native.
*
* Returns: Native representation of little-endian val.
**/
* @param addr The address of the integer to read.
* Does not need to be divisible by 8
* the way a \c uint64_t* usually would be.
* @return The first eight bytes of \c addr as a 64-bit unsigned integer,
* byteswapped from little-endian to host-native order if necessary.
*/
static INLINE uint64_t retro_get_unaligned_64le(void *addr) {
return retro_le_to_cpu64(retro_unaligned64(addr));
}
/**
* retro_set_unaligned_16le:
* @addr : pointer to unsigned 16-bit value
* @val : value to store
* Writes a 16-bit unsigned integer to the given address
* (converted to little-endian order if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert native value to unsigned unaligned 16-bit little-endian value
*
**/
* @param addr The address to write the integer to.
* Does not need to be divisible by 2
* the way a \c uint16_t* usually would be.
* @param v The value to write.
*/
static INLINE void retro_set_unaligned_16le(void *addr, uint16_t v) {
retro_unaligned16(addr) = retro_cpu_to_le16(v);
}
/**
* retro_set_unaligned_32le:
* @addr : pointer to unsigned 32-bit value
* @val : value to store
* Writes a 32-bit unsigned integer to the given address
* (converted to little-endian order if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert native value to unsigned unaligned 32-bit little-endian value
*
**/
* @param addr The address to write the integer to.
* Does not need to be divisible by 4
* the way a \c uint32_t* usually would be.
* @param v The value to write.
*/
static INLINE void retro_set_unaligned_32le(void *addr, uint32_t v) {
retro_unaligned32(addr) = retro_cpu_to_le32(v);
}
/**
* retro_set_unaligned_32le:
* @addr : pointer to unsigned 32-bit value
* @val : value to store
* Writes a 64-bit unsigned integer to the given address
* (converted to little-endian order if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert native value to unsigned unaligned 32-bit little-endian value
*
**/
* @param addr The address to write the integer to.
* Does not need to be divisible by 8
* the way a \c uint64_t* usually would be.
* @param v The value to write.
*/
static INLINE void retro_set_unaligned_64le(void *addr, uint64_t v) {
retro_unaligned64(addr) = retro_cpu_to_le64(v);
}
/**
* retro_set_unaligned_16be:
* @addr : pointer to unsigned 16-bit value
* @val : value to store
* Writes a 16-bit unsigned integer to the given address
* (converted to big-endian order if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert native value to unsigned unaligned 16-bit big-endian value
*
**/
* @param addr The address to write the integer to.
* Does not need to be divisible by 2
* the way a \c uint16_t* usually would be.
* @param v The value to write.
*/
static INLINE void retro_set_unaligned_16be(void *addr, uint16_t v) {
retro_unaligned16(addr) = retro_cpu_to_be16(v);
}
/**
* retro_set_unaligned_32be:
* @addr : pointer to unsigned 32-bit value
* @val : value to store
* Writes a 32-bit unsigned integer to the given address
* (converted to big-endian order if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert native value to unsigned unaligned 32-bit big-endian value
*
**/
* @param addr The address to write the integer to.
* Does not need to be divisible by 4
* the way a \c uint32_t* usually would be.
* @param v The value to write.
*/
static INLINE void retro_set_unaligned_32be(void *addr, uint32_t v) {
retro_unaligned32(addr) = retro_cpu_to_be32(v);
}
/**
* retro_set_unaligned_32be:
* @addr : pointer to unsigned 32-bit value
* @val : value to store
* Writes a 64-bit unsigned integer to the given address
* (converted to big-endian order if necessary),
* regardless of the CPU's alignment requirements.
*
* Convert native value to unsigned unaligned 32-bit big-endian value
*
**/
* @param addr The address to write the integer to.
* Does not need to be divisible by 8
* the way a \c uint64_t* usually would be.
* @param v The value to write.
*/
static INLINE void retro_set_unaligned_64be(void *addr, uint64_t v) {
retro_unaligned64(addr) = retro_cpu_to_be64(v);
}

View file

@ -25,6 +25,12 @@
#ifndef INLINE
/**
* Cross-platform inline specifier.
*
* Expands to something like \c __inline or \c inline,
* depending on the compiler.
*/
#if defined(_WIN32) || defined(__INTEL_COMPILER)
#define INLINE __inline
#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L

View file

@ -53,6 +53,13 @@
#include <sys/param.h>
#endif
/**
* Computes the bitwise OR of two bit arrays.
*
* @param a[in,out] The first bit array, and the location of the result.
* @param b[in] The second bit array.
* @param count The length of each bit array, in 32-bit words.
*/
static INLINE void bits_or_bits(uint32_t *a, uint32_t *b, uint32_t count)
{
uint32_t i;
@ -60,6 +67,14 @@ static INLINE void bits_or_bits(uint32_t *a, uint32_t *b, uint32_t count)
a[i] |= b[i];
}
/**
* Clears every bit in \c a that is set in \c b.
*
* @param a[in,out] The bit array to modify.
* @param b[in] The bit array to use for reference.
* @param count The length of each bit array, in 32-bit words
* (\em not bits or bytes).
*/
static INLINE void bits_clear_bits(uint32_t *a, uint32_t *b, uint32_t count)
{
uint32_t i;
@ -67,6 +82,15 @@ static INLINE void bits_clear_bits(uint32_t *a, uint32_t *b, uint32_t count)
a[i] &= ~b[i];
}
/**
* Checks if any bits in \c ptr are set.
*
* @param ptr The bit array to check.
* @param count The length of the buffer pointed to by \c ptr, in 32-bit words
* (\em not bits or bytes).
* @return \c true if any bit in \c ptr is set,
* \c false if all bits are clear (zero).
*/
static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count)
{
uint32_t i;
@ -78,6 +102,16 @@ static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count)
return false;
}
/**
* Checks if any bits in \c a are different from those in \c b.
*
* @param a The first bit array to compare.
* @param b The second bit array to compare.
* @param count The length of each bit array, in 32-bit words
* (\em not bits or bytes).
* @return \c true if \c and \c differ by at least one bit,
* \c false if they're both identical.
*/
static INLINE bool bits_any_different(uint32_t *a, uint32_t *b, uint32_t count)
{
uint32_t i;
@ -93,46 +127,212 @@ static INLINE bool bits_any_different(uint32_t *a, uint32_t *b, uint32_t count)
#if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(__PSL1GHT__) || defined(__PS3__) || defined(HAVE_EMSCRIPTEN)
#define PATH_MAX_LENGTH 512
#else
/**
* An upper limit for the length of a path (including the filename).
* If a path is longer than this, it may not work properly.
* This value may vary by platform.
*/
#define PATH_MAX_LENGTH 4096
#endif
#endif
#ifndef NAME_MAX_LENGTH
/**
* An upper limit for the length of a file or directory (excluding parent directories).
* If a path has a component longer than this, it may not work properly.
*/
#define NAME_MAX_LENGTH 256
#endif
#ifndef MAX
/**
* @return \c a or \c b, whichever is larger.
*/
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
/**
* @return \c a or \c b, whichever is smaller.
*/
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
/**
* Gets the number of elements in an array whose size is known at compile time.
* @param a An array of fixed length.
* @return The number of elements in \c a.
*/
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
/** @defgroup BITS Bit Arrays
*
* @{
*/
#define BITS_GET_ELEM(a, i) ((a).data[i])
#define BITS_GET_ELEM_PTR(a, i) ((a)->data[i])
/** @defgroup BIT_ Arbitrary-length Bit Arrays
*
* @{
*/
/**
* Sets a particular bit within a bit array to 1.
*
* @param a A \c uint8_t array,
* treated here as a bit vector.
* @param bit Index of the bit to set, where 0 is the least significant.
*/
#define BIT_SET(a, bit) ((a)[(bit) >> 3] |= (1 << ((bit) & 7)))
/**
* Clears a particular bit within a bit array.
*
* @param a A \c uint8_t array,
* treated here as a bit vector.
* @param bit Index of the bit to clear, where 0 is the least significant.
*/
#define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7)))
/**
* Gets the value of a particular bit within a bit array.
*
* @param a A \c uint8_t array,
* treated here as a bit vector.
* @param bit Index of the bit to get, where 0 is the least significant.
* @return The value of the bit at the specified index.
*/
#define BIT_GET(a, bit) (((a)[(bit) >> 3] >> ((bit) & 7)) & 1)
/** @} */
/** @defgroup BIT16 16-bit Bit Arrays
*
* @{
*/
/**
* Sets a particular bit within a 16-bit integer to 1.
* @param a An unsigned 16-bit integer,
* treated as a bit array.
* @param bit Index of the bit to set, where 0 is the least significant and 15 is the most.
*/
#define BIT16_SET(a, bit) ((a) |= (1 << ((bit) & 15)))
/**
* Clears a particular bit within a 16-bit integer.
*
* @param a An unsigned 16-bit integer,
* treated as a bit array.
* @param bit Index of the bit to clear, where 0 is the least significant and 15 is the most.
*/
#define BIT16_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 15)))
/**
* Gets the value of a particular bit within a 16-bit integer.
*
* @param a An unsigned 16-bit integer,
* treated as a bit array.
* @param bit Index of the bit to get, where 0 is the least significant and 15 is the most.
* @return The value of the bit at the specified index.
*/
#define BIT16_GET(a, bit) (((a) >> ((bit) & 15)) & 1)
/**
* Clears all bits in a 16-bit bitmask.
*/
#define BIT16_CLEAR_ALL(a) ((a) = 0)
/** @} */
/** @defgroup BIT32 32-bit Bit Arrays
*
* @{
*/
/**
* Sets a particular bit within a 32-bit integer to 1.
*
* @param a An unsigned 32-bit integer,
* treated as a bit array.
* @param bit Index of the bit to set, where 0 is the least significant and 31 is the most.
*/
#define BIT32_SET(a, bit) ((a) |= (UINT32_C(1) << ((bit) & 31)))
/**
* Clears a particular bit within a 32-bit integer.
*
* @param a An unsigned 32-bit integer,
* treated as a bit array.
* @param bit Index of the bit to clear, where 0 is the least significant and 31 is the most.
*/
#define BIT32_CLEAR(a, bit) ((a) &= ~(UINT32_C(1) << ((bit) & 31)))
/**
* Gets the value of a particular bit within a 32-bit integer.
*
* @param a An unsigned 32-bit integer,
* treated as a bit array.
* @param bit Index of the bit to get, where 0 is the least significant and 31 is the most.
* @return The value of the bit at the specified index.
*/
#define BIT32_GET(a, bit) (((a) >> ((bit) & 31)) & 1)
/**
* Clears all bits in a 32-bit bitmask.
*
* @param a An unsigned 32-bit integer,
* treated as a bit array.
*/
#define BIT32_CLEAR_ALL(a) ((a) = 0)
/** @} */
/**
* @defgroup BIT64 64-bit Bit Arrays
* @{
*/
/**
* Sets a particular bit within a 64-bit integer to 1.
*
* @param a An unsigned 64-bit integer,
* treated as a bit array.
* @param bit Index of the bit to set, where 0 is the least significant and 63 is the most.
*/
#define BIT64_SET(a, bit) ((a) |= (UINT64_C(1) << ((bit) & 63)))
/**
* Clears a particular bit within a 64-bit integer.
*
* @param a An unsigned 64-bit integer,
* treated as a bit array.
* @param bit Index of the bit to clear, where 0 is the least significant and 63 is the most.
*/
#define BIT64_CLEAR(a, bit) ((a) &= ~(UINT64_C(1) << ((bit) & 63)))
/**
* Gets the value of a particular bit within a 64-bit integer.
*
* @param a An unsigned 64-bit integer,
* treated as a bit array.
* @param bit Index of the bit to get, where 0 is the least significant and 63 is the most.
* @return The value of the bit at the specified index.
*/
#define BIT64_GET(a, bit) (((a) >> ((bit) & 63)) & 1)
/**
* Clears all bits in a 64-bit bitmask.
*
* @param a An unsigned 64-bit integer,
* treated as a bit array.
*/
#define BIT64_CLEAR_ALL(a) ((a) = 0)
/** @} */
#define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (UINT32_C(1) << ((bit) & 31)))
#define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(UINT32_C(1) << ((bit) & 31)))
#define BIT128_GET(a, bit) (((a).data[(bit) >> 5] >> ((bit) & 31)) & 1)
@ -143,24 +343,98 @@ static INLINE bool bits_any_different(uint32_t *a, uint32_t *b, uint32_t count)
#define BIT128_GET_PTR(a, bit) BIT128_GET(*a, bit)
#define BIT128_CLEAR_ALL_PTR(a) BIT128_CLEAR_ALL(*a)
/**
* Sets a single bit from a 256-bit \c retro_bits_t to 1.
*
* @param a A 256-bit \c retro_bits_t.
* @param bit Index of the bit to set,
* where 0 is the least significant and 255 is the most.
*/
#define BIT256_SET(a, bit) BIT128_SET(a, bit)
/**
* Clears a single bit from a 256-bit \c retro_bits_t.
*
* @param a A 256-bit \c retro_bits_t.
* @param bit Index of the bit to clear,
* where 0 is the least significant and 255 is the most.
*/
#define BIT256_CLEAR(a, bit) BIT128_CLEAR(a, bit)
/**
* Gets the value of a single bit from a 256-bit \c retro_bits_t.
*
* @param a A 256-bit \c retro_bits_t.
* @param bit Index of the bit to get,
* where 0 is the least significant and 255 is the most.
* @return The value of the bit at the specified index.
*/
#define BIT256_GET(a, bit) BIT128_GET(a, bit)
/**
* Clears all bits in a 256-bit \c retro_bits_t.
*
* @param a A 256-bit \c retro_bits_t.
*/
#define BIT256_CLEAR_ALL(a) BIT128_CLEAR_ALL(a)
/** Variant of BIT256_SET() that takes a pointer to a \c retro_bits_t. */
#define BIT256_SET_PTR(a, bit) BIT256_SET(*a, bit)
/** Variant of BIT256_CLEAR() that takes a pointer to a \c retro_bits_t. */
#define BIT256_CLEAR_PTR(a, bit) BIT256_CLEAR(*a, bit)
/** Variant of BIT256_GET() that takes a pointer to a \c retro_bits_t. */
#define BIT256_GET_PTR(a, bit) BIT256_GET(*a, bit)
/** Variant of BIT256_CLEAR_ALL() that takes a pointer to a \c retro_bits_t. */
#define BIT256_CLEAR_ALL_PTR(a) BIT256_CLEAR_ALL(*a)
/**
* Sets a single bit from a 512-bit \c retro_bits_512_t to 1.
*
* @param a A 512-bit \c retro_bits_512_t.
* @param bit Index of the bit to set,
* where 0 is the least significant and 511 is the most.
*/
#define BIT512_SET(a, bit) BIT256_SET(a, bit)
/**
* Clears a single bit from a 512-bit \c retro_bits_512_t.
*
* @param a A 512-bit \c retro_bits_512_t.
* @param bit Index of the bit to clear,
* where 0 is the least significant and 511 is the most.
*/
#define BIT512_CLEAR(a, bit) BIT256_CLEAR(a, bit)
/**
* Gets the value of a single bit from a 512-bit \c retro_bits_512_t.
*
* @param a A 512-bit \c retro_bits_512_t.
* @param bit Index of the bit to get,
* where 0 is the least significant and 511 is the most.
* @return The value of the bit at the specified index.
*/
#define BIT512_GET(a, bit) BIT256_GET(a, bit)
/**
* Clears all bits in a 512-bit \c retro_bits_512_t.
*
* @param a A 512-bit \c retro_bits_512_t.
*/
#define BIT512_CLEAR_ALL(a) BIT256_CLEAR_ALL(a)
/** Variant of BIT512_SET() that takes a pointer to a \c retro_bits_512_t. */
#define BIT512_SET_PTR(a, bit) BIT512_SET(*a, bit)
/** Variant of BIT512_CLEAR() that takes a pointer to a \c retro_bits_512_t. */
#define BIT512_CLEAR_PTR(a, bit) BIT512_CLEAR(*a, bit)
/** Variant of BIT512_GET() that takes a pointer to a \c retro_bits_512_t. */
#define BIT512_GET_PTR(a, bit) BIT512_GET(*a, bit)
/** Variant of BIT512_CLEAR_ALL() that takes a pointer to a \c retro_bits_512_t. */
#define BIT512_CLEAR_ALL_PTR(a) BIT512_CLEAR_ALL(*a)
#define BITS_COPY16_PTR(a,bits) \
@ -183,18 +457,23 @@ static INLINE bool bits_any_different(uint32_t *a, uint32_t *b, uint32_t count)
}
/* Helper macros and struct to keep track of many booleans. */
/* This struct has 256 bits. */
/** A 256-bit boolean array. */
typedef struct
{
/** @private 256 bits. Not intended for direct use. */
uint32_t data[8];
} retro_bits_t;
/* This struct has 512 bits. */
/** A 512-bit boolean array. */
typedef struct
{
/** @private 512 bits. Not intended for direct use. */
uint32_t data[16];
} retro_bits_512_t;
/** @} */
#ifdef _WIN32
# ifdef _WIN64
# define PRI_SIZET PRIu64

View file

@ -80,10 +80,9 @@ static int nanosleepDOS(const struct timespec *rqtp, struct timespec *rmtp)
#endif
/**
* retro_sleep:
* @msec : amount in milliseconds to sleep
* Briefly suspends the running thread.
*
* Sleeps for a specified amount of milliseconds (@msec).
* @param msec The time to sleep for, in milliseconds.
**/
#if defined(VITA)
#define retro_sleep(msec) (sceKernelDelayThread(1000 * (msec)))

View file

@ -32,235 +32,274 @@
RETRO_BEGIN_DECLS
/** Platform-agnostic handle to a thread. */
typedef struct sthread sthread_t;
/** Platform-agnostic handle to a mutex. */
typedef struct slock slock_t;
/** Platform-agnostic handle to a condition variable. */
typedef struct scond scond_t;
#ifdef HAVE_THREAD_STORAGE
/** Platform-agnostic handle to thread-local storage. */
typedef unsigned sthread_tls_t;
#endif
/**
* sthread_create:
* @start_routine : thread entry callback function
* @userdata : pointer to userdata that will be made
* available in thread entry callback function
* Creates a new thread and starts running it.
*
* Create a new thread.
*
* Returns: pointer to new thread if successful, otherwise NULL.
* @param thread_func Function to run in the new thread.
* Called with the value given in \c userdata as an argument.
* @param userdata Pointer to anything (even \c NULL), passed directly to \c thread_func.
* Must be cleaned up by the caller or the thread.
* @return Pointer to the new thread,
* or \c NULL if there was an error.
* @warn Make sure that the thread can respond to cancellation requests,
* especially if used in a core.
* If a core-created thread isn't terminated by the time the core is unloaded,
* it may leak into the frontend and cause undefined behavior
* (especially if another session with the core is started).
*/
sthread_t *sthread_create(void (*thread_func)(void*), void *userdata);
/**
* sthread_create_with_priority:
* @start_routine : thread entry callback function
* @userdata : pointer to userdata that will be made
* available in thread entry callback function
* @thread_priority : thread priority hint value from [1-100]
* Creates a new thread with a specific priority hint and starts running it.
*
* Create a new thread. It is possible for the caller to give a hint
* for the thread's priority from [1-100]. Any passed in @thread_priority
* values that are outside of this range will cause sthread_create() to
* create a new thread using the operating system's default thread
* priority.
*
* Returns: pointer to new thread if successful, otherwise NULL.
* @param thread_func Function to run in the new thread.
* Called with the value given in \c userdata as an argument.
* @param userdata Pointer to anything (even \c NULL), passed directly to \c thread_func.
* Must be cleaned up by the caller or the thread.
* @param thread_priority Priority hint for the new thread.
* Threads with a higher number are more likely to be scheduled first.
* Should be between 1 and 100, inclusive;
* if not, the operating system will assign a default priority.
* May be ignored.
* @return Pointer to the new thread,
* or \c NULL if there was an error.
*/
sthread_t *sthread_create_with_priority(void (*thread_func)(void*), void *userdata, int thread_priority);
/**
* sthread_detach:
* @thread : pointer to thread object
* Detaches the given thread.
*
* Detach a thread. When a detached thread terminates, its
* resource sare automatically released back to the system
* without the need for another thread to join with the
* terminated thread.
* When a detached thread terminates,
* its resources are automatically released back to the operating system
* without needing another thread to join with it.
*
* Returns: 0 on success, otherwise it returns a non-zero error number.
* @param thread Thread to detach.
* @return 0 on success, a non-zero error code on failure.
* @warn Once a thread is detached, it cannot be joined.
* @see sthread_join
*/
int sthread_detach(sthread_t *thread);
/**
* sthread_join:
* @thread : pointer to thread object
* Waits for the given thread to terminate.
*
* Join with a terminated thread. Waits for the thread specified by
* @thread to terminate. If that thread has already terminated, then
* it will return immediately. The thread specified by @thread must
* be joinable.
*
* Returns: 0 on success, otherwise it returns a non-zero error number.
* @param thread The thread to wait for.
* Must be joinable.
* Returns immediately if it's already terminated
* or if it's \c NULL.
*/
void sthread_join(sthread_t *thread);
/**
* sthread_isself:
* @thread : pointer to thread object
* Returns whether the given thread is the same as the calling thread.
*
* Returns: true (1) if calling thread is the specified thread
* @param thread Thread to check.
* @return \c true if \c thread is the same as the calling thread,
* \c false if not or if it's \c NULL.
* @note libretro does not have a notion of a "main" thread,
* since the core may not be running on the same thread
* that called \c main (or local equivalent).
* @see sthread_get_thread_id
*/
bool sthread_isself(sthread_t *thread);
/**
* slock_new:
* Creates a new mutex (a.k.a. lock) that can be used to synchronize shared data.
*
* Create and initialize a new mutex. Must be manually
* freed.
* Must be manually freed with \c slock_free.
*
* Returns: pointer to a new mutex if successful, otherwise NULL.
**/
* @return Pointer to the new mutex,
* or \c NULL if there was an error.
*/
slock_t *slock_new(void);
/**
* slock_free:
* @lock : pointer to mutex object
*
* Frees a mutex.
**/
*
* Behavior is undefined if \c lock was previously freed.
*
* @param lock Pointer to the mutex to free.
* May be \c NULL, in which this function does nothing.
*/
void slock_free(slock_t *lock);
/**
* slock_lock:
* @lock : pointer to mutex object
* Locks a mutex, preventing other threads from claiming it until it's unlocked.
*
* Locks a mutex. If a mutex is already locked by
* another thread, the calling thread shall block until
* the mutex becomes available.
**/
* If the mutex is already locked by another thread,
* the calling thread will block until the mutex is unlocked.
*
* @param lock Pointer to the mutex to lock.
* If \c NULL, will return without further action.
* @see slock_try_lock
*/
void slock_lock(slock_t *lock);
/**
* slock_try_lock:
* @lock : pointer to mutex object
* Tries to lock a mutex if it's not already locked by another thread.
*
* Attempts to lock a mutex. If a mutex is already locked by
* another thread, return false. If the lock is acquired, return true.
**/
* If the mutex is already in use by another thread,
* returns immediately without waiting for it.
*
* @param lock The mutex to try to lock.
* @return \c true if the mutex was successfully locked,
* \c false if it was already locked by another thread or if \c lock is \c NULL.
* @see slock_lock
*/
bool slock_try_lock(slock_t *lock);
/**
* slock_unlock:
* @lock : pointer to mutex object
* Unlocks a mutex, allowing other threads to claim it.
*
* Unlocks a mutex.
**/
* @post The mutex is unlocked,
* and another thread may lock it.
* @param lock The mutex to unlock.
* If \c NULL, this function is a no-op.
*/
void slock_unlock(slock_t *lock);
/**
* scond_new:
* Creates and initializes a condition variable.
*
* Creates and initializes a condition variable. Must
* be manually freed.
* Must be manually freed with \c scond_free.
*
* Returns: pointer to new condition variable on success,
* otherwise NULL.
**/
* @return Pointer to the new condition variable,
* or \c NULL if there was an error.
*/
scond_t *scond_new(void);
/**
* scond_free:
* @cond : pointer to condition variable object
*
* Frees a condition variable.
**/
*
* @param cond Pointer to the condition variable to free.
* If \c NULL, this function is a no-op.
* Behavior is undefined if \c cond was previously freed.
*/
void scond_free(scond_t *cond);
/**
* scond_wait:
* @cond : pointer to condition variable object
* @lock : pointer to mutex object
* Blocks until the given condition variable is signaled or broadcast.
*
* Block on a condition variable (i.e. wait on a condition).
**/
* @param cond Condition variable to wait on.
* This function blocks until another thread
* calls \c scond_signal or \c scond_broadcast with this condition variable.
* @param lock Mutex to lock while waiting.
*
* @see scond_signal
* @see scond_broadcast
* @see scond_wait_timeout
*/
void scond_wait(scond_t *cond, slock_t *lock);
/**
* scond_wait_timeout:
* @cond : pointer to condition variable object
* @lock : pointer to mutex object
* @timeout_us : timeout (in microseconds)
* Blocks until the given condition variable is signaled or broadcast,
* or until the specified time has passed.
*
* Try to block on a condition variable (i.e. wait on a condition) until
* @timeout_us elapses.
* @param cond Condition variable to wait on.
* This function blocks until another thread
* calls \c scond_signal or \c scond_broadcast with this condition variable.
* @param lock Mutex to lock while waiting.
* @param timeout_us Time to wait for a signal, in microseconds.
*
* Returns: false (0) if timeout elapses before condition variable is
* signaled or broadcast, otherwise true (1).
**/
* @return \c false if \c timeout_us elapses
* before \c cond is signaled or broadcast, otherwise \c true.
*/
bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us);
/**
* scond_broadcast:
* @cond : pointer to condition variable object
* Unblocks all threads waiting on the specified condition variable.
*
* Broadcast a condition. Unblocks all threads currently blocked
* on the specified condition variable @cond.
**/
* @param cond Condition variable to broadcast.
* @return 0 on success, non-zero on failure.
*/
int scond_broadcast(scond_t *cond);
/**
* scond_signal:
* @cond : pointer to condition variable object
* Unblocks at least one thread waiting on the specified condition variable.
*
* Signal a condition. Unblocks at least one of the threads currently blocked
* on the specified condition variable @cond.
**/
* @param cond Condition variable to signal.
*/
void scond_signal(scond_t *cond);
#ifdef HAVE_THREAD_STORAGE
/**
* @brief Creates a thread local storage key
* Creates a thread-local storage key.
*
* This function shall create thread-specific data key visible to all threads in
* the process. The same key can be used by multiple threads to store
* thread-local data.
* Thread-local storage keys have a single value associated with them
* that is unique to the thread that uses them.
*
* When the key is created NULL shall be associated with it in all active
* threads. Whenever a new thread is spawned the all defined keys will be
* associated with NULL on that thread.
* New thread-local storage keys have a value of \c NULL for all threads,
* and new threads initialize all existing thread-local storage to \c NULL.
*
* @param tls
* @return whether the operation suceeded or not
* @param tls[in,out] Pointer to the thread local storage key that will be initialized.
* Must be cleaned up with \c sthread_tls_delete.
* Behavior is undefined if \c NULL.
* @return \c true if the operation succeeded, \c false otherwise.
* @see sthread_tls_delete
*/
bool sthread_tls_create(sthread_tls_t *tls);
/**
* @brief Deletes a thread local storage
* @param tls
* @return whether the operation suceeded or not
* Deletes a thread local storage key.
*
* The value must be cleaned up separately \em before calling this function,
* if necessary.
*
* @param tls The thread local storage key to delete.
* Behavior is undefined if \c NULL.
* @return \c true if the operation succeeded, \c false otherwise.
*/
bool sthread_tls_delete(sthread_tls_t *tls);
/**
* @brief Retrieves thread specific data associated with a key
* Gets the calling thread's local data for the given key.
*
* There is no way to tell whether this function failed.
*
* @param tls
* @return
* @param tls The thread-local storage key to get the data for.
* @return The calling thread's local data associated with \c tls,
* which should previously have been set with \c sthread_tls_set.
* Will be \c NULL if this thread has not set a value or if there was an error.
*/
void *sthread_tls_get(sthread_tls_t *tls);
/**
* @brief Binds thread specific data to a key
* @param tls
* @return Whether the operation suceeded or not
* Sets the calling thread's local data for the given key.
*
* @param tls The thread-local storage key to set the data for.
* @param data Pointer to the data that will be associated with \c tls.
* May be \c NULL.
* @return \c true if \c data was successfully assigned to \c tls,
* \c false if there was an error.
*/
bool sthread_tls_set(sthread_tls_t *tls, const void *data);
#endif
/*
* @brief Get thread ID of specified thread
* @param thread
* @return The ID of the specified thread
/**
* Gets a thread's unique ID.
*
* @param thread The thread to get the ID of.
* @return The provided thread's ID,
* or 0 if it's \c NULL.
*/
uintptr_t sthread_get_thread_id(sthread_t *thread);
/*
* @brief Get thread ID of the current thread
* @param
* @return The ID of the current thread
/**
* Get the calling thread's unique ID.
* @return The calling thread's ID.
* @see sthread_get_thread_id
*/
uintptr_t sthread_get_current_thread_id(void);

View file

@ -38,105 +38,377 @@
#include <stdarg.h>
#include <vfs/vfs_implementation.h>
/** @defgroup file_stream File Streams
*
* All functions in this header will use the VFS interface set in \ref filestream_vfs_init if possible,
* or else they will fall back to built-in equivalents.
*
* @note These functions are modeled after those in the C standard library
* (and may even use them internally),
* but identical behavior is not guaranteed.
*
* @{
*/
/**
* The minimum version of the VFS interface required by the \c filestream functions.
*/
#define FILESTREAM_REQUIRED_VFS_VERSION 2
RETRO_BEGIN_DECLS
/**
* Opaque handle to a file stream.
* @warning This is not interchangeable with \c FILE* or \c retro_vfs_file_handle.
*/
typedef struct RFILE RFILE;
#define FILESTREAM_REQUIRED_VFS_VERSION 2
/**
* Initializes the \c filestream functions to use the VFS interface provided by the frontend.
* Optional; if not called, all \c filestream functions
* will use libretro-common's built-in implementations.
*
* @param vfs_info The VFS interface returned by the frontend.
* If \c vfs_info::iface (but \em not \c vfs_info itself) is \c NULL,
* then libretro-common's built-in VFS implementation will be used.
*/
void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info);
/**
* Returns the size of the given file, in bytes.
*
* @param stream The open file to query.
* @return The size of \c stream in bytes,
* or -1 if there was an error.
* @see retro_vfs_size_t
*/
int64_t filestream_get_size(RFILE *stream);
/**
* Sets the size of the given file,
* truncating or extending it as necessary.
*
* @param stream The file to resize.
* @param length The new size of \c stream, in bytes.
* @return 0 if the resize was successful,
* or -1 if there was an error.
* @see retro_vfs_truncate_t
*/
int64_t filestream_truncate(RFILE *stream, int64_t length);
/**
* filestream_open:
* @path : path to file
* @mode : file mode to use when opening (read/write)
* @bufsize : optional buffer size (-1 or 0 to use default)
* Opens a file for reading or writing.
*
* Opens a file for reading or writing, depending on the requested mode.
* @return A pointer to an RFILE if opened successfully, otherwise NULL.
**/
* @param path Path to the file to open.
* Should be in the format described in \ref GET_VFS_INTERFACE.
* @param mode The mode to open the file in.
* Should be one or more of the flags in \refitem RETRO_VFS_FILE_ACCESS OR'd together,
* and \c RETRO_VFS_FILE_ACCESS_READ or \c RETRO_VFS_FILE_ACCESS_WRITE
* (or both) must be included.
* @param hints Optional hints to pass to the frontend.
*
* @return The opened file, or \c NULL if there was an error.
* Must be cleaned up with \c filestream_close when no longer needed.
* @see retro_vfs_open_t
*/
RFILE* filestream_open(const char *path, unsigned mode, unsigned hints);
/**
* Sets the current position of the file stream.
* Use this to read specific sections of a file.
*
* @param stream The file to set the stream position of.
* @param offset The new stream position, in bytes.
* @param seek_position The position to seek from.
* Should be one of the values in \refitem RETRO_VFS_SEEK_POSITION.
* @return The new stream position in bytes relative to the beginning,
* or -1 if there was an error.
* @see RETRO_VFS_SEEK_POSITION
* @see retro_vfs_seek_t
*/
int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position);
/**
* Reads data from the given file into a buffer.
* If the read is successful,
* the file's stream position will advance by the number of bytes read.
*
* @param stream The file to read from.
* @param data The buffer in which to store the read data.
* @param len The size of \c data, in bytes.
* @return The number of bytes read,
* or -1 if there was an error.
* May be less than \c len, but never more.
* @see retro_vfs_read_t
*/
int64_t filestream_read(RFILE *stream, void *data, int64_t len);
/**
* Writes data from a buffer to the given file.
* If the write is successful,
* the file's stream position will advance by the number of bytes written.
*
* @param stream The file to write to.
* @param data The buffer containing the data to write.
* @param len The size of \c data, in bytes.
* @return The number of bytes written,
* or -1 if there was an error.
* May be less than \c len, but never more.
* @see retro_vfs_write_t
*/
int64_t filestream_write(RFILE *stream, const void *data, int64_t len);
/**
* Returns the current position of the given file in bytes.
*
* @param stream The file to return the stream position for.
* @return The current stream position in bytes relative to the beginning,
* or -1 if there was an error.
* @see retro_vfs_tell_t
*/
int64_t filestream_tell(RFILE *stream);
/**
* Rewinds the given file to the beginning.
* Equivalent to <tt>filestream_seek(stream, 0, RETRO_VFS_SEEK_POSITION_START)</tt>.
* @param stream The file to rewind.
* May be \c NULL, in which case this function does nothing.
*/
void filestream_rewind(RFILE *stream);
/**
* Closes the given file.
*
* @param stream The file to close.
* This should have been created with \c filestream_open.
* Behavior is undefined if \c NULL.
* @return 0 if the file was closed successfully,
* or -1 if there was an error.
* @post \c stream is no longer valid and should not be used,
* even if this function fails.
* @see retro_vfs_close_t
*/
int filestream_close(RFILE *stream);
/**
* filestream_read_file:
* @path : path to file.
* @buf : buffer to allocate and read the contents of the
* file into. Needs to be freed manually.
* @len : optional output integer containing bytes read.
* Opens a file, reads its contents into a newly-allocated buffer,
* then closes it.
*
* Read the contents of a file into @buf.
*
* @return Non-zero on success.
* @param path[in] Path to the file to read.
* Should be in the format described in \ref GET_VFS_INTERFACE.
* @param buf[out] A pointer to the address of the newly-allocated buffer.
* The buffer will contain the entirety of the file at \c path.
* Will be allocated with \c malloc and must be freed with \c free.
* @param len[out] Pointer to the size of the buffer in bytes.
* May be \c NULL, in which case the length is not written.
* Value is unspecified if this function fails.
* @return 1 if the file was read successfully,
* 0 if there was an error.
* @see filestream_write_file
*/
int64_t filestream_read_file(const char *path, void **buf, int64_t *len);
/**
* Reads a line of text from the given file,
* up to a given length.
*
* Will read to the next newline or until the buffer is full,
* whichever comes first.
*
* @param stream The file to read from.
* @param s The buffer to write the retrieved line to.
* Will contain at most \c len - 1 characters
* plus a null terminator.
* The newline character (if any) will not be included.
* The line delimiter must be Unix-style (\c '\n').
* Carriage returns (\c '\r') will not be treated specially.
* @param len The length of the buffer \c s, in bytes.
* @return \s if successful, \c NULL if there was an error.
*/
char* filestream_gets(RFILE *stream, char *s, size_t len);
/**
* Reads a single character from the given file.
*
* @param stream The file to read from.
* @return The character read, or -1 upon reaching the end of the file.
*/
int filestream_getc(RFILE *stream);
/**
* Reads formatted text from the given file,
* with arguments provided as a standard \c va_list.
*
* @param stream The file to read from.
* @param format The string to write, possibly including scanf-compatible format specifiers.
* @param args Argument list with zero or more elements
* whose values will be updated according to the semantics of \c format.
* @return The number of arguments in \c args that were successfully assigned,
* or -1 if there was an error.
* @see https://en.cppreference.com/w/c/io/fscanf
* @see https://en.cppreference.com/w/c/variadic
*/
int filestream_vscanf(RFILE *stream, const char* format, va_list *args);
/**
* Reads formatted text from the given file.
*
* @param stream The file to read from.
* @param format The string to write, possibly including scanf-compatible format specifiers.
* @param ... Zero or more arguments that will be updated according to the semantics of \c format.
* @return The number of arguments in \c ... that were successfully assigned,
* or -1 if there was an error.
* @see https://en.cppreference.com/w/c/io/fscanf
*/
int filestream_scanf(RFILE *stream, const char* format, ...);
/**
* Determines if there's any more data left to read from this file.
*
* @param stream The file to check the position of.
* @return -1 if this stream has reached the end of the file,
* 0 if not.
*/
int filestream_eof(RFILE *stream);
/**
* filestream_write_file:
* @path : path to file.
* @data : contents to write to the file.
* @size : size of the contents.
* Writes the entirety of a given buffer to a file at a given path.
* Any file that already exists will be overwritten.
*
* Writes data to a file.
*
* @return true on success, otherwise false.
**/
* @param path Path to the file that will be written to.
* @param data The buffer to write to \c path.
* @param size The size of \c data, in bytes.
* @return \c true if the file was written successfully,
* \c false if there was an error.
*/
bool filestream_write_file(const char *path, const void *data, int64_t size);
/**
* Writes a single character to the given file.
*
* @param stream The file to write to.
* @param c The character to write.
* @return The character written,
* or -1 if there was an error.
* Will return -1 if \c stream is \c NULL.
*/
int filestream_putc(RFILE *stream, int c);
/**
* Writes formatted text to the given file,
* with arguments provided as a standard \c va_list.
*
* @param stream The file to write to.
* @param format The string to write, possibly including printf-compatible format specifiers.
* @param args A list of arguments to be formatted and inserted in the resulting string.
* @return The number of characters written,
* or -1 if there was an error.
* @see https://en.cppreference.com/w/c/io/vfprintf
* @see https://en.cppreference.com/w/c/variadic
*/
int filestream_vprintf(RFILE *stream, const char* format, va_list args);
/**
* Writes formatted text to the given file.
*
* @param stream The file to write to.
* @param format The string to write, possibly including printf-compatible format specifiers.
* @param ... Zero or more arguments to be formatted and inserted into the resulting string.
* @return The number of characters written,
* or -1 if there was an error.
* @see https://en.cppreference.com/w/c/io/printf
*/
int filestream_printf(RFILE *stream, const char* format, ...);
/**
* Checks if there was an error in using the given file stream.
*
* @param stream The file stream to check for errors.
* @return \c true if there was an error in using this stream,
* \c false if not or if \c stream is \c NULL.
*/
int filestream_error(RFILE *stream);
/**
* Flushes pending writes to the operating system's file layer.
* There is no guarantee that pending writes will be written to disk immediately.
*
* @param stream The file to flush.
* @return 0 if the flush was successful,
* or -1 if there was an error.
* @see retro_vfs_flush_t
*/
int filestream_flush(RFILE *stream);
/**
* Deletes the file at the given path.
* If the file is open by any process,
* the behavior is platform-specific.
*
* @note This function might or might not delete directories recursively,
* depending on the platform and the underlying VFS implementation.
*
* @param path The file to delete.
* @return 0 if the file was deleted successfully,
* or -1 if there was an error.
* @see retro_vfs_remove_t
*/
int filestream_delete(const char *path);
/**
* Moves a file to a new location, with a new name.
*
* @param old_path Path to the file to rename.
* @param new_path The target name and location of the file.
* @return 0 if the file was renamed successfully,
* or -1 if there was an error.
* @see retro_vfs_rename_t
*/
int filestream_rename(const char *old_path, const char *new_path);
/**
* Get the path that was used to open a file.
*
* @param stream The file to get the path of.
* @return The path that was used to open \c stream,
* or \c NULL if there was an error.
* The string is owned by \c stream and must not be modified or freed by the caller.
*/
const char* filestream_get_path(RFILE *stream);
/**
* Determines if a file exists at the given path.
*
* @param path The path to check for existence.
* @return \c true if a file exists at \c path,
* \c false if not or if \c path is \c NULL or empty.
*/
bool filestream_exists(const char *path);
/**
* filestream_getline:
* Reads a line from the given file into a newly-allocated buffer.
*
* Returned pointer must be freed by the caller.
**/
* @param stream The file to read from.
* @return Pointer to the line read from \c stream,
* or \c NULL if there was an error.
* Must be freed with \c free when no longer needed.
*/
char* filestream_getline(RFILE *stream);
/**
* Returns the open file handle
* that was originally returned by the VFS interface.
*
* @param stream File handle returned by \c filestream_open.
* @return The file handle returned by the underlying VFS implementation.
*/
libretro_vfs_implementation_file* filestream_get_vfs_handle(RFILE *stream);
RETRO_END_DECLS
/** @} */
#endif

View file

@ -28,10 +28,23 @@
#include <retro_common_api.h>
#include <streams/file_stream.h>
/**
* @file file_stream_transforms.h
*
* Contains macros that redirect standard C I/O functions
* to libretro's own file stream API.
* Useful when porting an existing emulator to a core.
* To use these functions without overriding the standard I/O functions,
* define \c SKIP_STDIO_REDEFINES before including this header.
*
* @see https://man7.org/linux/man-pages/man3/stdio.3.html
*/
RETRO_BEGIN_DECLS
#ifndef SKIP_STDIO_REDEFINES
/** @see https://en.cppreference.com/w/c/io/FILE */
#define FILE RFILE
#undef fopen
@ -66,34 +79,48 @@ RETRO_BEGIN_DECLS
#endif
/** @see https://en.cppreference.com/w/c/io/fopen */
RFILE* rfopen(const char *path, const char *mode);
/** @see https://en.cppreference.com/w/c/io/fclose */
int rfclose(RFILE* stream);
/** @see https://en.cppreference.com/w/c/io/ftell */
int64_t rftell(RFILE* stream);
/** @see https://en.cppreference.com/w/c/io/fseek */
int64_t rfseek(RFILE* stream, int64_t offset, int origin);
/** @see https://en.cppreference.com/w/c/io/fread */
int64_t rfread(void* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
/** @see https://en.cppreference.com/w/c/io/fgets */
char *rfgets(char *buffer, int maxCount, RFILE* stream);
/** @see https://en.cppreference.com/w/c/io/fgetc */
int rfgetc(RFILE* stream);
/** @see https://en.cppreference.com/w/c/io/fwrite */
int64_t rfwrite(void const* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
/** @see https://en.cppreference.com/w/c/io/fputc */
int rfputc(int character, RFILE * stream);
/** @see https://en.cppreference.com/w/c/io/fflush */
int64_t rfflush(RFILE * stream);
/** @see https://en.cppreference.com/w/c/io/fprintf */
int rfprintf(RFILE * stream, const char * format, ...);
/** @see https://en.cppreference.com/w/c/io/ferror */
int rferror(RFILE* stream);
/** @see https://en.cppreference.com/w/c/io/feof */
int rfeof(RFILE* stream);
/** @see https://en.cppreference.com/w/c/io/fscanf */
int rfscanf(RFILE * stream, const char * format, ...);
RETRO_END_DECLS

View file

@ -34,230 +34,359 @@ RETRO_BEGIN_DECLS
enum
{
/**
* Indicates that \c netstream_seek should seek
* relative to the beginning of the stream.
*/
NETSTREAM_SEEK_SET = 0,
/**
* Indicates that \c netstream_seek should seek
* relative to its current position.
*/
NETSTREAM_SEEK_CUR,
/**
* Indicates that \c netstream_seek should seek
* relative to the end of the stream.
*/
NETSTREAM_SEEK_END
};
/**
* A stream that ensures data is read/written in network byte order (big endian).
*
* @note Despite what the name may suggests,
* this object does \em not actually perform any network operations.
* It is intended to be used as input/output for functions that do.
*/
typedef struct netstream
{
/** The buffer used by the stream for reading or writing. */
void *buf;
/** The size of \c buf in bytes. */
size_t size;
/** The number of bytes that have been written to \c buf. */
size_t used;
/**
* The current position of the stream, in bytes.
* @see netstream_seek
*/
size_t pos;
} netstream_t;
/**
* netstream_open:
* Opens a network-order stream.
*
* @stream : Pointer to a network stream object.
* @buf : Pre-allocated buffer. Pass NULL to dynamically allocate a buffer.
* @size : Buffer size. Pass 0 for no pre-allocated/initial buffer.
* @used : Buffer bytes in use. Ignored for non pre-allocated buffers.
*
* Opens a network stream.
*
* Returns: true on success, false otherwise.
* @param stream Pointer to the network-order stream to initialize.
* Behavior is undefined if \c NULL.
* @param buf Pre-allocated buffer.
* May be \c NULL, in which case a new buffer will be created with \c malloc.
* @param size Buffer size in bytes.
* If \c buf is \c NULL, then this will be the size of the newly-allocated buffer.
* If not, then this is the size of the existing buffer.
* If zero, then a buffer will not be allocated.
* @param used The number of bytes in use.
* Ignored for non pre-allocated buffers.
* @return \c true if the stream was opened.
* For new buffers, \c false if allocation failed.
* For existing buffers, \c false if \c size is zero
* or less than \c used.
* @see netstream_close
*/
bool netstream_open(netstream_t *stream, void *buf, size_t size, size_t used);
/**
* netstream_close:
*
* @stream : Pointer to a network stream object.
* @dealloc : Whether to deallocate/free the buffer or not.
*
* Closes a network stream.
* Closes a network-order stream.
*
* @param stream Pointer to the network-order stream to close.
* The stream itself is not deallocated,
* but its fields will be reset.
* Behavior is undefined if \c NULL.
* @param dealloc Whether to release the underlying buffer with \c free.
* Set to \c true if the creating \c netstream_open call allocated a buffer,
* or else its memory will be leaked.
* @note \c stream itself is not deallocated.
* This function can be used on static or local variables.
* @see netstream_open
*/
void netstream_close(netstream_t *stream, bool dealloc);
/**
* netstream_reset:
* Resets the stream to the beginning and discards any used bytes.
*
* @stream : Pointer to a network stream object.
*
* Resets a network stream to its initial position,
* discarding any used bytes in the process.
* @param stream The network-order stream to reset.
* Behavior is undefined if \c NULL.
*
* @note This does not deallocate the underlying buffer,
* nor does it wipe its memory.
*/
void netstream_reset(netstream_t *stream);
/**
* netstream_truncate:
* Resizes the "used" portion of the stream.
*
* @stream : Pointer to a network stream object.
* @used : Amount of bytes used.
*
* Truncates the network stream.
* Truncation can either extend or reduce the amount of bytes used.
*
* Returns: true on success, false otherwise.
* @param stream The network-order stream to resize.
* Behavior is undefined if \c NULL.
* @param used The number of bytes in the stream that are considered written.
* @return \c true if the stream's "used" region was resized,
* \c false if it would've been extended past the buffer's capacity.
* @note This function does not reallocate or clear the underlying buffer.
* It only sets the boundaries of the "used" portion of the stream.
*/
bool netstream_truncate(netstream_t *stream, size_t used);
/**
* netstream_data:
*
* @stream : Pointer to a network stream object.
* @data : Pointer to an object to store a reference of the stream's data.
* @len : Pointer to an object to store the amount of bytes in use.
*
* Gets the network stream's data.
* Retrieves the network-order stream's data.
*
* @param stream Pointer to the network-order stream.
* Behavior is undefined if \c NULL.
* @param data[out] Pointer to a variable to store the stream's data.
* The data itself is not copied,
* so the pointer will be invalidated
* if the stream is closed or reallocated.
* @param len[out] Set to the length of the stream's data in bytes.
*/
void netstream_data(netstream_t *stream, void **data, size_t *len);
/**
* netstream_eof:
* Checks whether the network-order stream has any more data to read,
* or any more room to write data.
*
* @stream : Pointer to a network stream object.
*
* Checks whether the network stream is at EOF or not.
*
* Returns: true if the stream is at EOF, false otherwise.
* @param stream The network-order stream to check.
* @return \c true if the stream is at EOF, \c false otherwise.
*/
bool netstream_eof(netstream_t *stream);
/**
* netstream_tell:
* Gets the network-order stream's current position.
*
* @stream : Pointer to a network stream object.
*
* Gets the network stream's current position.
*
* Returns: current value of the position indicator.
* @param stream Pointer to a network-order stream.
* @return The stream's position indicator.
*/
size_t netstream_tell(netstream_t *stream);
/**
* netstream_seek:
* Sets the network-order stream's current position.
*
* @stream : Pointer to a network stream object.
* @offset : Position's offset.
* @origin : Position used as reference for the offset.
*
* Sets the network stream's current position.
*
* Returns: true on success, false otherwise.
* @param stream Pointer to a network-order stream.
* @param offset The new position of the stream, in bytes.
* @param origin The position used as reference for the offset.
* Must be one of \c NETSTREAM_SEEK_SET, \c NETSTREAM_SEEK_CUR or \c NETSTREAM_SEEK_END.
* @return \c true on success, \c false on failure.
*/
bool netstream_seek(netstream_t *stream, long offset, int origin);
/**
* netstream_read:
* Reads data from the network-order stream.
* Does not byte-swap any data;
* this is useful for reading strings or unspecified binary data.
*
* @stream : Pointer to a network stream object.
* @data : Pointer to a storage for data read from the network stream.
* @len : Amount of bytes to read. Pass 0 to read all remaining bytes.
*
* Reads raw data from the network stream.
*
* Returns: true on success, false otherwise.
* @param stream The network-order stream to read from.
* @param data The buffer that will receive data from the stream.
* @param len The number of bytes to read.
* If 0, will read all remaining bytes.
* @return \c true on success, \c false on failure.
*/
bool netstream_read(netstream_t *stream, void *data, size_t len);
/**
* netstream_read_(type):
* Reads a single byte from the network-order stream.
*
* @stream : Pointer to a network stream object.
* @data : Pointer to a storage for data read from the network stream.
*
* Reads data from the network stream.
* Network byte order is always big endian.
*
* Returns: true on success, false otherwise.
* @param stream[in] The network-order stream to read from.
* @param data[out] Pointer to the byte that will receive the read value.
* @return \c true on success, \c false if there was an error.
*/
bool netstream_read_byte(netstream_t *stream, uint8_t *data);
/**
* Reads an unsigned 16-bit integer from the network-order stream,
* byte-swapping it from big endian to host-native byte order if necessary.
*
* @param stream[in] The network-order stream to read from.
* @param data[out] Pointer to the value that will receive the read value.
* @return \c true on success, \c false if there was an error.
*/
bool netstream_read_word(netstream_t *stream, uint16_t *data);
/**
* Reads an unsigned 32-bit integer from the network-order stream,
* byte-swapping it from big endian to host-native byte order if necessary.
*
* @param stream[in] The network-order stream to read from.
* @param data[out] Pointer to the value that will receive the read value.
* @return \c true on success, \c false if there was an error.
*/
bool netstream_read_dword(netstream_t *stream, uint32_t *data);
/**
* Reads an unsigned 64-bit integer from the network-order stream,
* byte-swapping it from big endian to host-native byte order if necessary.
*
* @param stream[in] The network-order stream to read from.
* @param data[out] Pointer to the value that will receive the read value.
* @return \c true on success, \c false if there was an error.
*/
bool netstream_read_qword(netstream_t *stream, uint64_t *data);
#ifdef __STDC_IEC_559__
/**
* Reads a 32-bit floating-point number from the network-order stream,
* byte-swapping it from big endian to host-native byte order if necessary.
*
* @param stream[in] The network-order stream to read from.
* @param data[out] Pointer to the value that will receive the read value.
* @return \c true on success, \c false if there was an error.
*/
bool netstream_read_float(netstream_t *stream, float *data);
/**
* Reads a 64-bit floating-point number from the network-order stream,
* byte-swapping it from big endian to host-native byte order if necessary.
*
* @param stream[in] The network-order stream to read from.
* @param data[out] Pointer to the value that will receive the read value.
* @return \c true on success, \c false if there was an error.
*/
bool netstream_read_double(netstream_t *stream, double *data);
#endif
/**
* netstream_read_string:
* Reads a null-terminated string from the network-order stream,
* up to the given length.
*
* @stream : Pointer to a network stream object.
* @s : Pointer to a string buffer.
* @len : Size of the string buffer.
*
* Reads a string from the network stream.
*
* Returns: Length of the original string on success or
* a negative value on error.
* @param stream Pointer to a network stream object.
* @param s[out] The buffer that will receive the string.
* Will be \c NULL-terminated.
* @param len The length of \c s, in bytes.
* @return The length of the read string in bytes,
* or -1 if there was an error.
*/
int netstream_read_string(netstream_t *stream, char *s, size_t len);
/**
* netstream_read_fixed_string:
* Reads a string of fixed length from a network-order stream.
* Will fail if there isn't enough data to read.
*
* @stream : Pointer to a network stream object.
* @s : Pointer to a string buffer.
* @len : Size of the string buffer.
* @param stream Pointer to a network stream object.
* @param s The buffer that will receive the string.
* Will be \c NULL-terminated.
* @param len The length of \c s in bytes,
* including the \c NULL terminator.
*
* Reads a fixed-length string from the network stream.
*
* Returns: true on success, false otherwise.
* @return \c true if a string of the exact length was read,
* \c false if there was an error.
*/
bool netstream_read_fixed_string(netstream_t *stream, char *s, size_t len);
/**
* netstream_write:
* Writes arbitrary data to a network-order stream.
* Does not byte-swap any data;
* this is useful for writing strings or unspecified binary data.
*
* @stream : Pointer to a network stream object.
* @data : Data to write into the network stream.
* @len : Amount of bytes to write.
*
* Writes raw data into the network stream.
*
* Returns: true on success, false otherwise.
* @param stream Pointer to a network stream object.
* @param data The data to write into the network stream.
* @param len The length of \c data, in bytes.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write(netstream_t *stream, const void *data, size_t len);
/**
* netstream_write_(type):
* Writes a single byte to a network-order stream.
*
* @stream : Pointer to a network stream object.
* @data : Data to write into the network stream.
*
* Writes data into the network stream.
* Network byte order is always big endian.
*
* Returns: true on success, false otherwise.
* @param stream Pointer to a network stream object.
* @param data The byte to write to the stream.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write_byte(netstream_t *stream, uint8_t data);
/**
* Writes an unsigned 16-bit integer to a network-order stream,
* byte-swapping it from host-native byte order to big-endian if necessary.
*
* @param stream Pointer to a network stream object.
* @param data The value to write to the stream.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write_word(netstream_t *stream, uint16_t data);
/**
* Writes an unsigned 32-bit integer to a network-order stream,
* byte-swapping it from host-native byte order to big-endian if necessary.
*
* @param stream Pointer to a network stream object.
* @param data The value to write to the stream.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write_dword(netstream_t *stream, uint32_t data);
/**
* Writes an unsigned 64-bit integer to a network-order stream,
* byte-swapping it from host-native byte order to big-endian if necessary.
*
* @param stream Pointer to a network stream object.
* @param data The value to write to the stream.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write_qword(netstream_t *stream, uint64_t data);
#ifdef __STDC_IEC_559__
/**
* Writes a 32-bit floating-point number to a network-order stream,
* byte-swapping it from host-native byte order to big-endian if necessary.
*
* @param stream Pointer to a network stream object.
* @param data The value to write to the stream.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write_float(netstream_t *stream, float data);
/**
* Writes a 64-bit floating-point number to a network-order stream,
* byte-swapping it from host-native byte order to big-endian if necessary.
*
* @param stream Pointer to a network stream object.
* @param data The value to write to the stream.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write_double(netstream_t *stream, double data);
#endif
/**
* netstream_write_string:
* Writes a null-terminated string to a network-order stream.
* Does not byte-swap any data.
*
* @stream : Pointer to a network stream object.
* @s : Pointer to a string.
*
* Writes a null-terminated string into the network stream.
*
* Returns: true on success, false otherwise.
* @param stream Pointer to a network stream object.
* @param s A \c NULL-terminated string.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write_string(netstream_t *stream, const char *s);
/**
* netstream_write_fixed_string:
* Writes a string of fixed length to a network-order stream,
* \c NULL-terminating it if necessary.
*
* @stream : Pointer to a network stream object.
* @s : Pointer to a string.
* @len : Size of the string.
*
* Writes a null-terminated fixed-length string into the network stream.
*
* Returns: true on success, false otherwise.
* @param stream Pointer to a network stream object.
* @param s Pointer to a string.
* Does not need to be \c NULL-terminated,
* but \c NULL values will not stop processing.
* Will be \c NULL
* @param len Length of \c s in bytes,
* including the \c NULL terminator.
* Exactly this many bytes will be written to the stream;
* the last character will be set to \c NULL.
* @return \c true on success,
* \c false if there was an error.
*/
bool netstream_write_fixed_string(netstream_t *stream, const char *s,
size_t len);

View file

@ -32,6 +32,17 @@
RETRO_BEGIN_DECLS
/**
* Reads data from \c stdin if supported by the current platform.
* @param buf[out] The buffer to read data into.
* @param size The length of \c buf in bytes.
* @return The number of bytes that were read,
* or 0 if there was an error
* (including a lack of platform support).
* @note \c stdin is commonly used for text,
* but this function can read binary data as well.
* @see https://man7.org/linux/man-pages/man3/stdout.3.html
*/
size_t read_stdin(char *buf, size_t size);
RETRO_END_DECLS

View file

@ -34,13 +34,28 @@ RETRO_BEGIN_DECLS
/* TODO/FIXME: Move all generic time handling functions
* to this file */
/* Must be called before using rtime_localtime() */
/**
* Must be called before using \c rtime_localtime().
* May be called multiple times without ill effects,
* but must only be called from the main thread.
*/
void rtime_init(void);
/* Must be called upon program termination */
/**
* Must be called upon program or core termination.
* May be called multiple times without ill effects,
* but must only be called from the main thread.
*/
void rtime_deinit(void);
/* Thread-safe wrapper for localtime() */
/**
* Thread-safe wrapper around standard \c localtime(),
* which by itself is not guaranteed to be thread-safe.
* @param timep Pointer to a time_t object to convert.
* @param result Pointer to a tm object to store the result in.
* @return \c result.
* @see https://en.cppreference.com/w/c/chrono/localtime
*/
struct tm *rtime_localtime(const time_t *timep, struct tm *result);
RETRO_END_DECLS

View file

@ -150,16 +150,6 @@ static void *thread_wrap(void *data_)
return 0;
}
/**
* sthread_create:
* @start_routine : thread entry callback function
* @userdata : pointer to userdata that will be made
* available in thread entry callback function
*
* Create a new thread.
*
* Returns: pointer to new thread if successful, otherwise NULL.
*/
sthread_t *sthread_create(void (*thread_func)(void*), void *userdata)
{
return sthread_create_with_priority(thread_func, userdata, 0);
@ -170,21 +160,6 @@ sthread_t *sthread_create(void (*thread_func)(void*), void *userdata)
#define HAVE_THREAD_ATTR
#endif
/**
* sthread_create_with_priority:
* @start_routine : thread entry callback function
* @userdata : pointer to userdata that will be made
* available in thread entry callback function
* @thread_priority : thread priority hint value from [1-100]
*
* Create a new thread. It is possible for the caller to give a hint
* for the thread's priority from [1-100]. Any passed in @thread_priority
* values that are outside of this range will cause sthread_create() to
* create a new thread using the operating system's default thread
* priority.
*
* Returns: pointer to new thread if successful, otherwise NULL.
*/
sthread_t *sthread_create_with_priority(void (*thread_func)(void*), void *userdata, int thread_priority)
{
#ifdef HAVE_THREAD_ATTR
@ -231,7 +206,7 @@ sthread_t *sthread_create_with_priority(void (*thread_func)(void*), void *userda
pthread_attr_setstacksize(&thread_attr , 0x10000 );
thread_attr_needed = true;
#elif defined(__APPLE__)
/* Default stack size on Apple is 512Kb;
/* Default stack size on Apple is 512Kb;
* for PS2 disc scanning and other reasons, we'd like 2MB. */
pthread_attr_setstacksize(&thread_attr , 0x200000 );
thread_attr_needed = true;
@ -256,17 +231,6 @@ sthread_t *sthread_create_with_priority(void (*thread_func)(void*), void *userda
return NULL;
}
/**
* sthread_detach:
* @thread : pointer to thread object
*
* Detach a thread. When a detached thread terminates, its
* resources are automatically released back to the system
* without the need for another thread to join with the
* terminated thread.
*
* Returns: 0 on success, otherwise it returns a non-zero error number.
*/
int sthread_detach(sthread_t *thread)
{
#ifdef USE_WIN32_THREADS
@ -280,17 +244,6 @@ int sthread_detach(sthread_t *thread)
#endif
}
/**
* sthread_join:
* @thread : pointer to thread object
*
* Join with a terminated thread. Waits for the thread specified by
* @thread to terminate. If that thread has already terminated, then
* it will return immediately. The thread specified by @thread must
* be joinable.
*
* Returns: 0 on success, otherwise it returns a non-zero error number.
*/
void sthread_join(sthread_t *thread)
{
if (!thread)
@ -305,12 +258,6 @@ void sthread_join(sthread_t *thread)
}
#if !defined(GEKKO)
/**
* sthread_isself:
* @thread : pointer to thread object
*
* Returns: true (1) if calling thread is the specified thread
*/
bool sthread_isself(sthread_t *thread)
{
#ifdef USE_WIN32_THREADS
@ -321,14 +268,6 @@ bool sthread_isself(sthread_t *thread)
}
#endif
/**
* slock_new:
*
* Create and initialize a new mutex. Must be manually
* freed.
*
* Returns: pointer to a new mutex if successful, otherwise NULL.
**/
slock_t *slock_new(void)
{
slock_t *lock = (slock_t*)calloc(1, sizeof(*lock));
@ -346,12 +285,6 @@ slock_t *slock_new(void)
return lock;
}
/**
* slock_free:
* @lock : pointer to mutex object
*
* Frees a mutex.
**/
void slock_free(slock_t *lock)
{
if (!lock)
@ -365,14 +298,6 @@ void slock_free(slock_t *lock)
free(lock);
}
/**
* slock_lock:
* @lock : pointer to mutex object
*
* Locks a mutex. If a mutex is already locked by
* another thread, the calling thread shall block until
* the mutex becomes available.
**/
void slock_lock(slock_t *lock)
{
if (!lock)
@ -384,13 +309,6 @@ void slock_lock(slock_t *lock)
#endif
}
/**
* slock_try_lock:
* @lock : pointer to mutex object
*
* Attempts to lock a mutex. If a mutex is already locked by
* another thread, return false. If the lock is acquired, return true.
**/
bool slock_try_lock(slock_t *lock)
{
#ifdef USE_WIN32_THREADS
@ -400,12 +318,6 @@ bool slock_try_lock(slock_t *lock)
#endif
}
/**
* slock_unlock:
* @lock : pointer to mutex object
*
* Unlocks a mutex.
**/
void slock_unlock(slock_t *lock)
{
if (!lock)
@ -417,15 +329,6 @@ void slock_unlock(slock_t *lock)
#endif
}
/**
* scond_new:
*
* Creates and initializes a condition variable. Must
* be manually freed.
*
* Returns: pointer to new condition variable on success,
* otherwise NULL.
**/
scond_t *scond_new(void)
{
scond_t *cond = (scond_t*)calloc(1, sizeof(*cond));
@ -480,12 +383,6 @@ error:
return NULL;
}
/**
* scond_free:
* @cond : pointer to condition variable object
*
* Frees a condition variable.
**/
void scond_free(scond_t *cond)
{
if (!cond)
@ -707,13 +604,6 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds
}
#endif
/**
* scond_wait:
* @cond : pointer to condition variable object
* @lock : pointer to mutex object
*
* Block on a condition variable (i.e. wait on a condition).
**/
void scond_wait(scond_t *cond, slock_t *lock)
{
#ifdef USE_WIN32_THREADS
@ -723,13 +613,6 @@ void scond_wait(scond_t *cond, slock_t *lock)
#endif
}
/**
* scond_broadcast:
* @cond : pointer to condition variable object
*
* Broadcast a condition. Unblocks all threads currently blocked
* on the specified condition variable @cond.
**/
int scond_broadcast(scond_t *cond)
{
#ifdef USE_WIN32_THREADS
@ -750,13 +633,6 @@ int scond_broadcast(scond_t *cond)
#endif
}
/**
* scond_signal:
* @cond : pointer to condition variable object
*
* Signal a condition. Unblocks at least one of the threads currently blocked
* on the specified condition variable @cond.
**/
void scond_signal(scond_t *cond)
{
#ifdef USE_WIN32_THREADS
@ -796,18 +672,6 @@ void scond_signal(scond_t *cond)
#endif
}
/**
* scond_wait_timeout:
* @cond : pointer to condition variable object
* @lock : pointer to mutex object
* @timeout_us : timeout (in microseconds)
*
* Try to block on a condition variable (i.e. wait on a condition) until
* @timeout_us elapses.
*
* Returns: false (0) if timeout elapses before condition variable is
* signaled or broadcast, otherwise true (1).
**/
bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us)
{
#ifdef USE_WIN32_THREADS

View file

@ -81,7 +81,7 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
filestream_rename_cb = NULL;
if (
(vfs_info->required_interface_version <
(vfs_info->required_interface_version <
FILESTREAM_REQUIRED_VFS_VERSION)
|| !vfs_iface)
return;
@ -152,15 +152,6 @@ int64_t filestream_truncate(RFILE *stream, int64_t length)
return output;
}
/**
* filestream_open:
* @path : path to file
* @mode : file mode to use when opening (read/write)
* @hints :
*
* Opens a file for reading or writing, depending on the requested mode.
* @return A pointer to an RFILE if opened successfully, otherwise NULL.
**/
RFILE* filestream_open(const char *path, unsigned mode, unsigned hints)
{
struct retro_vfs_file_handle *fp = NULL;
@ -269,9 +260,9 @@ int filestream_vscanf(RFILE *stream, const char* format, va_list *args)
*subfmtiter++ = *format++;
}
else if (
*format == 'j' ||
*format == 'z' ||
*format == 't' ||
*format == 'j' ||
*format == 'z' ||
*format == 't' ||
*format == 'L')
{
*subfmtiter++ = *format++;
@ -470,8 +461,8 @@ int filestream_putc(RFILE *stream, int c)
char c_char = (char)c;
if (!stream)
return EOF;
return filestream_write(stream, &c_char, 1) == 1
? (int)(unsigned char)c
return filestream_write(stream, &c_char, 1) == 1
? (int)(unsigned char)c
: EOF;
}
@ -521,17 +512,6 @@ int filestream_close(RFILE *stream)
return output;
}
/**
* filestream_read_file:
* @path : path to file.
* @buf : buffer to allocate and read the contents of the
* file into. Needs to be freed manually.
* @len : optional output integer containing bytes read.
*
* Read the contents of a file into @buf.
*
* @return Non-zero on success.
*/
int64_t filestream_read_file(const char *path, void **buf, int64_t *len)
{
int64_t ret = 0;
@ -584,16 +564,6 @@ error:
return 0;
}
/**
* filestream_write_file:
* @path : path to file.
* @data : contents to write to the file.
* @size : size of the contents.
*
* Writes data to a file.
*
* @return true on success, otherwise false.
**/
bool filestream_write_file(const char *path, const void *data, int64_t size)
{
int64_t ret = 0;
@ -608,11 +578,6 @@ bool filestream_write_file(const char *path, const void *data, int64_t size)
return (ret == size);
}
/**
* filestream_getline:
*
* Returned pointer must be freed by the caller.
**/
char *filestream_getline(RFILE *stream)
{
char *newline_tmp = NULL;

View file

@ -3110,26 +3110,26 @@ bool runloop_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE:
{
int result = 0;
video_driver_state_t *video_st = video_state_get_ptr();
audio_driver_state_t *audio_st = audio_state_get_ptr();
enum retro_av_enable_flags result = 0;
video_driver_state_t *video_st = video_state_get_ptr();
audio_driver_state_t *audio_st = audio_state_get_ptr();
if ( !(audio_st->flags & AUDIO_FLAG_SUSPENDED)
&& (audio_st->flags & AUDIO_FLAG_ACTIVE))
result |= 2;
result |= RETRO_AV_ENABLE_AUDIO;
if ( (video_st->flags & VIDEO_FLAG_ACTIVE)
&& !(video_st->current_video->frame == video_null.frame))
result |= 1;
result |= RETRO_AV_ENABLE_VIDEO;
#ifdef HAVE_RUNAHEAD
if (audio_st->flags & AUDIO_FLAG_HARD_DISABLE)
result |= 8;
result |= RETRO_AV_ENABLE_HARD_DISABLE_AUDIO;
#endif
#ifdef HAVE_NETWORKING
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_REPLAYING, NULL))
result &= ~(1|2);
result &= ~(RETRO_AV_ENABLE_VIDEO|RETRO_AV_ENABLE_AUDIO);
#endif
#if defined(HAVE_RUNAHEAD) || defined(HAVE_NETWORKING)
@ -3137,11 +3137,11 @@ bool runloop_environment_cb(unsigned cmd, void *data)
Use RETRO_ENVIRONMENT_GET_SAVESTATE_CONTEXT instead. */
/* TODO/FIXME: Get rid of this ugly hack. */
if (runloop_st->flags & RUNLOOP_FLAG_REQUEST_SPECIAL_SAVESTATE)
result |= 4;
result |= RETRO_AV_ENABLE_FAST_SAVESTATES;
#endif
if (data)
{
int* result_p = (int*)data;
enum retro_av_enable_flags* result_p = (enum retro_av_enable_flags*)data;
*result_p = result;
}
break;