diff options
author | 2017-12-01 13:22:27 +0100 | |
---|---|---|
committer | 2017-12-01 13:22:27 +0100 | |
commit | 39176274946d70ff520f265dee8fbd16d5fe0000 (patch) | |
tree | 318801d93146752050c9a492654ae3738820e3b9 /3rdparty/bx | |
parent | 6829ecb3b037d6bfbe0b84e818d17d712f71bce6 (diff) |
Updated GENie, BGFX, BX, added BIMG since it is separated now, updated all shader binaries and MAME part of code to support new interfaces [Miodrag Milanovic]
Diffstat (limited to '3rdparty/bx')
114 files changed, 10420 insertions, 3993 deletions
diff --git a/3rdparty/bx/.appveyor.yml b/3rdparty/bx/.appveyor.yml index db402c41b97..96ec072ce84 100644 --- a/3rdparty/bx/.appveyor.yml +++ b/3rdparty/bx/.appveyor.yml @@ -1,13 +1,12 @@ shallow_clone: true os: - - Visual Studio 2015 + - Visual Studio 2017 environment: matrix: - - TOOLSET: vs2012 - - TOOLSET: vs2013 - TOOLSET: vs2015 + - TOOLSET: vs2017 configuration: - Debug diff --git a/3rdparty/bx/3rdparty/.editorconfig b/3rdparty/bx/3rdparty/.editorconfig new file mode 100644 index 00000000000..b41989621d5 --- /dev/null +++ b/3rdparty/bx/3rdparty/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[ini/*] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true diff --git a/3rdparty/bx/3rdparty/ini/README.md b/3rdparty/bx/3rdparty/ini/README.md new file mode 100644 index 00000000000..bc4d7c72905 --- /dev/null +++ b/3rdparty/bx/3rdparty/ini/README.md @@ -0,0 +1 @@ +https://github.com/mattiasgustavsson/libs/ diff --git a/3rdparty/bx/3rdparty/ini/ini.h b/3rdparty/bx/3rdparty/ini/ini.h new file mode 100644 index 00000000000..394c19645a7 --- /dev/null +++ b/3rdparty/bx/3rdparty/ini/ini.h @@ -0,0 +1,1054 @@ +/* +------------------------------------------------------------------------------ + Licensing information can be found at the end of the file. +------------------------------------------------------------------------------ + +ini.h - v1.1 - Simple ini-file reader for C/C++. + +Do this: + #define INI_IMPLEMENTATION +before you include this file in *one* C/C++ file to create the implementation. +*/ + +#ifndef ini_h +#define ini_h + +#define INI_GLOBAL_SECTION ( 0 ) +#define INI_NOT_FOUND ( -1 ) + +typedef struct ini_t ini_t; + +ini_t* ini_create( void* memctx ); +ini_t* ini_load( char const* data, void* memctx ); + +int ini_save( ini_t const* ini, char* data, int size ); +void ini_destroy( ini_t* ini ); + +int ini_section_count( ini_t const* ini ); +char const* ini_section_name( ini_t const* ini, int section ); + +int ini_property_count( ini_t const* ini, int section ); +char const* ini_property_name( ini_t const* ini, int section, int property ); +char const* ini_property_value( ini_t const* ini, int section, int property ); + +int ini_find_section( ini_t const* ini, char const* name, int name_length ); +int ini_find_property( ini_t const* ini, int section, char const* name, int name_length ); + +int ini_section_add( ini_t* ini, char const* name, int length ); +void ini_property_add( ini_t* ini, int section, char const* name, int name_length, char const* value, int value_length ); +void ini_section_remove( ini_t* ini, int section ); +void ini_property_remove( ini_t* ini, int section, int property ); + +void ini_section_name_set( ini_t* ini, int section, char const* name, int length ); +void ini_property_name_set( ini_t* ini, int section, int property, char const* name, int length ); +void ini_property_value_set( ini_t* ini, int section, int property, char const* value, int length ); + +#endif /* ini_h */ + + +/** + +Examples +======== + +Loading an ini file and retrieving values +----------------------------------------- + + #define INI_IMPLEMENTATION + #include "ini.h" + + #include <stdio.h> + #include <stdlib.h> + + int main() + { + FILE* fp = fopen( "test.ini", "r" ); + fseek( fp, 0, SEEK_END ); + int size = ftell( fp ); + fseek( fp, 0, SEEK_SET ); + char* data = (char*) malloc( size + 1 ); + fread( data, 1, size, fp ); + data[ size ] = '\0'; + fclose( fp ); + + ini_t* ini = ini_load( data ); + free( data ); + int second_index = ini_find_property( ini, INI_GLOBAL_SECTION, "SecondSetting" ); + char const* second = ini_property_value( ini, INI_GLOBAL_SECTION, second_index ); + printf( "%s=%s\n", "SecondSetting", second ); + int section = ini_find_section( ini, "MySection" ); + int third_index = ini_find_property( ini, section, "ThirdSetting" ); + char const* third = ini_property_value( ini, section, third_index ); + printf( "%s=%s\n", "ThirdSetting", third ); + ini_destroy( ini ); + + return 0; + } + + +Creating a new ini file +----------------------- + + #define INI_IMPLEMENTATION + #include "ini.h" + + #include <stdio.h> + #include <stdlib.h> + + int main() + { + ini_t* ini = ini_create(); + ini_property_add( ini, INI_GLOBAL_SECTION, "FirstSetting", "Test" ); + ini_property_add( ini, INI_GLOBAL_SECTION, "SecondSetting", "2" ); + int section = ini_section_add( ini, "MySection" ); + ini_property_add( ini, section, "ThirdSetting", "Three" ); + + int size = ini_save( ini, NULL, 0 ); // Find the size needed + char* data = (char*) malloc( size ); + size = ini_save( ini, data, size ); // Actually save the file + ini_destroy( ini ); + + FILE* fp = fopen( "test.ini", "w" ); + fwrite( data, 1, size, fp ); + fclose( fp ); + free( data ); + + return 0; + } + + + +API Documentation +================= + +ini.h is a small library for reading classic .ini files. It is a single-header library, and does not need any .lib files +or other binaries, or any build scripts. To use it, you just include ini.h to get the API declarations. To get the +definitions, you must include ini.h from *one* single C or C++ file, and #define the symbol `INI_IMPLEMENTATION` before +you do. + + +Customization +------------- +There are a few different things in ini.h which are configurable by #defines. The customizations only affect the +implementation, so will only need to be defined in the file where you have the #define INI_IMPLEMENTATION. + +Note that if all customizations are utilized, ini.h will include no external files whatsoever, which might be useful +if you need full control over what code is being built. + + +### Custom memory allocators + +To store the internal data structures, ini.h needs to do dynamic allocation by calling `malloc`. Programs might want to +keep track of allocations done, or use custom defined pools to allocate memory from. ini.h allows for specifying custom +memory allocation functions for `malloc` and `free`. +This is done with the following code: + + #define INI_IMPLEMENTATION + #define INI_MALLOC( ctx, size ) ( my_custom_malloc( ctx, size ) ) + #define INI_FREE( ctx, ptr ) ( my_custom_free( ctx, ptr ) ) + #include "ini.h" + +where `my_custom_malloc` and `my_custom_free` are your own memory allocation/deallocation functions. The `ctx` parameter +is an optional parameter of type `void*`. When `ini_create` or `ini_load` is called, you can pass in a `memctx` +parameter, which can be a pointer to anything you like, and which will be passed through as the `ctx` parameter to every +`INI_MALLOC`/`INI_FREE` call. For example, if you are doing memory tracking, you can pass a pointer to your tracking +data as `memctx`, and in your custom allocation/deallocation function, you can cast the `ctx` param back to the +right type, and access the tracking data. + +If no custom allocator is defined, ini.h will default to `malloc` and `free` from the C runtime library. + + +### Custom C runtime function + +The library makes use of three additional functions from the C runtime library, and for full flexibility, it allows you +to substitute them for your own. Here's an example: + + #define INI_IMPLEMENTATION + #define INI_MEMCPY( dst, src, cnt ) ( my_memcpy_func( dst, src, cnt ) ) + #define INI_STRLEN( s ) ( my_strlen_func( s ) ) + #define INI_STRNICMP( s1, s2, cnt ) ( my_strnicmp_func( s1, s2, cnt ) ) + #include "ini.h" + +If no custom function is defined, ini.h will default to the C runtime library equivalent. + + +ini_create +---------- + + ini_t* ini_create( void* memctx ) + +Instantiates a new, empty ini structure, which can be manipulated with other API calls, to fill it with data. To save it +out to an ini-file string, use `ini_save`. When no longer needed, it can be destroyed by calling `ini_destroy`. +`memctx` is a pointer to user defined data which will be passed through to the custom INI_MALLOC/INI_FREE calls. It can +be NULL if no user defined data is needed. + + +ini_load +-------- + + ini_t* ini_load( char const* data, void* memctx ) + +Parse the zero-terminated string `data` containing an ini-file, and create a new ini_t instance containing the data. +The instance can be manipulated with other API calls to enumerate sections/properties and retrieve values. When no +longer needed, it can be destroyed by calling `ini_destroy`. `memctx` is a pointer to user defined data which will be +passed through to the custom INI_MALLOC/INI_FREE calls. It can be NULL if no user defined data is needed. + + +ini_save +-------- + + int ini_save( ini_t const* ini, char* data, int size ) + +Saves an ini structure as a zero-terminated ini-file string, into the specified buffer. Returns the number of bytes +written, including the zero terminator. If `data` is NULL, nothing is written, but `ini_save` still returns the number +of bytes it would have written. If the size of `data`, as specified in the `size` parameter, is smaller than that +required, only part of the ini-file string will be written. `ini_save` still returns the number of bytes it would have +written had the buffer been large enough. + + +ini_destroy +----------- + + void ini_destroy( ini_t* ini ) + +Destroy an `ini_t` instance created by calling `ini_load` or `ini_create`, releasing the memory allocated by it. No +further API calls are valid on an `ini_t` instance after calling `ini_destroy` on it. + + +ini_section_count +----------------- + + int ini_section_count( ini_t const* ini ) + +Returns the number of sections in an ini file. There's at least one section in an ini file (the global section), but +there can be many more, each specified in the file by the section name wrapped in square brackets [ ]. + + +ini_section_name +---------------- + + char const* ini_section_name( ini_t const* ini, int section ) + +Returns the name of the section with the specified index. `section` must be non-negative and less than the value +returned by `ini_section_count`, or `ini_section_name` will return NULL. The defined constant `INI_GLOBAL_SECTION` can +be used to indicate the global section. + + +ini_property_count +------------------ + + int ini_property_count( ini_t const* ini, int section ) + +Returns the number of properties belonging to the section with the specified index. `section` must be non-negative and +less than the value returned by `ini_section_count`, or `ini_section_name` will return 0. The defined constant +`INI_GLOBAL_SECTION` can be used to indicate the global section. Properties are declared in the ini-file on he format +`name=value`. + + +ini_property_name +----------------- + + char const* ini_property_name( ini_t const* ini, int section, int property ) + +Returns the name of the property with the specified index `property` in the section with the specified index `section`. +`section` must be non-negative and less than the value returned by `ini_section_count`, and `property` must be +non-negative and less than the value returned by `ini_property_count`, or `ini_property_name` will return NULL. The +defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. + + +ini_property_value +------------------ + + char const* ini_property_value( ini_t const* ini, int section, int property ) + +Returns the value of the property with the specified index `property` in the section with the specified index `section`. +`section` must be non-negative and less than the value returned by `ini_section_count`, and `property` must be +non-negative and less than the value returned by `ini_property_count`, or `ini_property_value` will return NULL. The +defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. + + +ini_find_section +---------------- + + int ini_find_section( ini_t const* ini, char const* name, int name_length ) + +Finds the section with the specified name, and returns its index. `name_length` specifies the number of characters in +`name`, which does not have to be zero-terminated. If `name_length` is zero, the length is determined automatically, but +in this case `name` has to be zero-terminated. If no section with the specified name could be found, the value +`INI_NOT_FOUND` is returned. + + +ini_find_property +----------------- + + int ini_find_property( ini_t const* ini, int section, char const* name, int name_length ) + +Finds the property with the specified name, within the section with the specified index, and returns the index of the +property. `name_length` specifies the number of characters in `name`, which does not have to be zero-terminated. If +`name_length` is zero, the length is determined automatically, but in this case `name` has to be zero-terminated. If no +property with the specified name could be found within the specified section, the value `INI_NOT_FOUND` is returned. +`section` must be non-negative and less than the value returned by `ini_section_count`, or `ini_find_property` will +return `INI_NOT_FOUND`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. + + +ini_section_add +--------------- + + int ini_section_add( ini_t* ini, char const* name, int length ) + +Adds a section with the specified name, and returns the index it was added at. There is no check done to see if a +section with the specified name already exists - multiple sections of the same name are allowed. `length` specifies the +number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, the length is determined +automatically, but in this case `name` has to be zero-terminated. + + +ini_property_add +---------------- + + void ini_property_add( ini_t* ini, int section, char const* name, int name_length, char const* value, int value_length ) + +Adds a property with the specified name and value to the specified section, and returns the index it was added at. There +is no check done to see if a property with the specified name already exists - multiple properties of the same name are +allowed. `name_length` and `value_length` specifies the number of characters in `name` and `value`, which does not have +to be zero-terminated. If `name_length` or `value_length` is zero, the length is determined automatically, but in this +case `name`/`value` has to be zero-terminated. `section` must be non-negative and less than the value returned by +`ini_section_count`, or the property will not be added. The defined constant `INI_GLOBAL_SECTION` can be used to +indicate the global section. + + +ini_section_remove +------------------ + + void ini_section_remove( ini_t* ini, int section ) + +Removes the section with the specified index, and all properties within it. `section` must be non-negative and less than +the value returned by `ini_section_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global +section. Note that removing a section will shuffle section indices, so that section indices you may have stored will no +longer indicate the same section as it did before the remove. Use the find functions to update your indices. + + +ini_property_remove +------------------- + + void ini_property_remove( ini_t* ini, int section, int property ) + +Removes the property with the specified index from the specified section. `section` must be non-negative and less than +the value returned by `ini_section_count`, and `property` must be non-negative and less than the value returned by +`ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. Note that +removing a property will shuffle property indices within the specified section, so that property indices you may have +stored will no longer indicate the same property as it did before the remove. Use the find functions to update your +indices. + + +ini_section_name_set +-------------------- + + void ini_section_name_set( ini_t* ini, int section, char const* name, int length ) + +Change the name of the section with the specified index. `section` must be non-negative and less than the value returned +by `ini_section_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. `length` +specifies the number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, the length +is determined automatically, but in this case `name` has to be zero-terminated. + + +ini_property_name_set +--------------------- + + void ini_property_name_set( ini_t* ini, int section, int property, char const* name, int length ) + +Change the name of the property with the specified index in the specified section. `section` must be non-negative and +less than the value returned by `ini_section_count`, and `property` must be non-negative and less than the value +returned by `ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. +`length` specifies the number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, +the length is determined automatically, but in this case `name` has to be zero-terminated. + + +ini_property_value_set +---------------------- + + void ini_property_value_set( ini_t* ini, int section, int property, char const* value, int length ) + +Change the value of the property with the specified index in the specified section. `section` must be non-negative and +less than the value returned by `ini_section_count`, and `property` must be non-negative and less than the value +returned by `ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. +`length` specifies the number of characters in `value`, which does not have to be zero-terminated. If `length` is zero, +the length is determined automatically, but in this case `value` has to be zero-terminated. + +**/ + + +/* +---------------------- + IMPLEMENTATION +---------------------- +*/ + +#ifdef INI_IMPLEMENTATION +#undef INI_IMPLEMENTATION + +#define INITIAL_CAPACITY ( 256 ) + +#ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE +#endif + +#ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS +#endif + +#include <stddef.h> + +#ifndef INI_MALLOC + #include <stdlib.h> + #define INI_MALLOC( ctx, size ) ( malloc( size ) ) + #define INI_FREE( ctx, ptr ) ( free( ptr ) ) +#endif + +#ifndef INI_MEMCPY + #include <string.h> + #define INI_MEMCPY( dst, src, cnt ) ( memcpy( dst, src, cnt ) ) +#endif + +#ifndef INI_STRLEN + #include <string.h> + #define INI_STRLEN( s ) ( strlen( s ) ) +#endif + +#ifndef INI_STRNICMP + #ifdef _WIN32 + #include <string.h> + #define INI_STRNICMP( s1, s2, cnt ) ( strnicmp( s1, s2, cnt ) ) + #else + #include <string.h> + #define INI_STRNICMP( s1, s2, cnt ) ( strncasecmp( s1, s2, cnt ) ) + #endif +#endif + + +struct ini_internal_section_t + { + char name[ 32 ]; + char* name_large; + }; + + +struct ini_internal_property_t + { + int section; + char name[ 32 ]; + char* name_large; + char value[ 64 ]; + char* value_large; + }; + + +struct ini_t + { + struct ini_internal_section_t* sections; + int section_capacity; + int section_count; + + struct ini_internal_property_t* properties; + int property_capacity; + int property_count; + + void* memctx; + }; + + +static int ini_internal_property_index( ini_t const* ini, int section, int property ) + { + int i; + int p; + + if( ini && section >= 0 && section < ini->section_count ) + { + p = 0; + for( i = 0; i < ini->property_count; ++i ) + { + if( ini->properties[ i ].section == section ) + { + if( p == property ) return i; + ++p; + } + } + } + + return INI_NOT_FOUND; + } + + +ini_t* ini_create( void* memctx ) + { + ini_t* ini; + + ini = (ini_t*) INI_MALLOC( memctx, sizeof( ini_t ) ); + ini->memctx = memctx; + ini->sections = (struct ini_internal_section_t*) INI_MALLOC( ini->memctx, INITIAL_CAPACITY * sizeof( ini->sections[ 0 ] ) ); + ini->section_capacity = INITIAL_CAPACITY; + ini->section_count = 1; /* global section */ + ini->sections[ 0 ].name[ 0 ] = '\0'; + ini->sections[ 0 ].name_large = 0; + ini->properties = (struct ini_internal_property_t*) INI_MALLOC( ini->memctx, INITIAL_CAPACITY * sizeof( ini->properties[ 0 ] ) ); + ini->property_capacity = INITIAL_CAPACITY; + ini->property_count = 0; + return ini; + } + + +ini_t* ini_load( char const* data, void* memctx ) + { + ini_t* ini; + char const* ptr; + int s; + char const* start; + char const* start2; + int l; + + ini = ini_create( memctx ); + + ptr = data; + if( ptr ) + { + s = 0; + while( *ptr ) + { + /* trim leading whitespace */ + while( *ptr && *ptr <=' ' ) + ++ptr; + + /* done? */ + if( !*ptr ) break; + + /* comment */ + else if( *ptr == ';' ) + { + while( *ptr && *ptr !='\n' ) + ++ptr; + } + /* section */ + else if( *ptr == '[' ) + { + ++ptr; + start = ptr; + while( *ptr && *ptr !=']' && *ptr != '\n' ) + ++ptr; + + if( *ptr == ']' ) + { + s = ini_section_add( ini, start, (int)( ptr - start) ); + ++ptr; + } + } + /* property */ + else + { + start = ptr; + while( *ptr && *ptr !='=' && *ptr != '\n' ) + ++ptr; + + if( *ptr == '=' ) + { + l = (int)( ptr - start); + ++ptr; + while( *ptr && *ptr <= ' ' && *ptr != '\n' ) + ptr++; + start2 = ptr; + while( *ptr && *ptr != '\n' ) + ++ptr; + while( *(--ptr) <= ' ' ) + (void)ptr; + ptr++; + ini_property_add( ini, s, start, l, start2, (int)( ptr - start2) ); + } + } + } + } + + return ini; + } + + +int ini_save( ini_t const* ini, char* data, int size ) + { + int s; + int p; + int i; + int l; + char* n; + int pos; + + if( ini ) + { + pos = 0; + for( s = 0; s < ini->section_count; ++s ) + { + n = ini->sections[ s ].name_large ? ini->sections[ s ].name_large : ini->sections[ s ].name; + l = (int) INI_STRLEN( n ); + if( l > 0 ) + { + if( data && pos < size ) data[ pos ] = '['; + ++pos; + for( i = 0; i < l; ++i ) + { + if( data && pos < size ) data[ pos ] = n[ i ]; + ++pos; + } + if( data && pos < size ) data[ pos ] = ']'; + ++pos; + if( data && pos < size ) data[ pos ] = '\n'; + ++pos; + } + + for( p = 0; p < ini->property_count; ++p ) + { + if( ini->properties[ p ].section == s ) + { + n = ini->properties[ p ].name_large ? ini->properties[ p ].name_large : ini->properties[ p ].name; + l = (int) INI_STRLEN( n ); + for( i = 0; i < l; ++i ) + { + if( data && pos < size ) data[ pos ] = n[ i ]; + ++pos; + } + if( data && pos < size ) data[ pos ] = '='; + ++pos; + n = ini->properties[ p ].value_large ? ini->properties[ p ].value_large : ini->properties[ p ].value; + l = (int) INI_STRLEN( n ); + for( i = 0; i < l; ++i ) + { + if( data && pos < size ) data[ pos ] = n[ i ]; + ++pos; + } + if( data && pos < size ) data[ pos ] = '\n'; + ++pos; + } + } + + if( pos > 0 ) + { + if( data && pos < size ) data[ pos ] = '\n'; + ++pos; + } + } + + if( data && pos < size ) data[ pos ] = '\0'; + ++pos; + + return pos; + } + + return 0; + } + + +void ini_destroy( ini_t* ini ) + { + int i; + + if( ini ) + { + for( i = 0; i < ini->property_count; ++i ) + { + if( ini->properties[ i ].value_large ) INI_FREE( ini->memctx, ini->properties[ i ].value_large ); + if( ini->properties[ i ].name_large ) INI_FREE( ini->memctx, ini->properties[ i ].name_large ); + } + for( i = 0; i < ini->section_count; ++i ) + if( ini->sections[ i ].name_large ) INI_FREE( ini->memctx, ini->sections[ i ].name_large ); + INI_FREE( ini->memctx, ini->properties ); + INI_FREE( ini->memctx, ini->sections ); + INI_FREE( ini->memctx, ini ); + } + } + + +int ini_section_count( ini_t const* ini ) + { + if( ini ) return ini->section_count; + return 0; + } + + +char const* ini_section_name( ini_t const* ini, int section ) + { + if( ini && section >= 0 && section < ini->section_count ) + return ini->sections[ section ].name_large ? ini->sections[ section ].name_large : ini->sections[ section ].name; + + return NULL; + } + + +int ini_property_count( ini_t const* ini, int section ) + { + int i; + int count; + + if( ini ) + { + count = 0; + for( i = 0; i < ini->property_count; ++i ) + { + if( ini->properties[ i ].section == section ) ++count; + } + return count; + } + + return 0; + } + + +char const* ini_property_name( ini_t const* ini, int section, int property ) + { + int p; + + if( ini && section >= 0 && section < ini->section_count ) + { + p = ini_internal_property_index( ini, section, property ); + if( p != INI_NOT_FOUND ) + return ini->properties[ p ].name_large ? ini->properties[ p ].name_large : ini->properties[ p ].name; + } + + return NULL; + } + + +char const* ini_property_value( ini_t const* ini, int section, int property ) + { + int p; + + if( ini && section >= 0 && section < ini->section_count ) + { + p = ini_internal_property_index( ini, section, property ); + if( p != INI_NOT_FOUND ) + return ini->properties[ p ].value_large ? ini->properties[ p ].value_large : ini->properties[ p ].value; + } + + return NULL; + } + + +int ini_find_section( ini_t const* ini, char const* name, int name_length ) + { + int i; + + if( ini && name ) + { + if( name_length <= 0 ) name_length = (int) INI_STRLEN( name ); + for( i = 0; i < ini->section_count; ++i ) + { + char const* const other = + ini->sections[ i ].name_large ? ini->sections[ i ].name_large : ini->sections[ i ].name; + if( (int) INI_STRLEN( other ) == name_length && INI_STRNICMP( name, other, name_length ) == 0 ) + return i; + } + } + + return INI_NOT_FOUND; + } + + +int ini_find_property( ini_t const* ini, int section, char const* name, int name_length ) + { + int i; + int c; + + if( ini && name && section >= 0 && section < ini->section_count) + { + if( name_length <= 0 ) name_length = (int) INI_STRLEN( name ); + c = 0; + for( i = 0; i < ini->property_capacity; ++i ) + { + if( ini->properties[ i ].section == section ) + { + char const* const other = + ini->properties[ i ].name_large ? ini->properties[ i ].name_large : ini->properties[ i ].name; + if( (int) INI_STRLEN( other ) == name_length && INI_STRNICMP( name, other, name_length ) == 0 ) + return c; + ++c; + } + } + } + + return INI_NOT_FOUND; + } + + +int ini_section_add( ini_t* ini, char const* name, int length ) + { + struct ini_internal_section_t* new_sections; + + if( ini && name ) + { + if( length <= 0 ) length = (int) INI_STRLEN( name ); + if( ini->section_count >= ini->section_capacity ) + { + ini->section_capacity *= 2; + new_sections = (struct ini_internal_section_t*) INI_MALLOC( ini->memctx, + ini->section_capacity * sizeof( ini->sections[ 0 ] ) ); + INI_MEMCPY( new_sections, ini->sections, ini->section_count * sizeof( ini->sections[ 0 ] ) ); + INI_FREE( ini->memctx, ini->sections ); + ini->sections = new_sections; + } + + ini->sections[ ini->section_count ].name_large = 0; + if( length + 1 >= sizeof( ini->sections[ 0 ].name ) ) + { + ini->sections[ ini->section_count ].name_large = (char*) INI_MALLOC( ini->memctx, (size_t) length + 1 ); + INI_MEMCPY( ini->sections[ ini->section_count ].name_large, name, (size_t) length ); + ini->sections[ ini->section_count ].name_large[ length ] = '\0'; + } + else + { + INI_MEMCPY( ini->sections[ ini->section_count ].name, name, (size_t) length ); + ini->sections[ ini->section_count ].name[ length ] = '\0'; + } + + return ini->section_count++; + } + return INI_NOT_FOUND; + } + + +void ini_property_add( ini_t* ini, int section, char const* name, int name_length, char const* value, int value_length ) + { + struct ini_internal_property_t* new_properties; + + if( ini && name && section >= 0 && section < ini->section_count ) + { + if( name_length <= 0 ) name_length = (int) INI_STRLEN( name ); + if( value_length <= 0 ) value_length = (int) INI_STRLEN( value ); + + if( ini->property_count >= ini->property_capacity ) + { + + ini->property_capacity *= 2; + new_properties = (struct ini_internal_property_t*) INI_MALLOC( ini->memctx, + ini->property_capacity * sizeof( ini->properties[ 0 ] ) ); + INI_MEMCPY( new_properties, ini->properties, ini->property_count * sizeof( ini->properties[ 0 ] ) ); + INI_FREE( ini->memctx, ini->properties ); + ini->properties = new_properties; + } + + ini->properties[ ini->property_count ].section = section; + ini->properties[ ini->property_count ].name_large = 0; + ini->properties[ ini->property_count ].value_large = 0; + + if( name_length + 1 >= sizeof( ini->properties[ 0 ].name ) ) + { + ini->properties[ ini->property_count ].name_large = (char*) INI_MALLOC( ini->memctx, (size_t) name_length + 1 ); + INI_MEMCPY( ini->properties[ ini->property_count ].name_large, name, (size_t) name_length ); + ini->properties[ ini->property_count ].name_large[ name_length ] = '\0'; + } + else + { + INI_MEMCPY( ini->properties[ ini->property_count ].name, name, (size_t) name_length ); + ini->properties[ ini->property_count ].name[ name_length ] = '\0'; + } + + if( value_length + 1 >= sizeof( ini->properties[ 0 ].value ) ) + { + ini->properties[ ini->property_count ].value_large = (char*) INI_MALLOC( ini->memctx, (size_t) value_length + 1 ); + INI_MEMCPY( ini->properties[ ini->property_count ].value_large, value, (size_t) value_length ); + ini->properties[ ini->property_count ].value_large[ value_length ] = '\0'; + } + else + { + INI_MEMCPY( ini->properties[ ini->property_count ].value, value, (size_t) value_length ); + ini->properties[ ini->property_count ].value[ value_length ] = '\0'; + } + + ++ini->property_count; + } + } + + +void ini_section_remove( ini_t* ini, int section ) + { + int p; + + if( ini && section >= 0 && section < ini->section_count ) + { + if( ini->sections[ section ].name_large ) INI_FREE( ini->memctx, ini->sections[ section ].name_large ); + for( p = ini->property_count - 1; p >= 0; --p ) + { + if( ini->properties[ p ].section == section ) + { + if( ini->properties[ p ].value_large ) INI_FREE( ini->memctx, ini->properties[ p ].value_large ); + if( ini->properties[ p ].name_large ) INI_FREE( ini->memctx, ini->properties[ p ].name_large ); + ini->properties[ p ] = ini->properties[ --ini->property_count ]; + } + } + + ini->sections[ section ] = ini->sections[ --ini->section_count ]; + + for( p = 0; p < ini->property_count; ++p ) + { + if( ini->properties[ p ].section == ini->section_count ) + ini->properties[ p ].section = section; + } + } + } + + +void ini_property_remove( ini_t* ini, int section, int property ) + { + int p; + + if( ini && section >= 0 && section < ini->section_count ) + { + p = ini_internal_property_index( ini, section, property ); + if( p != INI_NOT_FOUND ) + { + if( ini->properties[ p ].value_large ) INI_FREE( ini->memctx, ini->properties[ p ].value_large ); + if( ini->properties[ p ].name_large ) INI_FREE( ini->memctx, ini->properties[ p ].name_large ); + ini->properties[ p ] = ini->properties[ --ini->property_count ]; + return; + } + } + } + + +void ini_section_name_set( ini_t* ini, int section, char const* name, int length ) + { + if( ini && name && section >= 0 && section < ini->section_count ) + { + if( length <= 0 ) length = (int) INI_STRLEN( name ); + if( ini->sections[ section ].name_large ) INI_FREE( ini->memctx, ini->sections[ section ].name_large ); + ini->sections[ section ].name_large = 0; + + if( length + 1 >= sizeof( ini->sections[ 0 ].name ) ) + { + ini->sections[ section ].name_large = (char*) INI_MALLOC( ini->memctx, (size_t) length + 1 ); + INI_MEMCPY( ini->sections[ section ].name_large, name, (size_t) length ); + ini->sections[ section ].name_large[ length ] = '\0'; + } + else + { + INI_MEMCPY( ini->sections[ section ].name, name, (size_t) length ); + ini->sections[ section ].name[ length ] = '\0'; + } + } + } + + +void ini_property_name_set( ini_t* ini, int section, int property, char const* name, int length ) + { + int p; + + if( ini && name && section >= 0 && section < ini->section_count ) + { + if( length <= 0 ) length = (int) INI_STRLEN( name ); + p = ini_internal_property_index( ini, section, property ); + if( p != INI_NOT_FOUND ) + { + if( ini->properties[ p ].name_large ) INI_FREE( ini->memctx, ini->properties[ p ].name_large ); + ini->properties[ ini->property_count ].name_large = 0; + + if( length + 1 >= sizeof( ini->properties[ 0 ].name ) ) + { + ini->properties[ p ].name_large = (char*) INI_MALLOC( ini->memctx, (size_t) length + 1 ); + INI_MEMCPY( ini->properties[ p ].name_large, name, (size_t) length ); + ini->properties[ p ].name_large[ length ] = '\0'; + } + else + { + INI_MEMCPY( ini->properties[ p ].name, name, (size_t) length ); + ini->properties[ p ].name[ length ] = '\0'; + } + } + } + } + + +void ini_property_value_set( ini_t* ini, int section, int property, char const* value, int length ) + { + int p; + + if( ini && value && section >= 0 && section < ini->section_count ) + { + if( length <= 0 ) length = (int) INI_STRLEN( value ); + p = ini_internal_property_index( ini, section, property ); + if( p != INI_NOT_FOUND ) + { + if( ini->properties[ p ].value_large ) INI_FREE( ini->memctx, ini->properties[ p ].value_large ); + ini->properties[ ini->property_count ].value_large = 0; + + if( length + 1 >= sizeof( ini->properties[ 0 ].value ) ) + { + ini->properties[ p ].value_large = (char*) INI_MALLOC( ini->memctx, (size_t) length + 1 ); + INI_MEMCPY( ini->properties[ p ].name_large, value, (size_t) length ); + ini->properties[ p ].value_large[ length ] = '\0'; + } + else + { + INI_MEMCPY( ini->properties[ p ].value, value, (size_t) length ); + ini->properties[ p ].name[ length ] = '\0'; + } + } + } + } + + +#endif /* INI_IMPLEMENTATION */ + +/* +revision history: + 1.1 customization, added documentation, cleanup + 1.0 first publicly released version +*/ + +/* +------------------------------------------------------------------------------ + +This software is available under 2 licenses - you may choose the one you like. + +------------------------------------------------------------------------------ + +ALTERNATIVE A - MIT License + +Copyright (c) 2015 Mattias Gustavsson + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------ + +ALTERNATIVE B - Public Domain (www.unlicense.org) + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------------------------------------------------------------------------------ +*/ diff --git a/3rdparty/bx/3rdparty/ini/ini.md b/3rdparty/bx/3rdparty/ini/ini.md new file mode 100644 index 00000000000..0b204c025e3 --- /dev/null +++ b/3rdparty/bx/3rdparty/ini/ini.md @@ -0,0 +1,333 @@ +ini.h +===== + +Library: [ini.h](../ini.h) + + +Examples +======== + +Loading an ini file and retrieving values +----------------------------------------- + +```cpp +#define INI_IMPLEMENTATION +#include "ini.h" + +#include <stdio.h> +#include <stdlib.h> + +int main() + { + FILE* fp = fopen( "test.ini", "r" ); + fseek( fp, 0, SEEK_END ); + int size = ftell( fp ); + fseek( fp, 0, SEEK_SET ); + char* data = (char*) malloc( size + 1 ); + fread( data, 1, size, fp ); + data[ size ] = '\0'; + fclose( fp ); + + ini_t* ini = ini_load( data ); + free( data ); + int second_index = ini_find_property( ini, INI_GLOBAL_SECTION, "SecondSetting" ); + char const* second = ini_property_value( ini, INI_GLOBAL_SECTION, second_index ); + printf( "%s=%s\n", "SecondSetting", second ); + int section = ini_find_section( ini, "MySection" ); + int third_index = ini_find_property( ini, section, "ThirdSetting" ); + char const* third = ini_property_value( ini, section, third_index ); + printf( "%s=%s\n", "ThirdSetting", third ); + ini_destroy( ini ); + + return 0; + } +``` + +Creating a new ini file +----------------------- + +```cpp +#define INI_IMPLEMENTATION +#include "ini.h" + +#include <stdio.h> +#include <stdlib.h> + +int main() + { + ini_t* ini = ini_create(); + ini_property_add( ini, INI_GLOBAL_SECTION, "FirstSetting", "Test" ); + ini_property_add( ini, INI_GLOBAL_SECTION, "SecondSetting", "2" ); + int section = ini_section_add( ini, "MySection" ); + ini_property_add( ini, section, "ThirdSetting", "Three" ); + + int size = ini_save( ini, NULL, 0 ); // Find the size needed + char* data = (char*) malloc( size ); + size = ini_save( ini, data, size ); // Actually save the file + ini_destroy( ini ); + + FILE* fp = fopen( "test.ini", "w" ); + fwrite( data, 1, size, fp ); + fclose( fp ); + free( data ); + + return 0; + } +``` + + +API Documentation +================= + +ini.h is a small library for reading classic .ini files. It is a single-header library, and does not need any .lib files +or other binaries, or any build scripts. To use it, you just include ini.h to get the API declarations. To get the +definitions, you must include ini.h from *one* single C or C++ file, and #define the symbol `INI_IMPLEMENTATION` before +you do. + + +Customization +------------- +There are a few different things in ini.h which are configurable by #defines. The customizations only affect the +implementation, so will only need to be defined in the file where you have the #define INI_IMPLEMENTATION. + +Note that if all customizations are utilized, ini.h will include no external files whatsoever, which might be useful +if you need full control over what code is being built. + + +### Custom memory allocators + +To store the internal data structures, ini.h needs to do dynamic allocation by calling `malloc`. Programs might want to +keep track of allocations done, or use custom defined pools to allocate memory from. ini.h allows for specifying custom +memory allocation functions for `malloc` and `free`. +This is done with the following code: + + #define INI_IMPLEMENTATION + #define INI_MALLOC( ctx, size ) ( my_custom_malloc( ctx, size ) ) + #define INI_FREE( ctx, ptr ) ( my_custom_free( ctx, ptr ) ) + #include "ini.h" + +where `my_custom_malloc` and `my_custom_free` are your own memory allocation/deallocation functions. The `ctx` parameter +is an optional parameter of type `void*`. When `ini_create` or `ini_load` is called, you can pass in a `memctx` +parameter, which can be a pointer to anything you like, and which will be passed through as the `ctx` parameter to every +`INI_MALLOC`/`INI_FREE` call. For example, if you are doing memory tracking, you can pass a pointer to your tracking +data as `memctx`, and in your custom allocation/deallocation function, you can cast the `ctx` param back to the +right type, and access the tracking data. + +If no custom allocator is defined, ini.h will default to `malloc` and `free` from the C runtime library. + + +### Custom C runtime function + +The library makes use of three additional functions from the C runtime library, and for full flexibility, it allows you +to substitute them for your own. Here's an example: + + #define INI_IMPLEMENTATION + #define INI_MEMCPY( dst, src, cnt ) ( my_memcpy_func( dst, src, cnt ) ) + #define INI_STRLEN( s ) ( my_strlen_func( s ) ) + #define INI_STRICMP( s1, s2 ) ( my_stricmp_func( s1, s2 ) ) + #include "ini.h" + +If no custom function is defined, ini.h will default to the C runtime library equivalent. + + +ini_create +---------- + + ini_t* ini_create( void* memctx ) + +Instantiates a new, empty ini structure, which can be manipulated with other API calls, to fill it with data. To save it +out to an ini-file string, use `ini_save`. When no longer needed, it can be destroyed by calling `ini_destroy`. +`memctx` is a pointer to user defined data which will be passed through to the custom INI_MALLOC/INI_FREE calls. It can +be NULL if no user defined data is needed. + + +ini_load +-------- + + ini_t* ini_load( char const* data, void* memctx ) + +Parse the zero-terminated string `data` containing an ini-file, and create a new ini_t instance containing the data. +The instance can be manipulated with other API calls to enumerate sections/properties and retrieve values. When no +longer needed, it can be destroyed by calling `ini_destroy`. `memctx` is a pointer to user defined data which will be +passed through to the custom INI_MALLOC/INI_FREE calls. It can be NULL if no user defined data is needed. + + +ini_save +-------- + + int ini_save( ini_t const* ini, char* data, int size ) + +Saves an ini structure as a zero-terminated ini-file string, into the specified buffer. Returns the number of bytes +written, including the zero terminator. If `data` is NULL, nothing is written, but `ini_save` still returns the number +of bytes it would have written. If the size of `data`, as specified in the `size` parameter, is smaller than that +required, only part of the ini-file string will be written. `ini_save` still returns the number of bytes it would have +written had the buffer been large enough. + + +ini_destroy +----------- + + void ini_destroy( ini_t* ini ) + +Destroy an `ini_t` instance created by calling `ini_load` or `ini_create`, releasing the memory allocated by it. No +further API calls are valid on an `ini_t` instance after calling `ini_destroy` on it. + + +ini_section_count +----------------- + + int ini_section_count( ini_t const* ini ) + +Returns the number of sections in an ini file. There's at least one section in an ini file (the global section), but +there can be many more, each specified in the file by the section name wrapped in square brackets [ ]. + + +ini_section_name +---------------- + + char const* ini_section_name( ini_t const* ini, int section ) + +Returns the name of the section with the specified index. `section` must be non-negative and less than the value +returned by `ini_section_count`, or `ini_section_name` will return NULL. The defined constant `INI_GLOBAL_SECTION` can +be used to indicate the global section. + + +ini_property_count +------------------ + + int ini_property_count( ini_t const* ini, int section ) + +Returns the number of properties belonging to the section with the specified index. `section` must be non-negative and +less than the value returned by `ini_section_count`, or `ini_section_name` will return 0. The defined constant +`INI_GLOBAL_SECTION` can be used to indicate the global section. Properties are declared in the ini-file on he format +`name=value`. + + +ini_property_name +----------------- + + char const* ini_property_name( ini_t const* ini, int section, int property ) + +Returns the name of the property with the specified index `property` in the section with the specified index `section`. +`section` must be non-negative and less than the value returned by `ini_section_count`, and `property` must be +non-negative and less than the value returned by `ini_property_count`, or `ini_property_name` will return NULL. The +defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. + + +ini_property_value +------------------ + + char const* ini_property_value( ini_t const* ini, int section, int property ) + +Returns the value of the property with the specified index `property` in the section with the specified index `section`. +`section` must be non-negative and less than the value returned by `ini_section_count`, and `property` must be +non-negative and less than the value returned by `ini_property_count`, or `ini_property_value` will return NULL. The +defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. + + +ini_find_section +---------------- + + int ini_find_section( ini_t const* ini, char const* name, int name_length ) + +Finds the section with the specified name, and returns its index. `name_length` specifies the number of characters in +`name`, which does not have to be zero-terminated. If `name_length` is zero, the length is determined automatically, but +in this case `name` has to be zero-terminated. If no section with the specified name could be found, the value +`INI_NOT_FOUND` is returned. + + +ini_find_property +----------------- + + int ini_find_property( ini_t const* ini, int section, char const* name, int name_length ) + +Finds the property with the specified name, within the section with the specified index, and returns the index of the +property. `name_length` specifies the number of characters in `name`, which does not have to be zero-terminated. If +`name_length` is zero, the length is determined automatically, but in this case `name` has to be zero-terminated. If no +property with the specified name could be found within the specified section, the value `INI_NOT_FOUND` is returned. +`section` must be non-negative and less than the value returned by `ini_section_count`, or `ini_find_property` will +return `INI_NOT_FOUND`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. + + +ini_section_add +--------------- + + int ini_section_add( ini_t* ini, char const* name, int length ) + +Adds a section with the specified name, and returns the index it was added at. There is no check done to see if a +section with the specified name already exists - multiple sections of the same name are allowed. `length` specifies the +number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, the length is determined +automatically, but in this case `name` has to be zero-terminated. + + +ini_property_add +---------------- + + void ini_property_add( ini_t* ini, int section, char const* name, int name_length, char const* value, int value_length ) + +Adds a property with the specified name and value to the specified section, and returns the index it was added at. There +is no check done to see if a property with the specified name already exists - multiple properties of the same name are +allowed. `name_length` and `value_length` specifies the number of characters in `name` and `value`, which does not have +to be zero-terminated. If `name_length` or `value_length` is zero, the length is determined automatically, but in this +case `name`/`value` has to be zero-terminated. `section` must be non-negative and less than the value returned by +`ini_section_count`, or the property will not be added. The defined constant `INI_GLOBAL_SECTION` can be used to +indicate the global section. + + +ini_section_remove +------------------ + + void ini_section_remove( ini_t* ini, int section ) + +Removes the section with the specified index, and all properties within it. `section` must be non-negative and less than +the value returned by `ini_section_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global +section. Note that removing a section will shuffle section indices, so that section indices you may have stored will no +longer indicate the same section as it did before the remove. Use the find functions to update your indices. + + +ini_property_remove +------------------- + + void ini_property_remove( ini_t* ini, int section, int property ) + +Removes the property with the specified index from the specified section. `section` must be non-negative and less than +the value returned by `ini_section_count`, and `property` must be non-negative and less than the value returned by +`ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. Note that +removing a property will shuffle property indices within the specified section, so that property indices you may have +stored will no longer indicate the same property as it did before the remove. Use the find functions to update your +indices. + + +ini_section_name_set +-------------------- + + void ini_section_name_set( ini_t* ini, int section, char const* name, int length ) + +Change the name of the section with the specified index. `section` must be non-negative and less than the value returned +by `ini_section_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. `length` +specifies the number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, the length +is determined automatically, but in this case `name` has to be zero-terminated. + + +ini_property_name_set +--------------------- + + void ini_property_name_set( ini_t* ini, int section, int property, char const* name, int length ) + +Change the name of the property with the specified index in the specified section. `section` must be non-negative and +less than the value returned by `ini_section_count`, and `property` must be non-negative and less than the value +returned by `ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. +`length` specifies the number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, +the length is determined automatically, but in this case `name` has to be zero-terminated. + + +ini_property_value_set +---------------------- + + void ini_property_value_set( ini_t* ini, int section, int property, char const* value, int length ) + +Change the value of the property with the specified index in the specified section. `section` must be non-negative and +less than the value returned by `ini_section_count`, and `property` must be non-negative and less than the value +returned by `ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. +`length` specifies the number of characters in `value`, which does not have to be zero-terminated. If `length` is zero, +the length is determined automatically, but in this case `value` has to be zero-terminated. diff --git a/3rdparty/bx/README.md b/3rdparty/bx/README.md index 3da618f9f3d..69dfade5ccb 100644 --- a/3rdparty/bx/README.md +++ b/3rdparty/bx/README.md @@ -19,6 +19,10 @@ https://github.com/bkaradzic/bx [License (BSD 2-clause)](https://github.com/bkaradzic/bx/blob/master/LICENSE) ----------------------------------------------------------------------------- +<a href="http://opensource.org/licenses/BSD-2-Clause" target="_blank"> +<img align="right" src="http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png"> +</a> + Copyright 2010-2017 Branimir Karadzic. All rights reserved. https://github.com/bkaradzic/bx diff --git a/3rdparty/bx/include/bx/allocator.h b/3rdparty/bx/include/bx/allocator.h index 77646a5b29d..f920c08fa71 100644 --- a/3rdparty/bx/include/bx/allocator.h +++ b/3rdparty/bx/include/bx/allocator.h @@ -8,8 +8,6 @@ #include "bx.h" -#include <new> - #if BX_CONFIG_ALLOCATOR_DEBUG # define BX_ALLOC(_allocator, _size) bx::alloc(_allocator, _size, 0, __FILE__, __LINE__) # define BX_REALLOC(_allocator, _ptr, _size) bx::realloc(_allocator, _ptr, _size, 0, __FILE__, __LINE__) @@ -17,9 +15,7 @@ # define BX_ALIGNED_ALLOC(_allocator, _size, _align) bx::alloc(_allocator, _size, _align, __FILE__, __LINE__) # define BX_ALIGNED_REALLOC(_allocator, _ptr, _size, _align) bx::realloc(_allocator, _ptr, _size, _align, __FILE__, __LINE__) # define BX_ALIGNED_FREE(_allocator, _ptr, _align) bx::free(_allocator, _ptr, _align, __FILE__, __LINE__) -# define BX_NEW(_allocator, _type) ::new(BX_ALLOC(_allocator, sizeof(_type) ) ) _type # define BX_DELETE(_allocator, _ptr) bx::deleteObject(_allocator, _ptr, 0, __FILE__, __LINE__) -# define BX_ALIGNED_NEW(_allocator, _type, _align) ::new(BX_ALIGNED_ALLOC(_allocator, sizeof(_type), _align) ) _type # define BX_ALIGNED_DELETE(_allocator, _ptr, _align) bx::deleteObject(_allocator, _ptr, _align, __FILE__, __LINE__) #else # define BX_ALLOC(_allocator, _size) bx::alloc(_allocator, _size, 0) @@ -28,15 +24,18 @@ # define BX_ALIGNED_ALLOC(_allocator, _size, _align) bx::alloc(_allocator, _size, _align) # define BX_ALIGNED_REALLOC(_allocator, _ptr, _size, _align) bx::realloc(_allocator, _ptr, _size, _align) # define BX_ALIGNED_FREE(_allocator, _ptr, _align) bx::free(_allocator, _ptr, _align) -# define BX_NEW(_allocator, _type) ::new(BX_ALLOC(_allocator, sizeof(_type) ) ) _type # define BX_DELETE(_allocator, _ptr) bx::deleteObject(_allocator, _ptr, 0) -# define BX_ALIGNED_NEW(_allocator, _type, _align) ::new(BX_ALIGNED_ALLOC(_allocator, sizeof(_type), _align) ) _type # define BX_ALIGNED_DELETE(_allocator, _ptr, _align) bx::deleteObject(_allocator, _ptr, _align) #endif // BX_CONFIG_DEBUG_ALLOC -#ifndef BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT -# define BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT 8 -#endif // BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT +#define BX_NEW(_allocator, _type) BX_PLACEMENT_NEW(BX_ALLOC(_allocator, sizeof(_type) ), _type) +#define BX_ALIGNED_NEW(_allocator, _type, _align) BX_PLACEMENT_NEW(BX_ALIGNED_ALLOC(_allocator, sizeof(_type), _align), _type) +#define BX_PLACEMENT_NEW(_ptr, _type) ::new(bx::PlacementNewTag(), _ptr) _type + +namespace bx { struct PlacementNewTag {}; } + +void* operator new(size_t, bx::PlacementNewTag, void* _ptr); +void operator delete(void*, bx::PlacementNewTag, void*) throw(); namespace bx { @@ -54,7 +53,33 @@ namespace bx /// @param[in] _align Alignment. /// @param[in] _file Debug file path info. /// @param[in] _line Debug file line info. - virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) = 0; + virtual void* realloc( + void* _ptr + , size_t _size + , size_t _align + , const char* _file + , uint32_t _line + ) = 0; + }; + + /// + class DefaultAllocator : public AllocatorI + { + public: + /// + DefaultAllocator(); + + /// + virtual ~DefaultAllocator(); + + /// + virtual void* realloc( + void* _ptr + , size_t _size + , size_t _align + , const char* _file + , uint32_t _line + ) override; }; /// Check if pointer is aligned. _align must be power of two. @@ -64,7 +89,7 @@ namespace bx void* alignPtr( void* _ptr , size_t _extra - , size_t _align = BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT + , size_t _align = 0 ); /// Allocate memory. diff --git a/3rdparty/bx/include/bx/bx.h b/3rdparty/bx/include/bx/bx.h index 838c429a8f5..a87a9b0f6d3 100644 --- a/3rdparty/bx/include/bx/bx.h +++ b/3rdparty/bx/include/bx/bx.h @@ -15,6 +15,7 @@ #include "platform.h" #include "config.h" #include "macros.h" +#include "debug.h" /// #define BX_COUNTOF(_x) sizeof(bx::COUNTOF_REQUIRES_ARRAY_ARGUMENT(_x) ) @@ -27,20 +28,44 @@ namespace bx { + const int32_t kExitSuccess = 0; + const int32_t kExitFailure = 1; + /// Template for avoiding MSVC: C4127: conditional expression is constant template<bool> bool isEnabled(); - /// - bool ignoreC4127(bool _x); - - /// + /// Exchange two values. template<typename Ty> void xchg(Ty& _a, Ty& _b); - /// + /// Exchange memory. void xchg(void* _a, void* _b, size_t _numBytes); + /// Returns minimum of two values. + template<typename Ty> + Ty min(const Ty& _a, const Ty& _b); + + /// Returns maximum of two values. + template<typename Ty> + Ty max(const Ty& _a, const Ty& _b); + + /// Returns minimum of three values. + template<typename Ty> + Ty min(const Ty& _a, const Ty& _b, const Ty& _c); + + /// Returns maximum of three values. + template<typename Ty> + Ty max(const Ty& _a, const Ty& _b, const Ty& _c); + + /// Returns middle of three values. + template<typename Ty> + Ty mid(const Ty& _a, const Ty& _b, const Ty& _c); + + /// Returns clamped value between min/max. + template<typename Ty> + Ty clamp(const Ty& _a, const Ty& _min, const Ty& _max); + // http://cnicholson.net/2011/01/stupid-c-tricks-a-better-sizeof_array/ template<typename T, size_t N> char (&COUNTOF_REQUIRES_ARRAY_ARGUMENT(const T(&)[N]) )[N]; diff --git a/3rdparty/bx/include/bx/commandline.h b/3rdparty/bx/include/bx/commandline.h index 9b9a397360b..61a7eb33760 100644 --- a/3rdparty/bx/include/bx/commandline.h +++ b/3rdparty/bx/include/bx/commandline.h @@ -60,6 +60,12 @@ namespace bx /// bool hasArg(bool& _value, const char _short, const char* _long = NULL) const; + /// + int32_t getNum() const; + + /// + char const* get(int32_t _idx) const; + private: /// const char* find(int32_t _skip, const char _short, const char* _long, int32_t _numParams) const; diff --git a/3rdparty/bx/include/bx/config.h b/3rdparty/bx/include/bx/config.h index 2f7264f7c52..dea60b9d1f8 100644 --- a/3rdparty/bx/include/bx/config.h +++ b/3rdparty/bx/include/bx/config.h @@ -12,28 +12,6 @@ # define BX_CONFIG_ALLOCATOR_DEBUG 0 #endif // BX_CONFIG_DEBUG_ALLOC -#ifndef BX_CONFIG_ALLOCATOR_CRT -# define BX_CONFIG_ALLOCATOR_CRT 1 -#endif // BX_CONFIG_ALLOCATOR_CRT - -#ifndef BX_CONFIG_CRT_FILE_READER_WRITER -# define BX_CONFIG_CRT_FILE_READER_WRITER !(0 \ - || BX_PLATFORM_NACL \ - || BX_CRT_NONE \ - ) -#endif // BX_CONFIG_CRT_FILE_READER_WRITER - -#ifndef BX_CONFIG_CRT_PROCESS -# define BX_CONFIG_CRT_PROCESS !(0 \ - || BX_CRT_NONE \ - || BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOXONE \ - ) -#endif // BX_CONFIG_CRT_PROCESS - #ifndef BX_CONFIG_SUPPORTS_THREADING # define BX_CONFIG_SUPPORTS_THREADING !(0 \ || BX_PLATFORM_EMSCRIPTEN \ diff --git a/3rdparty/bx/include/bx/cpu.h b/3rdparty/bx/include/bx/cpu.h index 91ab437019d..40e67b603b7 100644 --- a/3rdparty/bx/include/bx/cpu.h +++ b/3rdparty/bx/include/bx/cpu.h @@ -8,315 +8,61 @@ #include "bx.h" -#if BX_COMPILER_MSVC -# if BX_PLATFORM_XBOX360 -# include <ppcintrinsics.h> -# include <xtl.h> -# else -# include <math.h> // math.h is included because VS bitches: - // warning C4985: 'ceil': attributes not present on previous declaration. - // must be included before intrin.h. -# include <intrin.h> -# include <windows.h> -# endif // !BX_PLATFORM_XBOX360 -# if BX_PLATFORM_WINRT -# define _InterlockedExchangeAdd64 InterlockedExchangeAdd64 -# endif // BX_PLATFORM_WINRT -extern "C" void _ReadBarrier(); -extern "C" void _WriteBarrier(); -extern "C" void _ReadWriteBarrier(); -# pragma intrinsic(_ReadBarrier) -# pragma intrinsic(_WriteBarrier) -# pragma intrinsic(_ReadWriteBarrier) -# pragma intrinsic(_InterlockedExchangeAdd) -# pragma intrinsic(_InterlockedCompareExchange) -#endif // BX_COMPILER_MSVC - namespace bx { /// - inline void readBarrier() - { -#if BX_COMPILER_MSVC - _ReadBarrier(); -#else - asm volatile("":::"memory"); -#endif // BX_COMPILER - } + void readBarrier(); /// - inline void writeBarrier() - { -#if BX_COMPILER_MSVC - _WriteBarrier(); -#else - asm volatile("":::"memory"); -#endif // BX_COMPILER - } + void writeBarrier(); /// - inline void readWriteBarrier() - { -#if BX_COMPILER_MSVC - _ReadWriteBarrier(); -#else - asm volatile("":::"memory"); -#endif // BX_COMPILER - } + void readWriteBarrier(); /// - inline void memoryBarrier() - { -#if BX_PLATFORM_XBOX360 - __lwsync(); -#elif BX_PLATFORM_WINRT - MemoryBarrier(); -#elif BX_COMPILER_MSVC - _mm_mfence(); -#else - __sync_synchronize(); -// asm volatile("mfence":::"memory"); -#endif // BX_COMPILER - } - - template<typename Ty> - inline Ty atomicFetchAndAdd(volatile Ty* _ptr, Ty _value); - - template<typename Ty> - inline Ty atomicAddAndFetch(volatile Ty* _ptr, Ty _value); + void memoryBarrier(); + /// template<typename Ty> - inline Ty atomicFetchAndSub(volatile Ty* _ptr, Ty _value); + Ty atomicFetchAndAdd(volatile Ty* _ptr, Ty _value); + /// template<typename Ty> - inline Ty atomicSubAndFetch(volatile Ty* _ptr, Ty _value); + Ty atomicAddAndFetch(volatile Ty* _ptr, Ty _value); + /// template<typename Ty> - inline Ty atomicCompareAndSwap(volatile void* _ptr, Ty _old, Ty _new); - - template<> - inline int32_t atomicCompareAndSwap(volatile void* _ptr, int32_t _old, int32_t _new); - - template<> - inline int64_t atomicCompareAndSwap(volatile void* _ptr, int64_t _old, int64_t _new); - - template<> - inline int32_t atomicFetchAndAdd<int32_t>(volatile int32_t* _ptr, int32_t _add) - { -#if BX_COMPILER_MSVC - return _InterlockedExchangeAdd( (volatile long*)_ptr, _add); -#else - return __sync_fetch_and_add(_ptr, _add); -#endif // BX_COMPILER_ - } - - template<> - inline int64_t atomicFetchAndAdd<int64_t>(volatile int64_t* _ptr, int64_t _add) - { -#if BX_COMPILER_MSVC -# if _WIN32_WINNT >= 0x600 - return _InterlockedExchangeAdd64( (volatile int64_t*)_ptr, _add); -# else - int64_t oldVal; - int64_t newVal = *(int64_t volatile*)_ptr; - do - { - oldVal = newVal; - newVal = atomicCompareAndSwap(_ptr, oldVal, newVal + _add); - - } while (oldVal != newVal); - - return oldVal; -# endif -#else - return __sync_fetch_and_add(_ptr, _add); -#endif // BX_COMPILER_ - } - - template<> - inline uint32_t atomicFetchAndAdd<uint32_t>(volatile uint32_t* _ptr, uint32_t _add) - { - return uint32_t(atomicFetchAndAdd<int32_t>( (volatile int32_t*)_ptr, int32_t(_add) ) ); - } - - template<> - inline uint64_t atomicFetchAndAdd<uint64_t>(volatile uint64_t* _ptr, uint64_t _add) - { - return uint64_t(atomicFetchAndAdd<int64_t>( (volatile int64_t*)_ptr, int64_t(_add) ) ); - } - - template<> - inline int32_t atomicAddAndFetch<int32_t>(volatile int32_t* _ptr, int32_t _add) - { -#if BX_COMPILER_MSVC - return atomicFetchAndAdd(_ptr, _add) + _add; -#else - return __sync_add_and_fetch(_ptr, _add); -#endif // BX_COMPILER_ - } - - template<> - inline int64_t atomicAddAndFetch<int64_t>(volatile int64_t* _ptr, int64_t _add) - { -#if BX_COMPILER_MSVC - return atomicFetchAndAdd(_ptr, _add) + _add; -#else - return __sync_add_and_fetch(_ptr, _add); -#endif // BX_COMPILER_ - } - - template<> - inline uint32_t atomicAddAndFetch<uint32_t>(volatile uint32_t* _ptr, uint32_t _add) - { - return uint32_t(atomicAddAndFetch<int32_t>( (volatile int32_t*)_ptr, int32_t(_add) ) ); - } - - template<> - inline uint64_t atomicAddAndFetch<uint64_t>(volatile uint64_t* _ptr, uint64_t _add) - { - return uint64_t(atomicAddAndFetch<int64_t>( (volatile int64_t*)_ptr, int64_t(_add) ) ); - } + Ty atomicFetchAndSub(volatile Ty* _ptr, Ty _value); - template<> - inline int32_t atomicFetchAndSub<int32_t>(volatile int32_t* _ptr, int32_t _sub) - { -#if BX_COMPILER_MSVC - return atomicFetchAndAdd(_ptr, -_sub); -#else - return __sync_fetch_and_sub(_ptr, _sub); -#endif // BX_COMPILER_ - } - - template<> - inline int64_t atomicFetchAndSub<int64_t>(volatile int64_t* _ptr, int64_t _sub) - { -#if BX_COMPILER_MSVC - return atomicFetchAndAdd(_ptr, -_sub); -#else - return __sync_fetch_and_sub(_ptr, _sub); -#endif // BX_COMPILER_ - } - - template<> - inline uint32_t atomicFetchAndSub<uint32_t>(volatile uint32_t* _ptr, uint32_t _add) - { - return uint32_t(atomicFetchAndSub<int32_t>( (volatile int32_t*)_ptr, int32_t(_add) ) ); - } - - template<> - inline uint64_t atomicFetchAndSub<uint64_t>(volatile uint64_t* _ptr, uint64_t _add) - { - return uint64_t(atomicFetchAndSub<int64_t>( (volatile int64_t*)_ptr, int64_t(_add) ) ); - } - - template<> - inline int32_t atomicSubAndFetch<int32_t>(volatile int32_t* _ptr, int32_t _sub) - { -#if BX_COMPILER_MSVC - return atomicFetchAndAdd(_ptr, -_sub) - _sub; -#else - return __sync_sub_and_fetch(_ptr, _sub); -#endif // BX_COMPILER_ - } - - template<> - inline int64_t atomicSubAndFetch<int64_t>(volatile int64_t* _ptr, int64_t _sub) - { -#if BX_COMPILER_MSVC - return atomicFetchAndAdd(_ptr, -_sub) - _sub; -#else - return __sync_sub_and_fetch(_ptr, _sub); -#endif // BX_COMPILER_ - } - - template<> - inline uint32_t atomicSubAndFetch<uint32_t>(volatile uint32_t* _ptr, uint32_t _add) - { - return uint32_t(atomicSubAndFetch<int32_t>( (volatile int32_t*)_ptr, int32_t(_add) ) ); - } - - template<> - inline uint64_t atomicSubAndFetch<uint64_t>(volatile uint64_t* _ptr, uint64_t _add) - { - return uint64_t(atomicSubAndFetch<int64_t>( (volatile int64_t*)_ptr, int64_t(_add) ) ); - } - - /// Returns the resulting incremented value. + /// template<typename Ty> - inline Ty atomicInc(volatile Ty* _ptr) - { - return atomicAddAndFetch(_ptr, Ty(1) ); - } + Ty atomicSubAndFetch(volatile Ty* _ptr, Ty _value); - /// Returns the resulting decremented value. + /// template<typename Ty> - inline Ty atomicDec(volatile Ty* _ptr) - { - return atomicSubAndFetch(_ptr, Ty(1) ); - } + Ty atomicCompareAndSwap(volatile Ty* _ptr, Ty _old, Ty _new); /// - template<> - inline int32_t atomicCompareAndSwap(volatile void* _ptr, int32_t _old, int32_t _new) - { -#if BX_COMPILER_MSVC - return _InterlockedCompareExchange( (volatile LONG*)(_ptr), _new, _old); -#else - return __sync_val_compare_and_swap( (volatile int32_t*)_ptr, _old, _new); -#endif // BX_COMPILER - } + template<typename Ty> + Ty atomicFetchTestAndAdd(volatile Ty* _ptr, Ty _test, Ty _value); /// - template<> - inline int64_t atomicCompareAndSwap(volatile void* _ptr, int64_t _old, int64_t _new) - { -#if BX_COMPILER_MSVC - return _InterlockedCompareExchange64( (volatile LONG64*)(_ptr), _new, _old); -#else - return __sync_val_compare_and_swap( (volatile int64_t*)_ptr, _old, _new); -#endif // BX_COMPILER - } + template<typename Ty> + Ty atomicFetchTestAndSub(volatile Ty* _ptr, Ty _test, Ty _value); /// - inline void* atomicExchangePtr(void** _ptr, void* _new) - { -#if BX_COMPILER_MSVC - return InterlockedExchangePointer(_ptr, _new); -#else - return __sync_lock_test_and_set(_ptr, _new); -#endif // BX_COMPILER - } + template<typename Ty> + Ty atomicFetchAndAddsat(volatile Ty* _ptr, Ty _value, Ty _max); /// - inline int32_t atomicTestAndInc(volatile void* _ptr, int32_t _test) - { - int32_t oldVal; - int32_t newVal = *(int32_t volatile*)_ptr; - do - { - oldVal = newVal; - newVal = atomicCompareAndSwap(_ptr, oldVal, newVal >= _test ? _test : newVal+1); - - } while (oldVal != newVal); - - return oldVal; - } + template<typename Ty> + Ty atomicFetchAndSubsat(volatile Ty* _ptr, Ty _value, Ty _min); /// - inline int32_t atomicTestAndDec(volatile void* _ptr, int32_t _test) - { - int32_t oldVal; - int32_t newVal = *(int32_t volatile*)_ptr; - do - { - oldVal = newVal; - newVal = atomicCompareAndSwap(_ptr, oldVal, newVal <= _test ? _test : newVal-1); - - } while (oldVal != newVal); - - return oldVal; - } + void* atomicExchangePtr(void** _ptr, void* _new); } // namespace bx +#include "inline/cpu.inl" + #endif // BX_CPU_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/crtimpl.h b/3rdparty/bx/include/bx/crtimpl.h deleted file mode 100644 index 8176c6b9185..00000000000 --- a/3rdparty/bx/include/bx/crtimpl.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2010-2017 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#ifndef BX_CRTIMPL_H_HEADER_GUARD -#define BX_CRTIMPL_H_HEADER_GUARD - -#include "bx.h" - -#if BX_CONFIG_ALLOCATOR_CRT -# include "allocator.h" -#endif // BX_CONFIG_ALLOCATOR_CRT - -#if BX_CONFIG_CRT_FILE_READER_WRITER -# include "readerwriter.h" -#endif // BX_CONFIG_CRT_FILE_READER_WRITER - -namespace bx -{ -#if BX_CONFIG_ALLOCATOR_CRT - /// - class CrtAllocator : public AllocatorI - { - public: - /// - CrtAllocator(); - - /// - virtual ~CrtAllocator(); - - /// - virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE; - }; -#endif // BX_CONFIG_ALLOCATOR_CRT - -#if BX_CONFIG_CRT_FILE_READER_WRITER - /// - class CrtFileReader : public FileReaderI - { - public: - /// - CrtFileReader(); - - /// - virtual ~CrtFileReader(); - - /// - virtual bool open(const char* _filePath, Error* _err) BX_OVERRIDE; - - /// - virtual void close() BX_OVERRIDE; - - /// - virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE; - - /// - virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE; - - private: - void* m_file; - }; - - /// - class CrtFileWriter : public FileWriterI - { - public: - /// - CrtFileWriter(); - - /// - virtual ~CrtFileWriter(); - - /// - virtual bool open(const char* _filePath, bool _append, Error* _err) BX_OVERRIDE; - - /// - virtual void close() BX_OVERRIDE; - - /// - virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE; - - /// - virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE; - - private: - void* m_file; - }; -#endif // BX_CONFIG_CRT_FILE_READER_WRITER - -#if BX_CONFIG_CRT_PROCESS - /// - class ProcessReader : public ReaderOpenI, public CloserI, public ReaderI - { - public: - /// - ProcessReader(); - - /// - ~ProcessReader(); - - /// - virtual bool open(const char* _command, Error* _err) BX_OVERRIDE; - - /// - virtual void close() BX_OVERRIDE; - - /// - virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE; - - /// - int32_t getExitCode() const; - - private: - void* m_file; - int32_t m_exitCode; - }; - - /// - class ProcessWriter : public WriterOpenI, public CloserI, public WriterI - { - public: - /// - ProcessWriter(); - - /// - ~ProcessWriter(); - - /// - virtual bool open(const char* _command, bool, Error* _err) BX_OVERRIDE; - - /// - virtual void close() BX_OVERRIDE; - - /// - virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE; - - /// - int32_t getExitCode() const; - - private: - void* m_file; - int32_t m_exitCode; - }; -#endif // BX_CONFIG_CRT_PROCESS - -} // namespace bx - -#endif // BX_CRTIMPL_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/debug.h b/3rdparty/bx/include/bx/debug.h index 7c2ca8634d0..58940ac19e6 100644 --- a/3rdparty/bx/include/bx/debug.h +++ b/3rdparty/bx/include/bx/debug.h @@ -25,6 +25,9 @@ namespace bx /// void debugPrintfData(const void* _data, uint32_t _size, const char* _format, ...); + /// + struct WriterI* getDebugOut(); + } // namespace bx #endif // BX_DEBUG_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/easing.h b/3rdparty/bx/include/bx/easing.h index 62131578450..96849030211 100644 --- a/3rdparty/bx/include/bx/easing.h +++ b/3rdparty/bx/include/bx/easing.h @@ -6,7 +6,7 @@ #ifndef BX_EASING_H_HEADER_GUARD #define BX_EASING_H_HEADER_GUARD -#include "fpumath.h" +#include "math.h" // Reference: // http://easings.net/ @@ -20,6 +20,8 @@ namespace bx enum Enum { Linear, + Step, + SmoothStep, InQuad, OutQuad, InOutQuad, @@ -69,128 +71,1127 @@ namespace bx typedef float (*EaseFn)(float _t); /// + EaseFn getEaseFunc(Easing::Enum _enum); + + /// Linear. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ******* + /// | ******* + /// | ******** + /// | ******* + /// | ******* + /// | ******** + /// | ******* + /// | ******** + /// | ******* + /// +*******---------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | + /// float easeLinear(float _t); + /// Step. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | ******************************** + /// | + /// | + /// | + /// | + /// | + /// | + /// | + /// | + /// | + /// +********************************--------------------------------> + /// | + /// | + /// | + /// | + /// | + /// + float easeStep(float _t); + + /// Smooth step. + /// + /// | + /// | + /// | + /// | + /// | + /// | ************* + /// | ******* + /// | ****** + /// | ***** + /// | ***** + /// | ***** + /// | ***** + /// | ****** + /// | ******* + /// +*************---------------------------------------------------> + /// | + /// | + /// | + /// | + /// | + /// + float easeSmoothStep(float _t); + + /// Quad. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | **** + /// | **** + /// | ***** + /// | ***** + /// | ***** + /// | ****** + /// | ****** + /// | ******** + /// | ********* + /// +*********************-------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInQuad(float _t); + /// Out quad. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ********************* + /// | ********* + /// | ******* + /// | ****** + /// | ****** + /// | ***** + /// | ***** + /// | ***** + /// | **** + /// +****------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutQuad(float _t); + /// In out quad. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | *************** + /// | ******* + /// | ***** + /// | ***** + /// | **** + /// | ***** + /// | ***** + /// | ***** + /// | ******* + /// +***************-------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInOutQuad(float _t); + /// Out in quad. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | **** + /// | ***** + /// | ***** + /// | ******* + /// | *************** + /// | **************** + /// | ******* + /// | ***** + /// | ***** + /// +****------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInQuad(float _t); + /// In cubic. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | *** + /// | *** + /// | **** + /// | *** + /// | **** + /// | **** + /// | ****** + /// | ****** + /// | ********* + /// +******************************----------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInCubic(float _t); + /// Out cubic. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | * + /// | ****************************** + /// | ********* + /// | ****** + /// | ****** + /// | **** + /// | **** + /// | **** + /// | **** + /// | *** + /// +***-------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutCubic(float _t); + /// In out cubic. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | * + /// | ******************* + /// | ****** + /// | **** + /// | **** + /// | *** + /// | **** + /// | *** + /// | **** + /// | ****** + /// +*******************---------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInOutCubic(float _t); + /// Out in cubic. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | *** + /// | *** + /// | **** + /// | ****** + /// | ******************* + /// | ******************** + /// | ****** + /// | **** + /// | **** + /// +***-------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInCubic(float _t); + /// In quart. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ** + /// | *** + /// | *** + /// | *** + /// | **** + /// | **** + /// | **** + /// | ****** + /// | ******* + /// +************************************----------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInQuart(float _t); + /// Out quart. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | * + /// | ************************************ + /// | ******** + /// | ****** + /// | **** + /// | **** + /// | **** + /// | *** + /// | *** + /// | *** + /// +**--------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutQuart(float _t); + /// In out quart. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | * + /// | ********************** + /// | ***** + /// | **** + /// | *** + /// | ** + /// | *** + /// | *** + /// | **** + /// | ***** + /// +**********************------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInOutQuart(float _t); + /// Out in quart. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ** + /// | *** + /// | **** + /// | ***** + /// | *********************** + /// | *********************** + /// | ***** + /// | **** + /// | *** + /// +**--------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInQuart(float _t); + /// In quint. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ** + /// | ** + /// | *** + /// | *** + /// | *** + /// | *** + /// | **** + /// | ***** + /// | ******* + /// +*****************************************-----------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInQuint(float _t); + /// Out quint. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | ** + /// | ***************************************** + /// | ******* + /// | ***** + /// | **** + /// | *** + /// | *** + /// | *** + /// | *** + /// | ** + /// +**--------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutQuint(float _t); + /// In out quint. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | ** + /// | ************************ + /// | **** + /// | *** + /// | *** + /// | ** + /// | *** + /// | *** + /// | *** + /// | **** + /// +************************----------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInOutQuint(float _t); + /// Out in quint. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ** + /// | *** + /// | *** + /// | **** + /// | ************************* + /// | ************************** + /// | **** + /// | *** + /// | *** + /// +**--------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInQuint(float _t); + /// In sine. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | **** + /// | ***** + /// | ***** + /// | ***** + /// | ****** + /// | ****** + /// | ****** + /// | ******* + /// | ********* + /// +*******************---------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInSine(float _t); + /// Out sine. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ******************* + /// | ********* + /// | ******* + /// | ****** + /// | ****** + /// | ****** + /// | ***** + /// | ***** + /// | ***** + /// +*****-----------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutSine(float _t); + /// In out sine. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ************** + /// | ****** + /// | ****** + /// | ***** + /// | ***** + /// | ****** + /// | ***** + /// | ****** + /// | ****** + /// +**************--------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInOutSine(float _t); + /// Out in sine. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ***** + /// | ***** + /// | ****** + /// | ****** + /// | ************** + /// | *************** + /// | ****** + /// | ****** + /// | ***** + /// +*****-----------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInSine(float _t); + /// In exponential. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | * + /// | ** + /// | ** + /// | ** + /// | *** + /// | *** + /// | *** + /// | **** + /// | ******** + /// +*******************************************---------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInExpo(float _t); + /// Out exponential. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | * + /// | ******************************************* + /// | ******** + /// | **** + /// | **** + /// | *** + /// | *** + /// | ** + /// | ** + /// | ** + /// +*---------------------------------------------------------------> + /// | + /// | + /// | + /// | + /// | /// float easeOutExpo(float _t); + /// In out exponential. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | * + /// | ************************* + /// | **** + /// | *** + /// | ** + /// | ** + /// | * + /// | ** + /// | *** + /// | **** + /// +*************************---------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInOutExpo(float _t); + /// Out in exponential. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | * + /// | ** + /// | *** + /// | **** + /// | ************************** + /// | ************************** + /// | **** + /// | *** + /// | ** + /// +**--------------------------------------------------------------> + /// | + /// | + /// | + /// | + /// | /// float easeOutInExpo(float _t); + /// In circle. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | * + /// | ** + /// | ** + /// | **** + /// | **** + /// | ***** + /// | ******* + /// | ******** + /// | ************ + /// +****************************------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInCirc(float _t); + /// Out circle. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | **************************** + /// | ************ + /// | ******** + /// | ******* + /// | ***** + /// | **** + /// | *** + /// | ** + /// |** + /// +*---------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutCirc(float _t); + /// In out circle. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ******************** + /// | ******* + /// | ***** + /// | *** + /// | * + /// | ** + /// | *** + /// | ***** + /// | ******* + /// +********************--------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInOutCirc(float _t); + /// Out in circle. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | * + /// | *** + /// | ***** + /// | ******* + /// | ******************** + /// | ********************* + /// | ******* + /// | ***** + /// |*** + /// +*---------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInCirc(float _t); + /// Out elastic. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | * + /// | ** + /// | * + /// | ** + /// | * + /// | * + /// | * + /// | * + /// | ***** ** + /// +-***********--------***********---------****---***---------*----> + /// |** ********** *********** ** ** + /// | ** * + /// | ** * + /// | ***** + /// | /// float easeOutElastic(float _t); + /// In elastic. + /// + /// ^ + /// | + /// | ***** + /// | * ** + /// | ** ** + /// | ** ** ********** ********** ** + /// | * *** ***** *********** *********** + /// | ** ***** + /// | * + /// | * + /// | ** + /// | * + /// | ** + /// | * + /// |** + /// +*---------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInElastic(float _t); + /// In out elastic. + /// + /// ^ + /// | + /// | + /// | + /// | *** + /// | ** ** ***** ****** * + /// | * ****** ****** ****** + /// | * + /// | * + /// | ** + /// | * + /// | ** + /// | * + /// | * + /// | * + /// +******----******----*****----**---------------------------------> + /// |* ****** ****** *** * + /// | *** + /// | + /// | + /// | /// float easeInOutElastic(float _t); + /// Out in elastic. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | * + /// | * + /// | * + /// | *** * + /// | ** ** ***** ****** ******* ****** ***** ** + /// | * ****** ****** ******* ****** ****** *** * + /// | * *** + /// | * + /// |** + /// +*---------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInElastic(float _t); + /// In back. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | * + /// | ** + /// | ** + /// | ** + /// | ** + /// | ** + /// | ** + /// | ** + /// | ** + /// +*-------------------------------------------------***-----------> + /// |************* *** + /// | ******* **** + /// | ******* ***** + /// | ****************** + /// | /// float easeInBack(float _t); + /// Out back. + /// + /// ^ + /// | + /// | ****************** + /// | ***** ******* + /// | **** ******* + /// | *** ************* + /// | *** + /// | ** + /// | *** + /// | ** + /// | *** + /// | ** + /// | ** + /// | ** + /// | ** + /// +**--------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutBack(float _t); + /// In out back. + /// + /// ^ + /// | + /// | + /// | + /// | ************** + /// | **** ********** + /// | ** + /// | *** + /// | ** + /// | ** + /// | ** + /// | ** + /// | ** + /// | ** + /// | ** + /// +*------------------------**-------------------------------------> + /// |********** **** + /// | ************** + /// | + /// | + /// | /// float easeInOutBack(float _t); + /// Out in back. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | * + /// | ** + /// | ** + /// | ************** ** + /// | **** *********** ** + /// | ** ********** **** + /// | *** ************** + /// | ** + /// | ** + /// +**--------------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInBack(float _t); + /// Out bounce. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ******** + /// | **** + /// | *** + /// | *** + /// | *** + /// | ** + /// | ** + /// | ************** ** + /// | **** **** ** + /// +********************------------------****----------------------> + /// |* * + /// | + /// | + /// | + /// | /// float easeOutBounce(float _t); + /// In bounce. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | * + /// | **** ******************** + /// | *** **** **** + /// | ** ************** + /// | ** + /// | *** + /// | *** + /// | *** + /// | *** + /// | **** + /// +********--------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeInBounce(float _t); + /// In out bounce. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | * + /// | ***** ************ + /// | ** ******* + /// | *** + /// | *** + /// | ****** + /// | ******* + /// | *** + /// | ** + /// | ******* ** + /// +************------****------------------------------------------> + /// |* * + /// | + /// | + /// | + /// | /// float easeInOutBounce(float _t); + /// Out in bounce. + /// + /// ^ + /// | + /// | + /// | + /// | + /// | + /// | ****** + /// | *** + /// | ** + /// | ******* ** + /// | * ************ **** + /// | ***** ************* * + /// | ** ******* + /// | *** + /// | *** + /// +******----------------------------------------------------------> + /// |* + /// | + /// | + /// | + /// | /// float easeOutInBounce(float _t); + float easeInOutLinear(float _t); + } // namespace bx #include "inline/easing.inl" diff --git a/3rdparty/bx/include/bx/file.h b/3rdparty/bx/include/bx/file.h new file mode 100644 index 00000000000..144f965d2c4 --- /dev/null +++ b/3rdparty/bx/include/bx/file.h @@ -0,0 +1,98 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_FILE_H_HEADER_GUARD +#define BX_FILE_H_HEADER_GUARD + +#include "filepath.h" +#include "readerwriter.h" + +namespace bx +{ + /// + ReaderI* getStdIn(); + + /// + WriterI* getStdOut(); + + /// + WriterI* getStdErr(); + + /// + WriterI* getNullOut(); + + /// + class FileReader : public FileReaderI + { + public: + /// + FileReader(); + + /// + virtual ~FileReader(); + + /// + virtual bool open(const FilePath& _filePath, Error* _err) override; + + /// + virtual void close() override; + + /// + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override; + + /// + virtual int32_t read(void* _data, int32_t _size, Error* _err) override; + + private: + BX_ALIGN_DECL(16, uint8_t) m_internal[64]; + }; + + /// + class FileWriter : public FileWriterI + { + public: + /// + FileWriter(); + + /// + virtual ~FileWriter(); + + /// + virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override; + + /// + virtual void close() override; + + /// + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override; + + /// + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override; + + private: + BX_ALIGN_DECL(16, uint8_t) m_internal[64]; + }; + + /// + struct FileInfo + { + enum Enum + { + Regular, + Directory, + + Count + }; + + uint64_t m_size; + Enum m_type; + }; + + /// + bool stat(const FilePath& _filePath, FileInfo& _outFileInfo); + +} // namespace bx + +#endif // BX_FILE_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/filepath.h b/3rdparty/bx/include/bx/filepath.h new file mode 100644 index 00000000000..761f50c590d --- /dev/null +++ b/3rdparty/bx/include/bx/filepath.h @@ -0,0 +1,108 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_FILEPATH_H_HEADER_GUARD +#define BX_FILEPATH_H_HEADER_GUARD + +#include "error.h" +#include "string.h" + +BX_ERROR_RESULT(BX_ERROR_ACCESS, BX_MAKEFOURCC('b', 'x', 0, 0) ); +BX_ERROR_RESULT(BX_ERROR_NOT_DIRECTORY, BX_MAKEFOURCC('b', 'x', 0, 1) ); + +namespace bx +{ + const int32_t kMaxFilePath = 1024; + + /// + struct Dir + { + enum Enum /// + { + Current, + Temp, + Home, + + Count + }; + }; + + /// FilePath parser and helper. + /// + /// /abv/gd/555/333/pod.mac + /// ppppppppppppppppbbbeeee + /// ^ ^ ^ + /// +-path base-+ +-ext + /// ^^^^^^^ + /// +-filename + /// + class FilePath + { + public: + /// + FilePath(); + + /// + FilePath(Dir::Enum _dir); + + /// + FilePath(const char* _str); + + /// + FilePath(const StringView& _str); + + /// + FilePath& operator=(const StringView& _rhs); + + /// + void set(Dir::Enum _dir); + + /// + void set(const StringView& _str); + + /// + void join(const StringView& _str); + + /// + const char* get() const; + + /// If path is `/abv/gd/555/333/pod.mac` returns `/abv/gd/555/333/`. + /// + const StringView getPath() const; + + /// If path is `/abv/gd/555/333/pod.mac` returns `pod.mac`. + /// + const StringView getFileName() const; + + /// If path is `/abv/gd/555/333/pod.mac` returns `pod`. + /// + const StringView getBaseName() const; + + /// If path is `/abv/gd/555/333/pod.mac` returns `.mac`. + /// + const StringView getExt() const; + + /// + bool isAbsolute() const; + + private: + char m_filePath[kMaxFilePath]; + }; + + /// Creates a directory named `_filePath`. + bool make(const FilePath& _filePath, Error* _err = NULL); + + /// Creates a directory named `_filePath` along with all necessary parents. + bool makeAll(const FilePath& _filePath, Error* _err = NULL); + + /// Removes file or directory. + bool remove(const FilePath& _filePath, Error* _err = NULL); + + /// Removes file or directory recursivelly. + bool removeAll(const FilePath& _filePath, Error* _err = NULL); + +} // namespace bx + +#endif // BX_FILEPATH_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/float4x4_t.h b/3rdparty/bx/include/bx/float4x4_t.h index 44569b95a76..0a144534928 100644 --- a/3rdparty/bx/include/bx/float4x4_t.h +++ b/3rdparty/bx/include/bx/float4x4_t.h @@ -10,149 +10,29 @@ namespace bx { + /// BX_ALIGN_DECL_16(struct) float4x4_t { simd128_t col[4]; }; - BX_SIMD_FORCE_INLINE simd128_t simd_mul_xyz1(simd128_t _a, const float4x4_t* _b) - { - const simd128_t xxxx = simd_swiz_xxxx(_a); - const simd128_t yyyy = simd_swiz_yyyy(_a); - const simd128_t zzzz = simd_swiz_zzzz(_a); - const simd128_t col0 = simd_mul(_b->col[0], xxxx); - const simd128_t col1 = simd_mul(_b->col[1], yyyy); - const simd128_t col2 = simd_madd(_b->col[2], zzzz, col0); - const simd128_t col3 = simd_add(_b->col[3], col1); - const simd128_t result = simd_add(col2, col3); - - return result; - } - - BX_SIMD_FORCE_INLINE simd128_t simd_mul(simd128_t _a, const float4x4_t* _b) - { - const simd128_t xxxx = simd_swiz_xxxx(_a); - const simd128_t yyyy = simd_swiz_yyyy(_a); - const simd128_t zzzz = simd_swiz_zzzz(_a); - const simd128_t wwww = simd_swiz_wwww(_a); - const simd128_t col0 = simd_mul(_b->col[0], xxxx); - const simd128_t col1 = simd_mul(_b->col[1], yyyy); - const simd128_t col2 = simd_madd(_b->col[2], zzzz, col0); - const simd128_t col3 = simd_madd(_b->col[3], wwww, col1); - const simd128_t result = simd_add(col2, col3); - - return result; - } - - BX_SIMD_INLINE void float4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b) - { - _result->col[0] = simd_mul(_a->col[0], _b); - _result->col[1] = simd_mul(_a->col[1], _b); - _result->col[2] = simd_mul(_a->col[2], _b); - _result->col[3] = simd_mul(_a->col[3], _b); - } - - BX_SIMD_FORCE_INLINE void float4x4_transpose(float4x4_t* _result, const float4x4_t* _mtx) - { - const simd128_t aibj = simd_shuf_xAyB(_mtx->col[0], _mtx->col[2]); // aibj - const simd128_t emfn = simd_shuf_xAyB(_mtx->col[1], _mtx->col[3]); // emfn - const simd128_t ckdl = simd_shuf_zCwD(_mtx->col[0], _mtx->col[2]); // ckdl - const simd128_t gohp = simd_shuf_zCwD(_mtx->col[1], _mtx->col[3]); // gohp - _result->col[0] = simd_shuf_xAyB(aibj, emfn); // aeim - _result->col[1] = simd_shuf_zCwD(aibj, emfn); // bfjn - _result->col[2] = simd_shuf_xAyB(ckdl, gohp); // cgko - _result->col[3] = simd_shuf_zCwD(ckdl, gohp); // dhlp - } - - BX_SIMD_INLINE void float4x4_inverse(float4x4_t* _result, const float4x4_t* _a) - { - const simd128_t tmp0 = simd_shuf_xAzC(_a->col[0], _a->col[1]); - const simd128_t tmp1 = simd_shuf_xAzC(_a->col[2], _a->col[3]); - const simd128_t tmp2 = simd_shuf_yBwD(_a->col[0], _a->col[1]); - const simd128_t tmp3 = simd_shuf_yBwD(_a->col[2], _a->col[3]); - const simd128_t t0 = simd_shuf_xyAB(tmp0, tmp1); - const simd128_t t1 = simd_shuf_xyAB(tmp3, tmp2); - const simd128_t t2 = simd_shuf_zwCD(tmp0, tmp1); - const simd128_t t3 = simd_shuf_zwCD(tmp3, tmp2); - - const simd128_t t23 = simd_mul(t2, t3); - const simd128_t t23_yxwz = simd_swiz_yxwz(t23); - const simd128_t t23_wzyx = simd_swiz_wzyx(t23); - - simd128_t cof0, cof1, cof2, cof3; - - const simd128_t zero = simd_zero(); - cof0 = simd_nmsub(t1, t23_yxwz, zero); - cof0 = simd_madd(t1, t23_wzyx, cof0); - - cof1 = simd_nmsub(t0, t23_yxwz, zero); - cof1 = simd_madd(t0, t23_wzyx, cof1); - cof1 = simd_swiz_zwxy(cof1); + /// + simd128_t simd_mul_xyz1(simd128_t _a, const float4x4_t* _b); - const simd128_t t12 = simd_mul(t1, t2); - const simd128_t t12_yxwz = simd_swiz_yxwz(t12); - const simd128_t t12_wzyx = simd_swiz_wzyx(t12); + /// + simd128_t simd_mul(simd128_t _a, const float4x4_t* _b); - cof0 = simd_madd(t3, t12_yxwz, cof0); - cof0 = simd_nmsub(t3, t12_wzyx, cof0); + /// + void float4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b); - cof3 = simd_mul(t0, t12_yxwz); - cof3 = simd_nmsub(t0, t12_wzyx, cof3); - cof3 = simd_swiz_zwxy(cof3); + /// + void float4x4_transpose(float4x4_t* _result, const float4x4_t* _mtx); - const simd128_t t1_zwxy = simd_swiz_zwxy(t1); - const simd128_t t2_zwxy = simd_swiz_zwxy(t2); - - const simd128_t t13 = simd_mul(t1_zwxy, t3); - const simd128_t t13_yxwz = simd_swiz_yxwz(t13); - const simd128_t t13_wzyx = simd_swiz_wzyx(t13); - - cof0 = simd_madd(t2_zwxy, t13_yxwz, cof0); - cof0 = simd_nmsub(t2_zwxy, t13_wzyx, cof0); - - cof2 = simd_mul(t0, t13_yxwz); - cof2 = simd_nmsub(t0, t13_wzyx, cof2); - cof2 = simd_swiz_zwxy(cof2); - - const simd128_t t01 = simd_mul(t0, t1); - const simd128_t t01_yxwz = simd_swiz_yxwz(t01); - const simd128_t t01_wzyx = simd_swiz_wzyx(t01); - - cof2 = simd_nmsub(t3, t01_yxwz, cof2); - cof2 = simd_madd(t3, t01_wzyx, cof2); - - cof3 = simd_madd(t2_zwxy, t01_yxwz, cof3); - cof3 = simd_nmsub(t2_zwxy, t01_wzyx, cof3); - - const simd128_t t03 = simd_mul(t0, t3); - const simd128_t t03_yxwz = simd_swiz_yxwz(t03); - const simd128_t t03_wzyx = simd_swiz_wzyx(t03); - - cof1 = simd_nmsub(t2_zwxy, t03_yxwz, cof1); - cof1 = simd_madd(t2_zwxy, t03_wzyx, cof1); - - cof2 = simd_madd(t1, t03_yxwz, cof2); - cof2 = simd_nmsub(t1, t03_wzyx, cof2); - - const simd128_t t02 = simd_mul(t0, t2_zwxy); - const simd128_t t02_yxwz = simd_swiz_yxwz(t02); - const simd128_t t02_wzyx = simd_swiz_wzyx(t02); - - cof1 = simd_madd(t3, t02_yxwz, cof1); - cof1 = simd_nmsub(t3, t02_wzyx, cof1); - - cof3 = simd_nmsub(t1, t02_yxwz, cof3); - cof3 = simd_madd(t1, t02_wzyx, cof3); - - const simd128_t det = simd_dot(t0, cof0); - const simd128_t invdet = simd_rcp(det); - - _result->col[0] = simd_mul(cof0, invdet); - _result->col[1] = simd_mul(cof1, invdet); - _result->col[2] = simd_mul(cof2, invdet); - _result->col[3] = simd_mul(cof3, invdet); - } + /// + void float4x4_inverse(float4x4_t* _result, const float4x4_t* _a); } // namespace bx +#include "inline/float4x4_t.inl" + #endif // BX_FLOAT4X4_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/handlealloc.h b/3rdparty/bx/include/bx/handlealloc.h index eb98cac5821..fc200f72cdc 100644 --- a/3rdparty/bx/include/bx/handlealloc.h +++ b/3rdparty/bx/include/bx/handlealloc.h @@ -12,12 +12,12 @@ namespace bx { + static const uint16_t kInvalidHandle = UINT16_MAX; + /// class HandleAlloc { public: - static const uint16_t invalid = UINT16_MAX; - /// HandleAlloc(uint16_t _maxHandles); @@ -87,8 +87,6 @@ namespace bx class HandleListT { public: - static const uint16_t invalid = UINT16_MAX; - /// HandleListT(); @@ -152,8 +150,6 @@ namespace bx class HandleAllocLruT { public: - static const uint16_t invalid = UINT16_MAX; - /// HandleAllocLruT(); @@ -209,8 +205,6 @@ namespace bx class HandleHashMapT { public: - static const uint16_t invalid = UINT16_MAX; - /// HandleHashMapT(); @@ -280,8 +274,6 @@ namespace bx class HandleHashMapAllocT { public: - static const uint16_t invalid = UINT16_MAX; - /// HandleHashMapAllocT(); diff --git a/3rdparty/bx/include/bx/hash.h b/3rdparty/bx/include/bx/hash.h index feade562a3c..1dcd82e3f67 100644 --- a/3rdparty/bx/include/bx/hash.h +++ b/3rdparty/bx/include/bx/hash.h @@ -24,12 +24,42 @@ namespace bx void add(const void* _data, int _len); /// + template<typename Ty> + void add(Ty _value); + + /// + uint32_t end(); + + private: + /// void addAligned(const void* _data, int _len); /// void addUnaligned(const void* _data, int _len); /// + static void readUnaligned(const void* _data, uint32_t& _out); + + /// + void mixTail(const uint8_t*& _data, int& _len); + + uint32_t m_hash; + uint32_t m_tail; + uint32_t m_count; + uint32_t m_size; + }; + + /// + class HashAdler32 + { + public: + /// + void begin(); + + /// + void add(const void* _data, int _len); + + /// template<typename Ty> void add(Ty _value); @@ -37,30 +67,56 @@ namespace bx uint32_t end(); private: + uint32_t m_a; + uint32_t m_b; + }; + + /// + class HashCrc32 + { + public: + enum Enum + { + Ieee, //!< 0xedb88320 + Castagnoli, //!< 0x82f63b78 + Koopman, //!< 0xeb31d82e + + Count + }; + /// - static void readUnaligned(const void* _data, uint32_t& _out); + void begin(Enum _type = Ieee); /// - void mixTail(const uint8_t*& _data, int& _len); + void add(const void* _data, int _len); + + /// + template<typename Ty> + void add(Ty _value); + + /// + uint32_t end(); + private: + const uint32_t* m_table; uint32_t m_hash; - uint32_t m_tail; - uint32_t m_count; - uint32_t m_size; }; /// - uint32_t hashMurmur2A(const void* _data, uint32_t _size); + template<typename HashT> + uint32_t hash(const void* _data, uint32_t _size); /// - template <typename Ty> - uint32_t hashMurmur2A(const Ty& _data); + template<typename HashT, typename Ty> + uint32_t hash(const Ty& _data); /// - uint32_t hashMurmur2A(const StringView& _data); + template<typename HashT> + uint32_t hash(const StringView& _data); /// - uint32_t hashMurmur2A(const char* _data); + template<typename HashT> + uint32_t hash(const char* _data); } // namespace bx diff --git a/3rdparty/bx/include/bx/inline/allocator.inl b/3rdparty/bx/include/bx/inline/allocator.inl index 8a4898d8f60..7362d3fa06f 100644 --- a/3rdparty/bx/include/bx/inline/allocator.inl +++ b/3rdparty/bx/include/bx/inline/allocator.inl @@ -7,6 +7,15 @@ # error "Must be included from bx/allocator.h" #endif // BX_ALLOCATOR_H_HEADER_GUARD +inline void* operator new(size_t, bx::PlacementNewTag, void* _ptr) +{ + return _ptr; +} + +inline void operator delete(void*, bx::PlacementNewTag, void*) throw() +{ +} + namespace bx { inline AllocatorI::~AllocatorI() diff --git a/3rdparty/bx/include/bx/inline/bx.inl b/3rdparty/bx/include/bx/inline/bx.inl index f8e9c6303d4..70a6e6dec5e 100644 --- a/3rdparty/bx/include/bx/inline/bx.inl +++ b/3rdparty/bx/include/bx/inline/bx.inl @@ -32,4 +32,40 @@ namespace bx Ty tmp = _a; _a = _b; _b = tmp; } + template<typename Ty> + inline Ty min(const Ty& _a, const Ty& _b) + { + return _a < _b ? _a : _b; + } + + template<typename Ty> + inline Ty max(const Ty& _a, const Ty& _b) + { + return _a > _b ? _a : _b; + } + + template<typename Ty> + inline Ty min(const Ty& _a, const Ty& _b, const Ty& _c) + { + return min(min(_a, _b), _c); + } + + template<typename Ty> + inline Ty max(const Ty& _a, const Ty& _b, const Ty& _c) + { + return max(max(_a, _b), _c); + } + + template<typename Ty> + inline Ty mid(const Ty& _a, const Ty& _b, const Ty& _c) + { + return max(min(_a, _b), min(max(_a, _b), _c) ); + } + + template<typename Ty> + inline Ty clamp(const Ty& _a, const Ty& _min, const Ty& _max) + { + return max(min(_a, _max), _min); + } + } // namespace bx diff --git a/3rdparty/bx/include/bx/inline/cpu.inl b/3rdparty/bx/include/bx/inline/cpu.inl new file mode 100644 index 00000000000..f4d8aa70047 --- /dev/null +++ b/3rdparty/bx/include/bx/inline/cpu.inl @@ -0,0 +1,332 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_CPU_H_HEADER_GUARD +# error "Must be included from bx/cpu.h!" +#endif // BX_CPU_H_HEADER_GUARD + +#if BX_COMPILER_MSVC +# include <emmintrin.h> // _mm_fence + +extern "C" void _ReadBarrier(); +# pragma intrinsic(_ReadBarrier) + +extern "C" void _WriteBarrier(); +# pragma intrinsic(_WriteBarrier) + +extern "C" void _ReadWriteBarrier(); +# pragma intrinsic(_ReadWriteBarrier) + +extern "C" long _InterlockedExchangeAdd(long volatile* _ptr, long _value); +# pragma intrinsic(_InterlockedExchangeAdd) + +extern "C" int64_t __cdecl _InterlockedExchangeAdd64(int64_t volatile* _ptr, int64_t _value); +//# pragma intrinsic(_InterlockedExchangeAdd64) + +extern "C" long _InterlockedCompareExchange(long volatile* _ptr, long _exchange, long _comparand); +# pragma intrinsic(_InterlockedCompareExchange) + +extern "C" int64_t _InterlockedCompareExchange64(int64_t volatile* _ptr, int64_t _exchange, int64_t _comparand); +# pragma intrinsic(_InterlockedCompareExchange64) + +extern "C" void* _InterlockedExchangePointer(void* volatile* _ptr, void* _value); +# pragma intrinsic(_InterlockedExchangePointer) + +# if BX_PLATFORM_WINRT +# define _InterlockedExchangeAdd64 InterlockedExchangeAdd64 +# endif // BX_PLATFORM_WINRT +#endif // BX_COMPILER_MSVC + +namespace bx +{ + inline void readBarrier() + { +#if BX_COMPILER_MSVC + _ReadBarrier(); +#else + asm volatile("":::"memory"); +#endif // BX_COMPILER + } + + inline void writeBarrier() + { +#if BX_COMPILER_MSVC + _WriteBarrier(); +#else + asm volatile("":::"memory"); +#endif // BX_COMPILER + } + + inline void readWriteBarrier() + { +#if BX_COMPILER_MSVC + _ReadWriteBarrier(); +#else + asm volatile("":::"memory"); +#endif // BX_COMPILER + } + + inline void memoryBarrier() + { +#if BX_PLATFORM_WINRT + MemoryBarrier(); +#elif BX_COMPILER_MSVC + _mm_mfence(); +#else + __sync_synchronize(); +#endif // BX_COMPILER + } + + template<> + inline int32_t atomicCompareAndSwap<int32_t>(volatile int32_t* _ptr, int32_t _old, int32_t _new) + { +#if BX_COMPILER_MSVC + return int32_t(_InterlockedCompareExchange( (volatile long*)(_ptr), long(_new), long(_old) ) ); +#else + return __sync_val_compare_and_swap( (volatile int32_t*)_ptr, _old, _new); +#endif // BX_COMPILER + } + + template<> + inline uint32_t atomicCompareAndSwap<uint32_t>(volatile uint32_t* _ptr, uint32_t _old, uint32_t _new) + { +#if BX_COMPILER_MSVC + return uint32_t(_InterlockedCompareExchange( (volatile long*)(_ptr), long(_new), long(_old) ) ); +#else + return __sync_val_compare_and_swap( (volatile int32_t*)_ptr, _old, _new); +#endif // BX_COMPILER + } + + template<> + inline int64_t atomicCompareAndSwap<int64_t>(volatile int64_t* _ptr, int64_t _old, int64_t _new) + { +#if BX_COMPILER_MSVC + return _InterlockedCompareExchange64(_ptr, _new, _old); +#else + return __sync_val_compare_and_swap( (volatile int64_t*)_ptr, _old, _new); +#endif // BX_COMPILER + } + + template<> + inline uint64_t atomicCompareAndSwap<uint64_t>(volatile uint64_t* _ptr, uint64_t _old, uint64_t _new) + { +#if BX_COMPILER_MSVC + return uint64_t(_InterlockedCompareExchange64( (volatile int64_t*)(_ptr), int64_t(_new), int64_t(_old) ) ); +#else + return __sync_val_compare_and_swap( (volatile int64_t*)_ptr, _old, _new); +#endif // BX_COMPILER + } + + template<> + inline int32_t atomicFetchAndAdd<int32_t>(volatile int32_t* _ptr, int32_t _add) + { +#if BX_COMPILER_MSVC + return _InterlockedExchangeAdd( (volatile long*)_ptr, _add); +#else + return __sync_fetch_and_add(_ptr, _add); +#endif // BX_COMPILER_ + } + + template<> + inline uint32_t atomicFetchAndAdd<uint32_t>(volatile uint32_t* _ptr, uint32_t _add) + { + return uint32_t(atomicFetchAndAdd<int32_t>( (volatile int32_t*)_ptr, int32_t(_add) ) ); + } + + template<> + inline int64_t atomicFetchAndAdd<int64_t>(volatile int64_t* _ptr, int64_t _add) + { +#if BX_COMPILER_MSVC +# if _WIN32_WINNT >= 0x600 + return _InterlockedExchangeAdd64( (volatile int64_t*)_ptr, _add); +# else + int64_t oldVal; + int64_t newVal = *(int64_t volatile*)_ptr; + do + { + oldVal = newVal; + newVal = atomicCompareAndSwap<int64_t>(_ptr, oldVal, newVal + _add); + + } while (oldVal != newVal); + + return oldVal; +# endif +#else + return __sync_fetch_and_add(_ptr, _add); +#endif // BX_COMPILER_ + } + + template<> + inline uint64_t atomicFetchAndAdd<uint64_t>(volatile uint64_t* _ptr, uint64_t _add) + { + return uint64_t(atomicFetchAndAdd<int64_t>( (volatile int64_t*)_ptr, int64_t(_add) ) ); + } + + template<> + inline int32_t atomicAddAndFetch<int32_t>(volatile int32_t* _ptr, int32_t _add) + { +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, _add) + _add; +#else + return __sync_add_and_fetch(_ptr, _add); +#endif // BX_COMPILER_ + } + + template<> + inline int64_t atomicAddAndFetch<int64_t>(volatile int64_t* _ptr, int64_t _add) + { +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, _add) + _add; +#else + return __sync_add_and_fetch(_ptr, _add); +#endif // BX_COMPILER_ + } + + template<> + inline uint32_t atomicAddAndFetch<uint32_t>(volatile uint32_t* _ptr, uint32_t _add) + { + return uint32_t(atomicAddAndFetch<int32_t>( (volatile int32_t*)_ptr, int32_t(_add) ) ); + } + + template<> + inline uint64_t atomicAddAndFetch<uint64_t>(volatile uint64_t* _ptr, uint64_t _add) + { + return uint64_t(atomicAddAndFetch<int64_t>( (volatile int64_t*)_ptr, int64_t(_add) ) ); + } + + template<> + inline int32_t atomicFetchAndSub<int32_t>(volatile int32_t* _ptr, int32_t _sub) + { +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, -_sub); +#else + return __sync_fetch_and_sub(_ptr, _sub); +#endif // BX_COMPILER_ + } + + template<> + inline int64_t atomicFetchAndSub<int64_t>(volatile int64_t* _ptr, int64_t _sub) + { +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, -_sub); +#else + return __sync_fetch_and_sub(_ptr, _sub); +#endif // BX_COMPILER_ + } + + template<> + inline uint32_t atomicFetchAndSub<uint32_t>(volatile uint32_t* _ptr, uint32_t _add) + { + return uint32_t(atomicFetchAndSub<int32_t>( (volatile int32_t*)_ptr, int32_t(_add) ) ); + } + + template<> + inline uint64_t atomicFetchAndSub<uint64_t>(volatile uint64_t* _ptr, uint64_t _add) + { + return uint64_t(atomicFetchAndSub<int64_t>( (volatile int64_t*)_ptr, int64_t(_add) ) ); + } + + template<> + inline int32_t atomicSubAndFetch<int32_t>(volatile int32_t* _ptr, int32_t _sub) + { +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, -_sub) - _sub; +#else + return __sync_sub_and_fetch(_ptr, _sub); +#endif // BX_COMPILER_ + } + + template<> + inline int64_t atomicSubAndFetch<int64_t>(volatile int64_t* _ptr, int64_t _sub) + { +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, -_sub) - _sub; +#else + return __sync_sub_and_fetch(_ptr, _sub); +#endif // BX_COMPILER_ + } + + template<> + inline uint32_t atomicSubAndFetch<uint32_t>(volatile uint32_t* _ptr, uint32_t _add) + { + return uint32_t(atomicSubAndFetch<int32_t>( (volatile int32_t*)_ptr, int32_t(_add) ) ); + } + + template<> + inline uint64_t atomicSubAndFetch<uint64_t>(volatile uint64_t* _ptr, uint64_t _add) + { + return uint64_t(atomicSubAndFetch<int64_t>( (volatile int64_t*)_ptr, int64_t(_add) ) ); + } + + template<typename Ty> + inline Ty atomicFetchTestAndAdd(volatile Ty* _ptr, Ty _test, Ty _value) + { + Ty oldVal; + Ty newVal = *_ptr; + do + { + oldVal = newVal; + newVal = atomicCompareAndSwap<Ty>(_ptr, oldVal, newVal >= _test ? _test : newVal+_value); + + } while (oldVal != newVal); + + return oldVal; + } + + template<typename Ty> + inline Ty atomicFetchTestAndSub(volatile Ty* _ptr, Ty _test, Ty _value) + { + Ty oldVal; + Ty newVal = *_ptr; + do + { + oldVal = newVal; + newVal = atomicCompareAndSwap<Ty>(_ptr, oldVal, newVal <= _test ? _test : newVal-_value); + + } while (oldVal != newVal); + + return oldVal; + } + + template<typename Ty> + Ty atomicFetchAndAddsat(volatile Ty* _ptr, Ty _value, Ty _max) + { + Ty oldVal; + Ty newVal = *_ptr; + do + { + oldVal = newVal; + newVal = atomicCompareAndSwap<Ty>(_ptr, oldVal, newVal >= _max ? _max : min(_max, newVal+_value) ); + + } while (oldVal != newVal && oldVal != _max); + + return oldVal; + } + + template<typename Ty> + Ty atomicFetchAndSubsat(volatile Ty* _ptr, Ty _value, Ty _min) + { + Ty oldVal; + Ty newVal = *_ptr; + do + { + oldVal = newVal; + newVal = atomicCompareAndSwap<Ty>(_ptr, oldVal, newVal <= _min ? _min : max(_min, newVal-_value) ); + + } while (oldVal != newVal && oldVal != _min); + + return oldVal; + } + + inline void* atomicExchangePtr(void** _ptr, void* _new) + { +#if BX_COMPILER_MSVC + return _InterlockedExchangePointer(_ptr, _new); +#else + return __sync_lock_test_and_set(_ptr, _new); +#endif // BX_COMPILER + } + +} // namespace bx diff --git a/3rdparty/bx/include/bx/inline/easing.inl b/3rdparty/bx/include/bx/inline/easing.inl index b23edb1128a..d1e64ed20c6 100644 --- a/3rdparty/bx/include/bx/inline/easing.inl +++ b/3rdparty/bx/include/bx/inline/easing.inl @@ -29,6 +29,16 @@ namespace bx return _t; } + inline float easeStep(float _t) + { + return _t < 0.5f ? 0.0f : 1.0f; + } + + inline float easeSmoothStep(float _t) + { + return fsq(_t)*(3.0f - 2.0f*_t); + } + inline float easeInQuad(float _t) { return fsq(_t); @@ -111,7 +121,7 @@ namespace bx inline float easeInSine(float _t) { - return 1.0f - fcos(_t*piHalf); + return 1.0f - fcos(_t*kPiHalf); } inline float easeOutSine(float _t) @@ -171,7 +181,7 @@ namespace bx inline float easeOutElastic(float _t) { - return fpow(2.0f, -10.0f*_t)*fsin( (_t-0.3f/4.0f)*(2.0f*pi)/0.3f) + 1.0f; + return fpow(2.0f, -10.0f*_t)*fsin( (_t-0.3f/4.0f)*(2.0f*kPi)/0.3f) + 1.0f; } inline float easeInElastic(float _t) @@ -191,7 +201,7 @@ namespace bx inline float easeInBack(float _t) { - return easeInCubic(_t) - _t*fsin(_t*pi); + return easeInCubic(_t) - _t*fsin(_t*kPi); } inline float easeOutBack(float _t) diff --git a/3rdparty/bx/include/bx/inline/float4x4_t.inl b/3rdparty/bx/include/bx/inline/float4x4_t.inl new file mode 100644 index 00000000000..ea6873b5065 --- /dev/null +++ b/3rdparty/bx/include/bx/inline/float4x4_t.inl @@ -0,0 +1,150 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_FLOAT4X4_H_HEADER_GUARD +# error "Must be included from bx/float4x4.h!" +#endif // BX_FLOAT4X4_H_HEADER_GUARD + +namespace bx +{ + BX_SIMD_FORCE_INLINE simd128_t simd_mul_xyz1(simd128_t _a, const float4x4_t* _b) + { + const simd128_t xxxx = simd_swiz_xxxx(_a); + const simd128_t yyyy = simd_swiz_yyyy(_a); + const simd128_t zzzz = simd_swiz_zzzz(_a); + const simd128_t col0 = simd_mul(_b->col[0], xxxx); + const simd128_t col1 = simd_mul(_b->col[1], yyyy); + const simd128_t col2 = simd_madd(_b->col[2], zzzz, col0); + const simd128_t col3 = simd_add(_b->col[3], col1); + const simd128_t result = simd_add(col2, col3); + + return result; + } + + BX_SIMD_FORCE_INLINE simd128_t simd_mul(simd128_t _a, const float4x4_t* _b) + { + const simd128_t xxxx = simd_swiz_xxxx(_a); + const simd128_t yyyy = simd_swiz_yyyy(_a); + const simd128_t zzzz = simd_swiz_zzzz(_a); + const simd128_t wwww = simd_swiz_wwww(_a); + const simd128_t col0 = simd_mul(_b->col[0], xxxx); + const simd128_t col1 = simd_mul(_b->col[1], yyyy); + const simd128_t col2 = simd_madd(_b->col[2], zzzz, col0); + const simd128_t col3 = simd_madd(_b->col[3], wwww, col1); + const simd128_t result = simd_add(col2, col3); + + return result; + } + + BX_SIMD_INLINE void float4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b) + { + _result->col[0] = simd_mul(_a->col[0], _b); + _result->col[1] = simd_mul(_a->col[1], _b); + _result->col[2] = simd_mul(_a->col[2], _b); + _result->col[3] = simd_mul(_a->col[3], _b); + } + + BX_SIMD_FORCE_INLINE void float4x4_transpose(float4x4_t* _result, const float4x4_t* _mtx) + { + const simd128_t aibj = simd_shuf_xAyB(_mtx->col[0], _mtx->col[2]); // aibj + const simd128_t emfn = simd_shuf_xAyB(_mtx->col[1], _mtx->col[3]); // emfn + const simd128_t ckdl = simd_shuf_zCwD(_mtx->col[0], _mtx->col[2]); // ckdl + const simd128_t gohp = simd_shuf_zCwD(_mtx->col[1], _mtx->col[3]); // gohp + _result->col[0] = simd_shuf_xAyB(aibj, emfn); // aeim + _result->col[1] = simd_shuf_zCwD(aibj, emfn); // bfjn + _result->col[2] = simd_shuf_xAyB(ckdl, gohp); // cgko + _result->col[3] = simd_shuf_zCwD(ckdl, gohp); // dhlp + } + + BX_SIMD_INLINE void float4x4_inverse(float4x4_t* _result, const float4x4_t* _a) + { + const simd128_t tmp0 = simd_shuf_xAzC(_a->col[0], _a->col[1]); + const simd128_t tmp1 = simd_shuf_xAzC(_a->col[2], _a->col[3]); + const simd128_t tmp2 = simd_shuf_yBwD(_a->col[0], _a->col[1]); + const simd128_t tmp3 = simd_shuf_yBwD(_a->col[2], _a->col[3]); + const simd128_t t0 = simd_shuf_xyAB(tmp0, tmp1); + const simd128_t t1 = simd_shuf_xyAB(tmp3, tmp2); + const simd128_t t2 = simd_shuf_zwCD(tmp0, tmp1); + const simd128_t t3 = simd_shuf_zwCD(tmp3, tmp2); + + const simd128_t t23 = simd_mul(t2, t3); + const simd128_t t23_yxwz = simd_swiz_yxwz(t23); + const simd128_t t23_wzyx = simd_swiz_wzyx(t23); + + simd128_t cof0, cof1, cof2, cof3; + + const simd128_t zero = simd_zero(); + cof0 = simd_nmsub(t1, t23_yxwz, zero); + cof0 = simd_madd(t1, t23_wzyx, cof0); + + cof1 = simd_nmsub(t0, t23_yxwz, zero); + cof1 = simd_madd(t0, t23_wzyx, cof1); + cof1 = simd_swiz_zwxy(cof1); + + const simd128_t t12 = simd_mul(t1, t2); + const simd128_t t12_yxwz = simd_swiz_yxwz(t12); + const simd128_t t12_wzyx = simd_swiz_wzyx(t12); + + cof0 = simd_madd(t3, t12_yxwz, cof0); + cof0 = simd_nmsub(t3, t12_wzyx, cof0); + + cof3 = simd_mul(t0, t12_yxwz); + cof3 = simd_nmsub(t0, t12_wzyx, cof3); + cof3 = simd_swiz_zwxy(cof3); + + const simd128_t t1_zwxy = simd_swiz_zwxy(t1); + const simd128_t t2_zwxy = simd_swiz_zwxy(t2); + + const simd128_t t13 = simd_mul(t1_zwxy, t3); + const simd128_t t13_yxwz = simd_swiz_yxwz(t13); + const simd128_t t13_wzyx = simd_swiz_wzyx(t13); + + cof0 = simd_madd(t2_zwxy, t13_yxwz, cof0); + cof0 = simd_nmsub(t2_zwxy, t13_wzyx, cof0); + + cof2 = simd_mul(t0, t13_yxwz); + cof2 = simd_nmsub(t0, t13_wzyx, cof2); + cof2 = simd_swiz_zwxy(cof2); + + const simd128_t t01 = simd_mul(t0, t1); + const simd128_t t01_yxwz = simd_swiz_yxwz(t01); + const simd128_t t01_wzyx = simd_swiz_wzyx(t01); + + cof2 = simd_nmsub(t3, t01_yxwz, cof2); + cof2 = simd_madd(t3, t01_wzyx, cof2); + + cof3 = simd_madd(t2_zwxy, t01_yxwz, cof3); + cof3 = simd_nmsub(t2_zwxy, t01_wzyx, cof3); + + const simd128_t t03 = simd_mul(t0, t3); + const simd128_t t03_yxwz = simd_swiz_yxwz(t03); + const simd128_t t03_wzyx = simd_swiz_wzyx(t03); + + cof1 = simd_nmsub(t2_zwxy, t03_yxwz, cof1); + cof1 = simd_madd(t2_zwxy, t03_wzyx, cof1); + + cof2 = simd_madd(t1, t03_yxwz, cof2); + cof2 = simd_nmsub(t1, t03_wzyx, cof2); + + const simd128_t t02 = simd_mul(t0, t2_zwxy); + const simd128_t t02_yxwz = simd_swiz_yxwz(t02); + const simd128_t t02_wzyx = simd_swiz_wzyx(t02); + + cof1 = simd_madd(t3, t02_yxwz, cof1); + cof1 = simd_nmsub(t3, t02_wzyx, cof1); + + cof3 = simd_nmsub(t1, t02_yxwz, cof3); + cof3 = simd_madd(t1, t02_wzyx, cof3); + + const simd128_t det = simd_dot(t0, cof0); + const simd128_t invdet = simd_rcp(det); + + _result->col[0] = simd_mul(cof0, invdet); + _result->col[1] = simd_mul(cof1, invdet); + _result->col[2] = simd_mul(cof2, invdet); + _result->col[3] = simd_mul(cof3, invdet); + } + +} // namespace bx diff --git a/3rdparty/bx/include/bx/inline/fpumath.inl b/3rdparty/bx/include/bx/inline/fpumath.inl deleted file mode 100644 index e87b8272b2c..00000000000 --- a/3rdparty/bx/include/bx/inline/fpumath.inl +++ /dev/null @@ -1,1352 +0,0 @@ -/* - * Copyright 2011-2017 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -// FPU math lib - -#ifndef BX_FPU_MATH_H_HEADER_GUARD -# error "Must be included from bx/fpumath.h!" -#endif // BX_FPU_MATH_H_HEADER_GUARD - -namespace bx -{ - inline float toRad(float _deg) - { - return _deg * pi / 180.0f; - } - - inline float toDeg(float _rad) - { - return _rad * 180.0f / pi; - } - - inline uint32_t floatToBits(float _a) - { - union { float f; uint32_t ui; } u = { _a }; - return u.ui; - } - - inline float bitsToFloat(uint32_t _a) - { - union { uint32_t ui; float f; } u = { _a }; - return u.f; - } - - inline uint64_t doubleToBits(double _a) - { - union { double f; uint64_t ui; } u = { _a }; - return u.ui; - } - - inline double bitsToDouble(uint64_t _a) - { - union { uint64_t ui; double f; } u = { _a }; - return u.f; - } - - inline bool isNan(float _f) - { - const uint32_t tmp = floatToBits(_f) & INT32_MAX; - return tmp > UINT32_C(0x7f800000); - } - - inline bool isNan(double _f) - { - const uint64_t tmp = doubleToBits(_f) & INT64_MAX; - return tmp > UINT64_C(0x7ff0000000000000); - } - - inline bool isFinite(float _f) - { - const uint32_t tmp = floatToBits(_f) & INT32_MAX; - return tmp < UINT32_C(0x7f800000); - } - - inline bool isFinite(double _f) - { - const uint64_t tmp = doubleToBits(_f) & INT64_MAX; - return tmp < UINT64_C(0x7ff0000000000000); - } - - inline bool isInfinite(float _f) - { - const uint32_t tmp = floatToBits(_f) & INT32_MAX; - return tmp == UINT32_C(0x7f800000); - } - - inline bool isInfinite(double _f) - { - const uint64_t tmp = doubleToBits(_f) & INT64_MAX; - return tmp == UINT64_C(0x7ff0000000000000); - } - - inline float fround(float _f) - { - return ffloor(_f + 0.5f); - } - - inline float fmin(float _a, float _b) - { - return _a < _b ? _a : _b; - } - - inline float fmax(float _a, float _b) - { - return _a > _b ? _a : _b; - } - - inline float fmin3(float _a, float _b, float _c) - { - return fmin(_a, fmin(_b, _c) ); - } - - inline float fmax3(float _a, float _b, float _c) - { - return fmax(_a, fmax(_b, _c) ); - } - - inline float fclamp(float _a, float _min, float _max) - { - return fmin(fmax(_a, _min), _max); - } - - inline float fsaturate(float _a) - { - return fclamp(_a, 0.0f, 1.0f); - } - - inline float flerp(float _a, float _b, float _t) - { - return _a + (_b - _a) * _t; - } - - inline float fsign(float _a) - { - return _a < 0.0f ? -1.0f : 1.0f; - } - - inline float fsq(float _a) - { - return _a * _a; - } - - inline float fexp2(float _a) - { - return fpow(2.0f, _a); - } - - inline float flog2(float _a) - { - return flog(_a) * 1.442695041f; - } - - inline float frsqrt(float _a) - { - return 1.0f/fsqrt(_a); - } - - inline float ffract(float _a) - { - return _a - ffloor(_a); - } - - inline bool fequal(float _a, float _b, float _epsilon) - { - // http://realtimecollisiondetection.net/blog/?p=89 - const float lhs = fabsolute(_a - _b); - const float rhs = _epsilon * fmax3(1.0f, fabsolute(_a), fabsolute(_b) ); - return lhs <= rhs; - } - - inline bool fequal(const float* _a, const float* _b, uint32_t _num, float _epsilon) - { - bool equal = fequal(_a[0], _b[0], _epsilon); - for (uint32_t ii = 1; equal && ii < _num; ++ii) - { - equal = fequal(_a[ii], _b[ii], _epsilon); - } - return equal; - } - - inline float fwrap(float _a, float _wrap) - { - const float mod = fmod(_a, _wrap); - const float result = mod < 0.0f ? _wrap + mod : mod; - return result; - } - - inline float fstep(float _edge, float _a) - { - return _a < _edge ? 0.0f : 1.0f; - } - - inline float fpulse(float _a, float _start, float _end) - { - return fstep(_a, _start) - fstep(_a, _end); - } - - inline float fsmoothstep(float _a) - { - return fsq(_a)*(3.0f - 2.0f*_a); - } - - inline float fbias(float _time, float _bias) - { - return _time / ( ( (1.0f/_bias - 2.0f)*(1.0f - _time) ) + 1.0f); - } - - inline float fgain(float _time, float _gain) - { - if (_time < 0.5f) - { - return fbias(_time * 2.0f, _gain) * 0.5f; - } - - return fbias(_time * 2.0f - 1.0f, 1.0f - _gain) * 0.5f + 0.5f; - } - - inline void vec3Move(float* _result, const float* _a) - { - _result[0] = _a[0]; - _result[1] = _a[1]; - _result[2] = _a[2]; - } - - inline void vec3Abs(float* _result, const float* _a) - { - _result[0] = fabsolute(_a[0]); - _result[1] = fabsolute(_a[1]); - _result[2] = fabsolute(_a[2]); - } - - inline void vec3Neg(float* _result, const float* _a) - { - _result[0] = -_a[0]; - _result[1] = -_a[1]; - _result[2] = -_a[2]; - } - - inline void vec3Add(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[0] + _b[0]; - _result[1] = _a[1] + _b[1]; - _result[2] = _a[2] + _b[2]; - } - - inline void vec3Add(float* _result, const float* _a, float _b) - { - _result[0] = _a[0] + _b; - _result[1] = _a[1] + _b; - _result[2] = _a[2] + _b; - } - - inline void vec3Sub(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[0] - _b[0]; - _result[1] = _a[1] - _b[1]; - _result[2] = _a[2] - _b[2]; - } - - inline void vec3Sub(float* _result, const float* _a, float _b) - { - _result[0] = _a[0] - _b; - _result[1] = _a[1] - _b; - _result[2] = _a[2] - _b; - } - - inline void vec3Mul(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[0] * _b[0]; - _result[1] = _a[1] * _b[1]; - _result[2] = _a[2] * _b[2]; - } - - inline void vec3Mul(float* _result, const float* _a, float _b) - { - _result[0] = _a[0] * _b; - _result[1] = _a[1] * _b; - _result[2] = _a[2] * _b; - } - - inline float vec3Dot(const float* _a, const float* _b) - { - return _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2]; - } - - inline void vec3Cross(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[1]*_b[2] - _a[2]*_b[1]; - _result[1] = _a[2]*_b[0] - _a[0]*_b[2]; - _result[2] = _a[0]*_b[1] - _a[1]*_b[0]; - } - - inline float vec3Length(const float* _a) - { - return fsqrt(vec3Dot(_a, _a) ); - } - - inline void vec3Lerp(float* _result, const float* _a, const float* _b, float _t) - { - _result[0] = flerp(_a[0], _b[0], _t); - _result[1] = flerp(_a[1], _b[1], _t); - _result[2] = flerp(_a[2], _b[2], _t); - } - - inline void vec3Lerp(float* _result, const float* _a, const float* _b, const float* _c) - { - _result[0] = flerp(_a[0], _b[0], _c[0]); - _result[1] = flerp(_a[1], _b[1], _c[1]); - _result[2] = flerp(_a[2], _b[2], _c[2]); - } - - inline float vec3Norm(float* _result, const float* _a) - { - const float len = vec3Length(_a); - const float invLen = 1.0f/len; - _result[0] = _a[0] * invLen; - _result[1] = _a[1] * invLen; - _result[2] = _a[2] * invLen; - return len; - } - - inline void vec3Min(float* _result, const float* _a, const float* _b) - { - _result[0] = fmin(_a[0], _b[0]); - _result[1] = fmin(_a[1], _b[1]); - _result[2] = fmin(_a[2], _b[2]); - } - - inline void vec3Max(float* _result, const float* _a, const float* _b) - { - _result[0] = fmax(_a[0], _b[0]); - _result[1] = fmax(_a[1], _b[1]); - _result[2] = fmax(_a[2], _b[2]); - } - - inline void vec3Rcp(float* _result, const float* _a) - { - _result[0] = 1.0f / _a[0]; - _result[1] = 1.0f / _a[1]; - _result[2] = 1.0f / _a[2]; - } - - inline void vec3TangentFrame(const float* _n, float* _t, float* _b) - { - const float nx = _n[0]; - const float ny = _n[1]; - const float nz = _n[2]; - - if (bx::fabsolute(nx) > bx::fabsolute(nz) ) - { - float invLen = 1.0f / bx::fsqrt(nx*nx + nz*nz); - _t[0] = -nz * invLen; - _t[1] = 0.0f; - _t[2] = nx * invLen; - } - else - { - float invLen = 1.0f / bx::fsqrt(ny*ny + nz*nz); - _t[0] = 0.0f; - _t[1] = nz * invLen; - _t[2] = -ny * invLen; - } - - bx::vec3Cross(_b, _n, _t); - } - - inline void vec3TangentFrame(const float* _n, float* _t, float* _b, float _angle) - { - vec3TangentFrame(_n, _t, _b); - - const float sa = fsin(_angle); - const float ca = fcos(_angle); - - _t[0] = -sa * _b[0] + ca * _t[0]; - _t[1] = -sa * _b[1] + ca * _t[1]; - _t[2] = -sa * _b[2] + ca * _t[2]; - - bx::vec3Cross(_b, _n, _t); - } - - inline void quatIdentity(float* _result) - { - _result[0] = 0.0f; - _result[1] = 0.0f; - _result[2] = 0.0f; - _result[3] = 1.0f; - } - - inline void quatMove(float* _result, const float* _a) - { - _result[0] = _a[0]; - _result[1] = _a[1]; - _result[2] = _a[2]; - _result[3] = _a[3]; - } - - inline void quatMulXYZ(float* _result, const float* _qa, const float* _qb) - { - const float ax = _qa[0]; - const float ay = _qa[1]; - const float az = _qa[2]; - const float aw = _qa[3]; - - const float bx = _qb[0]; - const float by = _qb[1]; - const float bz = _qb[2]; - const float bw = _qb[3]; - - _result[0] = aw * bx + ax * bw + ay * bz - az * by; - _result[1] = aw * by - ax * bz + ay * bw + az * bx; - _result[2] = aw * bz + ax * by - ay * bx + az * bw; - } - - inline void quatMul(float* _result, const float* _qa, const float* _qb) - { - const float ax = _qa[0]; - const float ay = _qa[1]; - const float az = _qa[2]; - const float aw = _qa[3]; - - const float bx = _qb[0]; - const float by = _qb[1]; - const float bz = _qb[2]; - const float bw = _qb[3]; - - _result[0] = aw * bx + ax * bw + ay * bz - az * by; - _result[1] = aw * by - ax * bz + ay * bw + az * bx; - _result[2] = aw * bz + ax * by - ay * bx + az * bw; - _result[3] = aw * bw - ax * bx - ay * by - az * bz; - } - - inline void quatInvert(float* _result, const float* _quat) - { - _result[0] = -_quat[0]; - _result[1] = -_quat[1]; - _result[2] = -_quat[2]; - _result[3] = _quat[3]; - } - - inline float quatDot(const float* _a, const float* _b) - { - return _a[0]*_b[0] - + _a[1]*_b[1] - + _a[2]*_b[2] - + _a[3]*_b[3] - ; - } - - inline void quatNorm(float* _result, const float* _quat) - { - const float norm = quatDot(_quat, _quat); - if (0.0f < norm) - { - const float invNorm = 1.0f / fsqrt(norm); - _result[0] = _quat[0] * invNorm; - _result[1] = _quat[1] * invNorm; - _result[2] = _quat[2] * invNorm; - _result[3] = _quat[3] * invNorm; - } - else - { - quatIdentity(_result); - } - } - - inline void quatToEuler(float* _result, const float* _quat) - { - const float x = _quat[0]; - const float y = _quat[1]; - const float z = _quat[2]; - const float w = _quat[3]; - - const float yy = y * y; - const float zz = z * z; - - const float xx = x * x; - _result[0] = fatan2(2.0f * (x * w - y * z), 1.0f - 2.0f * (xx + zz) ); - _result[1] = fatan2(2.0f * (y * w + x * z), 1.0f - 2.0f * (yy + zz) ); - _result[2] = fasin (2.0f * (x * y + z * w) ); - } - - inline void quatRotateAxis(float* _result, const float* _axis, float _angle) - { - const float ha = _angle * 0.5f; - const float ca = fcos(ha); - const float sa = fsin(ha); - _result[0] = _axis[0] * sa; - _result[1] = _axis[1] * sa; - _result[2] = _axis[2] * sa; - _result[3] = ca; - } - - inline void quatRotateX(float* _result, float _ax) - { - const float hx = _ax * 0.5f; - const float cx = fcos(hx); - const float sx = fsin(hx); - _result[0] = sx; - _result[1] = 0.0f; - _result[2] = 0.0f; - _result[3] = cx; - } - - inline void quatRotateY(float* _result, float _ay) - { - const float hy = _ay * 0.5f; - const float cy = fcos(hy); - const float sy = fsin(hy); - _result[0] = 0.0f; - _result[1] = sy; - _result[2] = 0.0f; - _result[3] = cy; - } - - inline void quatRotateZ(float* _result, float _az) - { - const float hz = _az * 0.5f; - const float cz = fcos(hz); - const float sz = fsin(hz); - _result[0] = 0.0f; - _result[1] = 0.0f; - _result[2] = sz; - _result[3] = cz; - } - - inline void vec3MulQuat(float* _result, const float* _vec, const float* _quat) - { - float tmp0[4]; - quatInvert(tmp0, _quat); - - float qv[4]; - qv[0] = _vec[0]; - qv[1] = _vec[1]; - qv[2] = _vec[2]; - qv[3] = 0.0f; - - float tmp1[4]; - quatMul(tmp1, tmp0, qv); - - quatMulXYZ(_result, tmp1, _quat); - } - - inline void mtxIdentity(float* _result) - { - memSet(_result, 0, sizeof(float)*16); - _result[0] = _result[5] = _result[10] = _result[15] = 1.0f; - } - - inline void mtxTranslate(float* _result, float _tx, float _ty, float _tz) - { - mtxIdentity(_result); - _result[12] = _tx; - _result[13] = _ty; - _result[14] = _tz; - } - - inline void mtxScale(float* _result, float _sx, float _sy, float _sz) - { - memSet(_result, 0, sizeof(float) * 16); - _result[0] = _sx; - _result[5] = _sy; - _result[10] = _sz; - _result[15] = 1.0f; - } - - inline void mtxScale(float* _result, float _scale) - { - mtxScale(_result, _scale, _scale, _scale); - } - - inline void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos) - { - float tangent[3]; - float bitangent[3]; - vec3TangentFrame(_normal, tangent, bitangent); - - vec3Mul(&_result[ 0], bitangent, _scale); - vec3Mul(&_result[ 4], _normal, _scale); - vec3Mul(&_result[ 8], tangent, _scale); - - _result[ 3] = 0.0f; - _result[ 7] = 0.0f; - _result[11] = 0.0f; - _result[12] = _pos[0]; - _result[13] = _pos[1]; - _result[14] = _pos[2]; - _result[15] = 1.0f; - } - - inline void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos, float _angle) - { - float tangent[3]; - float bitangent[3]; - vec3TangentFrame(_normal, tangent, bitangent, _angle); - - vec3Mul(&_result[ 0], bitangent, _scale); - vec3Mul(&_result[ 4], _normal, _scale); - vec3Mul(&_result[ 8], tangent, _scale); - - _result[ 3] = 0.0f; - _result[ 7] = 0.0f; - _result[11] = 0.0f; - _result[12] = _pos[0]; - _result[13] = _pos[1]; - _result[14] = _pos[2]; - _result[15] = 1.0f; - } - - inline void mtxQuat(float* _result, const float* _quat) - { - const float x = _quat[0]; - const float y = _quat[1]; - const float z = _quat[2]; - const float w = _quat[3]; - - const float x2 = x + x; - const float y2 = y + y; - const float z2 = z + z; - const float x2x = x2 * x; - const float x2y = x2 * y; - const float x2z = x2 * z; - const float x2w = x2 * w; - const float y2y = y2 * y; - const float y2z = y2 * z; - const float y2w = y2 * w; - const float z2z = z2 * z; - const float z2w = z2 * w; - - _result[ 0] = 1.0f - (y2y + z2z); - _result[ 1] = x2y - z2w; - _result[ 2] = x2z + y2w; - _result[ 3] = 0.0f; - - _result[ 4] = x2y + z2w; - _result[ 5] = 1.0f - (x2x + z2z); - _result[ 6] = y2z - x2w; - _result[ 7] = 0.0f; - - _result[ 8] = x2z - y2w; - _result[ 9] = y2z + x2w; - _result[10] = 1.0f - (x2x + y2y); - _result[11] = 0.0f; - - _result[12] = 0.0f; - _result[13] = 0.0f; - _result[14] = 0.0f; - _result[15] = 1.0f; - } - - inline void mtxQuatTranslation(float* _result, const float* _quat, const float* _translation) - { - mtxQuat(_result, _quat); - _result[12] = -(_result[0]*_translation[0] + _result[4]*_translation[1] + _result[ 8]*_translation[2]); - _result[13] = -(_result[1]*_translation[0] + _result[5]*_translation[1] + _result[ 9]*_translation[2]); - _result[14] = -(_result[2]*_translation[0] + _result[6]*_translation[1] + _result[10]*_translation[2]); - } - - inline void mtxQuatTranslationHMD(float* _result, const float* _quat, const float* _translation) - { - float quat[4]; - quat[0] = -_quat[0]; - quat[1] = -_quat[1]; - quat[2] = _quat[2]; - quat[3] = _quat[3]; - mtxQuatTranslation(_result, quat, _translation); - } - - inline void mtxLookAt_Impl(float* _result, const float* _eye, const float* _view, const float* _up) - { - float up[3] = { 0.0f, 1.0f, 0.0f }; - if (NULL != _up) - { - up[0] = _up[0]; - up[1] = _up[1]; - up[2] = _up[2]; - } - - float tmp[4]; - vec3Cross(tmp, up, _view); - - float right[4]; - vec3Norm(right, tmp); - - vec3Cross(up, _view, right); - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = right[0]; - _result[ 1] = up[0]; - _result[ 2] = _view[0]; - - _result[ 4] = right[1]; - _result[ 5] = up[1]; - _result[ 6] = _view[1]; - - _result[ 8] = right[2]; - _result[ 9] = up[2]; - _result[10] = _view[2]; - - _result[12] = -vec3Dot(right, _eye); - _result[13] = -vec3Dot(up, _eye); - _result[14] = -vec3Dot(_view, _eye); - _result[15] = 1.0f; - } - - inline void mtxLookAtLh(float* _result, const float* _eye, const float* _at, const float* _up) - { - float tmp[4]; - vec3Sub(tmp, _at, _eye); - - float view[4]; - vec3Norm(view, tmp); - - mtxLookAt_Impl(_result, _eye, view, _up); - } - - inline void mtxLookAtRh(float* _result, const float* _eye, const float* _at, const float* _up) - { - float tmp[4]; - vec3Sub(tmp, _eye, _at); - - float view[4]; - vec3Norm(view, tmp); - - mtxLookAt_Impl(_result, _eye, view, _up); - } - - inline void mtxLookAt(float* _result, const float* _eye, const float* _at, const float* _up) - { - mtxLookAtLh(_result, _eye, _at, _up); - } - - template <Handness::Enum HandnessT> - inline void mtxProjXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc) - { - const float diff = _far-_near; - const float aa = _oglNdc ? (_far+_near)/diff : _far/diff; - const float bb = _oglNdc ? (2.0f*_far*_near)/diff : _near*aa; - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = _width; - _result[ 5] = _height; - _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x; - _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y; - _result[10] = (Handness::Right == HandnessT) ? -aa : aa; - _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f; - _result[14] = -bb; - } - - template <Handness::Enum HandnessT> - inline void mtxProj_impl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) - { - const float invDiffRl = 1.0f/(_rt - _lt); - const float invDiffUd = 1.0f/(_ut - _dt); - const float width = 2.0f*_near * invDiffRl; - const float height = 2.0f*_near * invDiffUd; - const float xx = (_rt + _lt) * invDiffRl; - const float yy = (_ut + _dt) * invDiffUd; - mtxProjXYWH<HandnessT>(_result, xx, yy, width, height, _near, _far, _oglNdc); - } - - template <Handness::Enum HandnessT> - inline void mtxProj_impl(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) - { - mtxProj_impl<HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc); - } - - template <Handness::Enum HandnessT> - inline void mtxProj_impl(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) - { - const float height = 1.0f/ftan(toRad(_fovy)*0.5f); - const float width = height * 1.0f/_aspect; - mtxProjXYWH<HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc); - } - - inline void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); - } - - inline void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Left>(_result, _fov, _near, _far, _oglNdc); - } - - inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc); - } - - inline void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); - } - - inline void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Left>(_result, _fov, _near, _far, _oglNdc); - } - - inline void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc); - } - - inline void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); - } - - inline void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Right>(_result, _fov, _near, _far, _oglNdc); - } - - inline void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) - { - mtxProj_impl<Handness::Right>(_result, _fovy, _aspect, _near, _far, _oglNdc); - } - - template <NearFar::Enum NearFarT, Handness::Enum HandnessT> - inline void mtxProjInfXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, bool _oglNdc) - { - float aa; - float bb; - if (BX_ENABLED(NearFar::Reverse == NearFarT) ) - { - aa = _oglNdc ? -1.0f : 0.0f; - bb = _oglNdc ? -2.0f*_near : -_near; - } - else - { - aa = 1.0f; - bb = _oglNdc ? 2.0f*_near : _near; - } - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = _width; - _result[ 5] = _height; - _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x; - _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y; - _result[10] = (Handness::Right == HandnessT) ? -aa : aa; - _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f; - _result[14] = -bb; - } - - template <NearFar::Enum NearFarT, Handness::Enum HandnessT> - inline void mtxProjInf_impl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) - { - const float invDiffRl = 1.0f/(_rt - _lt); - const float invDiffUd = 1.0f/(_ut - _dt); - const float width = 2.0f*_near * invDiffRl; - const float height = 2.0f*_near * invDiffUd; - const float xx = (_rt + _lt) * invDiffRl; - const float yy = (_ut + _dt) * invDiffUd; - mtxProjInfXYWH<NearFarT,HandnessT>(_result, xx, yy, width, height, _near, _oglNdc); - } - - template <NearFar::Enum NearFarT, Handness::Enum HandnessT> - inline void mtxProjInf_impl(float* _result, const float _fov[4], float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFarT,HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _oglNdc); - } - - template <NearFar::Enum NearFarT, Handness::Enum HandnessT> - inline void mtxProjInf_impl(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) - { - const float height = 1.0f/ftan(toRad(_fovy)*0.5f); - const float width = height * 1.0f/_aspect; - mtxProjInfXYWH<NearFarT,HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _oglNdc); - } - - inline void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc); - } - - inline void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); - } - - inline void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); - } - - inline void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); - } - - inline void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc); - } - - inline void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); - } - - inline void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); - } - - inline void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _fov, _near, _oglNdc); - } - - inline void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc); - } - - inline void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); - } - - inline void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _fov, _near, _oglNdc); - } - - inline void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); - } - - inline void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); - } - - inline void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _fov, _near, _oglNdc); - } - - inline void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) - { - mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc); - } - - template <Handness::Enum HandnessT> - inline void mtxOrtho_impl(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) - { - const float aa = 2.0f/(_right - _left); - const float bb = 2.0f/(_top - _bottom); - const float cc = (_oglNdc ? 2.0f : 1.0f) / (_far - _near); - const float dd = (_left + _right)/(_left - _right); - const float ee = (_top + _bottom)/(_bottom - _top); - const float ff = _oglNdc ? (_near + _far)/(_near - _far) : _near/(_near - _far); - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = aa; - _result[ 5] = bb; - _result[10] = (Handness::Right == HandnessT) ? -cc : cc; - _result[12] = dd + _offset; - _result[13] = ee; - _result[14] = ff; - _result[15] = 1.0f; - } - - inline void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) - { - mtxOrtho_impl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); - } - - inline void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) - { - mtxOrtho_impl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); - } - - inline void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) - { - mtxOrtho_impl<Handness::Right>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); - } - - inline void mtxRotateX(float* _result, float _ax) - { - const float sx = fsin(_ax); - const float cx = fcos(_ax); - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = 1.0f; - _result[ 5] = cx; - _result[ 6] = -sx; - _result[ 9] = sx; - _result[10] = cx; - _result[15] = 1.0f; - } - - inline void mtxRotateY(float* _result, float _ay) - { - const float sy = fsin(_ay); - const float cy = fcos(_ay); - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = cy; - _result[ 2] = sy; - _result[ 5] = 1.0f; - _result[ 8] = -sy; - _result[10] = cy; - _result[15] = 1.0f; - } - - inline void mtxRotateZ(float* _result, float _az) - { - const float sz = fsin(_az); - const float cz = fcos(_az); - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = cz; - _result[ 1] = -sz; - _result[ 4] = sz; - _result[ 5] = cz; - _result[10] = 1.0f; - _result[15] = 1.0f; - } - - inline void mtxRotateXY(float* _result, float _ax, float _ay) - { - const float sx = fsin(_ax); - const float cx = fcos(_ax); - const float sy = fsin(_ay); - const float cy = fcos(_ay); - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = cy; - _result[ 2] = sy; - _result[ 4] = sx*sy; - _result[ 5] = cx; - _result[ 6] = -sx*cy; - _result[ 8] = -cx*sy; - _result[ 9] = sx; - _result[10] = cx*cy; - _result[15] = 1.0f; - } - - inline void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az) - { - const float sx = fsin(_ax); - const float cx = fcos(_ax); - const float sy = fsin(_ay); - const float cy = fcos(_ay); - const float sz = fsin(_az); - const float cz = fcos(_az); - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = cy*cz; - _result[ 1] = -cy*sz; - _result[ 2] = sy; - _result[ 4] = cz*sx*sy + cx*sz; - _result[ 5] = cx*cz - sx*sy*sz; - _result[ 6] = -cy*sx; - _result[ 8] = -cx*cz*sy + sx*sz; - _result[ 9] = cz*sx + cx*sy*sz; - _result[10] = cx*cy; - _result[15] = 1.0f; - } - - inline void mtxRotateZYX(float* _result, float _ax, float _ay, float _az) - { - const float sx = fsin(_ax); - const float cx = fcos(_ax); - const float sy = fsin(_ay); - const float cy = fcos(_ay); - const float sz = fsin(_az); - const float cz = fcos(_az); - - memSet(_result, 0, sizeof(float)*16); - _result[ 0] = cy*cz; - _result[ 1] = cz*sx*sy-cx*sz; - _result[ 2] = cx*cz*sy+sx*sz; - _result[ 4] = cy*sz; - _result[ 5] = cx*cz + sx*sy*sz; - _result[ 6] = -cz*sx + cx*sy*sz; - _result[ 8] = -sy; - _result[ 9] = cy*sx; - _result[10] = cx*cy; - _result[15] = 1.0f; - }; - - inline void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz) - { - const float sx = fsin(_ax); - const float cx = fcos(_ax); - const float sy = fsin(_ay); - const float cy = fcos(_ay); - const float sz = fsin(_az); - const float cz = fcos(_az); - - const float sxsz = sx*sz; - const float cycz = cy*cz; - - _result[ 0] = _sx * (cycz - sxsz*sy); - _result[ 1] = _sx * -cx*sz; - _result[ 2] = _sx * (cz*sy + cy*sxsz); - _result[ 3] = 0.0f; - - _result[ 4] = _sy * (cz*sx*sy + cy*sz); - _result[ 5] = _sy * cx*cz; - _result[ 6] = _sy * (sy*sz -cycz*sx); - _result[ 7] = 0.0f; - - _result[ 8] = _sz * -cx*sy; - _result[ 9] = _sz * sx; - _result[10] = _sz * cx*cy; - _result[11] = 0.0f; - - _result[12] = _tx; - _result[13] = _ty; - _result[14] = _tz; - _result[15] = 1.0f; - } - - inline void vec3MulMtx(float* _result, const float* _vec, const float* _mat) - { - _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; - _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; - _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; - } - - inline void vec3MulMtxH(float* _result, const float* _vec, const float* _mat) - { - float xx = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; - float yy = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; - float zz = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; - float ww = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _mat[15]; - float invW = fsign(ww)/ww; - _result[0] = xx*invW; - _result[1] = yy*invW; - _result[2] = zz*invW; - } - - inline void vec4MulMtx(float* _result, const float* _vec, const float* _mat) - { - _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12]; - _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _vec[3] * _mat[13]; - _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _vec[3] * _mat[14]; - _result[3] = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _vec[3] * _mat[15]; - } - - inline void mtxMul(float* _result, const float* _a, const float* _b) - { - vec4MulMtx(&_result[ 0], &_a[ 0], _b); - vec4MulMtx(&_result[ 4], &_a[ 4], _b); - vec4MulMtx(&_result[ 8], &_a[ 8], _b); - vec4MulMtx(&_result[12], &_a[12], _b); - } - - inline void mtxTranspose(float* _result, const float* _a) - { - _result[ 0] = _a[ 0]; - _result[ 4] = _a[ 1]; - _result[ 8] = _a[ 2]; - _result[12] = _a[ 3]; - _result[ 1] = _a[ 4]; - _result[ 5] = _a[ 5]; - _result[ 9] = _a[ 6]; - _result[13] = _a[ 7]; - _result[ 2] = _a[ 8]; - _result[ 6] = _a[ 9]; - _result[10] = _a[10]; - _result[14] = _a[11]; - _result[ 3] = _a[12]; - _result[ 7] = _a[13]; - _result[11] = _a[14]; - _result[15] = _a[15]; - } - - /// Convert LH to RH projection matrix and vice versa. - inline void mtxProjFlipHandedness(float* _dst, const float* _src) - { - _dst[ 0] = -_src[ 0]; - _dst[ 1] = -_src[ 1]; - _dst[ 2] = -_src[ 2]; - _dst[ 3] = -_src[ 3]; - _dst[ 4] = _src[ 4]; - _dst[ 5] = _src[ 5]; - _dst[ 6] = _src[ 6]; - _dst[ 7] = _src[ 7]; - _dst[ 8] = -_src[ 8]; - _dst[ 9] = -_src[ 9]; - _dst[10] = -_src[10]; - _dst[11] = -_src[11]; - _dst[12] = _src[12]; - _dst[13] = _src[13]; - _dst[14] = _src[14]; - _dst[15] = _src[15]; - } - - /// Convert LH to RH view matrix and vice versa. - inline void mtxViewFlipHandedness(float* _dst, const float* _src) - { - _dst[ 0] = -_src[ 0]; - _dst[ 1] = _src[ 1]; - _dst[ 2] = -_src[ 2]; - _dst[ 3] = _src[ 3]; - _dst[ 4] = -_src[ 4]; - _dst[ 5] = _src[ 5]; - _dst[ 6] = -_src[ 6]; - _dst[ 7] = _src[ 7]; - _dst[ 8] = -_src[ 8]; - _dst[ 9] = _src[ 9]; - _dst[10] = -_src[10]; - _dst[11] = _src[11]; - _dst[12] = -_src[12]; - _dst[13] = _src[13]; - _dst[14] = -_src[14]; - _dst[15] = _src[15]; - } - - inline void calcNormal(float _result[3], float _va[3], float _vb[3], float _vc[3]) - { - float ba[3]; - vec3Sub(ba, _vb, _va); - - float ca[3]; - vec3Sub(ca, _vc, _va); - - float baxca[3]; - vec3Cross(baxca, ba, ca); - - vec3Norm(_result, baxca); - } - - inline void calcPlane(float _result[4], float _va[3], float _vb[3], float _vc[3]) - { - float normal[3]; - calcNormal(normal, _va, _vb, _vc); - - _result[0] = normal[0]; - _result[1] = normal[1]; - _result[2] = normal[2]; - _result[3] = -vec3Dot(normal, _va); - } - - inline void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints) - { - float sumX = 0.0f; - float sumY = 0.0f; - float sumXX = 0.0f; - float sumXY = 0.0f; - - const uint8_t* ptr = (const uint8_t*)_points; - for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride) - { - const float* point = (const float*)ptr; - float xx = point[0]; - float yy = point[1]; - sumX += xx; - sumY += yy; - sumXX += xx*xx; - sumXY += xx*yy; - } - - // [ sum(x^2) sum(x) ] [ A ] = [ sum(x*y) ] - // [ sum(x) numPoints ] [ B ] [ sum(y) ] - - float det = (sumXX*_numPoints - sumX*sumX); - float invDet = 1.0f/det; - - _result[0] = (-sumX * sumY + _numPoints * sumXY) * invDet; - _result[1] = (sumXX * sumY - sumX * sumXY) * invDet; - } - - inline void calcLinearFit3D(float _result[3], const void* _points, uint32_t _stride, uint32_t _numPoints) - { - float sumX = 0.0f; - float sumY = 0.0f; - float sumZ = 0.0f; - float sumXX = 0.0f; - float sumXY = 0.0f; - float sumXZ = 0.0f; - float sumYY = 0.0f; - float sumYZ = 0.0f; - - const uint8_t* ptr = (const uint8_t*)_points; - for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride) - { - const float* point = (const float*)ptr; - float xx = point[0]; - float yy = point[1]; - float zz = point[2]; - - sumX += xx; - sumY += yy; - sumZ += zz; - sumXX += xx*xx; - sumXY += xx*yy; - sumXZ += xx*zz; - sumYY += yy*yy; - sumYZ += yy*zz; - } - - // [ sum(x^2) sum(x*y) sum(x) ] [ A ] [ sum(x*z) ] - // [ sum(x*y) sum(y^2) sum(y) ] [ B ] = [ sum(y*z) ] - // [ sum(x) sum(y) numPoints ] [ C ] [ sum(z) ] - - float mtx[9] = - { - sumXX, sumXY, sumX, - sumXY, sumYY, sumY, - sumX, sumY, float(_numPoints), - }; - float invMtx[9]; - mtx3Inverse(invMtx, mtx); - - _result[0] = invMtx[0]*sumXZ + invMtx[1]*sumYZ + invMtx[2]*sumZ; - _result[1] = invMtx[3]*sumXZ + invMtx[4]*sumYZ + invMtx[5]*sumZ; - _result[2] = invMtx[6]*sumXZ + invMtx[7]*sumYZ + invMtx[8]*sumZ; - } - - inline void rgbToHsv(float _hsv[3], const float _rgb[3]) - { - const float rr = _rgb[0]; - const float gg = _rgb[1]; - const float bb = _rgb[2]; - - const float s0 = fstep(bb, gg); - - const float px = flerp(bb, gg, s0); - const float py = flerp(gg, bb, s0); - const float pz = flerp(-1.0f, 0.0f, s0); - const float pw = flerp(2.0f/3.0f, -1.0f/3.0f, s0); - - const float s1 = fstep(px, rr); - - const float qx = flerp(px, rr, s1); - const float qy = py; - const float qz = flerp(pw, pz, s1); - const float qw = flerp(rr, px, s1); - - const float dd = qx - fmin(qw, qy); - const float ee = 1.0e-10f; - - _hsv[0] = fabsolute(qz + (qw - qy) / (6.0f * dd + ee) ); - _hsv[1] = dd / (qx + ee); - _hsv[2] = qx; - } - - inline void hsvToRgb(float _rgb[3], const float _hsv[3]) - { - const float hh = _hsv[0]; - const float ss = _hsv[1]; - const float vv = _hsv[2]; - - const float px = fabsolute(ffract(hh + 1.0f ) * 6.0f - 3.0f); - const float py = fabsolute(ffract(hh + 2.0f/3.0f) * 6.0f - 3.0f); - const float pz = fabsolute(ffract(hh + 1.0f/3.0f) * 6.0f - 3.0f); - - _rgb[0] = vv * flerp(1.0f, fsaturate(px - 1.0f), ss); - _rgb[1] = vv * flerp(1.0f, fsaturate(py - 1.0f), ss); - _rgb[2] = vv * flerp(1.0f, fsaturate(pz - 1.0f), ss); - } - -} // namespace bx diff --git a/3rdparty/bx/include/bx/inline/handlealloc.inl b/3rdparty/bx/include/bx/inline/handlealloc.inl index 8738c3d7038..3ca3d41ed57 100644 --- a/3rdparty/bx/include/bx/inline/handlealloc.inl +++ b/3rdparty/bx/include/bx/inline/handlealloc.inl @@ -54,7 +54,7 @@ namespace bx return handle; } - return invalid; + return kInvalidHandle; } inline bool HandleAlloc::isValid(uint16_t _handle) const @@ -104,7 +104,7 @@ namespace bx inline HandleAlloc* createHandleAlloc(AllocatorI* _allocator, uint16_t _maxHandles) { uint8_t* ptr = (uint8_t*)BX_ALLOC(_allocator, sizeof(HandleAlloc) + 2*_maxHandles*sizeof(uint16_t) ); - return ::new (ptr) HandleAlloc(_maxHandles); + return BX_PLACEMENT_NEW(ptr, HandleAlloc)(_maxHandles); } inline void destroyHandleAlloc(AllocatorI* _allocator, HandleAlloc* _handleAlloc) @@ -139,12 +139,12 @@ namespace bx template <uint16_t MaxHandlesT> inline uint16_t HandleListT<MaxHandlesT>::popBack() { - uint16_t last = invalid != m_back + uint16_t last = kInvalidHandle != m_back ? m_back : m_front ; - if (invalid != last) + if (kInvalidHandle != last) { remove(last); } @@ -163,7 +163,7 @@ namespace bx { uint16_t front = m_front; - if (invalid != front) + if (kInvalidHandle != front) { remove(front); } @@ -205,7 +205,7 @@ namespace bx BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle); Link& curr = m_links[_handle]; - if (invalid != curr.m_prev) + if (kInvalidHandle != curr.m_prev) { Link& prev = m_links[curr.m_prev]; prev.m_next = curr.m_next; @@ -215,7 +215,7 @@ namespace bx m_front = curr.m_next; } - if (invalid != curr.m_next) + if (kInvalidHandle != curr.m_next) { Link& next = m_links[curr.m_next]; next.m_prev = curr.m_prev; @@ -225,16 +225,16 @@ namespace bx m_back = curr.m_prev; } - curr.m_prev = invalid; - curr.m_next = invalid; + curr.m_prev = kInvalidHandle; + curr.m_next = kInvalidHandle; } template <uint16_t MaxHandlesT> inline void HandleListT<MaxHandlesT>::reset() { memSet(m_links, 0xff, sizeof(m_links) ); - m_front = invalid; - m_back = invalid; + m_front = kInvalidHandle; + m_back = kInvalidHandle; } template <uint16_t MaxHandlesT> @@ -243,10 +243,10 @@ namespace bx Link& curr = m_links[_handle]; curr.m_next = _before; - if (invalid != _before) + if (kInvalidHandle != _before) { Link& link = m_links[_before]; - if (invalid != link.m_prev) + if (kInvalidHandle != link.m_prev) { Link& prev = m_links[link.m_prev]; prev.m_next = _handle; @@ -265,10 +265,10 @@ namespace bx Link& curr = m_links[_handle]; curr.m_prev = _after; - if (invalid != _after) + if (kInvalidHandle != _after) { Link& link = m_links[_after]; - if (invalid != link.m_next) + if (kInvalidHandle != link.m_next) { Link& next = m_links[link.m_next]; next.m_prev = _handle; @@ -292,12 +292,12 @@ namespace bx { Link& curr = m_links[_handle]; - if (invalid == curr.m_prev) + if (kInvalidHandle == curr.m_prev) { m_front = _handle; } - if (invalid == curr.m_next) + if (kInvalidHandle == curr.m_next) { m_back = _handle; } @@ -342,7 +342,7 @@ namespace bx inline uint16_t HandleAllocLruT<MaxHandlesT>::alloc() { uint16_t handle = m_alloc.alloc(); - if (invalid != handle) + if (kInvalidHandle != handle) { m_list.pushFront(handle); } @@ -417,7 +417,7 @@ namespace bx template <uint32_t MaxCapacityT, typename KeyT> inline bool HandleHashMapT<MaxCapacityT, KeyT>::insert(KeyT _key, uint16_t _handle) { - if (invalid == _handle) + if (kInvalidHandle == _handle) { return false; } @@ -427,7 +427,7 @@ namespace bx uint32_t idx = firstIdx; do { - if (m_handle[idx] == invalid) + if (m_handle[idx] == kInvalidHandle) { m_key[idx] = _key; m_handle[idx] = _handle; @@ -463,7 +463,7 @@ namespace bx template <uint32_t MaxCapacityT, typename KeyT> inline bool HandleHashMapT<MaxCapacityT, KeyT>::removeByHandle(uint16_t _handle) { - if (invalid != _handle) + if (kInvalidHandle != _handle) { for (uint32_t idx = 0; idx < MaxCapacityT; ++idx) { @@ -486,7 +486,7 @@ namespace bx return m_handle[idx]; } - return invalid; + return kInvalidHandle; } template <uint32_t MaxCapacityT, typename KeyT> @@ -512,7 +512,7 @@ namespace bx inline typename HandleHashMapT<MaxCapacityT, KeyT>::Iterator HandleHashMapT<MaxCapacityT, KeyT>::first() const { Iterator it; - it.handle = invalid; + it.handle = kInvalidHandle; it.pos = 0; it.num = m_numElements; @@ -535,7 +535,7 @@ namespace bx } for ( - ;_it.pos < MaxCapacityT && invalid == m_handle[_it.pos] + ;_it.pos < MaxCapacityT && kInvalidHandle == m_handle[_it.pos] ; ++_it.pos ); _it.handle = m_handle[_it.pos]; @@ -553,7 +553,7 @@ namespace bx uint32_t idx = firstIdx; do { - if (m_handle[idx] == invalid) + if (m_handle[idx] == kInvalidHandle) { return UINT32_MAX; } @@ -573,20 +573,20 @@ namespace bx template <uint32_t MaxCapacityT, typename KeyT> inline void HandleHashMapT<MaxCapacityT, KeyT>::removeIndex(uint32_t _idx) { - m_handle[_idx] = invalid; + m_handle[_idx] = kInvalidHandle; --m_numElements; for (uint32_t idx = (_idx + 1) % MaxCapacityT - ; m_handle[idx] != invalid + ; m_handle[idx] != kInvalidHandle ; idx = (idx + 1) % MaxCapacityT) { - if (m_handle[idx] != invalid) + if (m_handle[idx] != kInvalidHandle) { const KeyT key = m_key[idx]; if (idx != findIndex(key) ) { const uint16_t handle = m_handle[idx]; - m_handle[idx] = invalid; + m_handle[idx] = kInvalidHandle; --m_numElements; insert(key, handle); } @@ -627,16 +627,16 @@ namespace bx inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::alloc(KeyT _key) { uint16_t handle = m_alloc.alloc(); - if (invalid == handle) + if (kInvalidHandle == handle) { - return invalid; + return kInvalidHandle; } bool ok = m_table.insert(_key, handle); if (!ok) { m_alloc.free(handle); - return invalid; + return kInvalidHandle; } return handle; @@ -646,7 +646,7 @@ namespace bx inline void HandleHashMapAllocT<MaxHandlesT, KeyT>::free(KeyT _key) { uint16_t handle = m_table.find(_key); - if (invalid == handle) + if (kInvalidHandle == handle) { return; } diff --git a/3rdparty/bx/include/bx/inline/hash.inl b/3rdparty/bx/include/bx/inline/hash.inl index 50da33f0528..41031bbab2b 100644 --- a/3rdparty/bx/include/bx/inline/hash.inl +++ b/3rdparty/bx/include/bx/inline/hash.inl @@ -136,29 +136,72 @@ namespace bx #undef MURMUR_R #undef mmix - inline uint32_t hashMurmur2A(const void* _data, uint32_t _size) + inline void HashAdler32::begin() { - HashMurmur2A murmur; - murmur.begin(); - murmur.add(_data, (int)_size); - return murmur.end(); + m_a = 1; + m_b = 0; } - template <typename Ty> - inline uint32_t hashMurmur2A(const Ty& _data) + inline void HashAdler32::add(const void* _data, int _len) + { + const uint32_t kModAdler = 65521; + const uint8_t* data = (const uint8_t*)_data; + for (; _len != 0; --_len) + { + m_a = (m_a + *data++) % kModAdler; + m_b = (m_b + m_a ) % kModAdler; + } + } + + template<typename Ty> + inline void HashAdler32::add(Ty _value) + { + add(&_value, sizeof(Ty) ); + } + + inline uint32_t HashAdler32::end() + { + return m_a | (m_b<<16); + } + + template<typename Ty> + inline void HashCrc32::add(Ty _value) + { + add(&_value, sizeof(Ty) ); + } + + inline uint32_t HashCrc32::end() + { + m_hash ^= UINT32_MAX; + return m_hash; + } + + template<typename HashT> + inline uint32_t hash(const void* _data, uint32_t _size) + { + HashT hh; + hh.begin(); + hh.add(_data, (int)_size); + return hh.end(); + } + + template<typename HashT, typename Ty> + inline uint32_t hash(const Ty& _data) { BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) ); - return hashMurmur2A(&_data, sizeof(Ty) ); + return hash<HashT>(&_data, sizeof(Ty) ); } - inline uint32_t hashMurmur2A(const StringView& _data) + template<typename HashT> + inline uint32_t hash(const StringView& _data) { - return hashMurmur2A(_data.getPtr(), _data.getLength() ); + return hash<HashT>(_data.getPtr(), _data.getLength() ); } - inline uint32_t hashMurmur2A(const char* _data) + template<typename HashT> + inline uint32_t hash(const char* _data) { - return hashMurmur2A(StringView(_data) ); + return hash<HashT>(StringView(_data) ); } } // namespace bx diff --git a/3rdparty/bx/include/bx/inline/math.inl b/3rdparty/bx/include/bx/inline/math.inl new file mode 100644 index 00000000000..d6b8c57523a --- /dev/null +++ b/3rdparty/bx/include/bx/inline/math.inl @@ -0,0 +1,834 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +// FPU math lib + +#ifndef BX_FPU_MATH_H_HEADER_GUARD +# error "Must be included from bx/fpumath.h!" +#endif // BX_FPU_MATH_H_HEADER_GUARD + +namespace bx +{ + inline float toRad(float _deg) + { + return _deg * kPi / 180.0f; + } + + inline float toDeg(float _rad) + { + return _rad * 180.0f / kPi; + } + + inline uint32_t floatToBits(float _a) + { + union { float f; uint32_t ui; } u = { _a }; + return u.ui; + } + + inline float bitsToFloat(uint32_t _a) + { + union { uint32_t ui; float f; } u = { _a }; + return u.f; + } + + inline uint64_t doubleToBits(double _a) + { + union { double f; uint64_t ui; } u = { _a }; + return u.ui; + } + + inline double bitsToDouble(uint64_t _a) + { + union { uint64_t ui; double f; } u = { _a }; + return u.f; + } + + inline uint32_t floatFlip(uint32_t _value) + { + // Reference: + // http://archive.fo/2012.12.08-212402/http://stereopsis.com/radix.html + const uint32_t tmp0 = uint32_sra(_value, 31); + const uint32_t tmp1 = uint32_neg(tmp0); + const uint32_t mask = uint32_or(tmp1, 0x80000000); + const uint32_t result = uint32_xor(_value, mask); + return result; + } + + inline bool isNan(float _f) + { + const uint32_t tmp = floatToBits(_f) & INT32_MAX; + return tmp > UINT32_C(0x7f800000); + } + + inline bool isNan(double _f) + { + const uint64_t tmp = doubleToBits(_f) & INT64_MAX; + return tmp > UINT64_C(0x7ff0000000000000); + } + + inline bool isFinite(float _f) + { + const uint32_t tmp = floatToBits(_f) & INT32_MAX; + return tmp < UINT32_C(0x7f800000); + } + + inline bool isFinite(double _f) + { + const uint64_t tmp = doubleToBits(_f) & INT64_MAX; + return tmp < UINT64_C(0x7ff0000000000000); + } + + inline bool isInfinite(float _f) + { + const uint32_t tmp = floatToBits(_f) & INT32_MAX; + return tmp == UINT32_C(0x7f800000); + } + + inline bool isInfinite(double _f) + { + const uint64_t tmp = doubleToBits(_f) & INT64_MAX; + return tmp == UINT64_C(0x7ff0000000000000); + } + + inline float fround(float _f) + { + return ffloor(_f + 0.5f); + } + + inline float fmin(float _a, float _b) + { + return _a < _b ? _a : _b; + } + + inline float fmax(float _a, float _b) + { + return _a > _b ? _a : _b; + } + + inline float fmin3(float _a, float _b, float _c) + { + return fmin(_a, fmin(_b, _c) ); + } + + inline float fmax3(float _a, float _b, float _c) + { + return fmax(_a, fmax(_b, _c) ); + } + + inline float fclamp(float _a, float _min, float _max) + { + return fmin(fmax(_a, _min), _max); + } + + inline float fsaturate(float _a) + { + return fclamp(_a, 0.0f, 1.0f); + } + + inline float flerp(float _a, float _b, float _t) + { + return _a + (_b - _a) * _t; + } + + inline float fsign(float _a) + { + return _a < 0.0f ? -1.0f : 1.0f; + } + + inline float fsq(float _a) + { + return _a * _a; + } + + inline float fexp2(float _a) + { + return fpow(2.0f, _a); + } + + inline float flog2(float _a) + { + return flog(_a) * kInvLogNat2; + } + + inline float frsqrt(float _a) + { + return 1.0f/fsqrt(_a); + } + + inline float ffract(float _a) + { + return _a - ffloor(_a); + } + + inline bool fequal(float _a, float _b, float _epsilon) + { + // http://realtimecollisiondetection.net/blog/?p=89 + const float lhs = fabs(_a - _b); + const float rhs = _epsilon * fmax3(1.0f, fabs(_a), fabs(_b) ); + return lhs <= rhs; + } + + inline bool fequal(const float* _a, const float* _b, uint32_t _num, float _epsilon) + { + bool equal = fequal(_a[0], _b[0], _epsilon); + for (uint32_t ii = 1; equal && ii < _num; ++ii) + { + equal = fequal(_a[ii], _b[ii], _epsilon); + } + return equal; + } + + inline float fwrap(float _a, float _wrap) + { + const float mod = fmod(_a, _wrap); + const float result = mod < 0.0f ? _wrap + mod : mod; + return result; + } + + inline float fstep(float _edge, float _a) + { + return _a < _edge ? 0.0f : 1.0f; + } + + inline float fpulse(float _a, float _start, float _end) + { + return fstep(_a, _start) - fstep(_a, _end); + } + + inline float fsmoothstep(float _a) + { + return fsq(_a)*(3.0f - 2.0f*_a); + } + + inline float fbias(float _time, float _bias) + { + return _time / ( ( (1.0f/_bias - 2.0f)*(1.0f - _time) ) + 1.0f); + } + + inline float fgain(float _time, float _gain) + { + if (_time < 0.5f) + { + return fbias(_time * 2.0f, _gain) * 0.5f; + } + + return fbias(_time * 2.0f - 1.0f, 1.0f - _gain) * 0.5f + 0.5f; + } + + inline float angleDiff(float _a, float _b) + { + const float dist = fwrap(_b - _a, kPi2); + return fwrap(dist*2.0f, kPi2) - dist; + } + + inline float angleLerp(float _a, float _b, float _t) + { + return _a + angleDiff(_a, _b) * _t; + } + + inline void vec3Move(float* _result, const float* _a) + { + _result[0] = _a[0]; + _result[1] = _a[1]; + _result[2] = _a[2]; + } + + inline void vec3Abs(float* _result, const float* _a) + { + _result[0] = fabs(_a[0]); + _result[1] = fabs(_a[1]); + _result[2] = fabs(_a[2]); + } + + inline void vec3Neg(float* _result, const float* _a) + { + _result[0] = -_a[0]; + _result[1] = -_a[1]; + _result[2] = -_a[2]; + } + + inline void vec3Add(float* _result, const float* _a, const float* _b) + { + _result[0] = _a[0] + _b[0]; + _result[1] = _a[1] + _b[1]; + _result[2] = _a[2] + _b[2]; + } + + inline void vec3Add(float* _result, const float* _a, float _b) + { + _result[0] = _a[0] + _b; + _result[1] = _a[1] + _b; + _result[2] = _a[2] + _b; + } + + inline void vec3Sub(float* _result, const float* _a, const float* _b) + { + _result[0] = _a[0] - _b[0]; + _result[1] = _a[1] - _b[1]; + _result[2] = _a[2] - _b[2]; + } + + inline void vec3Sub(float* _result, const float* _a, float _b) + { + _result[0] = _a[0] - _b; + _result[1] = _a[1] - _b; + _result[2] = _a[2] - _b; + } + + inline void vec3Mul(float* _result, const float* _a, const float* _b) + { + _result[0] = _a[0] * _b[0]; + _result[1] = _a[1] * _b[1]; + _result[2] = _a[2] * _b[2]; + } + + inline void vec3Mul(float* _result, const float* _a, float _b) + { + _result[0] = _a[0] * _b; + _result[1] = _a[1] * _b; + _result[2] = _a[2] * _b; + } + + inline float vec3Dot(const float* _a, const float* _b) + { + return _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2]; + } + + inline void vec3Cross(float* _result, const float* _a, const float* _b) + { + _result[0] = _a[1]*_b[2] - _a[2]*_b[1]; + _result[1] = _a[2]*_b[0] - _a[0]*_b[2]; + _result[2] = _a[0]*_b[1] - _a[1]*_b[0]; + } + + inline float vec3Length(const float* _a) + { + return fsqrt(vec3Dot(_a, _a) ); + } + + inline void vec3Lerp(float* _result, const float* _a, const float* _b, float _t) + { + _result[0] = flerp(_a[0], _b[0], _t); + _result[1] = flerp(_a[1], _b[1], _t); + _result[2] = flerp(_a[2], _b[2], _t); + } + + inline void vec3Lerp(float* _result, const float* _a, const float* _b, const float* _c) + { + _result[0] = flerp(_a[0], _b[0], _c[0]); + _result[1] = flerp(_a[1], _b[1], _c[1]); + _result[2] = flerp(_a[2], _b[2], _c[2]); + } + + inline float vec3Norm(float* _result, const float* _a) + { + const float len = vec3Length(_a); + const float invLen = 1.0f/len; + _result[0] = _a[0] * invLen; + _result[1] = _a[1] * invLen; + _result[2] = _a[2] * invLen; + return len; + } + + inline void vec3Min(float* _result, const float* _a, const float* _b) + { + _result[0] = fmin(_a[0], _b[0]); + _result[1] = fmin(_a[1], _b[1]); + _result[2] = fmin(_a[2], _b[2]); + } + + inline void vec3Max(float* _result, const float* _a, const float* _b) + { + _result[0] = fmax(_a[0], _b[0]); + _result[1] = fmax(_a[1], _b[1]); + _result[2] = fmax(_a[2], _b[2]); + } + + inline void vec3Rcp(float* _result, const float* _a) + { + _result[0] = 1.0f / _a[0]; + _result[1] = 1.0f / _a[1]; + _result[2] = 1.0f / _a[2]; + } + + inline void vec3TangentFrame(const float* _n, float* _t, float* _b) + { + const float nx = _n[0]; + const float ny = _n[1]; + const float nz = _n[2]; + + if (bx::fabs(nx) > bx::fabs(nz) ) + { + float invLen = 1.0f / bx::fsqrt(nx*nx + nz*nz); + _t[0] = -nz * invLen; + _t[1] = 0.0f; + _t[2] = nx * invLen; + } + else + { + float invLen = 1.0f / bx::fsqrt(ny*ny + nz*nz); + _t[0] = 0.0f; + _t[1] = nz * invLen; + _t[2] = -ny * invLen; + } + + bx::vec3Cross(_b, _n, _t); + } + + inline void vec3TangentFrame(const float* _n, float* _t, float* _b, float _angle) + { + vec3TangentFrame(_n, _t, _b); + + const float sa = fsin(_angle); + const float ca = fcos(_angle); + + _t[0] = -sa * _b[0] + ca * _t[0]; + _t[1] = -sa * _b[1] + ca * _t[1]; + _t[2] = -sa * _b[2] + ca * _t[2]; + + bx::vec3Cross(_b, _n, _t); + } + + inline void vec3FromLatLong(float* _vec, float _u, float _v) + { + const float phi = _u * bx::kPi2; + const float theta = _v * bx::kPi; + + const float st = bx::fsin(theta); + const float sp = bx::fsin(phi); + const float ct = bx::fcos(theta); + const float cp = bx::fcos(phi); + + _vec[0] = -st*sp; + _vec[1] = ct; + _vec[2] = -st*cp; + } + + inline void vec3ToLatLong(float* _u, float* _v, const float* _vec) + { + const float phi = bx::fatan2(_vec[0], _vec[2]); + const float theta = bx::facos(_vec[1]); + + *_u = (bx::kPi + phi)*bx::kInvPi*0.5f; + *_v = theta*bx::kInvPi; + } + + inline void quatIdentity(float* _result) + { + _result[0] = 0.0f; + _result[1] = 0.0f; + _result[2] = 0.0f; + _result[3] = 1.0f; + } + + inline void quatMove(float* _result, const float* _a) + { + _result[0] = _a[0]; + _result[1] = _a[1]; + _result[2] = _a[2]; + _result[3] = _a[3]; + } + + inline void quatMulXYZ(float* _result, const float* _qa, const float* _qb) + { + const float ax = _qa[0]; + const float ay = _qa[1]; + const float az = _qa[2]; + const float aw = _qa[3]; + + const float bx = _qb[0]; + const float by = _qb[1]; + const float bz = _qb[2]; + const float bw = _qb[3]; + + _result[0] = aw * bx + ax * bw + ay * bz - az * by; + _result[1] = aw * by - ax * bz + ay * bw + az * bx; + _result[2] = aw * bz + ax * by - ay * bx + az * bw; + } + + inline void quatMul(float* _result, const float* _qa, const float* _qb) + { + const float ax = _qa[0]; + const float ay = _qa[1]; + const float az = _qa[2]; + const float aw = _qa[3]; + + const float bx = _qb[0]; + const float by = _qb[1]; + const float bz = _qb[2]; + const float bw = _qb[3]; + + _result[0] = aw * bx + ax * bw + ay * bz - az * by; + _result[1] = aw * by - ax * bz + ay * bw + az * bx; + _result[2] = aw * bz + ax * by - ay * bx + az * bw; + _result[3] = aw * bw - ax * bx - ay * by - az * bz; + } + + inline void quatInvert(float* _result, const float* _quat) + { + _result[0] = -_quat[0]; + _result[1] = -_quat[1]; + _result[2] = -_quat[2]; + _result[3] = _quat[3]; + } + + inline float quatDot(const float* _a, const float* _b) + { + return _a[0]*_b[0] + + _a[1]*_b[1] + + _a[2]*_b[2] + + _a[3]*_b[3] + ; + } + + inline void quatNorm(float* _result, const float* _quat) + { + const float norm = quatDot(_quat, _quat); + if (0.0f < norm) + { + const float invNorm = 1.0f / fsqrt(norm); + _result[0] = _quat[0] * invNorm; + _result[1] = _quat[1] * invNorm; + _result[2] = _quat[2] * invNorm; + _result[3] = _quat[3] * invNorm; + } + else + { + quatIdentity(_result); + } + } + + inline void quatToEuler(float* _result, const float* _quat) + { + const float x = _quat[0]; + const float y = _quat[1]; + const float z = _quat[2]; + const float w = _quat[3]; + + const float yy = y * y; + const float zz = z * z; + + const float xx = x * x; + _result[0] = fatan2(2.0f * (x * w - y * z), 1.0f - 2.0f * (xx + zz) ); + _result[1] = fatan2(2.0f * (y * w + x * z), 1.0f - 2.0f * (yy + zz) ); + _result[2] = fasin (2.0f * (x * y + z * w) ); + } + + inline void quatRotateAxis(float* _result, const float* _axis, float _angle) + { + const float ha = _angle * 0.5f; + const float ca = fcos(ha); + const float sa = fsin(ha); + _result[0] = _axis[0] * sa; + _result[1] = _axis[1] * sa; + _result[2] = _axis[2] * sa; + _result[3] = ca; + } + + inline void quatRotateX(float* _result, float _ax) + { + const float hx = _ax * 0.5f; + const float cx = fcos(hx); + const float sx = fsin(hx); + _result[0] = sx; + _result[1] = 0.0f; + _result[2] = 0.0f; + _result[3] = cx; + } + + inline void quatRotateY(float* _result, float _ay) + { + const float hy = _ay * 0.5f; + const float cy = fcos(hy); + const float sy = fsin(hy); + _result[0] = 0.0f; + _result[1] = sy; + _result[2] = 0.0f; + _result[3] = cy; + } + + inline void quatRotateZ(float* _result, float _az) + { + const float hz = _az * 0.5f; + const float cz = fcos(hz); + const float sz = fsin(hz); + _result[0] = 0.0f; + _result[1] = 0.0f; + _result[2] = sz; + _result[3] = cz; + } + + inline void vec3MulQuat(float* _result, const float* _vec, const float* _quat) + { + float tmp0[4]; + quatInvert(tmp0, _quat); + + float qv[4]; + qv[0] = _vec[0]; + qv[1] = _vec[1]; + qv[2] = _vec[2]; + qv[3] = 0.0f; + + float tmp1[4]; + quatMul(tmp1, tmp0, qv); + + quatMulXYZ(_result, tmp1, _quat); + } + + inline void mtxIdentity(float* _result) + { + memSet(_result, 0, sizeof(float)*16); + _result[0] = _result[5] = _result[10] = _result[15] = 1.0f; + } + + inline void mtxTranslate(float* _result, float _tx, float _ty, float _tz) + { + mtxIdentity(_result); + _result[12] = _tx; + _result[13] = _ty; + _result[14] = _tz; + } + + inline void mtxScale(float* _result, float _sx, float _sy, float _sz) + { + memSet(_result, 0, sizeof(float) * 16); + _result[0] = _sx; + _result[5] = _sy; + _result[10] = _sz; + _result[15] = 1.0f; + } + + inline void mtxScale(float* _result, float _scale) + { + mtxScale(_result, _scale, _scale, _scale); + } + + inline void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos) + { + float tangent[3]; + float bitangent[3]; + vec3TangentFrame(_normal, tangent, bitangent); + + vec3Mul(&_result[ 0], bitangent, _scale); + vec3Mul(&_result[ 4], _normal, _scale); + vec3Mul(&_result[ 8], tangent, _scale); + + _result[ 3] = 0.0f; + _result[ 7] = 0.0f; + _result[11] = 0.0f; + _result[12] = _pos[0]; + _result[13] = _pos[1]; + _result[14] = _pos[2]; + _result[15] = 1.0f; + } + + inline void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos, float _angle) + { + float tangent[3]; + float bitangent[3]; + vec3TangentFrame(_normal, tangent, bitangent, _angle); + + vec3Mul(&_result[ 0], bitangent, _scale); + vec3Mul(&_result[ 4], _normal, _scale); + vec3Mul(&_result[ 8], tangent, _scale); + + _result[ 3] = 0.0f; + _result[ 7] = 0.0f; + _result[11] = 0.0f; + _result[12] = _pos[0]; + _result[13] = _pos[1]; + _result[14] = _pos[2]; + _result[15] = 1.0f; + } + + inline void mtxQuat(float* _result, const float* _quat) + { + const float x = _quat[0]; + const float y = _quat[1]; + const float z = _quat[2]; + const float w = _quat[3]; + + const float x2 = x + x; + const float y2 = y + y; + const float z2 = z + z; + const float x2x = x2 * x; + const float x2y = x2 * y; + const float x2z = x2 * z; + const float x2w = x2 * w; + const float y2y = y2 * y; + const float y2z = y2 * z; + const float y2w = y2 * w; + const float z2z = z2 * z; + const float z2w = z2 * w; + + _result[ 0] = 1.0f - (y2y + z2z); + _result[ 1] = x2y - z2w; + _result[ 2] = x2z + y2w; + _result[ 3] = 0.0f; + + _result[ 4] = x2y + z2w; + _result[ 5] = 1.0f - (x2x + z2z); + _result[ 6] = y2z - x2w; + _result[ 7] = 0.0f; + + _result[ 8] = x2z - y2w; + _result[ 9] = y2z + x2w; + _result[10] = 1.0f - (x2x + y2y); + _result[11] = 0.0f; + + _result[12] = 0.0f; + _result[13] = 0.0f; + _result[14] = 0.0f; + _result[15] = 1.0f; + } + + inline void mtxQuatTranslation(float* _result, const float* _quat, const float* _translation) + { + mtxQuat(_result, _quat); + _result[12] = -(_result[0]*_translation[0] + _result[4]*_translation[1] + _result[ 8]*_translation[2]); + _result[13] = -(_result[1]*_translation[0] + _result[5]*_translation[1] + _result[ 9]*_translation[2]); + _result[14] = -(_result[2]*_translation[0] + _result[6]*_translation[1] + _result[10]*_translation[2]); + } + + inline void mtxQuatTranslationHMD(float* _result, const float* _quat, const float* _translation) + { + float quat[4]; + quat[0] = -_quat[0]; + quat[1] = -_quat[1]; + quat[2] = _quat[2]; + quat[3] = _quat[3]; + mtxQuatTranslation(_result, quat, _translation); + } + + inline void vec3MulMtx(float* _result, const float* _vec, const float* _mat) + { + _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; + _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; + _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; + } + + inline void vec3MulMtxXyz0(float* _result, const float* _vec, const float* _mat) + { + _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8]; + _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9]; + _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10]; + } + + inline void vec3MulMtxH(float* _result, const float* _vec, const float* _mat) + { + float xx = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; + float yy = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; + float zz = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; + float ww = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _mat[15]; + float invW = fsign(ww)/ww; + _result[0] = xx*invW; + _result[1] = yy*invW; + _result[2] = zz*invW; + } + + inline void vec4MulMtx(float* _result, const float* _vec, const float* _mat) + { + _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12]; + _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _vec[3] * _mat[13]; + _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _vec[3] * _mat[14]; + _result[3] = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _vec[3] * _mat[15]; + } + + inline void mtxMul(float* _result, const float* _a, const float* _b) + { + vec4MulMtx(&_result[ 0], &_a[ 0], _b); + vec4MulMtx(&_result[ 4], &_a[ 4], _b); + vec4MulMtx(&_result[ 8], &_a[ 8], _b); + vec4MulMtx(&_result[12], &_a[12], _b); + } + + inline void mtxTranspose(float* _result, const float* _a) + { + _result[ 0] = _a[ 0]; + _result[ 4] = _a[ 1]; + _result[ 8] = _a[ 2]; + _result[12] = _a[ 3]; + _result[ 1] = _a[ 4]; + _result[ 5] = _a[ 5]; + _result[ 9] = _a[ 6]; + _result[13] = _a[ 7]; + _result[ 2] = _a[ 8]; + _result[ 6] = _a[ 9]; + _result[10] = _a[10]; + _result[14] = _a[11]; + _result[ 3] = _a[12]; + _result[ 7] = _a[13]; + _result[11] = _a[14]; + _result[15] = _a[15]; + } + + /// Convert LH to RH projection matrix and vice versa. + inline void mtxProjFlipHandedness(float* _dst, const float* _src) + { + _dst[ 0] = -_src[ 0]; + _dst[ 1] = -_src[ 1]; + _dst[ 2] = -_src[ 2]; + _dst[ 3] = -_src[ 3]; + _dst[ 4] = _src[ 4]; + _dst[ 5] = _src[ 5]; + _dst[ 6] = _src[ 6]; + _dst[ 7] = _src[ 7]; + _dst[ 8] = -_src[ 8]; + _dst[ 9] = -_src[ 9]; + _dst[10] = -_src[10]; + _dst[11] = -_src[11]; + _dst[12] = _src[12]; + _dst[13] = _src[13]; + _dst[14] = _src[14]; + _dst[15] = _src[15]; + } + + /// Convert LH to RH view matrix and vice versa. + inline void mtxViewFlipHandedness(float* _dst, const float* _src) + { + _dst[ 0] = -_src[ 0]; + _dst[ 1] = _src[ 1]; + _dst[ 2] = -_src[ 2]; + _dst[ 3] = _src[ 3]; + _dst[ 4] = -_src[ 4]; + _dst[ 5] = _src[ 5]; + _dst[ 6] = -_src[ 6]; + _dst[ 7] = _src[ 7]; + _dst[ 8] = -_src[ 8]; + _dst[ 9] = _src[ 9]; + _dst[10] = -_src[10]; + _dst[11] = _src[11]; + _dst[12] = -_src[12]; + _dst[13] = _src[13]; + _dst[14] = -_src[14]; + _dst[15] = _src[15]; + } + + inline void calcNormal(float _result[3], float _va[3], float _vb[3], float _vc[3]) + { + float ba[3]; + vec3Sub(ba, _vb, _va); + + float ca[3]; + vec3Sub(ca, _vc, _va); + + float baxca[3]; + vec3Cross(baxca, ba, ca); + + vec3Norm(_result, baxca); + } + + inline void calcPlane(float _result[4], float _va[3], float _vb[3], float _vc[3]) + { + float normal[3]; + calcNormal(normal, _va, _vb, _vc); + + _result[0] = normal[0]; + _result[1] = normal[1]; + _result[2] = normal[2]; + _result[3] = -vec3Dot(normal, _va); + } + +} // namespace bx diff --git a/3rdparty/bx/include/bx/inline/mpscqueue.inl b/3rdparty/bx/include/bx/inline/mpscqueue.inl index 0216b509788..7a336788607 100644 --- a/3rdparty/bx/include/bx/inline/mpscqueue.inl +++ b/3rdparty/bx/include/bx/inline/mpscqueue.inl @@ -10,7 +10,8 @@ namespace bx { template <typename Ty> - inline MpScUnboundedQueueT<Ty>::MpScUnboundedQueueT() + inline MpScUnboundedQueueT<Ty>::MpScUnboundedQueueT(AllocatorI* _allocator) + : m_queue(_allocator) { } @@ -39,7 +40,8 @@ namespace bx } template <typename Ty> - inline MpScUnboundedBlockingQueue<Ty>::MpScUnboundedBlockingQueue() + inline MpScUnboundedBlockingQueue<Ty>::MpScUnboundedBlockingQueue(AllocatorI* _allocator) + : m_queue(_allocator) { } diff --git a/3rdparty/bx/include/bx/inline/pixelformat.inl b/3rdparty/bx/include/bx/inline/pixelformat.inl index cd4689224be..682417d7162 100644 --- a/3rdparty/bx/include/bx/inline/pixelformat.inl +++ b/3rdparty/bx/include/bx/inline/pixelformat.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -924,8 +924,8 @@ namespace bx _dst[3] = float( ( (packed>>30) & 0x3) ) / 3.0f; } - // R11G11B10F - inline void packR11G11B10F(void* _dst, const float* _src) + // RG11B10F + inline void packRG11B10F(void* _dst, const float* _src) { *( (uint32_t*)_dst) = 0 | ( (halfFromFloat(_src[0])>> 4) & 0x7ff) @@ -934,7 +934,7 @@ namespace bx ; } - inline void unpackR11G11B10F(float* _dst, const void* _src) + inline void unpackRG11B10F(float* _dst, const void* _src) { uint32_t packed = *( (const uint32_t*)_src); _dst[0] = halfToFloat( (packed<< 4) & 0x7ff0); diff --git a/3rdparty/bx/include/bx/inline/readerwriter.inl b/3rdparty/bx/include/bx/inline/readerwriter.inl index c2eb72a9ed5..dcdd8128da3 100644 --- a/3rdparty/bx/include/bx/inline/readerwriter.inl +++ b/3rdparty/bx/include/bx/inline/readerwriter.inl @@ -29,6 +29,10 @@ namespace bx { } + inline ProcessOpenI::~ProcessOpenI() + { + } + inline CloserI::~CloserI() { } @@ -196,10 +200,10 @@ namespace bx inline MemoryWriter::MemoryWriter(MemoryBlockI* _memBlock) : m_memBlock(_memBlock) - , m_data(NULL) - , m_pos(0) - , m_top(0) - , m_size(0) + , m_data(NULL) + , m_pos(0) + , m_top(0) + , m_size(0) { } @@ -293,6 +297,16 @@ namespace bx return _writer->write(_data, _size, _err); } + inline int32_t write(WriterI* _writer, const char* _str, Error* _err) + { + return write(_writer, _str, strLen(_str), _err); + } + + inline int32_t write(WriterI* _writer, const StringView& _str, Error* _err) + { + return write(_writer, _str.getPtr(), _str.getLength(), _err); + } + inline int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size, Error* _err) { BX_ERROR_SCOPE(_err); @@ -377,11 +391,19 @@ namespace bx inline int64_t getSize(SeekerI* _seeker) { int64_t offset = _seeker->seek(); - int64_t size = _seeker->seek(0, Whence::End); + int64_t size = _seeker->seek(0, Whence::End); _seeker->seek(offset, Whence::Begin); return size; } + inline int64_t getRemain(SeekerI* _seeker) + { + int64_t offset = _seeker->seek(); + int64_t size = _seeker->seek(0, Whence::End); + _seeker->seek(offset, Whence::Begin); + return size-offset; + } + inline int32_t peek(ReaderSeekerI* _reader, void* _data, int32_t _size, Error* _err) { BX_ERROR_SCOPE(_err); @@ -432,18 +454,24 @@ namespace bx return 0; } - inline bool open(ReaderOpenI* _reader, const char* _filePath, Error* _err) + inline bool open(ReaderOpenI* _reader, const FilePath& _filePath, Error* _err) { BX_ERROR_USE_TEMP_WHEN_NULL(_err); return _reader->open(_filePath, _err); } - inline bool open(WriterOpenI* _writer, const char* _filePath, bool _append, Error* _err) + inline bool open(WriterOpenI* _writer, const FilePath& _filePath, bool _append, Error* _err) { BX_ERROR_USE_TEMP_WHEN_NULL(_err); return _writer->open(_filePath, _append, _err); } + inline bool open(ProcessOpenI* _process, const FilePath& _filePath, const StringView& _args, Error* _err) + { + BX_ERROR_USE_TEMP_WHEN_NULL(_err); + return _process->open(_filePath, _args, _err); + } + inline void close(CloserI* _reader) { _reader->close(); diff --git a/3rdparty/bx/include/bx/inline/rng.inl b/3rdparty/bx/include/bx/inline/rng.inl index 11b466dadb3..df6c8262c70 100644 --- a/3rdparty/bx/include/bx/inline/rng.inl +++ b/3rdparty/bx/include/bx/inline/rng.inl @@ -28,25 +28,6 @@ namespace bx return (m_z<<16)+m_w; } - inline RngFib::RngFib(uint32_t _a, uint32_t _b) - : m_a(_a) - , m_b(_b) - { - } - - inline void RngFib::reset(uint32_t _a, uint32_t _b) - { - m_a = _a; - m_b = _b; - } - - inline uint32_t RngFib::gen() - { - m_b = m_a+m_b; - m_a = m_b-m_a; - return m_a; - } - inline RngShr3::RngShr3(uint32_t _jsr) : m_jsr(_jsr) { @@ -81,7 +62,7 @@ namespace bx template <typename Rng> inline void randUnitCircle(float _result[3], Rng* _rng) { - const float angle = frnd(_rng) * pi * 2.0f; + const float angle = frnd(_rng) * kPi2; _result[0] = fcos(angle); _result[1] = 0.0f; @@ -92,7 +73,7 @@ namespace bx inline void randUnitSphere(float _result[3], Rng* _rng) { const float rand0 = frnd(_rng) * 2.0f - 1.0f; - const float rand1 = frnd(_rng) * pi * 2.0f; + const float rand1 = frnd(_rng) * kPi2; const float sqrtf1 = fsqrt(1.0f - rand0*rand0); _result[0] = sqrtf1 * fcos(rand1); @@ -140,7 +121,7 @@ namespace bx tt = 2.0f * tt - 1.0f; const float phi = (ii + 0.5f) / _num; - const float phirad = phi * 2.0f * pi; + const float phirad = phi * kPi2; const float st = fsqrt(1.0f-tt*tt) * _scale; float* xyz = (float*)data; diff --git a/3rdparty/bx/include/bx/inline/simd128_langext.inl b/3rdparty/bx/include/bx/inline/simd128_langext.inl index c89e6123349..9fa3f410bff 100644 --- a/3rdparty/bx/include/bx/inline/simd128_langext.inl +++ b/3rdparty/bx/include/bx/inline/simd128_langext.inl @@ -1,44 +1,11 @@ /* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#ifndef BX_SIMD128_LANGEXT_H_HEADER_GUARD -#define BX_SIMD128_LANGEXT_H_HEADER_GUARD - -#define simd_rcp simd_rcp_ni -#define simd_orx simd_orx_ni -#define simd_orc simd_orc_ni -#define simd_neg simd_neg_ni -#define simd_madd simd_madd_ni -#define simd_nmsub simd_nmsub_ni -#define simd_div_nr simd_div_nr_ni -#define simd_selb simd_selb_ni -#define simd_sels simd_sels_ni -#define simd_not simd_not_ni -#define simd_abs simd_abs_ni -#define simd_clamp simd_clamp_ni -#define simd_lerp simd_lerp_ni -#define simd_rcp_est simd_rcp_ni -#define simd_rsqrt simd_rsqrt_ni -#define simd_rsqrt_nr simd_rsqrt_nr_ni -#define simd_rsqrt_carmack simd_rsqrt_carmack_ni -#define simd_sqrt_nr simd_sqrt_nr_ni -#define simd_log2 simd_log2_ni -#define simd_exp2 simd_exp2_ni -#define simd_pow simd_pow_ni -#define simd_cross3 simd_cross3_ni -#define simd_normalize3 simd_normalize3_ni -#define simd_dot3 simd_dot3_ni -#define simd_dot simd_dot_ni -#define simd_ceil simd_ceil_ni -#define simd_floor simd_floor_ni -#define simd_min simd_min_ni -#define simd_max simd_max_ni -#define simd_imin simd_imin_ni -#define simd_imax simd_imax_ni - -#include "simd_ni.inl" +#ifndef BX_SIMD_T_H_HEADER_GUARD +# error "Must be included from bx/simd_t.h!" +#endif // BX_SIMD_T_H_HEADER_GUARD namespace bx { @@ -46,13 +13,13 @@ namespace bx #define ELEMy 1 #define ELEMz 2 #define ELEMw 3 -#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - template<> \ - BX_SIMD_FORCE_INLINE simd128_langext_t simd_swiz_##_x##_y##_z##_w(simd128_langext_t _a) \ - { \ - simd128_langext_t result; \ +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<> \ + BX_SIMD_FORCE_INLINE simd128_langext_t simd_swiz_##_x##_y##_z##_w(simd128_langext_t _a) \ + { \ + simd128_langext_t result; \ result.vf = __builtin_shufflevector(_a.vf, _a.vf, ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w); \ - return result; \ + return result; \ } #include "simd128_swizzle.inl" @@ -63,27 +30,27 @@ namespace bx #undef ELEMy #undef ELEMx -#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ - template<> \ +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ + template<> \ BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_langext_t _test) \ - { \ - uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ - | ( (_test.uxyzw[2]>>31)<<2) \ - | ( (_test.uxyzw[1]>>31)<<1) \ - | ( _test.uxyzw[0]>>31) \ - ; \ - return 0 != (tmp&(_mask) ); \ - } \ - \ - template<> \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return 0 != (tmp&(_mask) ); \ + } \ + \ + template<> \ BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_langext_t _test) \ - { \ - uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ - | ( (_test.uxyzw[2]>>31)<<2) \ - | ( (_test.uxyzw[1]>>31)<<1) \ - | ( _test.uxyzw[0]>>31) \ - ; \ - return (_mask) == (tmp&(_mask) ); \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return (_mask) == (tmp&(_mask) ); \ } BX_SIMD128_IMPLEMENT_TEST(x , 0x1); @@ -145,7 +112,7 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); } template<> - BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_yBxA(simd128_langext_t _a, simd128_langext_t _b) + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_AxBy(simd128_langext_t _a, simd128_langext_t _b) { simd128_langext_t result; result.vf = __builtin_shufflevector(_a.vf, _b.vf, 1, 5, 0, 4); @@ -508,8 +475,192 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); return result; } + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_rcp(simd128_langext_t _a) + { + return simd_rcp_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_orx(simd128_langext_t _a) + { + return simd_orx_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_orc(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_orc_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_neg(simd128_langext_t _a) + { + return simd_neg_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_madd(simd128_langext_t _a, simd128_langext_t _b, simd128_langext_t _c) + { + return simd_madd_ni(_a, _b, _c); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_nmsub(simd128_langext_t _a, simd128_langext_t _b, simd128_langext_t _c) + { + return simd_nmsub_ni(_a, _b, _c); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_div_nr(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_div_nr_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_selb(simd128_langext_t _mask, simd128_langext_t _a, simd128_langext_t _b) + { + return simd_selb_ni(_mask, _a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_sels(simd128_langext_t _test, simd128_langext_t _a, simd128_langext_t _b) + { + return simd_sels_ni(_test, _a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_not(simd128_langext_t _a) + { + return simd_not_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_abs(simd128_langext_t _a) + { + return simd_abs_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_clamp(simd128_langext_t _a, simd128_langext_t _min, simd128_langext_t _max) + { + return simd_clamp_ni(_a, _min, _max); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_lerp(simd128_langext_t _a, simd128_langext_t _b, simd128_langext_t _s) + { + return simd_lerp_ni(_a, _b, _s); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_rcp_est(simd128_langext_t _a) + { + return simd_rcp_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_rsqrt(simd128_langext_t _a) + { + return simd_rsqrt_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_rsqrt_nr(simd128_langext_t _a) + { + return simd_rsqrt_nr_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_rsqrt_carmack(simd128_langext_t _a) + { + return simd_rsqrt_carmack_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_sqrt_nr(simd128_langext_t _a) + { + return simd_sqrt_nr_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_log2(simd128_langext_t _a) + { + return simd_log2_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_exp2(simd128_langext_t _a) + { + return simd_exp2_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_pow(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_pow_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_cross3(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_cross3_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_normalize3(simd128_langext_t _a) + { + return simd_normalize3_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_dot3(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_dot3_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_dot(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_dot_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_ceil(simd128_langext_t _a) + { + return simd_ceil_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_floor(simd128_langext_t _a) + { + return simd_floor_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_min(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_min_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_max(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_max_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_imin(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_imin_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_imax(simd128_langext_t _a, simd128_langext_t _b) + { + return simd_imax_ni(_a, _b); + } + typedef simd128_langext_t simd128_t; } // namespace bx - -#endif // BX_SIMD128_LANGEXT_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/inline/simd128_neon.inl b/3rdparty/bx/include/bx/inline/simd128_neon.inl index 1dd0d1f12b2..356b7c79901 100644 --- a/3rdparty/bx/include/bx/inline/simd128_neon.inl +++ b/3rdparty/bx/include/bx/inline/simd128_neon.inl @@ -1,41 +1,11 @@ /* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#ifndef BX_SIMD128_NEON_H_HEADER_GUARD -#define BX_SIMD128_NEON_H_HEADER_GUARD - -#define simd_rcp simd_rcp_ni -#define simd_orx simd_orx_ni -#define simd_orc simd_orc_ni -#define simd_neg simd_neg_ni -#define simd_madd simd_madd_ni -#define simd_nmsub simd_nmsub_ni -#define simd_div_nr simd_div_nr_ni -#define simd_div simd_div_nr_ni -#define simd_selb simd_selb_ni -#define simd_sels simd_sels_ni -#define simd_not simd_not_ni -#define simd_abs simd_abs_ni -#define simd_clamp simd_clamp_ni -#define simd_lerp simd_lerp_ni -#define simd_rsqrt simd_rsqrt_ni -#define simd_rsqrt_nr simd_rsqrt_nr_ni -#define simd_rsqrt_carmack simd_rsqrt_carmack_ni -#define simd_sqrt_nr simd_sqrt_nr_ni -#define simd_sqrt simd_sqrt_nr_ni -#define simd_log2 simd_log2_ni -#define simd_exp2 simd_exp2_ni -#define simd_pow simd_pow_ni -#define simd_cross3 simd_cross3_ni -#define simd_normalize3 simd_normalize3_ni -#define simd_dot3 simd_dot3_ni -#define simd_dot simd_dot_ni -#define simd_ceil simd_ceil_ni -#define simd_floor simd_floor_ni - -#include "simd_ni.inl" +#ifndef BX_SIMD_T_H_HEADER_GUARD +# error "Must be included from bx/simd_t.h!" +#endif // BX_SIMD_T_H_HEADER_GUARD namespace bx { @@ -43,10 +13,10 @@ namespace bx #define ELEMy 1 #define ELEMz 2 #define ELEMw 3 -#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - template<> \ - BX_SIMD_FORCE_INLINE simd128_neon_t simd_swiz_##_x##_y##_z##_w(simd128_neon_t _a) \ - { \ +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<> \ + BX_SIMD_FORCE_INLINE simd128_neon_t simd_swiz_##_x##_y##_z##_w(simd128_neon_t _a) \ + { \ return __builtin_shuffle(_a, (uint32x4_t){ ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w }); \ } @@ -58,19 +28,19 @@ namespace bx #undef ELEMy #undef ELEMx -#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _swizzle) \ - template<> \ +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _swizzle) \ + template<> \ BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_neon_t _test) \ - { \ - const simd128_neon_t tmp0 = simd_swiz_##_swizzle(_test); \ - return simd_test_any_ni(tmp0); \ - } \ - \ - template<> \ + { \ + const simd128_neon_t tmp0 = simd_swiz_##_swizzle(_test); \ + return simd_test_any_ni(tmp0); \ + } \ + \ + template<> \ BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_neon_t _test) \ - { \ - const simd128_neon_t tmp0 = simd_swiz_##_swizzle(_test); \ - return simd_test_all_ni(tmp0); \ + { \ + const simd128_neon_t tmp0 = simd_swiz_##_swizzle(_test); \ + return simd_test_all_ni(tmp0); \ } BX_SIMD128_IMPLEMENT_TEST(x, xxxx); @@ -132,7 +102,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww); } template<> - BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_yBxA(simd128_neon_t _a, simd128_neon_t _b) + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_AxBy(simd128_neon_t _a, simd128_neon_t _b) { return __builtin_shuffle(_a, _b, (uint32x4_t){ 1, 5, 0, 4 }); } @@ -455,18 +425,6 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww); } template<> - BX_SIMD_FORCE_INLINE simd128_neon_t simd_madd(simd128_neon_t _a, simd128_neon_t _b, simd128_neon_t _c) - { - return vmlaq_f32(_c, _a, _b); - } - - template<> - BX_SIMD_FORCE_INLINE simd128_neon_t simd_nmsub(simd128_neon_t _a, simd128_neon_t _b, simd128_neon_t _c) - { - return vmlsq_f32(_c, _a, _b); - } - - template<> BX_SIMD_FORCE_INLINE simd128_neon_t simd_icmpeq(simd128_neon_t _a, simd128_neon_t _b) { const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); @@ -555,8 +513,174 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww); return simd_shuf_yBwD_ni(_a, _b); } + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_rcp(simd128_neon_t _a) + { + return simd_rcp_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_orx(simd128_neon_t _a) + { + return simd_orx_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_orc(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_orc_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_neg(simd128_neon_t _a) + { + return simd_neg_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_madd(simd128_neon_t _a, simd128_neon_t _b, simd128_neon_t _c) + { + return simd_madd_ni(_a, _b, _c); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_nmsub(simd128_neon_t _a, simd128_neon_t _b, simd128_neon_t _c) + { + return simd_nmsub_ni(_a, _b, _c); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_div_nr(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_div_nr_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_div(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_div_nr_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_selb(simd128_neon_t _mask, simd128_neon_t _a, simd128_neon_t _b) + { + return simd_selb_ni(_mask, _a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_sels(simd128_neon_t _test, simd128_neon_t _a, simd128_neon_t _b) + { + return simd_sels_ni(_test, _a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_not(simd128_neon_t _a) + { + return simd_not_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_abs(simd128_neon_t _a) + { + return simd_abs_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_clamp(simd128_neon_t _a, simd128_neon_t _min, simd128_neon_t _max) + { + return simd_clamp_ni(_a, _min, _max); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_lerp(simd128_neon_t _a, simd128_neon_t _b, simd128_neon_t _s) + { + return simd_lerp_ni(_a, _b, _s); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_rsqrt(simd128_neon_t _a) + { + return simd_rsqrt_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_rsqrt_nr(simd128_neon_t _a) + { + return simd_rsqrt_nr_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_rsqrt_carmack(simd128_neon_t _a) + { + return simd_rsqrt_carmack_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_sqrt_nr(simd128_neon_t _a) + { + return simd_sqrt_nr_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_sqrt(simd128_neon_t _a) + { + return simd_sqrt_nr_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_log2(simd128_neon_t _a) + { + return simd_log2_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_exp2(simd128_neon_t _a) + { + return simd_exp2_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_pow(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_pow_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_cross3(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_cross3_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_normalize3(simd128_neon_t _a) + { + return simd_normalize3_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_dot3(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_dot3_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_dot(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_dot_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_ceil(simd128_neon_t _a) + { + return simd_ceil_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_floor(simd128_neon_t _a) + { + return simd_floor_ni(_a); + } + typedef simd128_neon_t simd128_t; } // namespace bx - -#endif // BX_SIMD128_NEON_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/inline/simd128_ref.inl b/3rdparty/bx/include/bx/inline/simd128_ref.inl index e85ae14c979..0ef8f68b1c1 100644 --- a/3rdparty/bx/include/bx/inline/simd128_ref.inl +++ b/3rdparty/bx/include/bx/inline/simd128_ref.inl @@ -1,41 +1,11 @@ /* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#ifndef BX_SIMD128_REF_H_HEADER_GUARD -#define BX_SIMD128_REF_H_HEADER_GUARD - -#define simd_shuf_xAzC simd_shuf_xAzC_ni -#define simd_shuf_yBwD simd_shuf_yBwD_ni -#define simd_rcp simd_rcp_ni -#define simd_orx simd_orx_ni -#define simd_orc simd_orc_ni -#define simd_neg simd_neg_ni -#define simd_madd simd_madd_ni -#define simd_nmsub simd_nmsub_ni -#define simd_div_nr simd_div_nr_ni -#define simd_selb simd_selb_ni -#define simd_sels simd_sels_ni -#define simd_not simd_not_ni -#define simd_abs simd_abs_ni -#define simd_clamp simd_clamp_ni -#define simd_lerp simd_lerp_ni -#define simd_rsqrt simd_rsqrt_ni -#define simd_rsqrt_nr simd_rsqrt_nr_ni -#define simd_rsqrt_carmack simd_rsqrt_carmack_ni -#define simd_sqrt_nr simd_sqrt_nr_ni -#define simd_log2 simd_log2_ni -#define simd_exp2 simd_exp2_ni -#define simd_pow simd_pow_ni -#define simd_cross3 simd_cross3_ni -#define simd_normalize3 simd_normalize3_ni -#define simd_dot3 simd_dot3_ni -#define simd_dot simd_dot_ni -#define simd_ceil simd_ceil_ni -#define simd_floor simd_floor_ni - -#include "simd_ni.inl" +#ifndef BX_SIMD_T_H_HEADER_GUARD +# error "Must be included from bx/simd_t.h!" +#endif // BX_SIMD_T_H_HEADER_GUARD namespace bx { @@ -43,16 +13,16 @@ namespace bx #define ELEMy 1 #define ELEMz 2 #define ELEMw 3 -#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - template<> \ +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<> \ BX_SIMD_FORCE_INLINE simd128_ref_t simd_swiz_##_x##_y##_z##_w(simd128_ref_t _a) \ - { \ - simd128_ref_t result; \ - result.ixyzw[0] = _a.ixyzw[ELEM##_x]; \ - result.ixyzw[1] = _a.ixyzw[ELEM##_y]; \ - result.ixyzw[2] = _a.ixyzw[ELEM##_z]; \ - result.ixyzw[3] = _a.ixyzw[ELEM##_w]; \ - return result; \ + { \ + simd128_ref_t result; \ + result.ixyzw[0] = _a.ixyzw[ELEM##_x]; \ + result.ixyzw[1] = _a.ixyzw[ELEM##_y]; \ + result.ixyzw[2] = _a.ixyzw[ELEM##_z]; \ + result.ixyzw[3] = _a.ixyzw[ELEM##_w]; \ + return result; \ } #include "simd128_swizzle.inl" @@ -63,27 +33,27 @@ namespace bx #undef ELEMy #undef ELEMx -#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ - template<> \ +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ + template<> \ BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_ref_t _test) \ - { \ - uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ - | ( (_test.uxyzw[2]>>31)<<2) \ - | ( (_test.uxyzw[1]>>31)<<1) \ - | ( _test.uxyzw[0]>>31) \ - ; \ - return 0 != (tmp&(_mask) ); \ - } \ - \ - template<> \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return 0 != (tmp&(_mask) ); \ + } \ + \ + template<> \ BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_ref_t _test) \ - { \ - uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ - | ( (_test.uxyzw[2]>>31)<<2) \ - | ( (_test.uxyzw[1]>>31)<<1) \ - | ( _test.uxyzw[0]>>31) \ - ; \ - return (_mask) == (tmp&(_mask) ); \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return (_mask) == (tmp&(_mask) ); \ } BX_SIMD128_IMPLEMENT_TEST(x , 0x1); @@ -160,7 +130,7 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); } template<> - BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_yBxA(simd128_ref_t _a, simd128_ref_t _b) + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_AxBy(simd128_ref_t _a, simd128_ref_t _b) { simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[1]; @@ -643,6 +613,207 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); return result; } -} // namespace bx + BX_SIMD_FORCE_INLINE simd128_t simd_zero() + { + return simd_zero<simd128_t>(); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_ld(const void* _ptr) + { + return simd_ld<simd128_t>(_ptr); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_ld(float _x, float _y, float _z, float _w) + { + return simd_ld<simd128_t>(_x, _y, _z, _w); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + return simd_ild<simd128_t>(_x, _y, _z, _w); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_splat(const void* _ptr) + { + return simd_splat<simd128_t>(_ptr); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_splat(float _a) + { + return simd_splat<simd128_t>(_a); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_isplat(uint32_t _a) + { + return simd_isplat<simd128_t>(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_xAzC(simd128_ref_t _a, simd128_ref_t _b) + { + return simd_shuf_xAzC_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_yBwD(simd128_ref_t _a, simd128_ref_t _b) + { + return simd_shuf_yBwD_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_rcp(simd128_ref_t _a) + { + return simd_rcp_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_orx(simd128_ref_t _a) + { + return simd_orx_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_orc(simd128_ref_t _a, simd128_ref_t _b) + { + return simd_orc_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_neg(simd128_ref_t _a) + { + return simd_neg_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_madd(simd128_ref_t _a, simd128_ref_t _b, simd128_ref_t _c) + { + return simd_madd_ni(_a, _b, _c); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_nmsub(simd128_ref_t _a, simd128_ref_t _b, simd128_ref_t _c) + { + return simd_nmsub_ni(_a, _b, _c); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_div_nr(simd128_ref_t _a, simd128_ref_t _b) + { + return simd_div_nr_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_selb(simd128_ref_t _mask, simd128_ref_t _a, simd128_ref_t _b) + { + return simd_selb_ni(_mask, _a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_sels(simd128_ref_t _test, simd128_ref_t _a, simd128_ref_t _b) + { + return simd_sels_ni(_test, _a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_not(simd128_ref_t _a) + { + return simd_not_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_abs(simd128_ref_t _a) + { + return simd_abs_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_clamp(simd128_ref_t _a, simd128_ref_t _min, simd128_ref_t _max) + { + return simd_clamp_ni(_a, _min, _max); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_lerp(simd128_ref_t _a, simd128_ref_t _b, simd128_ref_t _s) + { + return simd_lerp_ni(_a, _b, _s); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_rsqrt(simd128_ref_t _a) + { + return simd_rsqrt_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_rsqrt_nr(simd128_ref_t _a) + { + return simd_rsqrt_nr_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_rsqrt_carmack(simd128_ref_t _a) + { + return simd_rsqrt_carmack_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_sqrt_nr(simd128_ref_t _a) + { + return simd_sqrt_nr_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_log2(simd128_ref_t _a) + { + return simd_log2_ni(_a); + } -#endif // BX_SIMD128_REF_H_HEADER_GUARD + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_exp2(simd128_ref_t _a) + { + return simd_exp2_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_pow(simd128_ref_t _a, simd128_ref_t _b) + { + return simd_pow_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_cross3(simd128_ref_t _a, simd128_ref_t _b) + { + return simd_cross3_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_normalize3(simd128_ref_t _a) + { + return simd_normalize3_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_dot3(simd128_ref_t _a, simd128_ref_t _b) + { + return simd_dot3_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_dot(simd128_ref_t _a, simd128_ref_t _b) + { + return simd_dot_ni(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_ceil(simd128_ref_t _a) + { + return simd_ceil_ni(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_floor(simd128_ref_t _a) + { + return simd_floor_ni(_a); + } + +} // namespace bx diff --git a/3rdparty/bx/include/bx/inline/simd128_sse.inl b/3rdparty/bx/include/bx/inline/simd128_sse.inl index b0ed8520ab4..69f37d153c3 100644 --- a/3rdparty/bx/include/bx/inline/simd128_sse.inl +++ b/3rdparty/bx/include/bx/inline/simd128_sse.inl @@ -1,12 +1,11 @@ /* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#ifndef BX_SIMD128_SSE_H_HEADER_GUARD -#define BX_SIMD128_SSE_H_HEADER_GUARD - -#include "simd_ni.inl" +#ifndef BX_SIMD_T_H_HEADER_GUARD +# error "Must be included from bx/simd_t.h!" +#endif // BX_SIMD_T_H_HEADER_GUARD namespace bx { @@ -14,10 +13,10 @@ namespace bx #define ELEMy 1 #define ELEMz 2 #define ELEMw 3 -#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - template<> \ - BX_SIMD_FORCE_INLINE simd128_sse_t simd_swiz_##_x##_y##_z##_w(simd128_sse_t _a) \ - { \ +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<> \ + BX_SIMD_FORCE_INLINE simd128_sse_t simd_swiz_##_x##_y##_z##_w(simd128_sse_t _a) \ + { \ return _mm_shuffle_ps( _a, _a, _MM_SHUFFLE(ELEM##_w, ELEM##_z, ELEM##_y, ELEM##_x ) ); \ } @@ -29,17 +28,17 @@ namespace bx #undef ELEMy #undef ELEMx -#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ - template<> \ +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ + template<> \ BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_sse_t _test) \ - { \ - return 0x0 != (_mm_movemask_ps(_test)&(_mask) ); \ - } \ - \ - template<> \ + { \ + return 0x0 != (_mm_movemask_ps(_test)&(_mask) ); \ + } \ + \ + template<> \ BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_sse_t _test) \ - { \ - return (_mask) == (_mm_movemask_ps(_test)&(_mask) ); \ + { \ + return (_mask) == (_mm_movemask_ps(_test)&(_mask) ); \ } BX_SIMD128_IMPLEMENT_TEST(x , 0x1); @@ -91,7 +90,7 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); } template<> - BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_yBxA(simd128_sse_t _a, simd128_sse_t _b) + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_AxBy(simd128_sse_t _a, simd128_sse_t _b) { return _mm_unpacklo_ps(_b, _a); } @@ -643,5 +642,3 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); typedef simd128_sse_t simd128_t; } // namespace bx - -#endif // BX_SIMD128_SSE_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/inline/simd128_swizzle.inl b/3rdparty/bx/include/bx/inline/simd128_swizzle.inl index 4185be81b60..e734ce91955 100644 --- a/3rdparty/bx/include/bx/inline/simd128_swizzle.inl +++ b/3rdparty/bx/include/bx/inline/simd128_swizzle.inl @@ -1,6 +1,6 @@ /* * Copyright 2010-2015 Branimir Karadzic. All rights reserved. - * License: http://www.opensource.org/licenses/BSD-2-Clause + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ #ifndef BX_SIMD_T_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/inline/simd256_avx.inl b/3rdparty/bx/include/bx/inline/simd256_avx.inl index 5eed77ba3af..c59cc80cfbe 100644 --- a/3rdparty/bx/include/bx/inline/simd256_avx.inl +++ b/3rdparty/bx/include/bx/inline/simd256_avx.inl @@ -1,12 +1,11 @@ /* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#ifndef BX_SIMD256_AVX_H_HEADER_GUARD -#define BX_SIMD256_AVX_H_HEADER_GUARD - -#include "simd_ni.inl" +#ifndef BX_SIMD_T_H_HEADER_GUARD +# error "Must be included from bx/simd_t.h!" +#endif // BX_SIMD_T_H_HEADER_GUARD namespace bx { @@ -73,5 +72,3 @@ namespace bx typedef simd256_avx_t simd256_t; } // namespace bx - -#endif // BX_SIMD256_AVX_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/inline/simd256_ref.inl b/3rdparty/bx/include/bx/inline/simd256_ref.inl index 6d9a5a31ab5..fd8d8897fe9 100644 --- a/3rdparty/bx/include/bx/inline/simd256_ref.inl +++ b/3rdparty/bx/include/bx/inline/simd256_ref.inl @@ -1,12 +1,11 @@ /* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#ifndef BX_SIMD256_REF_H_HEADER_GUARD -#define BX_SIMD256_REF_H_HEADER_GUARD - -#include "simd_ni.inl" +#ifndef BX_SIMD_T_H_HEADER_GUARD +# error "Must be included from bx/simd_t.h!" +#endif // BX_SIMD_T_H_HEADER_GUARD namespace bx { @@ -83,5 +82,3 @@ namespace bx } } // namespace bx - -#endif // BX_SIMD256_REF_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/inline/simd_ni.inl b/3rdparty/bx/include/bx/inline/simd_ni.inl index 95767f25b95..6a0be796b7b 100644 --- a/3rdparty/bx/include/bx/inline/simd_ni.inl +++ b/3rdparty/bx/include/bx/inline/simd_ni.inl @@ -1,11 +1,8 @@ /* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#ifndef BX_SIMD_NI_H_HEADER_GUARD -#define BX_SIMD_NI_H_HEADER_GUARD - namespace bx { template<typename Ty> @@ -554,5 +551,3 @@ namespace bx } } // namespace bx - -#endif // BX_SIMD_NI_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/inline/spscqueue.inl b/3rdparty/bx/include/bx/inline/spscqueue.inl index 7d80f078f2b..7469953be63 100644 --- a/3rdparty/bx/include/bx/inline/spscqueue.inl +++ b/3rdparty/bx/include/bx/inline/spscqueue.inl @@ -10,8 +10,9 @@ namespace bx { // http://drdobbs.com/article/print?articleId=210604448&siteSectionName= - inline SpScUnboundedQueue::SpScUnboundedQueue() - : m_first(new Node(NULL) ) + inline SpScUnboundedQueue::SpScUnboundedQueue(AllocatorI* _allocator) + : m_allocator(_allocator) + , m_first(BX_NEW(m_allocator, Node)(NULL) ) , m_divider(m_first) , m_last(m_first) { @@ -23,19 +24,19 @@ namespace bx { Node* node = m_first; m_first = node->m_next; - delete node; + BX_DELETE(m_allocator, node); } } inline void SpScUnboundedQueue::push(void* _ptr) { - m_last->m_next = new Node( (void*)_ptr); + m_last->m_next = BX_NEW(m_allocator, Node)(_ptr); atomicExchangePtr( (void**)&m_last, m_last->m_next); while (m_first != m_divider) { Node* node = m_first; m_first = m_first->m_next; - delete node; + BX_DELETE(m_allocator, node); } } @@ -68,7 +69,8 @@ namespace bx } template<typename Ty> - inline SpScUnboundedQueueT<Ty>::SpScUnboundedQueueT() + inline SpScUnboundedQueueT<Ty>::SpScUnboundedQueueT(AllocatorI* _allocator) + : m_queue(_allocator) { } @@ -96,7 +98,8 @@ namespace bx } #if BX_CONFIG_SUPPORTS_THREADING - inline SpScBlockingUnboundedQueue::SpScBlockingUnboundedQueue() + inline SpScBlockingUnboundedQueue::SpScBlockingUnboundedQueue(AllocatorI* _allocator) + : m_queue(_allocator) { } @@ -106,7 +109,7 @@ namespace bx inline void SpScBlockingUnboundedQueue::push(void* _ptr) { - m_queue.push( (void*)_ptr); + m_queue.push(_ptr); m_count.post(); } @@ -126,7 +129,8 @@ namespace bx } template<typename Ty> - inline SpScBlockingUnboundedQueueT<Ty>::SpScBlockingUnboundedQueueT() + inline SpScBlockingUnboundedQueueT<Ty>::SpScBlockingUnboundedQueueT(AllocatorI* _allocator) + : m_queue(_allocator) { } diff --git a/3rdparty/bx/include/bx/inline/string.inl b/3rdparty/bx/include/bx/inline/string.inl index 7b6f6500b7c..4ee24003889 100644 --- a/3rdparty/bx/include/bx/inline/string.inl +++ b/3rdparty/bx/include/bx/inline/string.inl @@ -43,8 +43,8 @@ namespace bx { Ty str = _str; typename Ty::size_type startPos = 0; - const typename Ty::size_type fromLen = strnlen(_from); - const typename Ty::size_type toLen = strnlen(_to); + const typename Ty::size_type fromLen = strLen(_from); + const typename Ty::size_type toLen = strLen(_to); while ( (startPos = str.find(_from, startPos) ) != Ty::npos) { str.replace(startPos, fromLen, _to); @@ -64,6 +64,12 @@ namespace bx set(_rhs.m_ptr, _rhs.m_len); } + inline StringView& StringView::operator=(const char* _rhs) + { + set(_rhs); + return *this; + } + inline StringView& StringView::operator=(const StringView& _rhs) { set(_rhs.m_ptr, _rhs.m_len); @@ -75,13 +81,18 @@ namespace bx set(_ptr, _len); } + inline StringView::StringView(const char* _ptr, const char* _term) + { + set(_ptr, _term); + } + inline void StringView::set(const char* _ptr, int32_t _len) { clear(); if (NULL != _ptr) { - int32_t len = strnlen(_ptr, _len); + int32_t len = strLen(_ptr, _len); if (0 != len) { m_len = len; @@ -90,6 +101,16 @@ namespace bx } } + inline void StringView::set(const char* _ptr, const char* _term) + { + set(_ptr, int32_t(_term-_ptr) ); + } + + inline void StringView::set(const StringView& _str) + { + set(_str.m_ptr, _str.m_len); + } + inline void StringView::clear() { m_ptr = ""; @@ -126,26 +147,20 @@ namespace bx inline StringT<AllocatorT>::StringT(const StringT<AllocatorT>& _rhs) : StringView() { - set(_rhs.m_ptr, _rhs.m_len); + set(_rhs); } template<bx::AllocatorI** AllocatorT> inline StringT<AllocatorT>& StringT<AllocatorT>::operator=(const StringT<AllocatorT>& _rhs) { - set(_rhs.m_ptr, _rhs.m_len); + set(_rhs); return *this; } template<bx::AllocatorI** AllocatorT> - inline StringT<AllocatorT>::StringT(const char* _ptr, int32_t _len) - { - set(_ptr, _len); - } - - template<bx::AllocatorI** AllocatorT> inline StringT<AllocatorT>::StringT(const StringView& _rhs) { - set(_rhs.getPtr(), _rhs.getLength() ); + set(_rhs); } template<bx::AllocatorI** AllocatorT> @@ -155,22 +170,22 @@ namespace bx } template<bx::AllocatorI** AllocatorT> - inline void StringT<AllocatorT>::set(const char* _ptr, int32_t _len) + inline void StringT<AllocatorT>::set(const StringView& _str) { clear(); - append(_ptr, _len); + append(_str); } template<bx::AllocatorI** AllocatorT> - inline void StringT<AllocatorT>::append(const char* _ptr, int32_t _len) + inline void StringT<AllocatorT>::append(const StringView& _str) { - if (0 != _len) + if (0 != _str.getLength() ) { int32_t old = m_len; - int32_t len = m_len + strnlen(_ptr, _len); + int32_t len = m_len + strLen(_str); char* ptr = (char*)BX_REALLOC(*AllocatorT, 0 != m_len ? const_cast<char*>(m_ptr) : NULL, len+1); m_len = len; - strlncpy(ptr + old, len-old+1, _ptr, _len); + strCopy(ptr + old, len-old+1, _str); *const_cast<char**>(&m_ptr) = ptr; } diff --git a/3rdparty/bx/include/bx/macros.h b/3rdparty/bx/include/bx/macros.h index 1358507188d..79c624959f0 100644 --- a/3rdparty/bx/include/bx/macros.h +++ b/3rdparty/bx/include/bx/macros.h @@ -68,10 +68,14 @@ # define BX_FUNCTION __PRETTY_FUNCTION__ # define BX_LIKELY(_x) __builtin_expect(!!(_x), 1) # define BX_UNLIKELY(_x) __builtin_expect(!!(_x), 0) -# define BX_NO_INLINE __attribute__( (noinline) ) -# define BX_NO_RETURN __attribute__( (noreturn) ) +# define BX_NO_INLINE __attribute__( (noinline) ) +# define BX_NO_RETURN __attribute__( (noreturn) ) +# if BX_COMPILER_GCC >= 70000 +# define BX_FALLTHROUGH __attribute__( (fallthrough) ) +# else +# define BX_FALLTHROUGH BX_NOOP() +# endif // BX_COMPILER_GCC >= 70000 # define BX_NO_VTABLE -# define BX_OVERRIDE # define BX_PRINTF_ARGS(_format, _args) __attribute__( (format(__printf__, _format, _args) ) ) # if BX_CLANG_HAS_FEATURE(cxx_thread_local) # define BX_THREAD_LOCAL __thread @@ -92,8 +96,8 @@ # define BX_UNLIKELY(_x) (_x) # define BX_NO_INLINE __declspec(noinline) # define BX_NO_RETURN +# define BX_FALLTHROUGH BX_NOOP() # define BX_NO_VTABLE __declspec(novtable) -# define BX_OVERRIDE override # define BX_PRINTF_ARGS(_format, _args) # define BX_THREAD_LOCAL __declspec(thread) # define BX_ATTRIBUTE(_x) @@ -114,7 +118,14 @@ #define BX_NOOP(...) BX_MACRO_BLOCK_BEGIN BX_MACRO_BLOCK_END /// -#define BX_UNUSED_1(_a1) BX_MACRO_BLOCK_BEGIN (void)(true ? (void)0 : ( (void)(_a1) ) ); BX_MACRO_BLOCK_END +#define BX_UNUSED_1(_a1) \ + BX_MACRO_BLOCK_BEGIN \ + BX_PRAGMA_DIAGNOSTIC_PUSH(); \ + /*BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wuseless-cast");*/ \ + (void)(true ? (void)0 : ( (void)(_a1) ) ); \ + BX_PRAGMA_DIAGNOSTIC_POP(); \ + BX_MACRO_BLOCK_END + #define BX_UNUSED_2(_a1, _a2) BX_UNUSED_1(_a1); BX_UNUSED_1(_a2) #define BX_UNUSED_3(_a1, _a2, _a3) BX_UNUSED_2(_a1, _a2); BX_UNUSED_1(_a3) #define BX_UNUSED_4(_a1, _a2, _a3, _a4) BX_UNUSED_3(_a1, _a2, _a3); BX_UNUSED_1(_a4) diff --git a/3rdparty/bx/include/bx/fpumath.h b/3rdparty/bx/include/bx/math.h index b5b319ce047..66b0a51618d 100644 --- a/3rdparty/bx/include/bx/fpumath.h +++ b/3rdparty/bx/include/bx/math.h @@ -9,14 +9,20 @@ #define BX_FPU_MATH_H_HEADER_GUARD #include "bx.h" +#include "uint32_t.h" namespace bx { - extern const float pi; - extern const float invPi; - extern const float piHalf; - extern const float sqrt2; - extern const float huge; + extern const float kPi; + extern const float kPi2; + extern const float kInvPi; + extern const float kPiHalf; + extern const float kSqrt2; + extern const float kInvLogNat2; + extern const float kHuge; + + /// + typedef float (*LerpFn)(float _a, float _b, float _t); /// struct Handness @@ -57,6 +63,9 @@ namespace bx double bitsToDouble(uint64_t _a); /// + uint32_t floatFlip(uint32_t _value); + + /// bool isNan(float _f); /// @@ -108,7 +117,7 @@ namespace bx float fsign(float _a); /// - float fabsolute(float _a); + float fabs(float _a); /// float fsq(float _a); @@ -184,6 +193,12 @@ namespace bx float fgain(float _time, float _gain); /// + float angleDiff(float _a, float _b); + + /// Shortest distance linear interpolation between two angles. + float angleLerp(float _a, float _b, float _t); + + /// void vec3Move(float* _result, const float* _a); /// @@ -246,6 +261,12 @@ namespace bx void vec3TangentFrame(const float* _n, float* _t, float* _b, float _angle); /// + void vec3FromLatLong(float* _vec, float _u, float _v); + + /// + void vec3ToLatLong(float* _u, float* _v, const float* _vec); + + /// void quatIdentity(float* _result); /// @@ -312,7 +333,7 @@ namespace bx void mtxQuatTranslationHMD(float* _result, const float* _quat, const float* _translation); /// - void mtxLookAtLh(float* _result, const float* _eye, const float* _at, const float* _up = NULL);; + void mtxLookAtLh(float* _result, const float* _eye, const float* _at, const float* _up = NULL); /// void mtxLookAtRh(float* _result, const float* _eye, const float* _at, const float* _up = NULL); @@ -321,85 +342,85 @@ namespace bx void mtxLookAt(float* _result, const float* _eye, const float* _at, const float* _up = NULL); /// - void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false); + void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc); /// - void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false); + void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc); /// - void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false); + void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc); /// - void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false); + void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc); /// - void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false); + void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc); /// - void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false); + void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc); /// - void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false); + void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc); /// - void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false); + void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc); /// - void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false); + void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc); /// - void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc = false); + void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc); /// - void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false); + void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); /// - void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false); + void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); /// - void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false); + void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); /// - void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc = false); + void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc); /// - void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false); + void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); /// - void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false); + void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); /// - void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc = false); + void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc); /// - void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false); + void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); /// - void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false); + void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); /// - void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc = false); + void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc); /// - void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false); + void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); /// - void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false); + void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); /// - void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc = false); + void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc); /// - void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false); + void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); /// - void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false); + void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc); /// - void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false); + void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc); /// - void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false); + void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc); /// void mtxRotateX(float* _result, float _ax); @@ -426,6 +447,9 @@ namespace bx void vec3MulMtx(float* _result, const float* _vec, const float* _mat); /// + void vec3MulMtxXyz0(float* _result, const float* _vec, const float* _mat); + + /// void vec3MulMtxH(float* _result, const float* _vec, const float* _mat); /// @@ -471,6 +495,6 @@ namespace bx } // namespace bx -#include "inline/fpumath.inl" +#include "inline/math.inl" #endif // BX_FPU_MATH_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/mpscqueue.h b/3rdparty/bx/include/bx/mpscqueue.h index 0ac8f82915a..1735e83038c 100644 --- a/3rdparty/bx/include/bx/mpscqueue.h +++ b/3rdparty/bx/include/bx/mpscqueue.h @@ -6,6 +6,7 @@ #ifndef BX_MPSCQUEUE_H_HEADER_GUARD #define BX_MPSCQUEUE_H_HEADER_GUARD +#include "allocator.h" #include "mutex.h" #include "spscqueue.h" @@ -22,7 +23,7 @@ namespace bx public: /// - MpScUnboundedQueueT(); + MpScUnboundedQueueT(AllocatorI* _allocator); /// ~MpScUnboundedQueueT(); @@ -52,7 +53,7 @@ namespace bx public: /// - MpScUnboundedBlockingQueue(); + MpScUnboundedBlockingQueue(AllocatorI* _allocator); /// ~MpScUnboundedBlockingQueue(); diff --git a/3rdparty/bx/include/bx/os.h b/3rdparty/bx/include/bx/os.h index 56781b25b0e..3f52856dd3e 100644 --- a/3rdparty/bx/include/bx/os.h +++ b/3rdparty/bx/include/bx/os.h @@ -18,20 +18,6 @@ namespace bx { - struct FileInfo - { - enum Enum - { - Regular, - Directory, - - Count - }; - - uint64_t m_size; - Enum m_type; - }; - /// void sleep(uint32_t _ms); @@ -66,15 +52,6 @@ namespace bx int chdir(const char* _path); /// - char* pwd(char* _buffer, uint32_t _size); - - /// - bool getTempPath(char* _out, uint32_t* _inOutSize); - - /// - bool stat(const char* _filePath, FileInfo& _fileInfo); - - /// void* exec(const char* const* _argv); } // namespace bx diff --git a/3rdparty/bx/include/bx/pixelformat.h b/3rdparty/bx/include/bx/pixelformat.h index 78354e48425..ee2dd15bd31 100644 --- a/3rdparty/bx/include/bx/pixelformat.h +++ b/3rdparty/bx/include/bx/pixelformat.h @@ -6,14 +6,15 @@ #ifndef BX_PIXEL_FORMAT_H_HEADER_GUARD #define BX_PIXEL_FORMAT_H_HEADER_GUARD -#include "fpumath.h" +#include "math.h" #include "uint32_t.h" namespace bx { + /// struct EncodingType { - enum Enum + enum Enum /// { Unorm, Int, @@ -228,9 +229,9 @@ namespace bx void packRgb10A2(void* _dst, const float* _src); void unpackRgb10A2(float* _dst, const void* _src); - // R11G11B10F - void packR11G11B10F(void* _dst, const float* _src); - void unpackR11G11B10F(float* _dst, const void* _src); + // RG11B10F + void packRG11B10F(void* _dst, const float* _src); + void unpackRG11B10F(float* _dst, const void* _src); // RG32F void packRg32F(void* _dst, const float* _src); diff --git a/3rdparty/bx/include/bx/platform.h b/3rdparty/bx/include/bx/platform.h index 7e7591d3cb2..96b9202d704 100644 --- a/3rdparty/bx/include/bx/platform.h +++ b/3rdparty/bx/include/bx/platform.h @@ -46,12 +46,12 @@ // Platform #define BX_PLATFORM_ANDROID 0 -#define BX_PLATFORM_EMSCRIPTEN 0 #define BX_PLATFORM_BSD 0 +#define BX_PLATFORM_EMSCRIPTEN 0 #define BX_PLATFORM_HURD 0 #define BX_PLATFORM_IOS 0 #define BX_PLATFORM_LINUX 0 -#define BX_PLATFORM_NACL 0 +#define BX_PLATFORM_NX 0 #define BX_PLATFORM_OSX 0 #define BX_PLATFORM_PS4 0 #define BX_PLATFORM_QNX 0 @@ -59,7 +59,6 @@ #define BX_PLATFORM_STEAMLINK 0 #define BX_PLATFORM_WINDOWS 0 #define BX_PLATFORM_WINRT 0 -#define BX_PLATFORM_XBOX360 0 #define BX_PLATFORM_XBOXONE 0 // http://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers @@ -143,10 +142,7 @@ #endif // BX_PLATFORM_ // http://sourceforge.net/apps/mediawiki/predef/index.php?title=Operating_Systems -#if defined(_XBOX_VER) -# undef BX_PLATFORM_XBOX360 -# define BX_PLATFORM_XBOX360 1 -#elif defined(_DURANGO) || defined(_XBOX_ONE) +#if defined(_DURANGO) || defined(_XBOX_ONE) # undef BX_PLATFORM_XBOXONE # define BX_PLATFORM_XBOXONE 1 #elif defined(_WIN32) || defined(_WIN64) @@ -181,11 +177,6 @@ # include <sys/cdefs.h> // Defines __BIONIC__ and includes android/api-level.h # undef BX_PLATFORM_ANDROID # define BX_PLATFORM_ANDROID __ANDROID_API__ -#elif defined(__native_client__) -// NaCl compiler defines __linux__ -# include <ppapi/c/pp_macros.h> -# undef BX_PLATFORM_NACL -# define BX_PLATFORM_NACL PPAPI_RELEASE #elif defined(__STEAMLINK__) // SteamLink compiler defines __linux__ # undef BX_PLATFORM_STEAMLINK @@ -223,6 +214,9 @@ #elif defined(__GNU__) # undef BX_PLATFORM_HURD # define BX_PLATFORM_HURD 1 +#elif defined(__NX__) +# undef BX_PLATFORM_NX +# define BX_PLATFORM_NX 1 #endif // #if !BX_CRT_NONE @@ -258,27 +252,27 @@ #define BX_PLATFORM_POSIX (0 \ || BX_PLATFORM_ANDROID \ - || BX_PLATFORM_EMSCRIPTEN \ || BX_PLATFORM_BSD \ + || BX_PLATFORM_EMSCRIPTEN \ || BX_PLATFORM_HURD \ || BX_PLATFORM_IOS \ || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ + || BX_PLATFORM_NX \ || BX_PLATFORM_OSX \ - || BX_PLATFORM_QNX \ - || BX_PLATFORM_STEAMLINK \ || BX_PLATFORM_PS4 \ + || BX_PLATFORM_QNX \ || BX_PLATFORM_RPI \ + || BX_PLATFORM_STEAMLINK \ ) #define BX_PLATFORM_NONE !(0 \ || BX_PLATFORM_ANDROID \ - || BX_PLATFORM_EMSCRIPTEN \ || BX_PLATFORM_BSD \ + || BX_PLATFORM_EMSCRIPTEN \ || BX_PLATFORM_HURD \ || BX_PLATFORM_IOS \ || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ + || BX_PLATFORM_NX \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ || BX_PLATFORM_QNX \ @@ -286,7 +280,6 @@ || BX_PLATFORM_STEAMLINK \ || BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE \ ) @@ -321,22 +314,23 @@ #if BX_PLATFORM_ANDROID # define BX_PLATFORM_NAME "Android " \ BX_STRINGIZE(BX_PLATFORM_ANDROID) +#elif BX_PLATFORM_BSD +# define BX_PLATFORM_NAME "BSD" #elif BX_PLATFORM_EMSCRIPTEN # define BX_PLATFORM_NAME "asm.js " \ BX_STRINGIZE(__EMSCRIPTEN_major__) "." \ BX_STRINGIZE(__EMSCRIPTEN_minor__) "." \ BX_STRINGIZE(__EMSCRIPTEN_tiny__) -#elif BX_PLATFORM_BSD -# define BX_PLATFORM_NAME "BSD" #elif BX_PLATFORM_HURD # define BX_PLATFORM_NAME "Hurd" #elif BX_PLATFORM_IOS # define BX_PLATFORM_NAME "iOS" #elif BX_PLATFORM_LINUX # define BX_PLATFORM_NAME "Linux" -#elif BX_PLATFORM_NACL -# define BX_PLATFORM_NAME "NaCl " \ - BX_STRINGIZE(BX_PLATFORM_NACL) +#elif BX_PLATFORM_NONE +# define BX_PLATFORM_NAME "None" +#elif BX_PLATFORM_NX +# define BX_PLATFORM_NAME "NX" #elif BX_PLATFORM_OSX # define BX_PLATFORM_NAME "OSX" #elif BX_PLATFORM_PS4 @@ -351,12 +345,8 @@ # define BX_PLATFORM_NAME "Windows" #elif BX_PLATFORM_WINRT # define BX_PLATFORM_NAME "WinRT" -#elif BX_PLATFORM_XBOX360 -# define BX_PLATFORM_NAME "Xbox 360" #elif BX_PLATFORM_XBOXONE # define BX_PLATFORM_NAME "Xbox One" -#elif BX_PLATFORM_NONE -# define BX_PLATFORM_NAME "None" #else # error "Unknown BX_PLATFORM!" #endif // BX_PLATFORM_ diff --git a/3rdparty/bx/include/bx/process.h b/3rdparty/bx/include/bx/process.h new file mode 100644 index 00000000000..47a1119ea37 --- /dev/null +++ b/3rdparty/bx/include/bx/process.h @@ -0,0 +1,75 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_PROCESS_H_HEADER_GUARD +#define BX_PROCESS_H_HEADER_GUARD + +#include "readerwriter.h" + +namespace bx +{ + /// + class ProcessReader + : public ProcessOpenI + , public CloserI + , public ReaderI + { + public: + /// + ProcessReader(); + + /// + ~ProcessReader(); + + /// + virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) override; + + /// + virtual void close() override; + + /// + virtual int32_t read(void* _data, int32_t _size, Error* _err) override; + + /// + int32_t getExitCode() const; + + private: + void* m_file; + int32_t m_exitCode; + }; + + /// + class ProcessWriter + : public ProcessOpenI + , public CloserI + , public WriterI + { + public: + /// + ProcessWriter(); + + /// + ~ProcessWriter(); + + /// + virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) override; + + /// + virtual void close() override; + + /// + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override; + + /// + int32_t getExitCode() const; + + private: + void* m_file; + int32_t m_exitCode; + }; + +} // namespace bx + +#endif // BX_PROCESS_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/readerwriter.h b/3rdparty/bx/include/bx/readerwriter.h index 7fda6f08111..68c8227b540 100644 --- a/3rdparty/bx/include/bx/readerwriter.h +++ b/3rdparty/bx/include/bx/readerwriter.h @@ -8,6 +8,8 @@ #include "allocator.h" #include "error.h" +#include "endian.h" +#include "filepath.h" #include "uint32_t.h" BX_ERROR_RESULT(BX_ERROR_READERWRITER_OPEN, BX_MAKEFOURCC('R', 'W', 0, 1) ); @@ -64,14 +66,21 @@ namespace bx struct BX_NO_VTABLE ReaderOpenI { virtual ~ReaderOpenI() = 0; - virtual bool open(const char* _filePath, Error* _err) = 0; + virtual bool open(const FilePath& _filePath, Error* _err) = 0; }; /// struct BX_NO_VTABLE WriterOpenI { virtual ~WriterOpenI() = 0; - virtual bool open(const char* _filePath, bool _append, Error* _err) = 0; + virtual bool open(const FilePath& _filePath, bool _append, Error* _err) = 0; + }; + + /// + struct BX_NO_VTABLE ProcessOpenI + { + virtual ~ProcessOpenI() = 0; + virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) = 0; }; /// @@ -109,10 +118,10 @@ namespace bx virtual ~StaticMemoryBlock(); /// - virtual void* more(uint32_t _size = 0); + virtual void* more(uint32_t _size = 0) override; /// - virtual uint32_t getSize() BX_OVERRIDE; + virtual uint32_t getSize() override; private: void* m_data; @@ -130,10 +139,10 @@ namespace bx virtual ~MemoryBlock(); /// - virtual void* more(uint32_t _size = 0) BX_OVERRIDE; + virtual void* more(uint32_t _size = 0) override; /// - virtual uint32_t getSize() BX_OVERRIDE; + virtual uint32_t getSize() override; private: AllocatorI* m_allocator; @@ -141,7 +150,7 @@ namespace bx uint32_t m_size; }; - /// + /// Sizer writer. Dummy writter that only counts number of bytes written into it. class SizerWriter : public WriterSeekerI { public: @@ -152,10 +161,10 @@ namespace bx virtual ~SizerWriter(); /// - virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE; + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override; /// - virtual int32_t write(const void* /*_data*/, int32_t _size, Error* _err) BX_OVERRIDE; + virtual int32_t write(const void* /*_data*/, int32_t _size, Error* _err) override; private: int64_t m_pos; @@ -173,10 +182,10 @@ namespace bx virtual ~MemoryReader(); /// - virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE; + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override; /// - virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE; + virtual int32_t read(void* _data, int32_t _size, Error* _err) override; /// const uint8_t* getDataPtr() const; @@ -204,10 +213,10 @@ namespace bx virtual ~MemoryWriter(); /// - virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE; + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override; /// - virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE; + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override; private: MemoryBlockI* m_memBlock; @@ -217,7 +226,7 @@ namespace bx int64_t m_size; }; - /// + /// Static (fixed size) memory block writer. class StaticMemoryBlockWriter : public MemoryWriter { public: @@ -246,6 +255,12 @@ namespace bx /// Write data. int32_t write(WriterI* _writer, const void* _data, int32_t _size, Error* _err = NULL); + /// Write C string. + inline int32_t write(WriterI* _writer, const char* _str, Error* _err = NULL); + + /// Write string view. + inline int32_t write(WriterI* _writer, const StringView& _str, Error* _err = NULL); + /// Write repeat the same value. int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size, Error* _err = NULL); @@ -273,6 +288,9 @@ namespace bx /// Returns size of file. int64_t getSize(SeekerI* _seeker); + /// Returns remaining size from current offset of file. + int64_t getRemain(SeekerI* _seeker); + /// Peek data. int32_t peek(ReaderSeekerI* _reader, void* _data, int32_t _size, Error* _err = NULL); @@ -286,13 +304,16 @@ namespace bx /// Align writer stream (pads stream with zeros). int32_t align(WriterSeekerI* _writer, uint32_t _alignment, Error* _err = NULL); - /// - bool open(ReaderOpenI* _reader, const char* _filePath, Error* _err = NULL); + /// Open for read. + bool open(ReaderOpenI* _reader, const FilePath& _filePath, Error* _err = NULL); - /// - bool open(WriterOpenI* _writer, const char* _filePath, bool _append = false, Error* _err = NULL); + /// Open fro write. + bool open(WriterOpenI* _writer, const FilePath& _filePath, bool _append = false, Error* _err = NULL); - /// + /// Open process. + bool open(ProcessOpenI* _process, const FilePath& _filePath, const StringView& _args, Error* _err = NULL); + + /// Close. void close(CloserI* _reader); } // namespace bx diff --git a/3rdparty/bx/include/bx/rng.h b/3rdparty/bx/include/bx/rng.h index 56d7674957c..22fff273ebe 100644 --- a/3rdparty/bx/include/bx/rng.h +++ b/3rdparty/bx/include/bx/rng.h @@ -7,7 +7,7 @@ #define BX_RNG_H_HEADER_GUARD #include "bx.h" -#include "fpumath.h" +#include "math.h" #include "uint32_t.h" namespace bx @@ -30,24 +30,6 @@ namespace bx uint32_t m_w; }; - /// George Marsaglia's FIB - class RngFib - { - public: - /// - RngFib(uint32_t _a = 9983651, uint32_t _b = 95746118); - - /// - void reset(uint32_t _a = 9983651, uint32_t _b = 95746118); - - /// - uint32_t gen(); - - private: - uint32_t m_a; - uint32_t m_b; - }; - /// George Marsaglia's SHR3 class RngShr3 { diff --git a/3rdparty/bx/include/bx/settings.h b/3rdparty/bx/include/bx/settings.h new file mode 100644 index 00000000000..018e4c3504a --- /dev/null +++ b/3rdparty/bx/include/bx/settings.h @@ -0,0 +1,61 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_SETTINGS_H_HEADER_GUARD +#define BX_SETTINGS_H_HEADER_GUARD + +#include "allocator.h" +#include "readerwriter.h" +#include "string.h" + +namespace bx +{ + /// + class Settings + { + public: + /// + Settings(AllocatorI* _allocator, const void* _data = NULL, uint32_t _len = 0); + + /// + ~Settings(); + + /// + void clear(); + + /// + void load(const void* _data, uint32_t _len); + + /// + const char* get(const StringView& _name) const; + + /// + void set(const StringView& _name, const StringView& _value = ""); + + /// + void remove(const StringView& _name) const; + + /// + int32_t read(ReaderSeekerI* _reader, Error* _err); + + /// + int32_t write(WriterI* _writer, Error* _err) const; + + private: + Settings(); + + AllocatorI* m_allocator; + void* m_ini; + }; + + /// + int32_t read(ReaderSeekerI* _reader, Settings& _settings, Error* _err = NULL); + + /// + int32_t write(WriterI* _writer, const Settings& _settings, Error* _err = NULL); + +} // namespace bx + +#endif // BX_SETTINGS_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/simd_t.h b/3rdparty/bx/include/bx/simd_t.h index d3befc44ba0..f63dcfba389 100644 --- a/3rdparty/bx/include/bx/simd_t.h +++ b/3rdparty/bx/include/bx/simd_t.h @@ -7,7 +7,7 @@ #define BX_SIMD_T_H_HEADER_GUARD #include "bx.h" -#include "fpumath.h" +#include "math.h" #define BX_SIMD_FORCE_INLINE BX_FORCE_INLINE #define BX_SIMD_INLINE inline @@ -52,7 +52,7 @@ namespace bx #define ELEMw 3 #define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ template<typename Ty> \ - BX_SIMD_FORCE_INLINE Ty simd_swiz_##_x##_y##_z##_w(Ty _a); + Ty simd_swiz_##_x##_y##_z##_w(Ty _a); #include "inline/simd128_swizzle.inl" #undef BX_SIMD128_IMPLEMENT_SWIZZLE @@ -86,253 +86,361 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw); #undef BX_SIMD128_IMPLEMENT_TEST template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_shuf_xyAB(Ty _a, Ty _b); + Ty simd_shuf_xyAB(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_shuf_ABxy(Ty _a, Ty _b); + Ty simd_shuf_ABxy(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_shuf_CDzw(Ty _a, Ty _b); + Ty simd_shuf_CDzw(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_shuf_zwCD(Ty _a, Ty _b); + Ty simd_shuf_zwCD(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_shuf_xAyB(Ty _a, Ty _b); + Ty simd_shuf_xAyB(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_shuf_yBxA(Ty _a, Ty _b); + Ty simd_shuf_AxBy(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_shuf_zCwD(Ty _a, Ty _b); + Ty simd_shuf_zCwD(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_shuf_CzDw(Ty _a, Ty _b); + Ty simd_shuf_CzDw(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE float simd_x(Ty _a); + float simd_x(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE float simd_y(Ty _a); + float simd_y(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE float simd_z(Ty _a); + float simd_z(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE float simd_w(Ty _a); + float simd_w(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_ld(const void* _ptr); + Ty simd_ld(const void* _ptr); template<typename Ty> - BX_SIMD_FORCE_INLINE void simd_st(void* _ptr, Ty _a); + void simd_st(void* _ptr, Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE void simd_stx(void* _ptr, Ty _a); + void simd_stx(void* _ptr, Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE void simd_stream(void* _ptr, Ty _a); + void simd_stream(void* _ptr, Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_ld(float _x, float _y, float _z, float _w); + Ty simd_ld(float _x, float _y, float _z, float _w); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_ld(float _x, float _y, float _z, float _w, float _a, float _b, float _c, float _d); + Ty simd_ld(float _x, float _y, float _z, float _w, float _a, float _b, float _c, float _d); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w); + Ty simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w, uint32_t _a, uint32_t _b, uint32_t _c, uint32_t _d); + Ty simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w, uint32_t _a, uint32_t _b, uint32_t _c, uint32_t _d); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_splat(const void* _ptr); + Ty simd_splat(const void* _ptr); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_splat(float _a); + Ty simd_splat(float _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_isplat(uint32_t _a); + Ty simd_isplat(uint32_t _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_zero(); + Ty simd_zero(); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_itof(Ty _a); + Ty simd_itof(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_ftoi(Ty _a); + Ty simd_ftoi(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_round(Ty _a); + Ty simd_round(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_add(Ty _a, Ty _b); + Ty simd_add(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_sub(Ty _a, Ty _b); + Ty simd_sub(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_mul(Ty _a, Ty _b); + Ty simd_mul(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_div(Ty _a, Ty _b); + Ty simd_div(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_rcp_est(Ty _a); + Ty simd_rcp_est(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_sqrt(Ty _a); + Ty simd_sqrt(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_rsqrt_est(Ty _a); + Ty simd_rsqrt_est(Ty _a); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_dot3(Ty _a, Ty _b); + Ty simd_dot3(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_dot(Ty _a, Ty _b); + Ty simd_dot(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_cmpeq(Ty _a, Ty _b); + Ty simd_cmpeq(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_cmplt(Ty _a, Ty _b); + Ty simd_cmplt(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_cmple(Ty _a, Ty _b); + Ty simd_cmple(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_cmpgt(Ty _a, Ty _b); + Ty simd_cmpgt(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_cmpge(Ty _a, Ty _b); + Ty simd_cmpge(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_min(Ty _a, Ty _b); + Ty simd_min(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_max(Ty _a, Ty _b); + Ty simd_max(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_and(Ty _a, Ty _b); + Ty simd_and(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_andc(Ty _a, Ty _b); + Ty simd_andc(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_or(Ty _a, Ty _b); + Ty simd_or(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_xor(Ty _a, Ty _b); + Ty simd_xor(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_sll(Ty _a, int _count); + Ty simd_sll(Ty _a, int _count); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_srl(Ty _a, int _count); + Ty simd_srl(Ty _a, int _count); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_sra(Ty _a, int _count); + Ty simd_sra(Ty _a, int _count); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_icmpeq(Ty _a, Ty _b); + Ty simd_icmpeq(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_icmplt(Ty _a, Ty _b); + Ty simd_icmplt(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_icmpgt(Ty _a, Ty _b); + Ty simd_icmpgt(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_imin(Ty _a, Ty _b); + Ty simd_imin(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_imax(Ty _a, Ty _b); + Ty simd_imax(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_iadd(Ty _a, Ty _b); + Ty simd_iadd(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_FORCE_INLINE Ty simd_isub(Ty _a, Ty _b); + Ty simd_isub(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_shuf_xAzC(Ty _a, Ty _b); + Ty simd_shuf_xAzC(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_shuf_yBwD(Ty _a, Ty _b); + Ty simd_shuf_yBwD(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_rcp(Ty _a); + Ty simd_rcp(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_orx(Ty _a); + Ty simd_orx(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_orc(Ty _a, Ty _b); + Ty simd_orc(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_neg(Ty _a); + Ty simd_neg(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_madd(Ty _a, Ty _b, Ty _c); + Ty simd_madd(Ty _a, Ty _b, Ty _c); template<typename Ty> - BX_SIMD_INLINE Ty simd_nmsub(Ty _a, Ty _b, Ty _c); + Ty simd_nmsub(Ty _a, Ty _b, Ty _c); template<typename Ty> - BX_SIMD_INLINE Ty simd_div_nr(Ty _a, Ty _b); + Ty simd_div_nr(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_selb(Ty _mask, Ty _a, Ty _b); + Ty simd_selb(Ty _mask, Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_sels(Ty _test, Ty _a, Ty _b); + Ty simd_sels(Ty _test, Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_not(Ty _a); + Ty simd_not(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_abs(Ty _a); + Ty simd_abs(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_clamp(Ty _a, Ty _min, Ty _max); + Ty simd_clamp(Ty _a, Ty _min, Ty _max); template<typename Ty> - BX_SIMD_INLINE Ty simd_lerp(Ty _a, Ty _b, Ty _s); + Ty simd_lerp(Ty _a, Ty _b, Ty _s); template<typename Ty> - BX_SIMD_INLINE Ty simd_rsqrt(Ty _a); + Ty simd_rsqrt(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_rsqrt_nr(Ty _a); + Ty simd_rsqrt_nr(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_rsqrt_carmack(Ty _a); + Ty simd_rsqrt_carmack(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_sqrt_nr(Ty _a); + Ty simd_sqrt_nr(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_log2(Ty _a); + Ty simd_log2(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_exp2(Ty _a); + Ty simd_exp2(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_pow(Ty _a, Ty _b); + Ty simd_pow(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_cross3(Ty _a, Ty _b); + Ty simd_cross3(Ty _a, Ty _b); template<typename Ty> - BX_SIMD_INLINE Ty simd_normalize3(Ty _a); + Ty simd_normalize3(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_ceil(Ty _a); + Ty simd_ceil(Ty _a); template<typename Ty> - BX_SIMD_INLINE Ty simd_floor(Ty _a); + Ty simd_floor(Ty _a); + + template<typename Ty> + Ty simd_shuf_xAzC_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_shuf_yBwD_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_madd_ni(Ty _a, Ty _b, Ty _c); + + template<typename Ty> + Ty simd_nmsub_ni(Ty _a, Ty _b, Ty _c); + + template<typename Ty> + Ty simd_div_nr_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_rcp_ni(Ty _a); + + template<typename Ty> + Ty simd_orx_ni(Ty _a); + + template<typename Ty> + Ty simd_orc_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_neg_ni(Ty _a); + + template<typename Ty> + Ty simd_selb_ni(Ty _mask, Ty _a, Ty _b); + + template<typename Ty> + Ty simd_sels_ni(Ty _test, Ty _a, Ty _b); + + template<typename Ty> + Ty simd_not_ni(Ty _a); + + template<typename Ty> + Ty simd_min_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_max_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_abs_ni(Ty _a); + + template<typename Ty> + Ty simd_imin_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_imax_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_clamp_ni(Ty _a, Ty _min, Ty _max); + + template<typename Ty> + Ty simd_lerp_ni(Ty _a, Ty _b, Ty _s); + + template<typename Ty> + Ty simd_sqrt_nr_ni(Ty _a); + + template<typename Ty> + Ty simd_sqrt_nr1_ni(Ty _a); + + template<typename Ty> + Ty simd_rsqrt_ni(Ty _a); + + template<typename Ty> + Ty simd_rsqrt_nr_ni(Ty _a); + + template<typename Ty> + Ty simd_rsqrt_carmack_ni(Ty _a); + + template<typename Ty> + Ty simd_log2_ni(Ty _a); + + template<typename Ty> + Ty simd_exp2_ni(Ty _a); + + template<typename Ty> + Ty simd_pow_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_dot3_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_cross3_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_normalize3_ni(Ty _a); + + template<typename Ty> + Ty simd_dot_ni(Ty _a, Ty _b); + + template<typename Ty> + Ty simd_ceil_ni(Ty _a); + + template<typename Ty> + Ty simd_floor_ni(Ty _a); + + template<typename Ty> + Ty simd_round_ni(Ty _a); + + template<typename Ty> + bool simd_test_any_ni(Ty _a); + + template<typename Ty> + bool simd_test_all_ni(Ty _a); #if BX_SIMD_AVX typedef __m256 simd256_avx_t; @@ -421,47 +529,25 @@ namespace bx typedef simd256_ref_t simd256_t; #endif // !BX_SIMD_AVX -} // namespace bx + simd128_t simd_zero(); -#include "inline/simd128_ref.inl" -#include "inline/simd256_ref.inl" - -namespace bx -{ - BX_SIMD_FORCE_INLINE simd128_t simd_zero() - { - return simd_zero<simd128_t>(); - } + simd128_t simd_ld(const void* _ptr); - BX_SIMD_FORCE_INLINE simd128_t simd_ld(const void* _ptr) - { - return simd_ld<simd128_t>(_ptr); - } + simd128_t simd_ld(float _x, float _y, float _z, float _w); - BX_SIMD_FORCE_INLINE simd128_t simd_ld(float _x, float _y, float _z, float _w) - { - return simd_ld<simd128_t>(_x, _y, _z, _w); - } + simd128_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w); - BX_SIMD_FORCE_INLINE simd128_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) - { - return simd_ild<simd128_t>(_x, _y, _z, _w); - } + simd128_t simd_splat(const void* _ptr); - BX_SIMD_FORCE_INLINE simd128_t simd_splat(const void* _ptr) - { - return simd_splat<simd128_t>(_ptr); - } + simd128_t simd_splat(float _a); - BX_SIMD_FORCE_INLINE simd128_t simd_splat(float _a) - { - return simd_splat<simd128_t>(_a); - } + simd128_t simd_isplat(uint32_t _a); - BX_SIMD_FORCE_INLINE simd128_t simd_isplat(uint32_t _a) - { - return simd_isplat<simd128_t>(_a); - } } // namespace bx +#include "inline/simd128_ref.inl" +#include "inline/simd256_ref.inl" + +#include "inline/simd_ni.inl" + #endif // BX_SIMD_T_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/spscqueue.h b/3rdparty/bx/include/bx/spscqueue.h index 4d37d63b63f..c79b59547f9 100644 --- a/3rdparty/bx/include/bx/spscqueue.h +++ b/3rdparty/bx/include/bx/spscqueue.h @@ -6,7 +6,7 @@ #ifndef BX_SPSCQUEUE_H_HEADER_GUARD #define BX_SPSCQUEUE_H_HEADER_GUARD -#include "bx.h" +#include "allocator.h" #include "cpu.h" #include "semaphore.h" @@ -22,7 +22,7 @@ namespace bx public: /// - SpScUnboundedQueue(); + SpScUnboundedQueue(AllocatorI* _allocator); /// ~SpScUnboundedQueue(); @@ -46,6 +46,7 @@ namespace bx Node* m_next; }; + AllocatorI* m_allocator; Node* m_first; Node* m_divider; Node* m_last; @@ -62,7 +63,7 @@ namespace bx public: /// - SpScUnboundedQueueT(); + SpScUnboundedQueueT(AllocatorI* _allocator); /// ~SpScUnboundedQueueT(); @@ -80,7 +81,6 @@ namespace bx SpScUnboundedQueue m_queue; }; - #if BX_CONFIG_SUPPORTS_THREADING /// class SpScBlockingUnboundedQueue @@ -92,7 +92,7 @@ namespace bx public: /// - SpScBlockingUnboundedQueue(); + SpScBlockingUnboundedQueue(AllocatorI* _allocator); /// ~SpScBlockingUnboundedQueue(); @@ -122,7 +122,7 @@ namespace bx public: /// - SpScBlockingUnboundedQueueT(); + SpScBlockingUnboundedQueueT(AllocatorI* _allocator); /// ~SpScBlockingUnboundedQueueT(); diff --git a/3rdparty/bx/include/bx/string.h b/3rdparty/bx/include/bx/string.h index 440cbe15f17..331bda889b3 100644 --- a/3rdparty/bx/include/bx/string.h +++ b/3rdparty/bx/include/bx/string.h @@ -8,10 +8,17 @@ #include "allocator.h" -#include <wchar.h> // wchar_t - namespace bx { + struct Units + { + enum Enum + { + Kilo, + Kibi, + }; + }; + /// Non-zero-terminated string view. class StringView { @@ -23,15 +30,27 @@ namespace bx StringView(const StringView& _rhs); /// + StringView& operator=(const char* _rhs); + + /// StringView& operator=(const StringView& _rhs); /// StringView(const char* _ptr, int32_t _len = INT32_MAX); /// + StringView(const char* _ptr, const char* _term); + + /// void set(const char* _ptr, int32_t _len = INT32_MAX); /// + void set(const char* _ptr, const char* _term); + + /// + void set(const StringView& _str); + + /// void clear(); /// @@ -66,19 +85,16 @@ namespace bx StringT<AllocatorT>& operator=(const StringT<AllocatorT>& _rhs); /// - StringT(const char* _ptr, int32_t _len = INT32_MAX); - - /// StringT(const StringView& _rhs); /// ~StringT(); /// - void set(const char* _ptr, int32_t _len = INT32_MAX); + void set(const StringView& _str); /// - void append(const char* _ptr, int32_t _len = INT32_MAX); + void append(const StringView& _str); /// void clear(); @@ -88,24 +104,45 @@ namespace bx bool isSpace(char _ch); /// + bool isSpace(const StringView& _str); + + /// bool isUpper(char _ch); /// + bool isUpper(const StringView& _str); + + /// bool isLower(char _ch); /// + bool isLower(const StringView& _str); + + /// bool isAlpha(char _ch); /// + bool isAlpha(const StringView& _str); + + /// bool isNumeric(char _ch); /// + bool isNumeric(const StringView& _str); + + /// bool isAlphaNum(char _ch); /// + bool isAlphaNum(const StringView& _str); + + /// bool isPrint(char _ch); /// + bool isPrint(const StringView& _str); + + /// char toLower(char _ch); /// @@ -123,36 +160,48 @@ namespace bx /// void toUpper(char* _inOutStr, int32_t _max = INT32_MAX); - /// - bool toBool(const char* _str); - /// String compare. - int32_t strncmp(const char* _lhs, const char* _rhs, int32_t _max = INT32_MAX); + int32_t strCmp(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX); /// Case insensitive string compare. - int32_t strincmp(const char* _lhs, const char* _rhs, int32_t _max = INT32_MAX); + int32_t strCmpI(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX); - /// - int32_t strnlen(const char* _str, int32_t _max = INT32_MAX); + // Compare as strings holding indices/version numbers. + int32_t strCmpV(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX); + + /// Get string length. + int32_t strLen(const char* _str, int32_t _max = INT32_MAX); + + /// Get string length. + int32_t strLen(const StringView& _str, int32_t _max = INT32_MAX); /// Copy _num characters from string _src to _dst buffer of maximum _dstSize capacity /// including zero terminator. Copy will be terminated with '\0'. - int32_t strlncpy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num = INT32_MAX); + int32_t strCopy(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num = INT32_MAX); - /// - int32_t strlncat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num = INT32_MAX); + /// Concatinate string. + int32_t strCat(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num = INT32_MAX); - /// - const char* strnchr(const char* _str, char _ch, int32_t _max = INT32_MAX); + /// Find character in string. Limit search to _max characters. + const char* strFind(const StringView& _str, char _ch); + + /// Find character in string in reverse. Limit search to _max characters. + const char* strRFind(const StringView& _str, char _ch); + + /// Find substring in string. Limit search to _max characters. + const char* strFind(const StringView& _str, const StringView& _find, int32_t _num = INT32_MAX); + + /// Find substring in string. Case insensitive. Limit search to _max characters. + const char* strFindI(const StringView& _str, const StringView& _find, int32_t _num = INT32_MAX); /// - const char* strnrchr(const char* _str, char _ch, int32_t _max = INT32_MAX); + StringView strLTrim(const StringView& _str, const StringView& _chars); - /// Find substring in string. Limit search to _size. - const char* strnstr(const char* _str, const char* _find, int32_t _max = INT32_MAX); + /// + StringView strRTrim(const StringView& _str, const StringView& _chars); - /// Find substring in string. Case insensitive. Limit search to _max. - const char* stristr(const char* _str, const char* _find, int32_t _max = INT32_MAX); + /// + StringView strTrim(const StringView& _str, const StringView& _chars); /// Find new line. Returns pointer after new line terminator. const char* strnl(const char* _str); @@ -209,23 +258,11 @@ namespace bx template <typename Ty> Ty replaceAll(const Ty& _str, const char* _from, const char* _to); - /// Extract base file name from file path. - const char* baseName(const char* _filePath); + /// Convert size in bytes to human readable string kibi units. + int32_t prettify(char* _out, int32_t _count, uint64_t _value, Units::Enum _units = Units::Kibi); - /// Convert size in bytes to human readable string. - void prettify(char* _out, int32_t _count, uint64_t _size); - - /// Copy src to string dst of size siz. At most siz-1 characters - /// will be copied. Always NUL terminates (unless siz == 0). - /// Returns strlen(src); if retval >= siz, truncation occurred. - int32_t strlcpy(char* _dst, const char* _src, int32_t _max); - - /// Appends src to string dst of size siz (unlike strncat, siz is the - /// full size of dst, not space left). At most siz-1 characters - /// will be copied. Always NUL terminates (unless siz <= strlen(dst)). - /// Returns strlen(src) + MIN(siz, strlen(initial dst)). - /// If retval >= siz, truncation occurred. - int32_t strlcat(char* _dst, const char* _src, int32_t _max); + /// + int32_t toString(char* _out, int32_t _max, bool _value); /// int32_t toString(char* _out, int32_t _max, double _value); @@ -242,6 +279,21 @@ namespace bx /// int32_t toString(char* _out, int32_t _max, uint64_t _value, uint32_t _base = 10); + /// + bool fromString(bool* _out, const StringView& _str); + + /// + bool fromString(float* _out, const StringView& _str); + + /// + bool fromString(double* _out, const StringView& _str); + + /// + bool fromString(int32_t* _out, const StringView& _str); + + /// + bool fromString(uint32_t* _out, const StringView& _str); + } // namespace bx #include "inline/string.inl" diff --git a/3rdparty/bx/include/bx/thread.h b/3rdparty/bx/include/bx/thread.h index 72a072e7d62..3ba17e681b4 100644 --- a/3rdparty/bx/include/bx/thread.h +++ b/3rdparty/bx/include/bx/thread.h @@ -6,13 +6,13 @@ #ifndef BX_THREAD_H_HEADER_GUARD #define BX_THREAD_H_HEADER_GUARD -#include "bx.h" -#include "semaphore.h" +#include "allocator.h" +#include "mpscqueue.h" namespace bx { /// - typedef int32_t (*ThreadFn)(void* _userData); + typedef int32_t (*ThreadFn)(class Thread* _self, void* _userData); /// class Thread @@ -44,6 +44,12 @@ namespace bx /// void setThreadName(const char* _name); + /// + void push(void* _ptr); + + /// + void* pop(); + private: friend struct ThreadInternal; int32_t entry(); @@ -52,6 +58,7 @@ namespace bx ThreadFn m_fn; void* m_userData; + MpScUnboundedBlockingQueue<void> m_queue; Semaphore m_sem; uint32_t m_stackSize; int32_t m_exitCode; diff --git a/3rdparty/bx/include/bx/url.h b/3rdparty/bx/include/bx/url.h new file mode 100644 index 00000000000..11172a47f9f --- /dev/null +++ b/3rdparty/bx/include/bx/url.h @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_URL_H_HEADER_GUARD +#define BX_URL_H_HEADER_GUARD + +#include "string.h" + +namespace bx +{ + /// + class UrlView + { + public: + enum Enum + { + Scheme, + UserName, + Password, + Host, + Port, + Path, + Query, + Fragment, + + Count + }; + + /// + UrlView(); + + /// + void clear(); + + /// + bool parse(const StringView& _url); + + /// + const StringView& get(Enum _token) const; + + private: + StringView m_tokens[Count]; + }; + + /// + void urlEncode(char* _out, uint32_t _max, const StringView& _str); + +} // namespace bx + +#endif // BX_URL_H_HEADER_GUARD diff --git a/3rdparty/bx/include/compat/msvc/dirent.h b/3rdparty/bx/include/compat/msvc/dirent.h index 06523528177..a08d0fa4df3 100644 --- a/3rdparty/bx/include/compat/msvc/dirent.h +++ b/3rdparty/bx/include/compat/msvc/dirent.h @@ -27,7 +27,9 @@ #ifndef DIRENT_H #define DIRENT_H -#ifdef _MSC_VER +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wunused-function" +#elif defined(_MSC_VER) # pragma warning(disable:4505) // error C4505: '_wreaddir': unreferenced local function has been removed #else # pragma GCC diagnostic ignored "-Wunused-function" diff --git a/3rdparty/bx/include/compat/nacl/memory.h b/3rdparty/bx/include/compat/nacl/memory.h deleted file mode 100644 index 3b2f5900276..00000000000 --- a/3rdparty/bx/include/compat/nacl/memory.h +++ /dev/null @@ -1 +0,0 @@ -#include <string.h> diff --git a/3rdparty/bx/makefile b/3rdparty/bx/makefile index bf8d91167d2..e377204ee35 100644 --- a/3rdparty/bx/makefile +++ b/3rdparty/bx/makefile @@ -11,9 +11,6 @@ all: $(GENIE) --gcc=android-arm gmake $(GENIE) --gcc=android-mips gmake $(GENIE) --gcc=android-x86 gmake - $(GENIE) --gcc=nacl gmake - $(GENIE) --gcc=nacl-arm gmake - $(GENIE) --gcc=pnacl gmake $(GENIE) --gcc=mingw-gcc gmake $(GENIE) --gcc=linux-gcc gmake $(GENIE) --gcc=osx gmake @@ -87,34 +84,6 @@ mingw-clang: mingw-clang-debug32 mingw-clang-release32 mingw-clang-debug64 mingw .build/projects/vs2013: $(GENIE) vs2013 -.build/projects/gmake-nacl: - $(GENIE) --gcc=nacl gmake -nacl-debug32: .build/projects/gmake-nacl - make -R -C .build/projects/gmake-nacl config=debug32 -nacl-release32: .build/projects/gmake-nacl - make -R -C .build/projects/gmake-nacl config=release32 -nacl-debug64: .build/projects/gmake-nacl - make -R -C .build/projects/gmake-nacl config=debug64 -nacl-release64: .build/projects/gmake-nacl - make -R -C .build/projects/gmake-nacl config=release64 -nacl: nacl-debug32 nacl-release32 nacl-debug64 nacl-release64 - -.build/projects/gmake-nacl-arm: - $(GENIE) --gcc=nacl-arm gmake -nacl-arm-debug: .build/projects/gmake-nacl-arm - make -R -C .build/projects/gmake-nacl-arm config=debug -nacl-arm-release: .build/projects/gmake-nacl-arm - make -R -C .build/projects/gmake-nacl-arm config=release -nacl-arm: nacl-arm-debug32 nacl-arm-release32 - -.build/projects/gmake-pnacl: - $(GENIE) --gcc=pnacl gmake -pnacl-debug: .build/projects/gmake-pnacl - make -R -C .build/projects/gmake-pnacl config=debug -pnacl-release: .build/projects/gmake-pnacl - make -R -C .build/projects/gmake-pnacl config=release -pnacl: pnacl-debug pnacl-release - .build/projects/gmake-osx: $(GENIE) --gcc=osx gmake osx-debug32: .build/projects/gmake-osx diff --git a/3rdparty/bx/scripts/bin2c.lua b/3rdparty/bx/scripts/bin2c.lua index daa7b099498..0b1acdcefcb 100644 --- a/3rdparty/bx/scripts/bin2c.lua +++ b/3rdparty/bx/scripts/bin2c.lua @@ -27,6 +27,11 @@ project "bin2c" "pthread", } + configuration { "vs20* or mingw*" } + links { + "psapi", + } + configuration {} strip() diff --git a/3rdparty/bx/scripts/bx.lua b/3rdparty/bx/scripts/bx.lua index a84eec43b75..0f2f3ef0596 100644 --- a/3rdparty/bx/scripts/bx.lua +++ b/3rdparty/bx/scripts/bx.lua @@ -8,6 +8,7 @@ project "bx" includedirs { path.join(BX_DIR, "include"), + path.join(BX_DIR, "3rdparty"), } files { @@ -16,6 +17,11 @@ project "bx" path.join(BX_DIR, "src/**.cpp"), } + configuration { "Debug" } + defines { + "BX_CONFIG_DEBUG=1", + } + configuration { "linux-*" } buildoptions { "-fPIC", @@ -25,19 +31,27 @@ project "bx" if _OPTIONS["with-amalgamated"] then excludes { + path.join(BX_DIR, "src/allocator.cpp"), + path.join(BX_DIR, "src/bx.cpp"), path.join(BX_DIR, "src/commandline.cpp"), - path.join(BX_DIR, "src/crt.cpp"), - path.join(BX_DIR, "src/crtimpl.cpp"), + path.join(BX_DIR, "src/crtnone.cpp"), path.join(BX_DIR, "src/debug.cpp"), path.join(BX_DIR, "src/dtoa.cpp"), - path.join(BX_DIR, "src/fpumath.cpp"), + path.join(BX_DIR, "src/easing.cpp"), + path.join(BX_DIR, "src/file.cpp"), + path.join(BX_DIR, "src/filepath.cpp"), + path.join(BX_DIR, "src/hash.cpp"), + path.join(BX_DIR, "src/math.cpp"), path.join(BX_DIR, "src/mutex.cpp"), path.join(BX_DIR, "src/os.cpp"), - path.join(BX_DIR, "src/sem.cpp"), + path.join(BX_DIR, "src/process.cpp"), + path.join(BX_DIR, "src/semaphore.cpp"), + path.join(BX_DIR, "src/settings.cpp"), path.join(BX_DIR, "src/sort.cpp"), path.join(BX_DIR, "src/string.cpp"), path.join(BX_DIR, "src/thread.cpp"), path.join(BX_DIR, "src/timer.cpp"), + path.join(BX_DIR, "src/url.cpp"), } else excludes { diff --git a/3rdparty/bx/scripts/genie.lua b/3rdparty/bx/scripts/genie.lua index 9919b8c6181..aab0a8a5620 100644 --- a/3rdparty/bx/scripts/genie.lua +++ b/3rdparty/bx/scripts/genie.lua @@ -28,8 +28,8 @@ solution "bx" language "C++" BX_DIR = path.getabsolute("..") -local BX_BUILD_DIR = path.join(BX_DIR, ".build") -local BX_THIRD_PARTY_DIR = path.join(BX_DIR, "3rdparty") +BX_BUILD_DIR = path.join(BX_DIR, ".build") +BX_THIRD_PARTY_DIR = path.join(BX_DIR, "3rdparty") dofile "toolchain.lua" toolchain(BX_BUILD_DIR, BX_THIRD_PARTY_DIR) @@ -75,20 +75,6 @@ project "bx.test" "-shared", } - configuration { "nacl or nacl-arm" } - targetextension ".nexe" - links { - "ppapi", - "pthread", - } - - configuration { "pnacl" } - targetextension ".pexe" - links { - "ppapi", - "pthread", - } - configuration { "linux-*" } links { "pthread", @@ -134,20 +120,6 @@ project "bx.bench" "-shared", } - configuration { "nacl or nacl-arm" } - targetextension ".nexe" - links { - "ppapi", - "pthread", - } - - configuration { "pnacl" } - targetextension ".pexe" - links { - "ppapi", - "pthread", - } - configuration { "linux-*" } links { "pthread", diff --git a/3rdparty/bx/scripts/toolchain.lua b/3rdparty/bx/scripts/toolchain.lua index 0152ce79c32..076b8fbac60 100644 --- a/3rdparty/bx/scripts/toolchain.lua +++ b/3rdparty/bx/scripts/toolchain.lua @@ -4,7 +4,6 @@ -- local bxDir = path.getabsolute("..") -local naclToolchain = "" local function crtNone() @@ -69,11 +68,8 @@ function toolchain(_buildDir, _libDir) { "tvos-simulator", "tvOS - Simulator" }, { "mingw-gcc", "MinGW" }, { "mingw-clang", "MinGW (clang compiler)" }, - { "nacl", "Native Client" }, - { "nacl-arm", "Native Client - ARM" }, { "netbsd", "NetBSD" }, { "osx", "OSX" }, - { "pnacl", "Native Client - PNaCl" }, { "orbis", "Orbis" }, { "qnx-arm", "QNX/Blackberry - ARM" }, { "riscv", "RISC-V" }, @@ -135,7 +131,7 @@ function toolchain(_buildDir, _libDir) newoption { trigger = "with-windows", value = "#", - description = "Set the Windows target platform version (default: 10.0.10240.0).", + description = "Set the Windows target platform version (default: $WindowsSDKVersion or 8.1).", } newoption { @@ -179,7 +175,7 @@ function toolchain(_buildDir, _libDir) tvosPlatform = _OPTIONS["with-tvos"] end - local windowsPlatform = "10.0.10240.0" + local windowsPlatform = string.gsub(os.getenv("WindowsSDKVersion") or "8.1", "\\", "") if _OPTIONS["with-windows"] then windowsPlatform = _OPTIONS["with-windows"] end @@ -205,7 +201,7 @@ function toolchain(_buildDir, _libDir) if not os.getenv("ANDROID_NDK_ARM") or not os.getenv("ANDROID_NDK_CLANG") or not os.getenv("ANDROID_NDK_ROOT") then - print("Set ANDROID_NDK_CLANG, ANDROID_NDK_ARM, and ANDROID_NDK_ROOT envrionment variables.") + print("Set ANDROID_NDK_CLANG, ANDROID_NDK_ARM, and ANDROID_NDK_ROOT environment variables.") end premake.gcc.cc = "$(ANDROID_NDK_CLANG)/bin/clang" @@ -220,7 +216,7 @@ function toolchain(_buildDir, _libDir) if not os.getenv("ANDROID_NDK_MIPS") or not os.getenv("ANDROID_NDK_CLANG") or not os.getenv("ANDROID_NDK_ROOT") then - print("Set ANDROID_NDK_CLANG, ANDROID_NDK_ARM, and ANDROID_NDK_ROOT envrionment variables.") + print("Set ANDROID_NDK_CLANG, ANDROID_NDK_ARM, and ANDROID_NDK_ROOT environment variables.") end premake.gcc.cc = "$(ANDROID_NDK_CLANG)/bin/clang" @@ -233,7 +229,7 @@ function toolchain(_buildDir, _libDir) if not os.getenv("ANDROID_NDK_X86") or not os.getenv("ANDROID_NDK_CLANG") or not os.getenv("ANDROID_NDK_ROOT") then - print("Set ANDROID_NDK_CLANG, ANDROID_NDK_ARM, and ANDROID_NDK_ROOT envrionment variables.") + print("Set ANDROID_NDK_CLANG, ANDROID_NDK_ARM, and ANDROID_NDK_ROOT environment variables.") end premake.gcc.cc = "$(ANDROID_NDK_CLANG)/bin/clang" @@ -244,7 +240,7 @@ function toolchain(_buildDir, _libDir) elseif "asmjs" == _OPTIONS["gcc"] then if not os.getenv("EMSCRIPTEN") then - print("Set EMSCRIPTEN enviroment variable.") + print("Set EMSCRIPTEN environment variable.") end premake.gcc.cc = "\"$(EMSCRIPTEN)/emcc\"" @@ -316,7 +312,7 @@ function toolchain(_buildDir, _libDir) elseif "linux-steamlink" == _OPTIONS["gcc"] then if not os.getenv("MARVELL_SDK_PATH") then - print("Set MARVELL_SDK_PATH enviroment variable.") + print("Set MARVELL_SDK_PATH environment variable.") end premake.gcc.cc = "$(MARVELL_SDK_PATH)/toolchain/bin/armv7a-cros-linux-gnueabi-gcc" @@ -325,6 +321,10 @@ function toolchain(_buildDir, _libDir) location (path.join(_buildDir, "projects", _ACTION .. "-linux-steamlink")) elseif "mingw-gcc" == _OPTIONS["gcc"] then + if not os.getenv("MINGW") then + print("Set MINGW environment variable.") + end + local mingwToolchain = "x86_64-w64-mingw32" if compiler32bit then if os.is("linux") then @@ -347,42 +347,6 @@ function toolchain(_buildDir, _libDir) -- premake.gcc.llvm = true location (path.join(_buildDir, "projects", _ACTION .. "-mingw-clang")) - elseif "nacl" == _OPTIONS["gcc"] then - - if not os.getenv("NACL_SDK_ROOT") then - print("Set NACL_SDK_ROOT enviroment variable.") - end - - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/win_x86_glibc/bin/x86_64-nacl-" - if os.is("macosx") then - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/mac_x86_glibc/bin/x86_64-nacl-" - elseif os.is("linux") then - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/linux_x86_glibc/bin/x86_64-nacl-" - end - - premake.gcc.cc = naclToolchain .. "gcc" - premake.gcc.cxx = naclToolchain .. "g++" - premake.gcc.ar = naclToolchain .. "ar" - location (path.join(_buildDir, "projects", _ACTION .. "-nacl")) - - elseif "nacl-arm" == _OPTIONS["gcc"] then - - if not os.getenv("NACL_SDK_ROOT") then - print("Set NACL_SDK_ROOT enviroment variable.") - end - - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/win_arm_glibc/bin/arm-nacl-" - if os.is("macosx") then - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/mac_arm_glibc/bin/arm-nacl-" - elseif os.is("linux") then - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/linux_arm_glibc/bin/arm-nacl-" - end - - premake.gcc.cc = naclToolchain .. "gcc" - premake.gcc.cxx = naclToolchain .. "g++" - premake.gcc.ar = naclToolchain .. "ar" - location (path.join(_buildDir, "projects", _ACTION .. "-nacl-arm")) - elseif "netbsd" == _OPTIONS["gcc"] then location (path.join(_buildDir, "projects", _ACTION .. "-netbsd")) @@ -390,7 +354,7 @@ function toolchain(_buildDir, _libDir) if os.is("linux") then if not os.getenv("OSXCROSS") then - print("Set OSXCROSS enviroment variable.") + print("Set OSXCROSS environment variable.") end local osxToolchain = "x86_64-apple-darwin15-" @@ -400,28 +364,10 @@ function toolchain(_buildDir, _libDir) end location (path.join(_buildDir, "projects", _ACTION .. "-osx")) - elseif "pnacl" == _OPTIONS["gcc"] then - - if not os.getenv("NACL_SDK_ROOT") then - print("Set NACL_SDK_ROOT enviroment variable.") - end - - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/win_pnacl/bin/pnacl-" - if os.is("macosx") then - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/mac_pnacl/bin/pnacl-" - elseif os.is("linux") then - naclToolchain = "$(NACL_SDK_ROOT)/toolchain/linux_pnacl/bin/pnacl-" - end - - premake.gcc.cc = naclToolchain .. "clang" - premake.gcc.cxx = naclToolchain .. "clang++" - premake.gcc.ar = naclToolchain .. "ar" - location (path.join(_buildDir, "projects", _ACTION .. "-pnacl")) - elseif "orbis" == _OPTIONS["gcc"] then if not os.getenv("SCE_ORBIS_SDK_DIR") then - print("Set SCE_ORBIS_SDK_DIR enviroment variable.") + print("Set SCE_ORBIS_SDK_DIR environment variable.") end orbisToolchain = "$(SCE_ORBIS_SDK_DIR)/host_tools/bin/orbis-" @@ -434,7 +380,7 @@ function toolchain(_buildDir, _libDir) elseif "qnx-arm" == _OPTIONS["gcc"] then if not os.getenv("QNX_HOST") then - print("Set QNX_HOST enviroment variable.") + print("Set QNX_HOST environment variable.") end premake.gcc.cc = "$(QNX_HOST)/usr/bin/arm-unknown-nto-qnx8.0.0eabi-gcc" @@ -458,6 +404,10 @@ function toolchain(_buildDir, _libDir) or _ACTION == "vs2017" then + local action = premake.action.current() + action.vstudio.windowsTargetPlatformVersion = windowsPlatform + action.vstudio.windowsTargetPlatformMinVersion = windowsPlatform + if (_ACTION .. "-clang") == _OPTIONS["vs"] then if "vs2017-clang" == _OPTIONS["vs"] then premake.vstudio.toolset = "v141_clang_c2" @@ -488,10 +438,6 @@ function toolchain(_buildDir, _libDir) premake.vstudio.toolset = "v140" premake.vstudio.storeapp = "8.2" - local action = premake.action.current() - action.vstudio.windowsTargetPlatformVersion = windowsPlatform - action.vstudio.windowsTargetPlatformMinVersion = windowsPlatform - platforms { "ARM" } location (path.join(_buildDir, "projects", _ACTION .. "-winstore82")) @@ -507,14 +453,12 @@ function toolchain(_buildDir, _libDir) elseif "orbis" == _OPTIONS["vs"] then if not os.getenv("SCE_ORBIS_SDK_DIR") then - print("Set SCE_ORBIS_SDK_DIR enviroment variable.") + print("Set SCE_ORBIS_SDK_DIR environment variable.") end platforms { "Orbis" } location (path.join(_buildDir, "projects", _ACTION .. "-orbis")) - end - elseif ("vs2012-xp") == _OPTIONS["vs"] then premake.vstudio.toolset = ("v110_xp") location (path.join(_buildDir, "projects", _ACTION .. "-xp")) @@ -531,6 +475,8 @@ function toolchain(_buildDir, _libDir) premake.vstudio.toolset = ("v141_xp") location (path.join(_buildDir, "projects", _ACTION .. "-xp")) + end + elseif _ACTION == "xcode4" then if "osx" == _OPTIONS["xcode"] then @@ -601,7 +547,7 @@ function toolchain(_buildDir, _libDir) "EnableSSE2", } - configuration { "vs*", "not orbis" } + configuration { "vs*", "not orbis", "not NX32", "not NX64" } includedirs { path.join(bxDir, "include/compat/msvc") } defines { "WIN32", @@ -777,8 +723,16 @@ function toolchain(_buildDir, _libDir) configuration { "linux-gcc* or linux-clang*" } buildoptions { "-msse2", +-- "-Wdouble-promotion", +-- "-Wduplicated-branches", +-- "-Wduplicated-cond", +-- "-Wjump-misses-init", + "-Wlogical-op", + "-Wshadow", +-- "-Wnull-dereference", "-Wunused-value", "-Wundef", +-- "-Wuseless-cast", } buildoptions_cpp { "-std=c++11", @@ -1022,10 +976,14 @@ function toolchain(_buildDir, _libDir) libdirs { path.join(_libDir, "lib/asmjs") } buildoptions { "-i\"system$(EMSCRIPTEN)/system/include\"", + "-i\"system$(EMSCRIPTEN)/system/include/libcxx\"", "-i\"system$(EMSCRIPTEN)/system/include/libc\"", "-Wunused-value", "-Wundef", } + buildoptions_cpp { + "-std=c++11", + } configuration { "freebsd" } targetdir (path.join(_buildDir, "freebsd/bin")) @@ -1035,83 +993,6 @@ function toolchain(_buildDir, _libDir) path.join(bxDir, "include/compat/freebsd"), } - configuration { "nacl or nacl-arm or pnacl" } - buildoptions { - "-U__STRICT_ANSI__", -- strcasecmp, setenv, unsetenv,... - "-fno-stack-protector", - "-fdiagnostics-show-option", - "-fdata-sections", - "-ffunction-sections", - "-Wunused-value", - "-Wundef", - } - buildoptions_cpp { - "-std=c++11", - } - includedirs { - "$(NACL_SDK_ROOT)/include", - path.join(bxDir, "include/compat/nacl"), - } - - configuration { "nacl" } - buildoptions { - "-pthread", - "-mfpmath=sse", -- force SSE to get 32-bit and 64-bit builds deterministic. - "-msse2", - } - linkoptions { - "-Wl,--gc-sections", - } - - configuration { "x32", "nacl" } - targetdir (path.join(_buildDir, "nacl-x86/bin")) - objdir (path.join(_buildDir, "nacl-x86/obj")) - libdirs { path.join(_libDir, "lib/nacl-x86") } - linkoptions { "-melf32_nacl" } - - configuration { "x32", "nacl", "Debug" } - libdirs { "$(NACL_SDK_ROOT)/lib/glibc_x86_32/Debug" } - - configuration { "x32", "nacl", "Release" } - libdirs { "$(NACL_SDK_ROOT)/lib/glibc_x86_32/Release" } - - configuration { "x64", "nacl" } - targetdir (path.join(_buildDir, "nacl-x64/bin")) - objdir (path.join(_buildDir, "nacl-x64/obj")) - libdirs { path.join(_libDir, "lib/nacl-x64") } - linkoptions { "-melf64_nacl" } - - configuration { "x64", "nacl", "Debug" } - libdirs { "$(NACL_SDK_ROOT)/lib/glibc_x86_64/Debug" } - - configuration { "x64", "nacl", "Release" } - libdirs { "$(NACL_SDK_ROOT)/lib/glibc_x86_64/Release" } - - configuration { "nacl-arm" } - buildoptions { - "-Wno-psabi", -- note: the mangling of 'va_list' has changed in GCC 4.4.0 - } - targetdir (path.join(_buildDir, "nacl-arm/bin")) - objdir (path.join(_buildDir, "nacl-arm/obj")) - libdirs { path.join(_libDir, "lib/nacl-arm") } - - configuration { "nacl-arm", "Debug" } - libdirs { "$(NACL_SDK_ROOT)/lib/glibc_arm/Debug" } - - configuration { "nacl-arm", "Release" } - libdirs { "$(NACL_SDK_ROOT)/lib/glibc_arm/Release" } - - configuration { "pnacl" } - targetdir (path.join(_buildDir, "pnacl/bin")) - objdir (path.join(_buildDir, "pnacl/obj")) - libdirs { path.join(_libDir, "lib/pnacl") } - - configuration { "pnacl", "Debug" } - libdirs { "$(NACL_SDK_ROOT)/lib/pnacl/Debug" } - - configuration { "pnacl", "Release" } - libdirs { "$(NACL_SDK_ROOT)/lib/pnacl/Release" } - configuration { "xbox360" } targetdir (path.join(_buildDir, "xbox360/bin")) objdir (path.join(_buildDir, "xbox360/obj")) @@ -1163,6 +1044,9 @@ function toolchain(_buildDir, _libDir) buildoptions_cpp { "-std=c++11", } + buildoptions_objcpp { + "-std=c++11", + } buildoptions { "-Wfatal-errors", "-msse2", @@ -1178,6 +1062,9 @@ function toolchain(_buildDir, _libDir) buildoptions_cpp { "-std=c++11", } + buildoptions_objcpp { + "-std=c++11", + } buildoptions { "-Wfatal-errors", "-Wunused-value", @@ -1302,13 +1189,9 @@ function toolchain(_buildDir, _libDir) "$(SCE_ORBIS_SDK_DIR)/target/include", "$(SCE_ORBIS_SDK_DIR)/target/include_common", } - buildoptions { - } buildoptions_cpp { "-std=c++11", } - linkoptions { - } configuration { "qnx-arm" } targetdir (path.join(_buildDir, "qnx-arm/bin")) @@ -1418,18 +1301,6 @@ function strip() "$(SILENT) $(MINGW)/bin/strip -s \"$(TARGET)\"" } - configuration { "pnacl" } - postbuildcommands { - "$(SILENT) echo Running pnacl-finalize.", - "$(SILENT) " .. naclToolchain .. "finalize \"$(TARGET)\"" - } - - configuration { "*nacl*", "Release" } - postbuildcommands { - "$(SILENT) echo Stripping symbols.", - "$(SILENT) " .. naclToolchain .. "strip -s \"$(TARGET)\"" - } - configuration { "asmjs" } postbuildcommands { "$(SILENT) echo Running asmjs finalize.", @@ -1441,7 +1312,8 @@ function strip() -- .. "-s USE_WEBGL2=1 " .. "--memory-init-file 1 " .. "\"$(TARGET)\" -o \"$(TARGET)\".html " --- .. "--preload-file ../../../examples/runtime@/" +-- .. "--preload-file ../../../examples/runtime@/ " + .. "-s PRECISE_F32=1" } configuration { "riscv" } diff --git a/3rdparty/bx/src/allocator.cpp b/3rdparty/bx/src/allocator.cpp new file mode 100644 index 00000000000..e3b5b37c826 --- /dev/null +++ b/3rdparty/bx/src/allocator.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/allocator.h> + +#include <malloc.h> + +#ifndef BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT +# define BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT 8 +#endif // BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT + +namespace bx +{ + DefaultAllocator::DefaultAllocator() + { + } + + DefaultAllocator::~DefaultAllocator() + { + } + + void* DefaultAllocator::realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) + { + if (0 == _size) + { + if (NULL != _ptr) + { + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + ::free(_ptr); + return NULL; + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + _aligned_free(_ptr); +# else + bx::alignedFree(this, _ptr, _align, _file, _line); +# endif // BX_ + } + + return NULL; + } + else if (NULL == _ptr) + { + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + return ::malloc(_size); + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + return _aligned_malloc(_size, _align); +# else + return bx::alignedAlloc(this, _size, _align, _file, _line); +# endif // BX_ + } + + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + return ::realloc(_ptr, _size); + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + return _aligned_realloc(_ptr, _size, _align); +# else + return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line); +# endif // BX_ + } + +} // namespace bx diff --git a/3rdparty/bx/src/amalgamated.cpp b/3rdparty/bx/src/amalgamated.cpp index 1aeb2bb906d..7eaf04a58aa 100644 --- a/3rdparty/bx/src/amalgamated.cpp +++ b/3rdparty/bx/src/amalgamated.cpp @@ -3,17 +3,24 @@ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ +#include "allocator.cpp" #include "bx.cpp" #include "commandline.cpp" -#include "crtimpl.cpp" #include "crtnone.cpp" #include "debug.cpp" #include "dtoa.cpp" -#include "fpumath.cpp" +#include "easing.cpp" +#include "file.cpp" +#include "filepath.cpp" +#include "hash.cpp" +#include "math.cpp" #include "mutex.cpp" #include "os.cpp" +#include "process.cpp" #include "semaphore.cpp" +#include "settings.cpp" #include "sort.cpp" #include "string.cpp" #include "thread.cpp" #include "timer.cpp" +#include "url.cpp" diff --git a/3rdparty/bx/src/bx.cpp b/3rdparty/bx/src/bx.cpp index 8a063c56de9..ae9743e45a7 100644 --- a/3rdparty/bx/src/bx.cpp +++ b/3rdparty/bx/src/bx.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/debug.h> #include <bx/readerwriter.h> diff --git a/3rdparty/bx/src/bx_p.h b/3rdparty/bx/src/bx_p.h new file mode 100644 index 00000000000..df37a2c5791 --- /dev/null +++ b/3rdparty/bx/src/bx_p.h @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_P_H_HEADER_GUARD +#define BX_P_H_HEADER_GUARD + +#ifndef BX_CONFIG_DEBUG +# define BX_CONFIG_DEBUG 0 +#endif // BX_CONFIG_DEBUG + +#if BX_CONFIG_DEBUG +# define BX_TRACE _BX_TRACE +# define BX_WARN _BX_WARN +# define BX_CHECK _BX_CHECK +# define BX_CONFIG_ALLOCATOR_DEBUG 1 +#endif // BX_CONFIG_DEBUG + +#define _BX_TRACE(_format, ...) \ + BX_MACRO_BLOCK_BEGIN \ + bx::debugPrintf(__FILE__ "(" BX_STRINGIZE(__LINE__) "): BX " _format "\n", ##__VA_ARGS__); \ + BX_MACRO_BLOCK_END + +#define _BX_WARN(_condition, _format, ...) \ + BX_MACRO_BLOCK_BEGIN \ + if (!BX_IGNORE_C4127(_condition) ) \ + { \ + BX_TRACE("WARN " _format, ##__VA_ARGS__); \ + } \ + BX_MACRO_BLOCK_END + +#define _BX_CHECK(_condition, _format, ...) \ + BX_MACRO_BLOCK_BEGIN \ + if (!BX_IGNORE_C4127(_condition) ) \ + { \ + BX_TRACE("CHECK " _format, ##__VA_ARGS__); \ + bx::debugBreak(); \ + } \ + BX_MACRO_BLOCK_END + +#include <bx/bx.h> + +#endif // BX_P_H_HEADER_GUARD diff --git a/3rdparty/bx/src/commandline.cpp b/3rdparty/bx/src/commandline.cpp index 6ec2aadaaaf..de658261c41 100644 --- a/3rdparty/bx/src/commandline.cpp +++ b/3rdparty/bx/src/commandline.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/commandline.h> #include <bx/string.h> @@ -197,7 +198,7 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - _value = atoi(arg); + fromString(&_value, arg); return true; } @@ -209,7 +210,7 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - _value = atoi(arg); + fromString(&_value, arg); return true; } @@ -221,7 +222,7 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - _value = float(atof(arg)); + fromString(&_value, arg); return true; } @@ -233,7 +234,7 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - _value = atof(arg); + fromString(&_value, arg); return true; } @@ -245,11 +246,11 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - if ('0' == *arg || (0 == strincmp(arg, "false") ) ) + if ('0' == *arg || (0 == strCmpI(arg, "false") ) ) { _value = false; } - else if ('0' != *arg || (0 == strincmp(arg, "true") ) ) + else if ('0' != *arg || (0 == strCmpI(arg, "true") ) ) { _value = true; } @@ -262,7 +263,7 @@ namespace bx const char* CommandLine::find(int32_t _skip, const char _short, const char* _long, int32_t _numParams) const { - for (int32_t ii = 0; ii < m_argc; ++ii) + for (int32_t ii = 0; ii < m_argc && 0 != strCmp(m_argv[ii], "--"); ++ii) { const char* arg = m_argv[ii]; if ('-' == *arg) @@ -270,7 +271,7 @@ namespace bx ++arg; if (_short == *arg) { - if (1 == strnlen(arg) ) + if (1 == strLen(arg) ) { if (0 == _skip) { @@ -293,7 +294,7 @@ namespace bx } else if (NULL != _long && '-' == *arg - && 0 == strincmp(arg+1, _long) ) + && 0 == strCmpI(arg+1, _long) ) { if (0 == _skip) { @@ -319,4 +320,14 @@ namespace bx return NULL; } + int32_t CommandLine::getNum() const + { + return m_argc; + } + + char const* CommandLine::get(int32_t _idx) const + { + return m_argv[_idx]; + } + } // namespace bx diff --git a/3rdparty/bx/src/crtimpl.cpp b/3rdparty/bx/src/crtimpl.cpp deleted file mode 100644 index 064b9f6e3ad..00000000000 --- a/3rdparty/bx/src/crtimpl.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright 2010-2017 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#include <bx/crtimpl.h> -#include <stdio.h> - -#if BX_CONFIG_ALLOCATOR_CRT -# include <malloc.h> -#endif // BX_CONFIG_ALLOCATOR_CRT - -namespace bx -{ -#if BX_CONFIG_ALLOCATOR_CRT - CrtAllocator::CrtAllocator() - { - } - - CrtAllocator::~CrtAllocator() - { - } - - void* CrtAllocator::realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) - { - if (0 == _size) - { - if (NULL != _ptr) - { - if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) - { - ::free(_ptr); - return NULL; - } - -# if BX_COMPILER_MSVC - BX_UNUSED(_file, _line); - _aligned_free(_ptr); -# else - bx::alignedFree(this, _ptr, _align, _file, _line); -# endif // BX_ - } - - return NULL; - } - else if (NULL == _ptr) - { - if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) - { - return ::malloc(_size); - } - -# if BX_COMPILER_MSVC - BX_UNUSED(_file, _line); - return _aligned_malloc(_size, _align); -# else - return bx::alignedAlloc(this, _size, _align, _file, _line); -# endif // BX_ - } - - if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) - { - return ::realloc(_ptr, _size); - } - -# if BX_COMPILER_MSVC - BX_UNUSED(_file, _line); - return _aligned_realloc(_ptr, _size, _align); -# else - return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line); -# endif // BX_ - } -#endif // BX_CONFIG_ALLOCATOR_CRT - -#if BX_CONFIG_CRT_FILE_READER_WRITER - -# if BX_CRT_MSVC -# define fseeko64 _fseeki64 -# define ftello64 _ftelli64 -# elif 0 \ - || BX_PLATFORM_ANDROID \ - || BX_PLATFORM_BSD \ - || BX_PLATFORM_IOS \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_QNX -# define fseeko64 fseeko -# define ftello64 ftello -# elif BX_PLATFORM_PS4 -# define fseeko64 fseek -# define ftello64 ftell -# endif // BX_ - - CrtFileReader::CrtFileReader() - : m_file(NULL) - { - } - - CrtFileReader::~CrtFileReader() - { - } - - bool CrtFileReader::open(const char* _filePath, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open."); - return false; - } - - m_file = fopen(_filePath, "rb"); - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileReader: Failed to open file."); - return false; - } - - return true; - } - - void CrtFileReader::close() - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fclose(file); - m_file = NULL; - } - - int64_t CrtFileReader::seek(int64_t _offset, Whence::Enum _whence) - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fseeko64(file, _offset, _whence); - return ftello64(file); - } - - int32_t CrtFileReader::read(void* _data, int32_t _size, Error* _err) - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fread(_data, 1, _size, file); - if (size != _size) - { - if (0 != feof(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "CrtFileReader: EOF."); - } - else if (0 != ferror(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "CrtFileReader: read error."); - } - - return size >= 0 ? size : 0; - } - - return size; - } - - CrtFileWriter::CrtFileWriter() - : m_file(NULL) - { - } - - CrtFileWriter::~CrtFileWriter() - { - } - - bool CrtFileWriter::open(const char* _filePath, bool _append, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open."); - return false; - } - - m_file = fopen(_filePath, _append ? "ab" : "wb"); - - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileWriter: Failed to open file."); - return false; - } - - return true; - } - - void CrtFileWriter::close() - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fclose(file); - m_file = NULL; - } - - int64_t CrtFileWriter::seek(int64_t _offset, Whence::Enum _whence) - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fseeko64(file, _offset, _whence); - return ftello64(file); - } - - int32_t CrtFileWriter::write(const void* _data, int32_t _size, Error* _err) - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fwrite(_data, 1, _size, file); - if (size != _size) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "CrtFileWriter: write failed."); - return size >= 0 ? size : 0; - } - - return size; - } -#endif // BX_CONFIG_CRT_FILE_READER_WRITER - -#if BX_CONFIG_CRT_PROCESS - -#if BX_CRT_MSVC -# define popen _popen -# define pclose _pclose -#endif // BX_CRT_MSVC - - ProcessReader::ProcessReader() - : m_file(NULL) - { - } - - ProcessReader::~ProcessReader() - { - BX_CHECK(NULL == m_file, "Process not closed!"); - } - - bool ProcessReader::open(const char* _command, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open."); - return false; - } - - m_file = popen(_command, "r"); - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process."); - return false; - } - - return true; - } - - void ProcessReader::close() - { - BX_CHECK(NULL != m_file, "Process not open!"); - FILE* file = (FILE*)m_file; - m_exitCode = pclose(file); - m_file = NULL; - } - - int32_t ProcessReader::read(void* _data, int32_t _size, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fread(_data, 1, _size, file); - if (size != _size) - { - if (0 != feof(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF."); - } - else if (0 != ferror(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error."); - } - - return size >= 0 ? size : 0; - } - - return size; - } - - int32_t ProcessReader::getExitCode() const - { - return m_exitCode; - } - - ProcessWriter::ProcessWriter() - : m_file(NULL) - { - } - - ProcessWriter::~ProcessWriter() - { - BX_CHECK(NULL == m_file, "Process not closed!"); - } - - bool ProcessWriter::open(const char* _command, bool, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open."); - return false; - } - - m_file = popen(_command, "w"); - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process."); - return false; - } - - return true; - } - - void ProcessWriter::close() - { - BX_CHECK(NULL != m_file, "Process not open!"); - FILE* file = (FILE*)m_file; - m_exitCode = pclose(file); - m_file = NULL; - } - - int32_t ProcessWriter::write(const void* _data, int32_t _size, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fwrite(_data, 1, _size, file); - if (size != _size) - { - if (0 != ferror(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error."); - } - - return size >= 0 ? size : 0; - } - - return size; - } - - int32_t ProcessWriter::getExitCode() const - { - return m_exitCode; - } -#endif // BX_CONFIG_CRT_PROCESS - -} // namespace bx diff --git a/3rdparty/bx/src/crtnone.cpp b/3rdparty/bx/src/crtnone.cpp index 0e88551b6f3..85028212133 100644 --- a/3rdparty/bx/src/crtnone.cpp +++ b/3rdparty/bx/src/crtnone.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/debug.h> #include <bx/sort.h> #include <bx/readerwriter.h> @@ -39,50 +40,50 @@ extern "C" int32_t memcmp(const void* _lhs, const void* _rhs, size_t _numBytes) extern "C" size_t strlen(const char* _str) { - return bx::strnlen(_str); + return bx::strLen(_str); } extern "C" size_t strnlen(const char* _str, size_t _max) { - return bx::strnlen(_str, _max); + return bx::strLen(_str, _max); } extern "C" void* strcpy(char* _dst, const char* _src) { - bx::strlncpy(_dst, INT32_MAX, _src, INT32_MAX); + bx::strCopy(_dst, INT32_MAX, _src, INT32_MAX); return _dst; } extern "C" void* strncpy(char* _dst, const char* _src, size_t _num) { - bx::strlncpy(_dst, INT32_MAX, _src, _num); + bx::strCopy(_dst, INT32_MAX, _src, _num); return _dst; } extern "C" char* strcat(char* _dst, const char* _src) { - bx::strlncat(_dst, INT32_MAX, _src, INT32_MAX); + bx::strCat(_dst, INT32_MAX, _src, INT32_MAX); return _dst; } extern "C" const char* strchr(const char* _str, int _ch) { - return bx::strnchr(_str, _ch); + return bx::strFind(_str, _ch); } extern "C" int32_t strcmp(const char* _lhs, const char* _rhs) { - return bx::strncmp(_lhs, _rhs); + return bx::strCmp(_lhs, _rhs); } extern "C" int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max) { - return bx::strncmp(_lhs, _rhs, _max); + return bx::strCmp(_lhs, _rhs, _max); } extern "C" const char* strstr(const char* _str, const char* _find) { - return bx::strnstr(_str, _find); + return bx::strFind(_str, _find); } extern "C" void qsort(void* _base, size_t _num, size_t _size, bx::ComparisonFn _fn) @@ -244,14 +245,16 @@ extern "C" float fmodf(float _numer, float _denom) extern "C" int atoi(const char* _str) { - BX_UNUSED(_str); - return 0; + int32_t result = 0; + bx::fromString(&result, _str); + return result; } extern "C" double atof(const char* _str) { - BX_UNUSED(_str); - return 0.0; + double result = 0.0; + bx::fromString(&result, _str); + return result; } extern "C" struct DIR* opendir(const char* dirname) @@ -301,6 +304,10 @@ extern "C" int printf(const char* _format, ...) return -1; } +struct FILE +{ +}; + extern "C" int fprintf(FILE* _stream, const char* _format, ...) { BX_UNUSED(_stream, _format); diff --git a/3rdparty/bx/src/debug.cpp b/3rdparty/bx/src/debug.cpp index 5e52be86e88..d08fc9903e6 100644 --- a/3rdparty/bx/src/debug.cpp +++ b/3rdparty/bx/src/debug.cpp @@ -3,13 +3,17 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/debug.h> -#include <bx/string.h> // isPrint -#include <inttypes.h> // PRIx* +#include <bx/string.h> // isPrint +#include <bx/readerwriter.h> // WriterI +#include <inttypes.h> // PRIx* #if BX_PLATFORM_ANDROID # include <android/log.h> -#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOXONE extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str); #elif BX_PLATFORM_IOS || BX_PLATFORM_OSX # if defined(__OBJC__) @@ -33,7 +37,7 @@ namespace bx #elif BX_CPU_ARM __builtin_trap(); // asm("bkpt 0"); -#elif !BX_PLATFORM_NACL && BX_CPU_X86 && (BX_COMPILER_GCC || BX_COMPILER_CLANG) +#elif BX_CPU_X86 && (BX_COMPILER_GCC || BX_COMPILER_CLANG) // NaCl doesn't like int 3: // NativeClient: NaCl module load failed: Validation failure. File violates Native Client safety rules. __asm__ ("int $3"); @@ -50,7 +54,9 @@ namespace bx # define BX_ANDROID_LOG_TAG "" # endif // BX_ANDROID_LOG_TAG __android_log_write(ANDROID_LOG_DEBUG, BX_ANDROID_LOG_TAG, _out); -#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOXONE OutputDebugStringA(_out); #elif BX_PLATFORM_IOS || BX_PLATFORM_OSX # if defined(__OBJC__) @@ -125,7 +131,7 @@ namespace bx ascii[asciiPos] = '\0'; debugPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii); data += asciiPos; - hexPos = 0; + hexPos = 0; asciiPos = 0; } } @@ -142,4 +148,32 @@ namespace bx #undef HEX_DUMP_FORMAT } + class DebugWriter : public WriterI + { + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override + { + BX_UNUSED(_err); + + int32_t total = 0; + + char temp[4096]; + while (total != _size) + { + uint32_t len = bx::uint32_min(sizeof(temp)-1, _size-total); + memCopy(temp, _data, len); + temp[len] = '\0'; + debugOutput(temp); + total += len; + } + + return total; + } + }; + + WriterI* getDebugOut() + { + static DebugWriter s_debugOut; + return &s_debugOut; + } + } // namespace bx diff --git a/3rdparty/bx/src/dtoa.cpp b/3rdparty/bx/src/dtoa.cpp index 98640ede20b..6945210dad1 100644 --- a/3rdparty/bx/src/dtoa.cpp +++ b/3rdparty/bx/src/dtoa.cpp @@ -3,8 +3,9 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/cpu.h> -#include <bx/fpumath.h> +#include <bx/math.h> #include <bx/string.h> #include <bx/uint32_t.h> @@ -12,28 +13,31 @@ namespace bx { - // https://github.com/miloyip/dtoa-benchmark - // - // Copyright (C) 2014 Milo Yip - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights - // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - // copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in - // all copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - // THE SOFTWARE. - // + /* + * https://github.com/miloyip/dtoa-benchmark + * + * Copyright (C) 2014 Milo Yip + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + struct DiyFp { DiyFp() @@ -77,7 +81,7 @@ namespace bx DiyFp operator*(const DiyFp& rhs) const { - const uint64_t M32 = 0xFFFFFFFF; + const uint64_t M32 = UINT32_MAX; const uint64_t a = f >> 32; const uint64_t b = f & M32; const uint64_t c = rhs.f >> 32; @@ -105,23 +109,23 @@ namespace bx void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { - DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); - DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + DiyFp pl = DiyFp( (f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp( (f << 2) - 1, e - 2) : DiyFp( (f << 1) - 1, e - 1); mi.f <<= mi.e - pl.e; mi.e = pl.e; *plus = pl; *minus = mi; } -#define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l)) +#define UINT64_C2(h, l) ( (static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l) ) - static const int32_t kDiySignificandSize = 64; - static const int32_t kDpSignificandSize = 52; - static const int32_t kDpExponentBias = 0x3FF + kDpSignificandSize; - static const int32_t kDpMinExponent = -kDpExponentBias; - static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000); - static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF); - static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000); + static const int32_t kDiySignificandSize = 64; + static const int32_t kDpSignificandSize = 52; + static const int32_t kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int32_t kDpMinExponent = -kDpExponentBias; + static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000); uint64_t f; int32_t e; @@ -217,10 +221,10 @@ namespace bx k++; } - uint32_t index = static_cast<uint32_t>((k >> 3) + 1); - *K = -(-348 + static_cast<int32_t>(index << 3)); // decimal exponent no need lookup table + uint32_t index = static_cast<uint32_t>( (k >> 3) + 1); + *K = -(-348 + static_cast<int32_t>(index << 3) ); // decimal exponent no need lookup table - BX_CHECK(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0])); + BX_CHECK(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0]), ""); return DiyFp(s_kCachedPowers_F[index], s_kCachedPowers_E[index]); } @@ -228,7 +232,7 @@ namespace bx { while (rest < wp_w && delta - rest >= ten_kappa - && (rest + ten_kappa < wp_w || wp_w - rest > rest + ten_kappa - wp_w)) + && (rest + ten_kappa < wp_w || wp_w - rest > rest + ten_kappa - wp_w) ) { buffer[len - 1]--; rest += ten_kappa; @@ -256,7 +260,7 @@ namespace bx const DiyFp wp_w = Mp - W; uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e); uint64_t p2 = Mp.f & (one.f - 1); - int32_t kappa = static_cast<int32_t>(CountDecimalDigit32(p1)); + int32_t kappa = static_cast<int32_t>(CountDecimalDigit32(p1) ); *len = 0; while (kappa > 0) @@ -436,17 +440,17 @@ namespace bx if (isNan(_value) ) { - return (int32_t)strlncpy(_dst, _max, "nan") + sign; + return (int32_t)strCopy(_dst, _max, "nan") + sign; } else if (isInfinite(_value) ) { - return (int32_t)strlncpy(_dst, _max, "inf") + sign; + return (int32_t)strCopy(_dst, _max, "inf") + sign; } int32_t len; if (0.0 == _value) { - len = (int32_t)strlncpy(_dst, _max, "0.0"); + len = (int32_t)strCopy(_dst, _max, "0.0"); } else { @@ -557,4 +561,584 @@ namespace bx return toStringUnsigned(_dst, _max, _value, _base); } + /* + * https://github.com/grzegorz-kraszewski/stringtofloat/ + * + * MIT License + * + * Copyright (c) 2016 Grzegorz Kraszewski + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + /* + * IMPORTANT + * + * The code works in "round towards zero" mode. This is different from + * GCC standard library strtod(), which uses "round half to even" rule. + * Therefore it cannot be used as a direct drop-in replacement, as in + * some cases results will be different on the least significant bit of + * mantissa. Read more in the README.md file. + */ + +#define DIGITS 18 + +#define DOUBLE_PLUS_ZERO UINT64_C(0x0000000000000000) +#define DOUBLE_MINUS_ZERO UINT64_C(0x8000000000000000) +#define DOUBLE_PLUS_INFINITY UINT64_C(0x7ff0000000000000) +#define DOUBLE_MINUS_INFINITY UINT64_C(0xfff0000000000000) + + union HexDouble + { + double d; + uint64_t u; + }; + +#define lsr96(s2, s1, s0, d2, d1, d0) \ + d0 = ( (s0) >> 1) | ( ( (s1) & 1) << 31); \ + d1 = ( (s1) >> 1) | ( ( (s2) & 1) << 31); \ + d2 = (s2) >> 1; + +#define lsl96(s2, s1, s0, d2, d1, d0) \ + d2 = ( (s2) << 1) | ( ( (s1) & (1 << 31) ) >> 31); \ + d1 = ( (s1) << 1) | ( ( (s0) & (1 << 31) ) >> 31); \ + d0 = (s0) << 1; + + /* + * Undefine the below constant if your processor or compiler is slow + * at 64-bit arithmetic. This is a rare case however. 64-bit macros are + * better for deeply pipelined CPUs (no conditional execution), are + * very efficient for 64-bit processors and also fast on 32-bit processors + * featuring extended precision arithmetic (x86, PowerPC_32, M68k and probably + * more). + */ + +#define USE_64BIT_FOR_ADDSUB_MACROS 0 + +#if USE_64BIT_FOR_ADDSUB_MACROS + +#define add96(s2, s1, s0, d2, d1, d0) { \ + uint64_t w; \ + w = (uint64_t)(s0) + (uint64_t)(d0); \ + (s0) = w; \ + w >>= 32; \ + w += (uint64_t)(s1) + (uint64_t)(d1); \ + (s1) = w; \ + w >>= 32; \ + w += (uint64_t)(s2) + (uint64_t)(d2); \ + (s2) = w; } + +#define sub96(s2, s1, s0, d2, d1, d0) { \ + uint64_t w; \ + w = (uint64_t)(s0) - (uint64_t)(d0); \ + (s0) = w; \ + w >>= 32; \ + w += (uint64_t)(s1) - (uint64_t)(d1); \ + (s1) = w; \ + w >>= 32; \ + w += (uint64_t)(s2) - (uint64_t)(d2); \ + (s2) = w; } + +#else + +#define add96(s2, s1, s0, d2, d1, d0) { \ + uint32_t _x, _c; \ + _x = (s0); (s0) += (d0); \ + if ( (s0) < _x) _c = 1; else _c = 0; \ + _x = (s1); (s1) += (d1) + _c; \ + if ( ( (s1) < _x) || ( ( (s1) == _x) && _c) ) _c = 1; else _c = 0; \ + (s2) += (d2) + _c; } + +#define sub96(s2, s1, s0, d2, d1, d0) { \ + uint32_t _x, _c; \ + _x = (s0); (s0) -= (d0); \ + if ( (s0) > _x) _c = 1; else _c = 0; \ + _x = (s1); (s1) -= (d1) + _c; \ + if ( ( (s1) > _x) || ( ( (s1) == _x) && _c) ) _c = 1; else _c = 0; \ + (s2) -= (d2) + _c; } + +#endif /* USE_64BIT_FOR_ADDSUB_MACROS */ + + /* parser state machine states */ + +#define FSM_A 0 +#define FSM_B 1 +#define FSM_C 2 +#define FSM_D 3 +#define FSM_E 4 +#define FSM_F 5 +#define FSM_G 6 +#define FSM_H 7 +#define FSM_I 8 +#define FSM_STOP 9 + + /* The structure is filled by parser, then given to converter. */ + struct PrepNumber + { + int negative; /* 0 if positive number, 1 if negative */ + int32_t exponent; /* power of 10 exponent */ + uint64_t mantissa; /* integer mantissa */ + }; + + /* Possible parser return values. */ + +#define PARSER_OK 0 // parser finished OK +#define PARSER_PZERO 1 // no digits or number is smaller than +-2^-1022 +#define PARSER_MZERO 2 // number is negative, module smaller +#define PARSER_PINF 3 // number is higher than +HUGE_VAL +#define PARSER_MINF 4 // number is lower than -HUGE_VAL + + inline char next(const char*& _s, const char* _term) + { + return _s != _term + ? *_s++ + : '\0' + ; + } + + static int parser(const char* _s, const char* _term, PrepNumber* _pn) + { + int state = FSM_A; + int digx = 0; + char c = ' '; /* initial value for kicking off the state machine */ + int result = PARSER_OK; + int expneg = 0; + int32_t expexp = 0; + + while (state != FSM_STOP) // && _s != _term) + { + switch (state) + { + case FSM_A: + if (isSpace(c) ) + { + c = next(_s, _term); + } + else + { + state = FSM_B; + } + break; + + case FSM_B: + state = FSM_C; + + if (c == '+') + { + c = next(_s, _term); + } + else if (c == '-') + { + _pn->negative = 1; + c = next(_s, _term); + } + else if (isNumeric(c) ) + { + } + else if (c == '.') + { + } + else + { + state = FSM_STOP; + } + break; + + case FSM_C: + if (c == '0') + { + c = next(_s, _term); + } + else if (c == '.') + { + c = next(_s, _term); + state = FSM_D; + } + else + { + state = FSM_E; + } + break; + + case FSM_D: + if (c == '0') + { + c = next(_s, _term); + if (_pn->exponent > -2147483647) _pn->exponent--; + } + else + { + state = FSM_F; + } + break; + + case FSM_E: + if (isNumeric(c) ) + { + if (digx < DIGITS) + { + _pn->mantissa *= 10; + _pn->mantissa += c - '0'; + digx++; + } + else if (_pn->exponent < 2147483647) + { + _pn->exponent++; + } + + c = next(_s, _term); + } + else if (c == '.') + { + c = next(_s, _term); + state = FSM_F; + } + else + { + state = FSM_F; + } + break; + + case FSM_F: + if (isNumeric(c) ) + { + if (digx < DIGITS) + { + _pn->mantissa *= 10; + _pn->mantissa += c - '0'; + _pn->exponent--; + digx++; + } + + c = next(_s, _term); + } + else if ('e' == toLower(c) ) + { + c = next(_s, _term); + state = FSM_G; + } + else + { + state = FSM_G; + } + break; + + case FSM_G: + if (c == '+') + { + c = next(_s, _term); + } + else if (c == '-') + { + expneg = 1; + c = next(_s, _term); + } + + state = FSM_H; + break; + + case FSM_H: + if (c == '0') + { + c = next(_s, _term); + } + else + { + state = FSM_I; + } + break; + + case FSM_I: + if (isNumeric(c) ) + { + if (expexp < 214748364) + { + expexp *= 10; + expexp += c - '0'; + } + + c = next(_s, _term); + } + else + { + state = FSM_STOP; + } + break; + } + } + + if (expneg) + { + expexp = -expexp; + } + + _pn->exponent += expexp; + + if (_pn->mantissa == 0) + { + if (_pn->negative) + { + result = PARSER_MZERO; + } + else + { + result = PARSER_PZERO; + } + } + else if (_pn->exponent > 309) + { + if (_pn->negative) + { + result = PARSER_MINF; + } + else + { + result = PARSER_PINF; + } + } + else if (_pn->exponent < -328) + { + if (_pn->negative) + { + result = PARSER_MZERO; + } + else + { + result = PARSER_PZERO; + } + } + + return result; + } + + static double converter(PrepNumber* _pn) + { + int binexp = 92; + HexDouble hd; + uint32_t s2, s1, s0; /* 96-bit precision integer */ + uint32_t q2, q1, q0; /* 96-bit precision integer */ + uint32_t r2, r1, r0; /* 96-bit precision integer */ + uint32_t mask28 = UINT32_C(0xf) << 28; + + hd.u = 0; + + s0 = (uint32_t)(_pn->mantissa & UINT32_MAX); + s1 = (uint32_t)(_pn->mantissa >> 32); + s2 = 0; + + while (_pn->exponent > 0) + { + lsl96(s2, s1, s0, q2, q1, q0); // q = p << 1 + lsl96(q2, q1, q0, r2, r1, r0); // r = p << 2 + lsl96(r2, r1, r0, s2, s1, s0); // p = p << 3 + add96(s2, s1, s0, q2, q1, q0); // p = (p << 3) + (p << 1) + + _pn->exponent--; + + while (s2 & mask28) + { + lsr96(s2, s1, s0, q2, q1, q0); + binexp++; + s2 = q2; + s1 = q1; + s0 = q0; + } + } + + while (_pn->exponent < 0) + { + while (!(s2 & (1 << 31) ) ) + { + lsl96(s2, s1, s0, q2, q1, q0); + binexp--; + s2 = q2; + s1 = q1; + s0 = q0; + } + + q2 = s2 / 10; + r1 = s2 % 10; + r2 = (s1 >> 8) | (r1 << 24); + q1 = r2 / 10; + r1 = r2 % 10; + r2 = ( (s1 & 0xFF) << 16) | (s0 >> 16) | (r1 << 24); + r0 = r2 / 10; + r1 = r2 % 10; + q1 = (q1 << 8) | ( (r0 & 0x00FF0000) >> 16); + q0 = r0 << 16; + r2 = (s0 & UINT16_MAX) | (r1 << 16); + q0 |= r2 / 10; + s2 = q2; + s1 = q1; + s0 = q0; + + _pn->exponent++; + } + + if (s2 || s1 || s0) + { + while (!(s2 & mask28) ) + { + lsl96(s2, s1, s0, q2, q1, q0); + binexp--; + s2 = q2; + s1 = q1; + s0 = q0; + } + } + + binexp += 1023; + + if (binexp > 2046) + { + if (_pn->negative) + { + hd.u = DOUBLE_MINUS_INFINITY; + } + else + { + hd.u = DOUBLE_PLUS_INFINITY; + } + } + else if (binexp < 1) + { + if (_pn->negative) + { + hd.u = DOUBLE_MINUS_ZERO; + } + } + else if (s2) + { + uint64_t q; + uint64_t binexs2 = (uint64_t)binexp; + + binexs2 <<= 52; + q = ( (uint64_t)(s2 & ~mask28) << 24) + | ( ( (uint64_t)s1 + 128) >> 8) | binexs2; + + if (_pn->negative) + { + q |= (1ULL << 63); + } + + hd.u = q; + } + + return hd.d; + } + + int32_t toString(char* _out, int32_t _max, bool _value) + { + StringView str(_value ? "true" : "false"); + strCopy(_out, _max, str); + return str.getLength(); + } + + bool fromString(bool* _out, const StringView& _str) + { + char ch = toLower(_str.getPtr()[0]); + *_out = ch == 't' || ch == '1'; + return 0 != _str.getLength(); + } + + bool fromString(float* _out, const StringView& _str) + { + double dbl; + bool result = fromString(&dbl, _str); + *_out = float(dbl); + return result; + } + + bool fromString(double* _out, const StringView& _str) + { + PrepNumber pn; + pn.mantissa = 0; + pn.negative = 0; + pn.exponent = 0; + + HexDouble hd; + hd.u = DOUBLE_PLUS_ZERO; + + switch (parser(_str.getPtr(), _str.getTerm(), &pn) ) + { + case PARSER_OK: + *_out = converter(&pn); + break; + + case PARSER_PZERO: + *_out = hd.d; + break; + + case PARSER_MZERO: + hd.u = DOUBLE_MINUS_ZERO; + *_out = hd.d; + break; + + case PARSER_PINF: + hd.u = DOUBLE_PLUS_INFINITY; + *_out = hd.d; + break; + + case PARSER_MINF: + hd.u = DOUBLE_MINUS_INFINITY; + *_out = hd.d; + break; + } + + return true; + } + + bool fromString(int32_t* _out, const StringView& _str) + { + const char* str = _str.getPtr(); + const char* term = _str.getTerm(); + + str = strws(str); + char ch = *str++; + bool neg = false; + switch (ch) + { + case '-': + case '+': neg = '-' == ch; + break; + + default: + --str; + break; + } + + int32_t result = 0; + + for (ch = *str++; isNumeric(ch) && str <= term; ch = *str++) + { + result = 10*result - (ch - '0'); + } + + *_out = neg ? result : -result; + + return true; + } + + bool fromString(uint32_t* _out, const StringView& _str) + { + fromString( (int32_t*)_out, _str); + return true; + } + } // namespace bx diff --git a/3rdparty/bx/src/easing.cpp b/3rdparty/bx/src/easing.cpp new file mode 100644 index 00000000000..8ecb2d53299 --- /dev/null +++ b/3rdparty/bx/src/easing.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/easing.h> + +namespace bx +{ + static const EaseFn s_easeFunc[] = + { + easeLinear, + easeStep, + easeSmoothStep, + easeInQuad, + easeOutQuad, + easeInOutQuad, + easeOutInQuad, + easeInCubic, + easeOutCubic, + easeInOutCubic, + easeOutInCubic, + easeInQuart, + easeOutQuart, + easeInOutQuart, + easeOutInQuart, + easeInQuint, + easeOutQuint, + easeInOutQuint, + easeOutInQuint, + easeInSine, + easeOutSine, + easeInOutSine, + easeOutInSine, + easeInExpo, + easeOutExpo, + easeInOutExpo, + easeOutInExpo, + easeInCirc, + easeOutCirc, + easeInOutCirc, + easeOutInCirc, + easeInElastic, + easeOutElastic, + easeInOutElastic, + easeOutInElastic, + easeInBack, + easeOutBack, + easeInOutBack, + easeOutInBack, + easeInBounce, + easeOutBounce, + easeInOutBounce, + easeOutInBounce, + }; + BX_STATIC_ASSERT(BX_COUNTOF(s_easeFunc) == Easing::Count); + + EaseFn getEaseFunc(Easing::Enum _enum) + { + return s_easeFunc[_enum]; + } + +} // namespace bx diff --git a/3rdparty/bx/src/file.cpp b/3rdparty/bx/src/file.cpp new file mode 100644 index 00000000000..af74589c876 --- /dev/null +++ b/3rdparty/bx/src/file.cpp @@ -0,0 +1,408 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/file.h> + +#include <stdio.h> +#include <sys/stat.h> + +#ifndef BX_CONFIG_CRT_FILE_READER_WRITER +# define BX_CONFIG_CRT_FILE_READER_WRITER !(0 \ + || BX_CRT_NONE \ + ) +#endif // BX_CONFIG_CRT_FILE_READER_WRITER + +namespace bx +{ + class NoopWriterImpl : public FileWriterI + { + public: + NoopWriterImpl(void*) + { + } + + virtual ~NoopWriterImpl() + { + close(); + } + + virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override + { + BX_UNUSED(_filePath, _append, _err); + return false; + } + + virtual void close() override + { + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override + { + BX_UNUSED(_offset, _whence); + return 0; + } + + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override + { + BX_UNUSED(_data, _size, _err); + return 0; + } + }; + +#if BX_CONFIG_CRT_FILE_READER_WRITER + +# if BX_CRT_MSVC +# define fseeko64 _fseeki64 +# define ftello64 _ftelli64 +# elif 0 \ + || BX_PLATFORM_ANDROID \ + || BX_PLATFORM_BSD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_QNX +# define fseeko64 fseeko +# define ftello64 ftello +# elif BX_PLATFORM_PS4 +# define fseeko64 fseek +# define ftello64 ftell +# endif // BX_ + + class FileReaderImpl : public FileReaderI + { + public: + FileReaderImpl(FILE* _file) + : m_file(_file) + , m_open(false) + { + } + + virtual ~FileReaderImpl() + { + close(); + } + + virtual bool open(const FilePath& _filePath, Error* _err) override + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "FileReader: File is already open."); + return false; + } + + m_file = fopen(_filePath.get(), "rb"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileReader: Failed to open file."); + return false; + } + + m_open = true; + return true; + } + + virtual void close() override + { + if (m_open + && NULL != m_file) + { + fclose(m_file); + m_file = NULL; + } + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t read(void* _data, int32_t _size, Error* _err) override + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + int32_t size = (int32_t)fread(_data, 1, _size, m_file); + if (size != _size) + { + if (0 != feof(m_file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "FileReader: EOF."); + } + else if (0 != ferror(m_file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "FileReader: read error."); + } + + return size >= 0 ? size : 0; + } + + return size; + } + + private: + FILE* m_file; + bool m_open; + }; + + class FileWriterImpl : public FileWriterI + { + public: + FileWriterImpl(FILE* _file) + : m_file(_file) + , m_open(false) + { + } + + virtual ~FileWriterImpl() + { + close(); + } + + virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "FileReader: File is already open."); + return false; + } + + m_file = fopen(_filePath.get(), _append ? "ab" : "wb"); + + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileWriter: Failed to open file."); + return false; + } + + m_open = true; + return true; + } + + virtual void close() override + { + if (m_open + && NULL != m_file) + { + fclose(m_file); + m_file = NULL; + } + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + int32_t size = (int32_t)fwrite(_data, 1, _size, m_file); + if (size != _size) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "FileWriter: write failed."); + return size >= 0 ? size : 0; + } + + return size; + } + + private: + FILE* m_file; + bool m_open; + }; + +#else + + class FileReaderImpl : public FileReaderI + { + public: + FileReaderImpl(void*) + { + } + + virtual ~FileReaderImpl() + { + close(); + } + + virtual bool open(const FilePath& _filePath, Error* _err) override + { + BX_UNUSED(_filePath, _err); + return false; + } + + virtual void close() override + { + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override + { + BX_UNUSED(_offset, _whence); + return 0; + } + + virtual int32_t read(void* _data, int32_t _size, Error* _err) override + { + BX_UNUSED(_data, _size, _err); + return 0; + } + }; + + typedef NoopWriterImpl FileWriterImpl; + +#endif // BX_CONFIG_CRT_FILE_READER_WRITER + + FileReader::FileReader() + { + BX_STATIC_ASSERT(sizeof(FileReaderImpl) <= sizeof(m_internal) ); + BX_PLACEMENT_NEW(m_internal, FileReaderImpl)(NULL); + } + + FileReader::~FileReader() + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + impl->~FileReaderImpl(); + } + + bool FileReader::open(const FilePath& _filePath, Error* _err) + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + return impl->open(_filePath, _err); + } + + void FileReader::close() + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + impl->close(); + } + + int64_t FileReader::seek(int64_t _offset, Whence::Enum _whence) + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + return impl->seek(_offset, _whence); + } + + int32_t FileReader::read(void* _data, int32_t _size, Error* _err) + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + return impl->read(_data, _size, _err); + } + + FileWriter::FileWriter() + { + BX_STATIC_ASSERT(sizeof(FileWriterImpl) <= sizeof(m_internal) ); + BX_PLACEMENT_NEW(m_internal, FileWriterImpl)(NULL); + } + + FileWriter::~FileWriter() + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + impl->~FileWriterImpl(); + } + + bool FileWriter::open(const FilePath& _filePath, bool _append, Error* _err) + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + return impl->open(_filePath, _append, _err); + } + + void FileWriter::close() + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + impl->close(); + } + + int64_t FileWriter::seek(int64_t _offset, Whence::Enum _whence) + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + return impl->seek(_offset, _whence); + } + + int32_t FileWriter::write(const void* _data, int32_t _size, Error* _err) + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + return impl->write(_data, _size, _err); + } + + ReaderI* getStdIn() + { + static FileReaderImpl s_stdIn(stdout); + return &s_stdIn; + } + + WriterI* getStdOut() + { + static FileWriterImpl s_stdOut(stdout); + return &s_stdOut; + } + + WriterI* getStdErr() + { + static FileWriterImpl s_stdOut(stderr); + return &s_stdOut; + } + + WriterI* getNullOut() + { + static NoopWriterImpl s_nullOut(NULL); + return &s_nullOut; + } + + bool stat(const FilePath& _filePath, FileInfo& _outFileInfo) + { + _outFileInfo.m_size = 0; + _outFileInfo.m_type = FileInfo::Count; + +#if BX_COMPILER_MSVC + struct ::_stat64 st; + int32_t result = ::_stat64(_filePath.get(), &st); + + if (0 != result) + { + return false; + } + + if (0 != (st.st_mode & _S_IFREG) ) + { + _outFileInfo.m_type = FileInfo::Regular; + } + else if (0 != (st.st_mode & _S_IFDIR) ) + { + _outFileInfo.m_type = FileInfo::Directory; + } +#else + struct ::stat st; + int32_t result = ::stat(_filePath.get(), &st); + if (0 != result) + { + return false; + } + + if (0 != (st.st_mode & S_IFREG) ) + { + _outFileInfo.m_type = FileInfo::Regular; + } + else if (0 != (st.st_mode & S_IFDIR) ) + { + _outFileInfo.m_type = FileInfo::Directory; + } +#endif // BX_COMPILER_MSVC + + _outFileInfo.m_size = st.st_size; + + return true; + } + +} // namespace bx diff --git a/3rdparty/bx/src/filepath.cpp b/3rdparty/bx/src/filepath.cpp new file mode 100644 index 00000000000..b8bbe279a59 --- /dev/null +++ b/3rdparty/bx/src/filepath.cpp @@ -0,0 +1,543 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/file.h> +#include <bx/os.h> +#include <bx/readerwriter.h> + +#include <stdio.h> // remove +#include <dirent.h> // opendir + +#if BX_CRT_MSVC +# include <direct.h> // _getcwd +#else +# include <sys/stat.h> // mkdir +# include <unistd.h> // getcwd +#endif // BX_CRT_MSVC + +#if BX_PLATFORM_WINDOWS +extern "C" __declspec(dllimport) unsigned long __stdcall GetTempPathA(unsigned long _max, char* _ptr); +#endif // BX_PLATFORM_WINDOWS + +namespace bx +{ + static bool isPathSeparator(char _ch) + { + return false + || '/' == _ch + || '\\' == _ch + ; + } + + static int32_t normalizeFilePath(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) + { + // Reference: Lexical File Names in Plan 9 or Getting Dot-Dot Right + // https://9p.io/sys/doc/lexnames.html + + const int32_t num = strLen(_src, _num); + + if (0 == num) + { + return strCopy(_dst, _dstSize, "."); + } + + int32_t size = 0; + + StaticMemoryBlockWriter writer(_dst, _dstSize); + Error err; + + int32_t idx = 0; + int32_t dotdot = 0; + + if (2 <= num + && ':' == _src[1]) + { + size += write(&writer, toUpper(_src[idx]), &err); + size += write(&writer, ':', &err); + idx += 2; + dotdot = size; + } + + const int32_t slashIdx = idx; + + bool rooted = isPathSeparator(_src[idx]); + if (rooted) + { + size += write(&writer, '/', &err); + ++idx; + dotdot = size; + } + + bool trailingSlash = false; + + while (idx < num && err.isOk() ) + { + switch (_src[idx]) + { + case '/': + case '\\': + ++idx; + trailingSlash = idx == num; + break; + + case '.': + if (idx+1 == num + || isPathSeparator(_src[idx+1]) ) + { + ++idx; + break; + } + + if ('.' == _src[idx+1] + && (idx+2 == num || isPathSeparator(_src[idx+2]) ) ) + { + idx += 2; + + if (dotdot < size) + { + for (--size + ; dotdot < size && !isPathSeparator(_dst[size]) + ; --size) + { + } + seek(&writer, size, Whence::Begin); + } + else if (!rooted) + { + if (0 < size) + { + size += write(&writer, '/', &err); + } + + size += write(&writer, "..", &err); + dotdot = size; + } + + break; + } + + BX_FALLTHROUGH; + + default: + if ( ( rooted && slashIdx+1 != size) + || (!rooted && 0 != size) ) + { + size += write(&writer, '/', &err); + } + + for (; idx < num && !isPathSeparator(_src[idx]); ++idx) + { + size += write(&writer, _src[idx], &err); + } + + break; + } + } + + if (0 == size) + { + size += write(&writer, '.', &err); + } + + if (trailingSlash) + { + size += write(&writer, '/', &err); + } + + write(&writer, '\0', &err); + + return size; + } + + static bool getEnv(const char* _name, FileInfo::Enum _type, char* _out, uint32_t* _inOutSize) + { + uint32_t len = *_inOutSize; + *_out = '\0'; + + if (getenv(_name, _out, &len) ) + { + FileInfo fi; + if (stat(_out, fi) + && _type == fi.m_type) + { + *_inOutSize = len; + return true; + } + } + + return false; + } + + static char* pwd(char* _buffer, uint32_t _size) + { +#if BX_PLATFORM_PS4 \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT + BX_UNUSED(_buffer, _size); + return NULL; +#elif BX_CRT_MSVC + return ::_getcwd(_buffer, (int32_t)_size); +#else + return ::getcwd(_buffer, _size); +#endif // BX_COMPILER_ + } + + static bool getCurrentPath(char* _out, uint32_t* _inOutSize) + { + uint32_t len = *_inOutSize; + pwd(_out, len); + *_inOutSize = strLen(_out); + return true; + } + + static bool getHomePath(char* _out, uint32_t* _inOutSize) + { + return false +#if BX_PLATFORM_WINDOWS + || getEnv("USERPROFILE", FileInfo::Directory, _out, _inOutSize) +#endif // BX_PLATFORM_WINDOWS + || getEnv("HOME", FileInfo::Directory, _out, _inOutSize) + ; + } + + static bool getTempPath(char* _out, uint32_t* _inOutSize) + { +#if BX_PLATFORM_WINDOWS + uint32_t len = ::GetTempPathA(*_inOutSize, _out); + bool result = len != 0 && len < *_inOutSize; + *_inOutSize = len; + return result; +#else + static const char* s_tmp[] = + { + "TMPDIR", + "TMP", + "TEMP", + "TEMPDIR", + + NULL + }; + + for (const char** tmp = s_tmp; *tmp != NULL; ++tmp) + { + uint32_t len = *_inOutSize; + *_out = '\0'; + bool ok = getEnv(*tmp, FileInfo::Directory, _out, &len); + + if (ok + && len != 0 + && len < *_inOutSize) + { + *_inOutSize = len; + return ok; + } + } + + FileInfo fi; + if (stat("/tmp", fi) + && FileInfo::Directory == fi.m_type) + { + strCopy(_out, *_inOutSize, "/tmp"); + *_inOutSize = 4; + return true; + } + + return false; +#endif // BX_PLATFORM_* + } + + FilePath::FilePath() + { + set(""); + } + + FilePath::FilePath(Dir::Enum _dir) + { + set(_dir); + } + + FilePath::FilePath(const char* _rhs) + { + set(_rhs); + } + + FilePath::FilePath(const StringView& _filePath) + { + set(_filePath); + } + + FilePath& FilePath::operator=(const StringView& _rhs) + { + set(_rhs); + return *this; + } + + void FilePath::set(Dir::Enum _dir) + { + char tmp[kMaxFilePath]; + uint32_t len = BX_COUNTOF(tmp); + + switch (_dir) + { + case Dir::Current: + getCurrentPath(tmp, &len); + break; + + case Dir::Temp: + getTempPath(tmp, &len); + break; + + case Dir::Home: + getHomePath(tmp, &len); + break; + + default: + len = 0; + break; + } + + set(StringView(tmp, len) ); + } + + void FilePath::set(const StringView& _filePath) + { + normalizeFilePath( + m_filePath + , BX_COUNTOF(m_filePath) + , _filePath.getPtr() + , _filePath.getLength() + ); + } + + void FilePath::join(const StringView& _str) + { + char tmp[kMaxFilePath]; + strCopy(tmp, BX_COUNTOF(tmp), m_filePath); + strCat(tmp, BX_COUNTOF(tmp), "/"); + strCat(tmp, BX_COUNTOF(tmp), _str); + set(tmp); + } + + const char* FilePath::get() const + { + return m_filePath; + } + + const StringView FilePath::getPath() const + { + const char* end = strRFind(m_filePath, '/'); + if (NULL != end) + { + return StringView(m_filePath, end+1); + } + + return StringView(); + } + + const StringView FilePath::getFileName() const + { + const char* fileName = strRFind(m_filePath, '/'); + if (NULL != fileName) + { + return StringView(fileName+1); + } + + return get(); + } + + const StringView FilePath::getBaseName() const + { + const StringView fileName = getFileName(); + if (!fileName.isEmpty() ) + { + const char* ext = strFind(fileName, '.'); + if (ext != NULL) + { + return StringView(fileName.getPtr(), ext); + } + + return fileName; + } + + return StringView(); + } + + const StringView FilePath::getExt() const + { + const StringView fileName = getFileName(); + if (!fileName.isEmpty() ) + { + const char* ext = strFind(fileName, '.'); + return StringView(ext); + } + + return StringView(); + } + + bool FilePath::isAbsolute() const + { + return '/' == m_filePath[0] // no drive letter + || (':' == m_filePath[1] && '/' == m_filePath[2]) // with drive letter + ; + } + + bool make(const FilePath& _filePath, Error* _err) + { + BX_ERROR_SCOPE(_err); + + if (!_err->isOk() ) + { + return false; + } + +#if BX_CRT_MSVC + int32_t result = ::_mkdir(_filePath.get() ); +#elif BX_CRT_MINGW + int32_t result = ::mkdir(_filePath.get()); +#else + int32_t result = ::mkdir(_filePath.get(), 0700); +#endif // BX_CRT_MSVC + + if (0 != result) + { + BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process."); + return false; + } + + return true; + } + + bool makeAll(const FilePath& _filePath, Error* _err) + { + BX_ERROR_SCOPE(_err); + + if (!_err->isOk() ) + { + return false; + } + + FileInfo fi; + + if (stat(_filePath, fi) ) + { + if (FileInfo::Directory == fi.m_type) + { + return true; + } + + BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory."); + return false; + } + + const StringView dir = strRTrim(_filePath.get(), "/"); + const char* slash = strRFind(dir, '/'); + + if (NULL != slash + && slash - dir.getPtr() > 1) + { + if (!makeAll(StringView(dir.getPtr(), slash), _err) ) + { + return false; + } + } + + FilePath path(dir); + return make(path, _err); + } + + bool remove(const FilePath& _filePath, Error* _err) + { + BX_ERROR_SCOPE(_err); + + if (!_err->isOk() ) + { + return false; + } + +#if BX_CRT_MSVC + int32_t result = -1; + FileInfo fi; + if (stat(_filePath, fi) ) + { + if (FileInfo::Directory == fi.m_type) + { + result = ::_rmdir(_filePath.get() ); + } + else + { + result = ::remove(_filePath.get() ); + } + } +#else + int32_t result = ::remove(_filePath.get() ); +#endif // BX_CRT_MSVC + + if (0 != result) + { + BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process."); + return false; + } + + return true; + } + + bool removeAll(const FilePath& _filePath, Error* _err) + { + BX_ERROR_SCOPE(_err); + + if (remove(_filePath, _err) ) + { + return true; + } + + _err->reset(); + + FileInfo fi; + + if (!stat(_filePath, fi) ) + { + BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process."); + return false; + } + + if (FileInfo::Directory != fi.m_type) + { + BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory."); + return false; + } + +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX || BX_PLATFORM_OSX + DIR* dir = opendir(_filePath.get() ); + if (NULL == dir) + { + BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory."); + return false; + } + + for (dirent* item = readdir(dir); NULL != item; item = readdir(dir) ) + { + if (0 == strCmp(item->d_name, ".") + || 0 == strCmp(item->d_name, "..") ) + { + continue; + } + + FilePath path(_filePath); + path.join(item->d_name); + if (!removeAll(path, _err) ) + { + _err->reset(); + break; + } + } + + closedir(dir); +#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX || BX_PLATFORM_OSX + + return remove(_filePath, _err); + } + +} // namespace bx diff --git a/3rdparty/bx/src/fpumath.cpp b/3rdparty/bx/src/fpumath.cpp deleted file mode 100644 index e957ef9e960..00000000000 --- a/3rdparty/bx/src/fpumath.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2011-2017 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#include <bx/fpumath.h> -#include <math.h> - -namespace bx -{ - const float pi = 3.14159265358979323846f; - const float invPi = 1.0f/3.14159265358979323846f; - const float piHalf = 1.57079632679489661923f; - const float sqrt2 = 1.41421356237309504880f; -#if BX_COMPILER_MSVC - const float huge = float(HUGE_VAL); -#else - const float huge = HUGE_VALF; -#endif // BX_COMPILER_MSVC - - float fabsolute(float _a) - { - return ::fabsf(_a); - } - - float fsin(float _a) - { - return ::sinf(_a); - } - - float fasin(float _a) - { - return ::asinf(_a); - } - - float fcos(float _a) - { - return ::cosf(_a); - } - - float ftan(float _a) - { - return ::tanf(_a); - } - - float facos(float _a) - { - return ::acosf(_a); - } - - float fatan2(float _y, float _x) - { - return ::atan2f(_y, _x); - } - - float fpow(float _a, float _b) - { - return ::powf(_a, _b); - } - - float flog(float _a) - { - return ::logf(_a); - } - - float fsqrt(float _a) - { - return ::sqrtf(_a); - } - - float ffloor(float _f) - { - return ::floorf(_f); - } - - float fceil(float _f) - { - return ::ceilf(_f); - } - - float fmod(float _a, float _b) - { - return ::fmodf(_a, _b); - } - - void mtx3Inverse(float* _result, const float* _a) - { - float xx = _a[0]; - float xy = _a[1]; - float xz = _a[2]; - float yx = _a[3]; - float yy = _a[4]; - float yz = _a[5]; - float zx = _a[6]; - float zy = _a[7]; - float zz = _a[8]; - - float det = 0.0f; - det += xx * (yy*zz - yz*zy); - det -= xy * (yx*zz - yz*zx); - det += xz * (yx*zy - yy*zx); - - float invDet = 1.0f/det; - - _result[0] = +(yy*zz - yz*zy) * invDet; - _result[1] = -(xy*zz - xz*zy) * invDet; - _result[2] = +(xy*yz - xz*yy) * invDet; - - _result[3] = -(yx*zz - yz*zx) * invDet; - _result[4] = +(xx*zz - xz*zx) * invDet; - _result[5] = -(xx*yz - xz*yx) * invDet; - - _result[6] = +(yx*zy - yy*zx) * invDet; - _result[7] = -(xx*zy - xy*zx) * invDet; - _result[8] = +(xx*yy - xy*yx) * invDet; - } - - void mtxInverse(float* _result, const float* _a) - { - float xx = _a[ 0]; - float xy = _a[ 1]; - float xz = _a[ 2]; - float xw = _a[ 3]; - float yx = _a[ 4]; - float yy = _a[ 5]; - float yz = _a[ 6]; - float yw = _a[ 7]; - float zx = _a[ 8]; - float zy = _a[ 9]; - float zz = _a[10]; - float zw = _a[11]; - float wx = _a[12]; - float wy = _a[13]; - float wz = _a[14]; - float ww = _a[15]; - - float det = 0.0f; - det += xx * (yy*(zz*ww - zw*wz) - yz*(zy*ww - zw*wy) + yw*(zy*wz - zz*wy) ); - det -= xy * (yx*(zz*ww - zw*wz) - yz*(zx*ww - zw*wx) + yw*(zx*wz - zz*wx) ); - det += xz * (yx*(zy*ww - zw*wy) - yy*(zx*ww - zw*wx) + yw*(zx*wy - zy*wx) ); - det -= xw * (yx*(zy*wz - zz*wy) - yy*(zx*wz - zz*wx) + yz*(zx*wy - zy*wx) ); - - float invDet = 1.0f/det; - - _result[ 0] = +(yy*(zz*ww - wz*zw) - yz*(zy*ww - wy*zw) + yw*(zy*wz - wy*zz) ) * invDet; - _result[ 1] = -(xy*(zz*ww - wz*zw) - xz*(zy*ww - wy*zw) + xw*(zy*wz - wy*zz) ) * invDet; - _result[ 2] = +(xy*(yz*ww - wz*yw) - xz*(yy*ww - wy*yw) + xw*(yy*wz - wy*yz) ) * invDet; - _result[ 3] = -(xy*(yz*zw - zz*yw) - xz*(yy*zw - zy*yw) + xw*(yy*zz - zy*yz) ) * invDet; - - _result[ 4] = -(yx*(zz*ww - wz*zw) - yz*(zx*ww - wx*zw) + yw*(zx*wz - wx*zz) ) * invDet; - _result[ 5] = +(xx*(zz*ww - wz*zw) - xz*(zx*ww - wx*zw) + xw*(zx*wz - wx*zz) ) * invDet; - _result[ 6] = -(xx*(yz*ww - wz*yw) - xz*(yx*ww - wx*yw) + xw*(yx*wz - wx*yz) ) * invDet; - _result[ 7] = +(xx*(yz*zw - zz*yw) - xz*(yx*zw - zx*yw) + xw*(yx*zz - zx*yz) ) * invDet; - - _result[ 8] = +(yx*(zy*ww - wy*zw) - yy*(zx*ww - wx*zw) + yw*(zx*wy - wx*zy) ) * invDet; - _result[ 9] = -(xx*(zy*ww - wy*zw) - xy*(zx*ww - wx*zw) + xw*(zx*wy - wx*zy) ) * invDet; - _result[10] = +(xx*(yy*ww - wy*yw) - xy*(yx*ww - wx*yw) + xw*(yx*wy - wx*yy) ) * invDet; - _result[11] = -(xx*(yy*zw - zy*yw) - xy*(yx*zw - zx*yw) + xw*(yx*zy - zx*yy) ) * invDet; - - _result[12] = -(yx*(zy*wz - wy*zz) - yy*(zx*wz - wx*zz) + yz*(zx*wy - wx*zy) ) * invDet; - _result[13] = +(xx*(zy*wz - wy*zz) - xy*(zx*wz - wx*zz) + xz*(zx*wy - wx*zy) ) * invDet; - _result[14] = -(xx*(yy*wz - wy*yz) - xy*(yx*wz - wx*yz) + xz*(yx*wy - wx*yy) ) * invDet; - _result[15] = +(xx*(yy*zz - zy*yz) - xy*(yx*zz - zx*yz) + xz*(yx*zy - zx*yy) ) * invDet; - } - -} // namespace bx diff --git a/3rdparty/bx/src/hash.cpp b/3rdparty/bx/src/hash.cpp new file mode 100644 index 00000000000..4335443f245 --- /dev/null +++ b/3rdparty/bx/src/hash.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/hash.h> + +namespace bx +{ + +static const uint32_t s_crcTableIeee[] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; +BX_STATIC_ASSERT(BX_COUNTOF(s_crcTableIeee) == 256); + +static const uint32_t s_crcTableCastagnoli[] = +{ + 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, + 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, + 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, + 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, + 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, + 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, + 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, + 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, + 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, + 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, + 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, + 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, + 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, + 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, + 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, + 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, + 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, + 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, + 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, + 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, + 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, + 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, + 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, + 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, + 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, + 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, + 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, + 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, + 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, + 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, + 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, + 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351, +}; +BX_STATIC_ASSERT(BX_COUNTOF(s_crcTableCastagnoli) == 256); + +static const uint32_t s_crcTableKoopman[] = +{ + 0x00000000, 0x9695c4ca, 0xfb4839c9, 0x6dddfd03, 0x20f3c3cf, 0xb6660705, 0xdbbbfa06, 0x4d2e3ecc, + 0x41e7879e, 0xd7724354, 0xbaafbe57, 0x2c3a7a9d, 0x61144451, 0xf781809b, 0x9a5c7d98, 0x0cc9b952, + 0x83cf0f3c, 0x155acbf6, 0x788736f5, 0xee12f23f, 0xa33cccf3, 0x35a90839, 0x5874f53a, 0xcee131f0, + 0xc22888a2, 0x54bd4c68, 0x3960b16b, 0xaff575a1, 0xe2db4b6d, 0x744e8fa7, 0x199372a4, 0x8f06b66e, + 0xd1fdae25, 0x47686aef, 0x2ab597ec, 0xbc205326, 0xf10e6dea, 0x679ba920, 0x0a465423, 0x9cd390e9, + 0x901a29bb, 0x068fed71, 0x6b521072, 0xfdc7d4b8, 0xb0e9ea74, 0x267c2ebe, 0x4ba1d3bd, 0xdd341777, + 0x5232a119, 0xc4a765d3, 0xa97a98d0, 0x3fef5c1a, 0x72c162d6, 0xe454a61c, 0x89895b1f, 0x1f1c9fd5, + 0x13d52687, 0x8540e24d, 0xe89d1f4e, 0x7e08db84, 0x3326e548, 0xa5b32182, 0xc86edc81, 0x5efb184b, + 0x7598ec17, 0xe30d28dd, 0x8ed0d5de, 0x18451114, 0x556b2fd8, 0xc3feeb12, 0xae231611, 0x38b6d2db, + 0x347f6b89, 0xa2eaaf43, 0xcf375240, 0x59a2968a, 0x148ca846, 0x82196c8c, 0xefc4918f, 0x79515545, + 0xf657e32b, 0x60c227e1, 0x0d1fdae2, 0x9b8a1e28, 0xd6a420e4, 0x4031e42e, 0x2dec192d, 0xbb79dde7, + 0xb7b064b5, 0x2125a07f, 0x4cf85d7c, 0xda6d99b6, 0x9743a77a, 0x01d663b0, 0x6c0b9eb3, 0xfa9e5a79, + 0xa4654232, 0x32f086f8, 0x5f2d7bfb, 0xc9b8bf31, 0x849681fd, 0x12034537, 0x7fdeb834, 0xe94b7cfe, + 0xe582c5ac, 0x73170166, 0x1ecafc65, 0x885f38af, 0xc5710663, 0x53e4c2a9, 0x3e393faa, 0xa8acfb60, + 0x27aa4d0e, 0xb13f89c4, 0xdce274c7, 0x4a77b00d, 0x07598ec1, 0x91cc4a0b, 0xfc11b708, 0x6a8473c2, + 0x664dca90, 0xf0d80e5a, 0x9d05f359, 0x0b903793, 0x46be095f, 0xd02bcd95, 0xbdf63096, 0x2b63f45c, + 0xeb31d82e, 0x7da41ce4, 0x1079e1e7, 0x86ec252d, 0xcbc21be1, 0x5d57df2b, 0x308a2228, 0xa61fe6e2, + 0xaad65fb0, 0x3c439b7a, 0x519e6679, 0xc70ba2b3, 0x8a259c7f, 0x1cb058b5, 0x716da5b6, 0xe7f8617c, + 0x68fed712, 0xfe6b13d8, 0x93b6eedb, 0x05232a11, 0x480d14dd, 0xde98d017, 0xb3452d14, 0x25d0e9de, + 0x2919508c, 0xbf8c9446, 0xd2516945, 0x44c4ad8f, 0x09ea9343, 0x9f7f5789, 0xf2a2aa8a, 0x64376e40, + 0x3acc760b, 0xac59b2c1, 0xc1844fc2, 0x57118b08, 0x1a3fb5c4, 0x8caa710e, 0xe1778c0d, 0x77e248c7, + 0x7b2bf195, 0xedbe355f, 0x8063c85c, 0x16f60c96, 0x5bd8325a, 0xcd4df690, 0xa0900b93, 0x3605cf59, + 0xb9037937, 0x2f96bdfd, 0x424b40fe, 0xd4de8434, 0x99f0baf8, 0x0f657e32, 0x62b88331, 0xf42d47fb, + 0xf8e4fea9, 0x6e713a63, 0x03acc760, 0x953903aa, 0xd8173d66, 0x4e82f9ac, 0x235f04af, 0xb5cac065, + 0x9ea93439, 0x083cf0f3, 0x65e10df0, 0xf374c93a, 0xbe5af7f6, 0x28cf333c, 0x4512ce3f, 0xd3870af5, + 0xdf4eb3a7, 0x49db776d, 0x24068a6e, 0xb2934ea4, 0xffbd7068, 0x6928b4a2, 0x04f549a1, 0x92608d6b, + 0x1d663b05, 0x8bf3ffcf, 0xe62e02cc, 0x70bbc606, 0x3d95f8ca, 0xab003c00, 0xc6ddc103, 0x504805c9, + 0x5c81bc9b, 0xca147851, 0xa7c98552, 0x315c4198, 0x7c727f54, 0xeae7bb9e, 0x873a469d, 0x11af8257, + 0x4f549a1c, 0xd9c15ed6, 0xb41ca3d5, 0x2289671f, 0x6fa759d3, 0xf9329d19, 0x94ef601a, 0x027aa4d0, + 0x0eb31d82, 0x9826d948, 0xf5fb244b, 0x636ee081, 0x2e40de4d, 0xb8d51a87, 0xd508e784, 0x439d234e, + 0xcc9b9520, 0x5a0e51ea, 0x37d3ace9, 0xa1466823, 0xec6856ef, 0x7afd9225, 0x17206f26, 0x81b5abec, + 0x8d7c12be, 0x1be9d674, 0x76342b77, 0xe0a1efbd, 0xad8fd171, 0x3b1a15bb, 0x56c7e8b8, 0xc0522c72, +}; +BX_STATIC_ASSERT(BX_COUNTOF(s_crcTableKoopman) == 256); + +static const uint32_t* s_crcTable[] = +{ + s_crcTableIeee, + s_crcTableCastagnoli, + s_crcTableKoopman, +}; +BX_STATIC_ASSERT(BX_COUNTOF(s_crcTable) == HashCrc32::Count); + +void HashCrc32::begin(Enum _type) +{ + m_hash = UINT32_MAX; + m_table = s_crcTable[_type]; +} + +void HashCrc32::add(const void* _data, int _len) +{ + const uint8_t* data = (const uint8_t*)_data; + + uint32_t hash = m_hash; + + while (_len--) + { + hash = m_table[(hash ^ (*data++) ) & UINT8_MAX] ^ (hash >> 8); + } + + m_hash = hash; +} + +} // namespace bx diff --git a/3rdparty/bx/src/math.cpp b/3rdparty/bx/src/math.cpp new file mode 100644 index 00000000000..8327570e936 --- /dev/null +++ b/3rdparty/bx/src/math.cpp @@ -0,0 +1,744 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/math.h> + +#include <math.h> + +namespace bx +{ + const float kPi = 3.1415926535897932384626433832795f; + const float kPi2 = 6.2831853071795864769252867665590f; + const float kInvPi = 1.0f/kPi; + const float kPiHalf = 1.5707963267948966192313216916398f; + const float kSqrt2 = 1.4142135623730950488016887242097f; + const float kInvLogNat2 = 1.4426950408889634073599246810019f; +#if BX_COMPILER_MSVC + const float kHuge = float(HUGE_VAL); +#else + const float kHuge = HUGE_VALF; +#endif // BX_COMPILER_MSVC + + float fabs(float _a) + { + return ::fabsf(_a); + } + + float fsin(float _a) + { + return ::sinf(_a); + } + + float fasin(float _a) + { + return ::asinf(_a); + } + + float fcos(float _a) + { + return ::cosf(_a); + } + + float ftan(float _a) + { + return ::tanf(_a); + } + + float facos(float _a) + { + return ::acosf(_a); + } + + float fatan2(float _y, float _x) + { + return ::atan2f(_y, _x); + } + + float fpow(float _a, float _b) + { + return ::powf(_a, _b); + } + + float flog(float _a) + { + return ::logf(_a); + } + + float fsqrt(float _a) + { + return ::sqrtf(_a); + } + + float ffloor(float _f) + { + return ::floorf(_f); + } + + float fceil(float _f) + { + return ::ceilf(_f); + } + + float fmod(float _a, float _b) + { + return ::fmodf(_a, _b); + } + + void mtxLookAtImpl(float* _result, const float* _eye, const float* _view, const float* _up) + { + float up[3] = { 0.0f, 1.0f, 0.0f }; + if (NULL != _up) + { + up[0] = _up[0]; + up[1] = _up[1]; + up[2] = _up[2]; + } + + float tmp[4]; + vec3Cross(tmp, up, _view); + + float right[4]; + vec3Norm(right, tmp); + + vec3Cross(up, _view, right); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = right[0]; + _result[ 1] = up[0]; + _result[ 2] = _view[0]; + + _result[ 4] = right[1]; + _result[ 5] = up[1]; + _result[ 6] = _view[1]; + + _result[ 8] = right[2]; + _result[ 9] = up[2]; + _result[10] = _view[2]; + + _result[12] = -vec3Dot(right, _eye); + _result[13] = -vec3Dot(up, _eye); + _result[14] = -vec3Dot(_view, _eye); + _result[15] = 1.0f; + } + + void mtxLookAtLh(float* _result, const float* _eye, const float* _at, const float* _up) + { + float tmp[4]; + vec3Sub(tmp, _at, _eye); + + float view[4]; + vec3Norm(view, tmp); + + mtxLookAtImpl(_result, _eye, view, _up); + } + + void mtxLookAtRh(float* _result, const float* _eye, const float* _at, const float* _up) + { + float tmp[4]; + vec3Sub(tmp, _eye, _at); + + float view[4]; + vec3Norm(view, tmp); + + mtxLookAtImpl(_result, _eye, view, _up); + } + + void mtxLookAt(float* _result, const float* _eye, const float* _at, const float* _up) + { + mtxLookAtLh(_result, _eye, _at, _up); + } + + template<Handness::Enum HandnessT> + void mtxProjXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc) + { + const float diff = _far-_near; + const float aa = _oglNdc ? ( _far+_near)/diff : _far/diff; + const float bb = _oglNdc ? (2.0f*_far*_near)/diff : _near*aa; + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = _width; + _result[ 5] = _height; + _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x; + _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y; + _result[10] = (Handness::Right == HandnessT) ? -aa : aa; + _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f; + _result[14] = -bb; + } + + template<Handness::Enum HandnessT> + void mtxProjImpl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) + { + const float invDiffRl = 1.0f/(_rt - _lt); + const float invDiffUd = 1.0f/(_ut - _dt); + const float width = 2.0f*_near * invDiffRl; + const float height = 2.0f*_near * invDiffUd; + const float xx = (_rt + _lt) * invDiffRl; + const float yy = (_ut + _dt) * invDiffUd; + mtxProjXYWH<HandnessT>(_result, xx, yy, width, height, _near, _far, _oglNdc); + } + + template<Handness::Enum HandnessT> + void mtxProjImpl(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) + { + mtxProjImpl<HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc); + } + + template<Handness::Enum HandnessT> + void mtxProjImpl(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) + { + const float height = 1.0f/ftan(toRad(_fovy)*0.5f); + const float width = height * 1.0f/_aspect; + mtxProjXYWH<HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc); + } + + void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + } + + void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _fov, _near, _far, _oglNdc); + } + + void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc); + } + + void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + } + + void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _fov, _near, _far, _oglNdc); + } + + void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc); + } + + void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + } + + void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Right>(_result, _fov, _near, _far, _oglNdc); + } + + void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Right>(_result, _fovy, _aspect, _near, _far, _oglNdc); + } + + template<NearFar::Enum NearFarT, Handness::Enum HandnessT> + void mtxProjInfXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, bool _oglNdc) + { + float aa; + float bb; + if (BX_ENABLED(NearFar::Reverse == NearFarT) ) + { + aa = _oglNdc ? -1.0f : 0.0f; + bb = _oglNdc ? -2.0f*_near : -_near; + } + else + { + aa = 1.0f; + bb = _oglNdc ? 2.0f*_near : _near; + } + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = _width; + _result[ 5] = _height; + _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x; + _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y; + _result[10] = (Handness::Right == HandnessT) ? -aa : aa; + _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f; + _result[14] = -bb; + } + + template<NearFar::Enum NearFarT, Handness::Enum HandnessT> + void mtxProjInfImpl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + const float invDiffRl = 1.0f/(_rt - _lt); + const float invDiffUd = 1.0f/(_ut - _dt); + const float width = 2.0f*_near * invDiffRl; + const float height = 2.0f*_near * invDiffUd; + const float xx = (_rt + _lt) * invDiffRl; + const float yy = (_ut + _dt) * invDiffUd; + mtxProjInfXYWH<NearFarT,HandnessT>(_result, xx, yy, width, height, _near, _oglNdc); + } + + template<NearFar::Enum NearFarT, Handness::Enum HandnessT> + void mtxProjInfImpl(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFarT,HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _oglNdc); + } + + template<NearFar::Enum NearFarT, Handness::Enum HandnessT> + void mtxProjInfImpl(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + const float height = 1.0f/ftan(toRad(_fovy)*0.5f); + const float width = height * 1.0f/_aspect; + mtxProjInfXYWH<NearFarT,HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _oglNdc); + } + + void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc); + } + + void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); + } + + void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc); + } + + void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); + } + + void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Right>(_result, _fov, _near, _oglNdc); + } + + void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc); + } + + void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Left>(_result, _fov, _near, _oglNdc); + } + + void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); + } + + void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Right>(_result, _fov, _near, _oglNdc); + } + + void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc); + } + + template<Handness::Enum HandnessT> + void mtxOrthoImpl(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) + { + const float aa = 2.0f/(_right - _left); + const float bb = 2.0f/(_top - _bottom); + const float cc = (_oglNdc ? 2.0f : 1.0f) / (_far - _near); + const float dd = (_left + _right )/(_left - _right); + const float ee = (_top + _bottom)/(_bottom - _top ); + const float ff = _oglNdc + ? (_near + _far)/(_near - _far) + : _near /(_near - _far) + ; + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = aa; + _result[ 5] = bb; + _result[10] = (Handness::Right == HandnessT) ? -cc : cc; + _result[12] = dd + _offset; + _result[13] = ee; + _result[14] = ff; + _result[15] = 1.0f; + } + + void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) + { + mtxOrthoImpl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + } + + void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) + { + mtxOrthoImpl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + } + + void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) + { + mtxOrthoImpl<Handness::Right>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + } + + void mtxRotateX(float* _result, float _ax) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = 1.0f; + _result[ 5] = cx; + _result[ 6] = -sx; + _result[ 9] = sx; + _result[10] = cx; + _result[15] = 1.0f; + } + + void mtxRotateY(float* _result, float _ay) + { + const float sy = fsin(_ay); + const float cy = fcos(_ay); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cy; + _result[ 2] = sy; + _result[ 5] = 1.0f; + _result[ 8] = -sy; + _result[10] = cy; + _result[15] = 1.0f; + } + + void mtxRotateZ(float* _result, float _az) + { + const float sz = fsin(_az); + const float cz = fcos(_az); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cz; + _result[ 1] = -sz; + _result[ 4] = sz; + _result[ 5] = cz; + _result[10] = 1.0f; + _result[15] = 1.0f; + } + + void mtxRotateXY(float* _result, float _ax, float _ay) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + const float sy = fsin(_ay); + const float cy = fcos(_ay); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cy; + _result[ 2] = sy; + _result[ 4] = sx*sy; + _result[ 5] = cx; + _result[ 6] = -sx*cy; + _result[ 8] = -cx*sy; + _result[ 9] = sx; + _result[10] = cx*cy; + _result[15] = 1.0f; + } + + void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + const float sy = fsin(_ay); + const float cy = fcos(_ay); + const float sz = fsin(_az); + const float cz = fcos(_az); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cy*cz; + _result[ 1] = -cy*sz; + _result[ 2] = sy; + _result[ 4] = cz*sx*sy + cx*sz; + _result[ 5] = cx*cz - sx*sy*sz; + _result[ 6] = -cy*sx; + _result[ 8] = -cx*cz*sy + sx*sz; + _result[ 9] = cz*sx + cx*sy*sz; + _result[10] = cx*cy; + _result[15] = 1.0f; + } + + void mtxRotateZYX(float* _result, float _ax, float _ay, float _az) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + const float sy = fsin(_ay); + const float cy = fcos(_ay); + const float sz = fsin(_az); + const float cz = fcos(_az); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cy*cz; + _result[ 1] = cz*sx*sy-cx*sz; + _result[ 2] = cx*cz*sy+sx*sz; + _result[ 4] = cy*sz; + _result[ 5] = cx*cz + sx*sy*sz; + _result[ 6] = -cz*sx + cx*sy*sz; + _result[ 8] = -sy; + _result[ 9] = cy*sx; + _result[10] = cx*cy; + _result[15] = 1.0f; + }; + + void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + const float sy = fsin(_ay); + const float cy = fcos(_ay); + const float sz = fsin(_az); + const float cz = fcos(_az); + + const float sxsz = sx*sz; + const float cycz = cy*cz; + + _result[ 0] = _sx * (cycz - sxsz*sy); + _result[ 1] = _sx * -cx*sz; + _result[ 2] = _sx * (cz*sy + cy*sxsz); + _result[ 3] = 0.0f; + + _result[ 4] = _sy * (cz*sx*sy + cy*sz); + _result[ 5] = _sy * cx*cz; + _result[ 6] = _sy * (sy*sz -cycz*sx); + _result[ 7] = 0.0f; + + _result[ 8] = _sz * -cx*sy; + _result[ 9] = _sz * sx; + _result[10] = _sz * cx*cy; + _result[11] = 0.0f; + + _result[12] = _tx; + _result[13] = _ty; + _result[14] = _tz; + _result[15] = 1.0f; + } + + void mtx3Inverse(float* _result, const float* _a) + { + float xx = _a[0]; + float xy = _a[1]; + float xz = _a[2]; + float yx = _a[3]; + float yy = _a[4]; + float yz = _a[5]; + float zx = _a[6]; + float zy = _a[7]; + float zz = _a[8]; + + float det = 0.0f; + det += xx * (yy*zz - yz*zy); + det -= xy * (yx*zz - yz*zx); + det += xz * (yx*zy - yy*zx); + + float invDet = 1.0f/det; + + _result[0] = +(yy*zz - yz*zy) * invDet; + _result[1] = -(xy*zz - xz*zy) * invDet; + _result[2] = +(xy*yz - xz*yy) * invDet; + + _result[3] = -(yx*zz - yz*zx) * invDet; + _result[4] = +(xx*zz - xz*zx) * invDet; + _result[5] = -(xx*yz - xz*yx) * invDet; + + _result[6] = +(yx*zy - yy*zx) * invDet; + _result[7] = -(xx*zy - xy*zx) * invDet; + _result[8] = +(xx*yy - xy*yx) * invDet; + } + + void mtxInverse(float* _result, const float* _a) + { + float xx = _a[ 0]; + float xy = _a[ 1]; + float xz = _a[ 2]; + float xw = _a[ 3]; + float yx = _a[ 4]; + float yy = _a[ 5]; + float yz = _a[ 6]; + float yw = _a[ 7]; + float zx = _a[ 8]; + float zy = _a[ 9]; + float zz = _a[10]; + float zw = _a[11]; + float wx = _a[12]; + float wy = _a[13]; + float wz = _a[14]; + float ww = _a[15]; + + float det = 0.0f; + det += xx * (yy*(zz*ww - zw*wz) - yz*(zy*ww - zw*wy) + yw*(zy*wz - zz*wy) ); + det -= xy * (yx*(zz*ww - zw*wz) - yz*(zx*ww - zw*wx) + yw*(zx*wz - zz*wx) ); + det += xz * (yx*(zy*ww - zw*wy) - yy*(zx*ww - zw*wx) + yw*(zx*wy - zy*wx) ); + det -= xw * (yx*(zy*wz - zz*wy) - yy*(zx*wz - zz*wx) + yz*(zx*wy - zy*wx) ); + + float invDet = 1.0f/det; + + _result[ 0] = +(yy*(zz*ww - wz*zw) - yz*(zy*ww - wy*zw) + yw*(zy*wz - wy*zz) ) * invDet; + _result[ 1] = -(xy*(zz*ww - wz*zw) - xz*(zy*ww - wy*zw) + xw*(zy*wz - wy*zz) ) * invDet; + _result[ 2] = +(xy*(yz*ww - wz*yw) - xz*(yy*ww - wy*yw) + xw*(yy*wz - wy*yz) ) * invDet; + _result[ 3] = -(xy*(yz*zw - zz*yw) - xz*(yy*zw - zy*yw) + xw*(yy*zz - zy*yz) ) * invDet; + + _result[ 4] = -(yx*(zz*ww - wz*zw) - yz*(zx*ww - wx*zw) + yw*(zx*wz - wx*zz) ) * invDet; + _result[ 5] = +(xx*(zz*ww - wz*zw) - xz*(zx*ww - wx*zw) + xw*(zx*wz - wx*zz) ) * invDet; + _result[ 6] = -(xx*(yz*ww - wz*yw) - xz*(yx*ww - wx*yw) + xw*(yx*wz - wx*yz) ) * invDet; + _result[ 7] = +(xx*(yz*zw - zz*yw) - xz*(yx*zw - zx*yw) + xw*(yx*zz - zx*yz) ) * invDet; + + _result[ 8] = +(yx*(zy*ww - wy*zw) - yy*(zx*ww - wx*zw) + yw*(zx*wy - wx*zy) ) * invDet; + _result[ 9] = -(xx*(zy*ww - wy*zw) - xy*(zx*ww - wx*zw) + xw*(zx*wy - wx*zy) ) * invDet; + _result[10] = +(xx*(yy*ww - wy*yw) - xy*(yx*ww - wx*yw) + xw*(yx*wy - wx*yy) ) * invDet; + _result[11] = -(xx*(yy*zw - zy*yw) - xy*(yx*zw - zx*yw) + xw*(yx*zy - zx*yy) ) * invDet; + + _result[12] = -(yx*(zy*wz - wy*zz) - yy*(zx*wz - wx*zz) + yz*(zx*wy - wx*zy) ) * invDet; + _result[13] = +(xx*(zy*wz - wy*zz) - xy*(zx*wz - wx*zz) + xz*(zx*wy - wx*zy) ) * invDet; + _result[14] = -(xx*(yy*wz - wy*yz) - xy*(yx*wz - wx*yz) + xz*(yx*wy - wx*yy) ) * invDet; + _result[15] = +(xx*(yy*zz - zy*yz) - xy*(yx*zz - zx*yz) + xz*(yx*zy - zx*yy) ) * invDet; + } + + void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints) + { + float sumX = 0.0f; + float sumY = 0.0f; + float sumXX = 0.0f; + float sumXY = 0.0f; + + const uint8_t* ptr = (const uint8_t*)_points; + for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride) + { + const float* point = (const float*)ptr; + float xx = point[0]; + float yy = point[1]; + sumX += xx; + sumY += yy; + sumXX += xx*xx; + sumXY += xx*yy; + } + + // [ sum(x^2) sum(x) ] [ A ] = [ sum(x*y) ] + // [ sum(x) numPoints ] [ B ] [ sum(y) ] + + float det = (sumXX*_numPoints - sumX*sumX); + float invDet = 1.0f/det; + + _result[0] = (-sumX * sumY + _numPoints * sumXY) * invDet; + _result[1] = (sumXX * sumY - sumX * sumXY) * invDet; + } + + void calcLinearFit3D(float _result[3], const void* _points, uint32_t _stride, uint32_t _numPoints) + { + float sumX = 0.0f; + float sumY = 0.0f; + float sumZ = 0.0f; + float sumXX = 0.0f; + float sumXY = 0.0f; + float sumXZ = 0.0f; + float sumYY = 0.0f; + float sumYZ = 0.0f; + + const uint8_t* ptr = (const uint8_t*)_points; + for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride) + { + const float* point = (const float*)ptr; + float xx = point[0]; + float yy = point[1]; + float zz = point[2]; + + sumX += xx; + sumY += yy; + sumZ += zz; + sumXX += xx*xx; + sumXY += xx*yy; + sumXZ += xx*zz; + sumYY += yy*yy; + sumYZ += yy*zz; + } + + // [ sum(x^2) sum(x*y) sum(x) ] [ A ] [ sum(x*z) ] + // [ sum(x*y) sum(y^2) sum(y) ] [ B ] = [ sum(y*z) ] + // [ sum(x) sum(y) numPoints ] [ C ] [ sum(z) ] + + float mtx[9] = + { + sumXX, sumXY, sumX, + sumXY, sumYY, sumY, + sumX, sumY, float(_numPoints), + }; + float invMtx[9]; + mtx3Inverse(invMtx, mtx); + + _result[0] = invMtx[0]*sumXZ + invMtx[1]*sumYZ + invMtx[2]*sumZ; + _result[1] = invMtx[3]*sumXZ + invMtx[4]*sumYZ + invMtx[5]*sumZ; + _result[2] = invMtx[6]*sumXZ + invMtx[7]*sumYZ + invMtx[8]*sumZ; + } + + void rgbToHsv(float _hsv[3], const float _rgb[3]) + { + const float rr = _rgb[0]; + const float gg = _rgb[1]; + const float bb = _rgb[2]; + + const float s0 = fstep(bb, gg); + + const float px = flerp(bb, gg, s0); + const float py = flerp(gg, bb, s0); + const float pz = flerp(-1.0f, 0.0f, s0); + const float pw = flerp(2.0f/3.0f, -1.0f/3.0f, s0); + + const float s1 = fstep(px, rr); + + const float qx = flerp(px, rr, s1); + const float qy = py; + const float qz = flerp(pw, pz, s1); + const float qw = flerp(rr, px, s1); + + const float dd = qx - fmin(qw, qy); + const float ee = 1.0e-10f; + + _hsv[0] = fabs(qz + (qw - qy) / (6.0f * dd + ee) ); + _hsv[1] = dd / (qx + ee); + _hsv[2] = qx; + } + + void hsvToRgb(float _rgb[3], const float _hsv[3]) + { + const float hh = _hsv[0]; + const float ss = _hsv[1]; + const float vv = _hsv[2]; + + const float px = fabs(ffract(hh + 1.0f ) * 6.0f - 3.0f); + const float py = fabs(ffract(hh + 2.0f/3.0f) * 6.0f - 3.0f); + const float pz = fabs(ffract(hh + 1.0f/3.0f) * 6.0f - 3.0f); + + _rgb[0] = vv * flerp(1.0f, fsaturate(px - 1.0f), ss); + _rgb[1] = vv * flerp(1.0f, fsaturate(py - 1.0f), ss); + _rgb[2] = vv * flerp(1.0f, fsaturate(pz - 1.0f), ss); + } + +} // namespace bx diff --git a/3rdparty/bx/src/mutex.cpp b/3rdparty/bx/src/mutex.cpp index 988084bbf0b..74e3c14cf28 100644 --- a/3rdparty/bx/src/mutex.cpp +++ b/3rdparty/bx/src/mutex.cpp @@ -3,13 +3,13 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/mutex.h> #if BX_CONFIG_SUPPORTS_THREADING #if BX_PLATFORM_ANDROID \ || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ @@ -17,7 +17,6 @@ # include <pthread.h> #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE # include <windows.h> # include <errno.h> @@ -25,7 +24,9 @@ namespace bx { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT typedef CRITICAL_SECTION pthread_mutex_t; typedef unsigned pthread_mutexattr_t; @@ -69,7 +70,9 @@ namespace bx pthread_mutexattr_t attr; -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT #else pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); diff --git a/3rdparty/bx/src/os.cpp b/3rdparty/bx/src/os.cpp index 0c7e9dc9a8e..d13ae7859c3 100644 --- a/3rdparty/bx/src/os.cpp +++ b/3rdparty/bx/src/os.cpp @@ -3,48 +3,53 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" +#include <bx/string.h> #include <bx/os.h> #include <bx/uint32_t.h> -#include <bx/string.h> #if !BX_PLATFORM_NONE #include <stdio.h> -#include <sys/stat.h> + +#if BX_CRT_MSVC +# include <direct.h> +#else +# include <unistd.h> +#endif // BX_CRT_MSVC #if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT # include <windows.h> # include <psapi.h> -#elif BX_PLATFORM_ANDROID \ +#elif BX_PLATFORM_ANDROID \ || BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_BSD \ - || BX_PLATFORM_HURD \ - || BX_PLATFORM_IOS \ - || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_RPI \ - || BX_PLATFORM_STEAMLINK + || BX_PLATFORM_BSD \ + || BX_PLATFORM_HURD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_RPI \ + || BX_PLATFORM_STEAMLINK \ + || BX_PLATFORM_NX # include <sched.h> // sched_yield -# if BX_PLATFORM_BSD \ - || BX_PLATFORM_IOS \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_PS4 \ +# if BX_PLATFORM_BSD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_PS4 \ || BX_PLATFORM_STEAMLINK # include <pthread.h> // mach_port_t # endif // BX_PLATFORM_* # include <time.h> // nanosleep -# if !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL +# if !BX_PLATFORM_PS4 # include <dlfcn.h> // dlopen, dlclose, dlsym -# endif // !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL +# endif // !BX_PLATFORM_PS4 # if BX_PLATFORM_ANDROID # include <malloc.h> // mallinfo -# elif BX_PLATFORM_LINUX \ - || BX_PLATFORM_RPI \ +# elif BX_PLATFORM_LINUX \ + || BX_PLATFORM_RPI \ || BX_PLATFORM_STEAMLINK # include <unistd.h> // syscall # include <sys/syscall.h> @@ -57,25 +62,20 @@ # endif // BX_PLATFORM_ANDROID #endif // BX_PLATFORM_ -#if BX_CRT_MSVC -# include <direct.h> // _getcwd -#else -# include <unistd.h> // getcwd -#endif // BX_CRT_MSVC - namespace bx { void sleep(uint32_t _ms) { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 +#if BX_PLATFORM_WINDOWS ::Sleep(_ms); -#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#elif BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT BX_UNUSED(_ms); debugOutput("sleep is not implemented"); debugBreak(); #else - timespec req = {(time_t)_ms/1000, (long)((_ms%1000)*1000000)}; - timespec rem = {0, 0}; + timespec req = { (time_t)_ms/1000, (long)( (_ms%1000)*1000000) }; + timespec rem = { 0, 0 }; ::nanosleep(&req, &rem); #endif // BX_PLATFORM_ } @@ -84,9 +84,8 @@ namespace bx { #if BX_PLATFORM_WINDOWS ::SwitchToThread(); -#elif BX_PLATFORM_XBOX360 - ::Sleep(0); -#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#elif BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT debugOutput("yield is not implemented"); debugBreak(); #else ::sched_yield(); @@ -97,20 +96,21 @@ namespace bx { #if BX_PLATFORM_WINDOWS return ::GetCurrentThreadId(); -#elif BX_PLATFORM_LINUX || BX_PLATFORM_RPI || BX_PLATFORM_STEAMLINK +#elif BX_PLATFORM_LINUX \ + || BX_PLATFORM_RPI \ + || BX_PLATFORM_STEAMLINK return (pid_t)::syscall(SYS_gettid); -#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX +#elif BX_PLATFORM_IOS \ + || BX_PLATFORM_OSX return (mach_port_t)::pthread_mach_thread_np(pthread_self() ); -#elif BX_PLATFORM_BSD || BX_PLATFORM_NACL - // Casting __nc_basic_thread_data*... need better way to do this. +#elif BX_PLATFORM_BSD return *(uint32_t*)::pthread_self(); #elif BX_PLATFORM_HURD return (pthread_t)::pthread_self(); #else -//# pragma message "not implemented." debugOutput("getTid is not implemented"); debugBreak(); return 0; -#endif // +#endif // BX_PLATFORM_ } size_t getProcessMemoryUsed() @@ -118,7 +118,8 @@ namespace bx #if BX_PLATFORM_ANDROID struct mallinfo mi = mallinfo(); return mi.uordblks; -#elif BX_PLATFORM_LINUX || BX_PLATFORM_HURD +#elif BX_PLATFORM_LINUX \ + || BX_PLATFORM_HURD FILE* file = fopen("/proc/self/statm", "r"); if (NULL == file) { @@ -142,7 +143,7 @@ namespace bx , (task_info_t)&info , &infoCount ); -# else // MACH_TASK_BASIC_INFO +# else task_basic_info info; mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT; @@ -151,7 +152,7 @@ namespace bx , (task_info_t)&info , &infoCount ); -# endif // MACH_TASK_BASIC_INFO +# endif // defined(MACH_TASK_BASIC_INFO) if (KERN_SUCCESS != result) { return 0; @@ -175,9 +176,8 @@ namespace bx #if BX_PLATFORM_WINDOWS return (void*)::LoadLibraryA(_filePath); #elif BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_filePath); return NULL; @@ -191,9 +191,8 @@ namespace bx #if BX_PLATFORM_WINDOWS ::FreeLibrary( (HMODULE)_handle); #elif BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_handle); #else @@ -206,9 +205,8 @@ namespace bx #if BX_PLATFORM_WINDOWS return (void*)::GetProcAddress( (HMODULE)_handle, _symbol); #elif BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_handle, _symbol); return NULL; @@ -224,7 +222,7 @@ namespace bx bool result = len != 0 && len < *_inOutSize; *_inOutSize = len; return result; -#elif BX_PLATFORM_PS4 \ +#elif BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_name, _out, _inOutSize); @@ -235,12 +233,12 @@ namespace bx bool result = false; if (NULL != ptr) { - len = (uint32_t)strnlen(ptr); + len = (uint32_t)strLen(ptr); result = len != 0 && len < *_inOutSize; if (len < *_inOutSize) { - strlncpy(_out, len, ptr); + strCopy(_out, *_inOutSize, ptr); } } @@ -253,7 +251,7 @@ namespace bx { #if BX_PLATFORM_WINDOWS ::SetEnvironmentVariableA(_name, _value); -#elif BX_PLATFORM_PS4 \ +#elif BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_name, _value); @@ -266,7 +264,7 @@ namespace bx { #if BX_PLATFORM_WINDOWS ::SetEnvironmentVariableA(_name, NULL); -#elif BX_PLATFORM_PS4 \ +#elif BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_name); @@ -277,7 +275,7 @@ namespace bx int chdir(const char* _path) { -#if BX_PLATFORM_PS4 \ +#if BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_path); @@ -289,114 +287,10 @@ namespace bx #endif // BX_COMPILER_ } - char* pwd(char* _buffer, uint32_t _size) - { -#if BX_PLATFORM_PS4 \ - || BX_PLATFORM_XBOXONE \ - || BX_PLATFORM_WINRT - BX_UNUSED(_buffer, _size); - return NULL; -#elif BX_CRT_MSVC - return ::_getcwd(_buffer, (int)_size); -#else - return ::getcwd(_buffer, _size); -#endif // BX_COMPILER_ - } - - bool getTempPath(char* _out, uint32_t* _inOutSize) - { -#if BX_PLATFORM_WINDOWS - uint32_t len = ::GetTempPathA(*_inOutSize, _out); - bool result = len != 0 && len < *_inOutSize; - *_inOutSize = len; - return result; -#else - static const char* s_tmp[] = - { - "TMPDIR", - "TMP", - "TEMP", - "TEMPDIR", - - NULL - }; - - for (const char** tmp = s_tmp; *tmp != NULL; ++tmp) - { - uint32_t len = *_inOutSize; - *_out = '\0'; - bool result = getenv(*tmp, _out, &len); - - if (result - && len != 0 - && len < *_inOutSize) - { - *_inOutSize = len; - return result; - } - } - - FileInfo fi; - if (stat("/tmp", fi) - && FileInfo::Directory == fi.m_type) - { - strlncpy(_out, *_inOutSize, "/tmp"); - *_inOutSize = 4; - return true; - } - - return false; -#endif // BX_PLATFORM_* - } - - bool stat(const char* _filePath, FileInfo& _fileInfo) - { - _fileInfo.m_size = 0; - _fileInfo.m_type = FileInfo::Count; - -#if BX_COMPILER_MSVC - struct ::_stat64 st; - int32_t result = ::_stat64(_filePath, &st); - - if (0 != result) - { - return false; - } - - if (0 != (st.st_mode & _S_IFREG) ) - { - _fileInfo.m_type = FileInfo::Regular; - } - else if (0 != (st.st_mode & _S_IFDIR) ) - { - _fileInfo.m_type = FileInfo::Directory; - } -#else - struct ::stat st; - int32_t result = ::stat(_filePath, &st); - if (0 != result) - { - return false; - } - - if (0 != (st.st_mode & S_IFREG) ) - { - _fileInfo.m_type = FileInfo::Regular; - } - else if (0 != (st.st_mode & S_IFDIR) ) - { - _fileInfo.m_type = FileInfo::Directory; - } -#endif // BX_COMPILER_MSVC - - _fileInfo.m_size = st.st_size; - - return true; - } - void* exec(const char* const* _argv) { -#if BX_PLATFORM_LINUX || BX_PLATFORM_HURD +#if BX_PLATFORM_LINUX \ + || BX_PLATFORM_HURD pid_t pid = fork(); if (0 == pid) @@ -408,9 +302,9 @@ namespace bx return (void*)uintptr_t(pid); #elif BX_PLATFORM_WINDOWS - STARTUPINFO si; - memSet(&si, 0, sizeof(STARTUPINFO) ); - si.cb = sizeof(STARTUPINFO); + STARTUPINFOA si; + memSet(&si, 0, sizeof(STARTUPINFOA) ); + si.cb = sizeof(STARTUPINFOA); PROCESS_INFORMATION pi; memSet(&pi, 0, sizeof(PROCESS_INFORMATION) ); @@ -418,7 +312,7 @@ namespace bx int32_t total = 0; for (uint32_t ii = 0; NULL != _argv[ii]; ++ii) { - total += (int32_t)strnlen(_argv[ii]) + 1; + total += (int32_t)strLen(_argv[ii]) + 1; } char* temp = (char*)alloca(total); @@ -426,22 +320,22 @@ namespace bx for(uint32_t ii = 0; NULL != _argv[ii]; ++ii) { len += snprintf(&temp[len], bx::uint32_imax(0, total-len) - , "%s " - , _argv[ii] - ); + , "%s " + , _argv[ii] + ); } bool ok = !!CreateProcessA(_argv[0] - , temp - , NULL - , NULL - , false - , 0 - , NULL - , NULL - , &si - , &pi - ); + , temp + , NULL + , NULL + , false + , 0 + , NULL + , NULL + , &si + , &pi + ); if (ok) { return pi.hProcess; diff --git a/3rdparty/bx/src/process.cpp b/3rdparty/bx/src/process.cpp new file mode 100644 index 00000000000..b748260eece --- /dev/null +++ b/3rdparty/bx/src/process.cpp @@ -0,0 +1,169 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/process.h> + +#include <stdio.h> + +#ifndef BX_CONFIG_CRT_PROCESS +# define BX_CONFIG_CRT_PROCESS !(0 \ + || BX_CRT_NONE \ + || BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOXONE \ + ) +#endif // BX_CONFIG_CRT_PROCESS + +namespace bx +{ +#if BX_CONFIG_CRT_PROCESS + +#if BX_CRT_MSVC +# define popen _popen +# define pclose _pclose +#endif // BX_CRT_MSVC + + ProcessReader::ProcessReader() + : m_file(NULL) + { + } + + ProcessReader::~ProcessReader() + { + BX_CHECK(NULL == m_file, "Process not closed!"); + } + + bool ProcessReader::open(const FilePath& _filePath, const StringView& _args, Error* _err) + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open."); + return false; + } + + char tmp[kMaxFilePath*2] = "\""; + strCat(tmp, BX_COUNTOF(tmp), _filePath.get() ); + strCat(tmp, BX_COUNTOF(tmp), "\" "); + strCat(tmp, BX_COUNTOF(tmp), _args); + + m_file = popen(tmp, "r"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process."); + return false; + } + + return true; + } + + void ProcessReader::close() + { + BX_CHECK(NULL != m_file, "Process not open!"); + FILE* file = (FILE*)m_file; + m_exitCode = pclose(file); + m_file = NULL; + } + + int32_t ProcessReader::read(void* _data, int32_t _size, Error* _err) + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); + + FILE* file = (FILE*)m_file; + int32_t size = (int32_t)fread(_data, 1, _size, file); + if (size != _size) + { + if (0 != feof(file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF."); + } + else if (0 != ferror(file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error."); + } + + return size >= 0 ? size : 0; + } + + return size; + } + + int32_t ProcessReader::getExitCode() const + { + return m_exitCode; + } + + ProcessWriter::ProcessWriter() + : m_file(NULL) + { + } + + ProcessWriter::~ProcessWriter() + { + BX_CHECK(NULL == m_file, "Process not closed!"); + } + + bool ProcessWriter::open(const FilePath& _filePath, const StringView& _args, Error* _err) + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open."); + return false; + } + + char tmp[kMaxFilePath*2] = "\""; + strCat(tmp, BX_COUNTOF(tmp), _filePath.get() ); + strCat(tmp, BX_COUNTOF(tmp), "\" "); + strCat(tmp, BX_COUNTOF(tmp), _args); + + m_file = popen(tmp, "w"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process."); + return false; + } + + return true; + } + + void ProcessWriter::close() + { + BX_CHECK(NULL != m_file, "Process not open!"); + FILE* file = (FILE*)m_file; + m_exitCode = pclose(file); + m_file = NULL; + } + + int32_t ProcessWriter::write(const void* _data, int32_t _size, Error* _err) + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); + + FILE* file = (FILE*)m_file; + int32_t size = (int32_t)fwrite(_data, 1, _size, file); + if (size != _size) + { + if (0 != ferror(file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error."); + } + + return size >= 0 ? size : 0; + } + + return size; + } + + int32_t ProcessWriter::getExitCode() const + { + return m_exitCode; + } +#endif // BX_CONFIG_CRT_PROCESS + +} // namespace bx diff --git a/3rdparty/bx/src/semaphore.cpp b/3rdparty/bx/src/semaphore.cpp index b4369ff0ce6..f321240be18 100644 --- a/3rdparty/bx/src/semaphore.cpp +++ b/3rdparty/bx/src/semaphore.cpp @@ -3,18 +3,21 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/semaphore.h> #if BX_CONFIG_SUPPORTS_THREADING -#if BX_PLATFORM_POSIX +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS +# include <dispatch/dispatch.h> +#elif BX_PLATFORM_POSIX # include <errno.h> # include <pthread.h> # include <semaphore.h> # include <time.h> #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE # include <windows.h> # include <limits.h> @@ -23,36 +26,87 @@ # endif // BX_PLATFORM_XBOXONE #endif // BX_PLATFORM_ -#ifndef BX_CONFIG_SEMAPHORE_PTHREAD -# define BX_CONFIG_SEMAPHORE_PTHREAD (0 \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_IOS \ - ) -#endif // BX_CONFIG_SEMAPHORE_PTHREAD - namespace bx { struct SemaphoreInternal { -#if BX_PLATFORM_POSIX -# if BX_CONFIG_SEMAPHORE_PTHREAD +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS + dispatch_semaphore_t m_handle; +#elif BX_PLATFORM_POSIX pthread_mutex_t m_mutex; pthread_cond_t m_cond; int32_t m_count; -# else - sem_t m_handle; -# endif // BX_CONFIG_SEMAPHORE_PTHREAD #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE HANDLE m_handle; #endif // BX_PLATFORM_ }; -#if BX_PLATFORM_POSIX +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS + + Semaphore::Semaphore() + { + BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); + + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + si->m_handle = dispatch_semaphore_create(0); + BX_CHECK(NULL != si->m_handle, "dispatch_semaphore_create failed."); + } + + Semaphore::~Semaphore() + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + dispatch_release(si->m_handle); + } + + void Semaphore::post(uint32_t _count) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + for (uint32_t ii = 0; ii < _count; ++ii) + { + dispatch_semaphore_signal(si->m_handle); + } + } + + bool Semaphore::wait(int32_t _msecs) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + dispatch_time_t dt = 0 > _msecs + ? DISPATCH_TIME_FOREVER + : dispatch_time(DISPATCH_TIME_NOW, _msecs*1000000) + ; + return !dispatch_semaphore_wait(si->m_handle, dt); + } + +#elif BX_PLATFORM_POSIX + + uint64_t toNs(const timespec& _ts) + { + return _ts.tv_sec*UINT64_C(1000000000) + _ts.tv_nsec; + } + + void toTimespecNs(timespec& _ts, uint64_t _nsecs) + { + _ts.tv_sec = _nsecs/UINT64_C(1000000000); + _ts.tv_nsec = _nsecs%UINT64_C(1000000000); + } + + void toTimespecMs(timespec& _ts, int32_t _msecs) + { + toTimespecNs(_ts, _msecs*1000000); + } + + void add(timespec& _ts, int32_t _msecs) + { + uint64_t ns = toNs(_ts); + toTimespecNs(_ts, ns + _msecs*1000000); + } -# if BX_CONFIG_SEMAPHORE_PTHREAD Semaphore::Semaphore() { BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); @@ -113,15 +167,6 @@ namespace bx int result = pthread_mutex_lock(&si->m_mutex); BX_CHECK(0 == result, "pthread_mutex_lock %d", result); -# if BX_PLATFORM_NACL || BX_PLATFORM_OSX - BX_UNUSED(_msecs); - BX_CHECK(-1 == _msecs, "NaCl and OSX don't support pthread_cond_timedwait at this moment."); - while (0 == result - && 0 >= si->m_count) - { - result = pthread_cond_wait(&si->m_cond, &si->m_mutex); - } -# elif BX_PLATFORM_IOS if (-1 == _msecs) { while (0 == result @@ -133,27 +178,16 @@ namespace bx else { timespec ts; - ts.tv_sec = _msecs/1000; - ts.tv_nsec = (_msecs%1000)*1000; + clock_gettime(CLOCK_REALTIME, &ts); + add(ts, _msecs); while (0 == result && 0 >= si->m_count) { - result = pthread_cond_timedwait_relative_np(&si->m_cond, &si->m_mutex, &ts); + result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts); } } -# else - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += _msecs/1000; - ts.tv_nsec += (_msecs%1000)*1000; - - while (0 == result - && 0 >= si->m_count) - { - result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts); - } -# endif // BX_PLATFORM_ + bool ok = 0 == result; if (ok) @@ -169,80 +203,16 @@ namespace bx return ok; } -# else - - Semaphore::Semaphore() - { - BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); - - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result = sem_init(&si->m_handle, 0, 0); - BX_CHECK(0 == result, "sem_init failed. errno %d", errno); - BX_UNUSED(result); - } - - Semaphore::~Semaphore() - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result = sem_destroy(&si->m_handle); - BX_CHECK(0 == result, "sem_destroy failed. errno %d", errno); - BX_UNUSED(result); - } - - void Semaphore::post(uint32_t _count) - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result; - for (uint32_t ii = 0; ii < _count; ++ii) - { - result = sem_post(&si->m_handle); - BX_CHECK(0 == result, "sem_post failed. errno %d", errno); - } - BX_UNUSED(result); - } - - bool Semaphore::wait(int32_t _msecs) - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - -# if BX_PLATFORM_NACL || BX_PLATFORM_OSX - BX_CHECK(-1 == _msecs, "NaCl and OSX don't support sem_timedwait at this moment."); BX_UNUSED(_msecs); - return 0 == sem_wait(&si->m_handle); -# else - if (0 > _msecs) - { - int32_t result; - do - { - result = sem_wait(&si->m_handle); - } // keep waiting when interrupted by a signal handler... - while (-1 == result && EINTR == errno); - BX_CHECK(0 == result, "sem_wait failed. errno %d", errno); - return 0 == result; - } - - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += _msecs/1000; - ts.tv_nsec += (_msecs%1000)*1000; - return 0 == sem_timedwait(&si->m_handle, &ts); -# endif // BX_PLATFORM_ - } -# endif // BX_CONFIG_SEMAPHORE_PTHREAD - #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE Semaphore::Semaphore() { SemaphoreInternal* si = (SemaphoreInternal*)m_internal; -#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINRT \ +|| BX_PLATFORM_XBOXONE si->m_handle = CreateSemaphoreExW(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS); #else si->m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL); @@ -269,7 +239,8 @@ namespace bx SemaphoreInternal* si = (SemaphoreInternal*)m_internal; DWORD milliseconds = (0 > _msecs) ? INFINITE : _msecs; -#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINRT \ +|| BX_PLATFORM_XBOXONE return WAIT_OBJECT_0 == WaitForSingleObjectEx(si->m_handle, milliseconds, FALSE); #else return WAIT_OBJECT_0 == WaitForSingleObject(si->m_handle, milliseconds); diff --git a/3rdparty/bx/src/settings.cpp b/3rdparty/bx/src/settings.cpp new file mode 100644 index 00000000000..52b8d606c2c --- /dev/null +++ b/3rdparty/bx/src/settings.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/settings.h> + +namespace +{ +#define INI_MALLOC(_ctx, _size) (BX_ALLOC(reinterpret_cast<bx::AllocatorI*>(_ctx), _size) ) +#define INI_FREE(_ctx, _ptr) (BX_FREE(reinterpret_cast<bx::AllocatorI*>(_ctx), _ptr) ) +#define INI_MEMCPY(_dst, _src, _count) (bx::memCopy(_dst, _src, _count) ) +#define INI_STRLEN(_str) (bx::strLen(_str) ) +#define INI_STRNICMP(_s1, _s2, _len) (bx::strCmpI(_s1, _s2, _len) ) + +#define INI_IMPLEMENTATION + +BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wunused-function"); + +BX_PRAGMA_DIAGNOSTIC_PUSH(); +BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wsign-compare"); +#include <ini/ini.h> +BX_PRAGMA_DIAGNOSTIC_POP(); +} + +namespace bx +{ + +Settings::Settings(AllocatorI* _allocator, const void* _data, uint32_t _len) + : m_allocator(_allocator) + , m_ini(NULL) +{ + load(_data, _len); +} + +#define INI_T(_ptr) reinterpret_cast<ini_t*>(_ptr) + +Settings::~Settings() +{ + ini_destroy(INI_T(m_ini) ); +} + +void Settings::clear() +{ + load(NULL, 0); +} + +void Settings::load(const void* _data, uint32_t _len) +{ + if (NULL != m_ini) + { + ini_destroy(INI_T(m_ini) ); + } + + if (NULL == _data) + { + m_ini = ini_create(m_allocator); + } + else + { + BX_UNUSED(_len); + m_ini = ini_load( (const char*)_data, m_allocator); + } +} + +const char* Settings::get(const StringView& _name) const +{ + ini_t* ini = INI_T(m_ini); + + FilePath uri(_name); + const StringView path(strTrim(uri.getPath(), "/") ); + const StringView& fileName(uri.getFileName() ); + int32_t section = INI_GLOBAL_SECTION; + + if (!path.isEmpty() ) + { + section = ini_find_section(ini, path.getPtr(), path.getLength() ); + if (INI_NOT_FOUND == section) + { + section = INI_GLOBAL_SECTION; + } + } + + int32_t property = ini_find_property(ini, section, fileName.getPtr(), fileName.getLength() ); + if (INI_NOT_FOUND == property) + { + return NULL; + } + + return ini_property_value(ini, section, property); +} + +void Settings::set(const StringView& _name, const StringView& _value) +{ + ini_t* ini = INI_T(m_ini); + + FilePath uri(_name); + const StringView path(strTrim(uri.getPath(), "/") ); + const StringView& fileName(uri.getFileName() ); + + int32_t section = INI_GLOBAL_SECTION; + + if (!path.isEmpty() ) + { + section = ini_find_section(ini, path.getPtr(), path.getLength() ); + if (INI_NOT_FOUND == section) + { + section = ini_section_add(ini, path.getPtr(), path.getLength() ); + } + } + + int32_t property = ini_find_property(ini, section, fileName.getPtr(), fileName.getLength() ); + if (INI_NOT_FOUND == property) + { + ini_property_add( + ini + , section + , fileName.getPtr() + , fileName.getLength() + , _value.getPtr() + , _value.getLength() + ); + } + else + { + ini_property_value_set( + ini + , section + , property + , _value.getPtr() + , _value.getLength() + ); + } +} + +void Settings::remove(const StringView& _name) const +{ + ini_t* ini = INI_T(m_ini); + + FilePath uri(_name); + const StringView path = strTrim(uri.getPath(), "/"); + const StringView& fileName = uri.getFileName(); + + int32_t section = INI_GLOBAL_SECTION; + + if (!path.isEmpty() ) + { + section = ini_find_section(ini, path.getPtr(), path.getLength() ); + if (INI_NOT_FOUND == section) + { + section = INI_GLOBAL_SECTION; + } + } + + int32_t property = ini_find_property(ini, section, fileName.getPtr(), fileName.getLength() ); + if (INI_NOT_FOUND == property) + { + return; + } + + ini_property_remove(ini, section, property); + + if (INI_GLOBAL_SECTION != section + && 0 == ini_property_count(ini, section) ) + { + ini_section_remove(ini, section); + } +} + +int32_t Settings::read(ReaderSeekerI* _reader, Error* _err) +{ + int32_t size = int32_t(getRemain(_reader) ); + + void* data = BX_ALLOC(m_allocator, size); + + int32_t total = bx::read(_reader, data, size, _err); + load(data, size); + + BX_FREE(m_allocator, data); + + return total; +} + +int32_t Settings::write(WriterI* _writer, Error* _err) const +{ + ini_t* ini = INI_T(m_ini); + + int32_t size = ini_save(ini, NULL, 0); + void* data = BX_ALLOC(m_allocator, size); + + ini_save(ini, (char*)data, size); + int32_t total = bx::write(_writer, data, size-1, _err); + + BX_FREE(m_allocator, data); + + return total; +} + +#undef INI_T + +int32_t read(ReaderSeekerI* _reader, Settings& _settings, Error* _err) +{ + BX_ERROR_SCOPE(_err); + return _settings.read(_reader, _err); +} + +int32_t write(WriterI* _writer, const Settings& _settings, Error* _err) +{ + BX_ERROR_SCOPE(_err); + return _settings.write(_writer, _err); +} + +} // namespace bx diff --git a/3rdparty/bx/src/sort.cpp b/3rdparty/bx/src/sort.cpp index 3b7485fe7fe..3dc1069f56e 100644 --- a/3rdparty/bx/src/sort.cpp +++ b/3rdparty/bx/src/sort.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/sort.h> namespace bx diff --git a/3rdparty/bx/src/string.cpp b/3rdparty/bx/src/string.cpp index dbb59e5090a..5fe272548d0 100644 --- a/3rdparty/bx/src/string.cpp +++ b/3rdparty/bx/src/string.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/allocator.h> #include <bx/hash.h> #include <bx/readerwriter.h> @@ -10,10 +11,16 @@ #if !BX_CRT_NONE # include <stdio.h> // vsnprintf, vsnwprintf +# include <wchar.h> // vswprintf #endif // !BX_CRT_NONE namespace bx { + inline bool isInRange(char _ch, char _from, char _to) + { + return unsigned(_ch - _from) <= unsigned(_to-_from); + } + bool isSpace(char _ch) { return ' ' == _ch @@ -27,12 +34,12 @@ namespace bx bool isUpper(char _ch) { - return _ch >= 'A' && _ch <= 'Z'; + return isInRange(_ch, 'A', 'Z'); } bool isLower(char _ch) { - return _ch >= 'a' && _ch <= 'z'; + return isInRange(_ch, 'a', 'z'); } bool isAlpha(char _ch) @@ -42,7 +49,7 @@ namespace bx bool isNumeric(char _ch) { - return _ch >= '0' && _ch <= '9'; + return isInRange(_ch, '0', '9'); } bool isAlphaNum(char _ch) @@ -52,7 +59,60 @@ namespace bx bool isPrint(char _ch) { - return isAlphaNum(_ch) || isSpace(_ch); + return isInRange(_ch, ' ', '~'); + } + + typedef bool (*CharTestFn)(char _ch); + + template<CharTestFn fn> + inline bool isCharTest(const StringView& _str) + { + bool result = true; + + for (const char* ptr = _str.getPtr(), *term = _str.getTerm() + ; ptr != term && result + ; ++ptr + ) + { + result &= fn(*ptr); + } + + return result; + } + + bool isSpace(const StringView& _str) + { + return isCharTest<isSpace>(_str); + } + + bool isUpper(const StringView& _str) + { + return isCharTest<isUpper>(_str); + } + + bool isLower(const StringView& _str) + { + return isCharTest<isLower>(_str); + } + + bool isAlpha(const StringView& _str) + { + return isCharTest<isAlpha>(_str); + } + + bool isNumeric(const StringView& _str) + { + return isCharTest<isNumeric>(_str); + } + + bool isAlphaNum(const StringView& _str) + { + return isCharTest<isAlphaNum>(_str); + } + + bool isPrint(const StringView& _str) + { + return isCharTest<isPrint>(_str); } char toLower(char _ch) @@ -70,7 +130,7 @@ namespace bx void toLower(char* _inOutStr, int32_t _max) { - const int32_t len = strnlen(_inOutStr, _max); + const int32_t len = strLen(_inOutStr, _max); toLowerUnsafe(_inOutStr, len); } @@ -89,16 +149,10 @@ namespace bx void toUpper(char* _inOutStr, int32_t _max) { - const int32_t len = strnlen(_inOutStr, _max); + const int32_t len = strLen(_inOutStr, _max); toUpperUnsafe(_inOutStr, len); } - bool toBool(const char* _str) - { - char ch = toLower(_str[0]); - return ch == 't' || ch == '1'; - } - typedef char (*CharFn)(char _ch); inline char toNoop(char _ch) @@ -107,11 +161,13 @@ namespace bx } template<CharFn fn> - int32_t strCmp(const char* _lhs, const char* _rhs, int32_t _max) + inline int32_t strCmp(const char* _lhs, int32_t _lhsMax, const char* _rhs, int32_t _rhsMax) { + int32_t max = min(_lhsMax, _rhsMax); + for ( - ; 0 < _max && fn(*_lhs) == fn(*_rhs) - ; ++_lhs, ++_rhs, --_max + ; 0 < max && fn(*_lhs) == fn(*_rhs) + ; ++_lhs, ++_rhs, --max ) { if (*_lhs == '\0' @@ -121,20 +177,105 @@ namespace bx } } - return 0 == _max ? 0 : fn(*_lhs) - fn(*_rhs); + return 0 == max && _lhsMax == _rhsMax ? 0 : fn(*_lhs) - fn(*_rhs); } - int32_t strncmp(const char* _lhs, const char* _rhs, int32_t _max) + int32_t strCmp(const StringView& _lhs, const StringView& _rhs, int32_t _max) { - return strCmp<toNoop>(_lhs, _rhs, _max); + return strCmp<toNoop>( + _lhs.getPtr() + , min(_lhs.getLength(), _max) + , _rhs.getPtr() + , min(_rhs.getLength(), _max) + ); } - int32_t strincmp(const char* _lhs, const char* _rhs, int32_t _max) + int32_t strCmpI(const StringView& _lhs, const StringView& _rhs, int32_t _max) { - return strCmp<toLower>(_lhs, _rhs, _max); + return strCmp<toLower>( + _lhs.getPtr() + , min(_lhs.getLength(), _max) + , _rhs.getPtr() + , min(_rhs.getLength(), _max) + ); } - int32_t strnlen(const char* _str, int32_t _max) + inline int32_t strCmpV(const char* _lhs, int32_t _lhsMax, const char* _rhs, int32_t _rhsMax) + { + int32_t max = min(_lhsMax, _rhsMax); + int32_t ii = 0; + int32_t idx = 0; + bool zero = true; + + for ( + ; 0 < max && _lhs[ii] == _rhs[ii] + ; ++ii, --max + ) + { + const uint8_t ch = _lhs[ii]; + if ('\0' == ch + || '\0' == _rhs[ii]) + { + break; + } + + if (!isNumeric(ch) ) + { + idx = ii+1; + zero = true; + } + else if ('0' != ch) + { + zero = false; + } + } + + if (0 == max) + { + return _lhsMax == _rhsMax ? 0 : _lhs[ii] - _rhs[ii]; + } + + if ('0' != _lhs[idx] + && '0' != _rhs[idx]) + { + int32_t jj = 0; + for (jj = ii + ; 0 < max && isNumeric(_lhs[jj]) + ; ++jj, --max + ) + { + if (!isNumeric(_rhs[jj]) ) + { + return 1; + } + } + + if (isNumeric(_rhs[jj])) + { + return -1; + } + } + else if (zero + && idx < ii + && (isNumeric(_lhs[ii]) || isNumeric(_rhs[ii]) ) ) + { + return (_lhs[ii] - '0') - (_rhs[ii] - '0'); + } + + return 0 == max && _lhsMax == _rhsMax ? 0 : _lhs[ii] - _rhs[ii]; + } + + int32_t strCmpV(const StringView& _lhs, const StringView& _rhs, int32_t _max) + { + return strCmpV( + _lhs.getPtr() + , min(_lhs.getLength(), _max) + , _rhs.getPtr() + , min(_rhs.getLength(), _max) + ); + } + + int32_t strLen(const char* _str, int32_t _max) { if (NULL == _str) { @@ -146,13 +287,18 @@ namespace bx return int32_t(ptr - _str); } - int32_t strlncpy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) + int32_t strLen(const StringView& _str, int32_t _max) + { + return strLen(_str.getPtr(), min(_str.getLength(), _max) ); + } + + inline int32_t strCopy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) { BX_CHECK(NULL != _dst, "_dst can't be NULL!"); BX_CHECK(NULL != _src, "_src can't be NULL!"); BX_CHECK(0 < _dstSize, "_dstSize can't be 0!"); - const int32_t len = strnlen(_src, _num); + const int32_t len = strLen(_src, _num); const int32_t max = _dstSize-1; const int32_t num = (len < max ? len : max); memCopy(_dst, _src, num); @@ -161,20 +307,30 @@ namespace bx return num; } - int32_t strlncat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) + int32_t strCopy(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num) + { + return strCopy(_dst, _dstSize, _str.getPtr(), min(_str.getLength(), _num) ); + } + + inline int32_t strCat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) { BX_CHECK(NULL != _dst, "_dst can't be NULL!"); BX_CHECK(NULL != _src, "_src can't be NULL!"); BX_CHECK(0 < _dstSize, "_dstSize can't be 0!"); const int32_t max = _dstSize; - const int32_t len = strnlen(_dst, max); - return strlncpy(&_dst[len], max-len, _src, _num); + const int32_t len = strLen(_dst, max); + return strCopy(&_dst[len], max-len, _src, _num); + } + + int32_t strCat(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num) + { + return strCat(_dst, _dstSize, _str.getPtr(), min(_str.getLength(), _num) ); } - const char* strnchr(const char* _str, char _ch, int32_t _max) + inline const char* strFindUnsafe(const char* _str, int32_t _len, char _ch) { - for (int32_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii) + for (int32_t ii = 0; ii < _len; ++ii) { if (_str[ii] == _ch) { @@ -185,9 +341,19 @@ namespace bx return NULL; } - const char* strnrchr(const char* _str, char _ch, int32_t _max) + inline const char* strFind(const char* _str, int32_t _max, char _ch) { - for (int32_t ii = strnlen(_str, _max); 0 < ii; --ii) + return strFindUnsafe(_str, strLen(_str, _max), _ch); + } + + const char* strFind(const StringView& _str, char _ch) + { + return strFind(_str.getPtr(), _str.getLength(), _ch); + } + + inline const char* strRFindUnsafe(const char* _str, int32_t _len, char _ch) + { + for (int32_t ii = _len; 0 <= ii; --ii) { if (_str[ii] == _ch) { @@ -198,13 +364,23 @@ namespace bx return NULL; } + inline const char* strRFind(const char* _str, int32_t _max, char _ch) + { + return strRFindUnsafe(_str, strLen(_str, _max), _ch); + } + + const char* strRFind(const StringView& _str, char _ch) + { + return strRFind(_str.getPtr(), _str.getLength(), _ch); + } + template<CharFn fn> - static const char* strStr(const char* _str, int32_t _strMax, const char* _find, int32_t _findMax) + inline const char* strFind(const char* _str, int32_t _strMax, const char* _find, int32_t _findMax) { const char* ptr = _str; - int32_t stringLen = strnlen(_str, _strMax); - const int32_t findLen = strnlen(_find, _findMax); + int32_t stringLen = strLen(_str, _strMax); + const int32_t findLen = strLen(_find, _findMax); for (; stringLen >= findLen; ++ptr, --stringLen) { @@ -239,27 +415,81 @@ namespace bx return NULL; } - const char* strnstr(const char* _str, const char* _find, int32_t _max) + const char* strFind(const StringView& _str, const StringView& _find, int32_t _num) + { + return strFind<toNoop>( + _str.getPtr() + , _str.getLength() + , _find.getPtr() + , min(_find.getLength(), _num) + ); + } + + const char* strFindI(const StringView& _str, const StringView& _find, int32_t _num) + { + return strFind<toLower>( + _str.getPtr() + , _str.getLength() + , _find.getPtr() + , min(_find.getLength(), _num) + ); + } + + StringView strLTrim(const StringView& _str, const StringView& _chars) { - return strStr<toNoop>(_str, _max, _find, INT32_MAX); + const char* ptr = _str.getPtr(); + const char* chars = _chars.getPtr(); + const uint32_t charsLen = _chars.getLength(); + + for (uint32_t ii = 0, len = _str.getLength(); ii < len; ++ii) + { + if (NULL == strFindUnsafe(chars, charsLen, ptr[ii]) ) + { + return StringView(ptr + ii, len-ii); + } + } + + return StringView(); } - const char* stristr(const char* _str, const char* _find, int32_t _max) + StringView strRTrim(const StringView& _str, const StringView& _chars) { - return strStr<toLower>(_str, _max, _find, INT32_MAX); + if (_str.isEmpty() ) + { + return StringView(); + } + + const char* ptr = _str.getPtr(); + const char* chars = _chars.getPtr(); + const uint32_t charsLen = _chars.getLength(); + + for (int32_t len = _str.getLength(), ii = len-1; 0 <= ii; --ii) + { + if (NULL == strFindUnsafe(chars, charsLen, ptr[ii]) ) + { + return StringView(ptr, ii+1); + } + } + + return StringView(); + } + + StringView strTrim(const StringView& _str, const StringView& _chars) + { + return strLTrim(strRTrim(_str, _chars), _chars); } const char* strnl(const char* _str) { - for (; '\0' != *_str; _str += strnlen(_str, 1024) ) + for (; '\0' != *_str; _str += strLen(_str, 1024) ) { - const char* eol = strnstr(_str, "\r\n", 1024); + const char* eol = strFind(StringView(_str, 1024), "\r\n"); if (NULL != eol) { return eol + 2; } - eol = strnstr(_str, "\n", 1024); + eol = strFind(StringView(_str, 1024), "\n"); if (NULL != eol) { return eol + 1; @@ -271,15 +501,15 @@ namespace bx const char* streol(const char* _str) { - for (; '\0' != *_str; _str += strnlen(_str, 1024) ) + for (; '\0' != *_str; _str += strLen(_str, 1024) ) { - const char* eol = strnstr(_str, "\r\n", 1024); + const char* eol = strFind(StringView(_str, 1024), "\r\n"); if (NULL != eol) { return eol; } - eol = strnstr(_str, "\n", 1024); + eol = strFind(StringView(_str, 1024), "\n"); if (NULL != eol) { return eol; @@ -348,9 +578,9 @@ namespace bx const char* findIdentifierMatch(const char* _str, const char* _word) { - int32_t len = strnlen(_word); - const char* ptr = strnstr(_str, _word); - for (; NULL != ptr; ptr = strnstr(ptr + len, _word) ) + int32_t len = strLen(_word); + const char* ptr = strFind(_str, _word); + for (; NULL != ptr; ptr = strFind(ptr + len, _word) ) { if (ptr != _str) { @@ -418,7 +648,7 @@ namespace bx static int32_t write(WriterI* _writer, const char* _str, int32_t _len, const Param& _param, Error* _err) { int32_t size = 0; - int32_t len = (int32_t)strnlen(_str, _len); + int32_t len = (int32_t)strLen(_str, _len); int32_t padding = _param.width > len ? _param.width - len : 0; bool sign = _param.sign && len > 1 && _str[0] != '-'; padding = padding > 0 ? padding - sign : 0; @@ -534,7 +764,7 @@ namespace bx toUpperUnsafe(str, len); } - const char* dot = strnchr(str, '.'); + const char* dot = strFind(str, INT32_MAX, '.'); if (NULL != dot) { const int32_t precLen = int32_t( @@ -574,7 +804,7 @@ namespace bx int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err) { - MemoryReader reader(_format, uint32_t(strnlen(_format) ) ); + MemoryReader reader(_format, uint32_t(strLen(_format) ) ); int32_t size = 0; @@ -793,9 +1023,9 @@ namespace bx { va_list argList; va_start(argList, _format); - int32_t size = write(_writer, _format, argList, _err); + int32_t total = write(_writer, _format, argList, _err); va_end(argList); - return size; + return total; } int32_t vsnprintfRef(char* _out, int32_t _max, const char* _format, va_list _argList) @@ -829,8 +1059,11 @@ namespace bx int32_t vsnprintf(char* _out, int32_t _max, const char* _format, va_list _argList) { + va_list argList; + va_copy(argList, _argList); + int32_t total = 0; #if BX_CRT_NONE - return vsnprintfRef(_out, _max, _format, _argList); + total = vsnprintfRef(_out, _max, _format, argList); #elif BX_CRT_MSVC int32_t len = -1; if (NULL != _out) @@ -840,26 +1073,30 @@ namespace bx len = ::vsnprintf_s(_out, _max, size_t(-1), _format, argListCopy); va_end(argListCopy); } - return -1 == len ? ::_vscprintf(_format, _argList) : len; + total = -1 == len ? ::_vscprintf(_format, argList) : len; #else - return ::vsnprintf(_out, _max, _format, _argList); + total = ::vsnprintf(_out, _max, _format, argList); #endif // BX_COMPILER_MSVC + va_end(argList); + return total; } int32_t snprintf(char* _out, int32_t _max, const char* _format, ...) { va_list argList; va_start(argList, _format); - int32_t len = vsnprintf(_out, _max, _format, argList); + int32_t total = vsnprintf(_out, _max, _format, argList); va_end(argList); - return len; + return total; } int32_t vsnwprintf(wchar_t* _out, int32_t _max, const wchar_t* _format, va_list _argList) { + va_list argList; + va_copy(argList, _argList); + int32_t total = 0; #if BX_CRT_NONE - BX_UNUSED(_out, _max, _format, _argList); - return 0; + BX_UNUSED(_out, _max, _format, argList); #elif BX_CRT_MSVC int32_t len = -1; if (NULL != _out) @@ -869,12 +1106,14 @@ namespace bx len = ::_vsnwprintf_s(_out, _max, size_t(-1), _format, argListCopy); va_end(argListCopy); } - return -1 == len ? ::_vscwprintf(_format, _argList) : len; + total = -1 == len ? ::_vscwprintf(_format, _argList) : len; #elif BX_CRT_MINGW - return ::vsnwprintf(_out, _max, _format, _argList); + total = ::vsnwprintf(_out, _max, _format, argList); #else - return ::vswprintf(_out, _max, _format, _argList); + total = ::vswprintf(_out, _max, _format, argList); #endif // BX_COMPILER_MSVC + va_end(argList); + return total; } int32_t swnprintf(wchar_t* _out, int32_t _max, const wchar_t* _format, ...) @@ -886,44 +1125,36 @@ namespace bx return len; } - const char* baseName(const char* _filePath) - { - const char* bs = strnrchr(_filePath, '\\'); - const char* fs = strnrchr(_filePath, '/'); - const char* slash = (bs > fs ? bs : fs); - const char* colon = strnrchr(_filePath, ':'); - const char* basename = slash > colon ? slash : colon; - if (NULL != basename) - { - return basename+1; - } - - return _filePath; - } + static const char s_units[] = { 'B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' }; - void prettify(char* _out, int32_t _count, uint64_t _size) + template<uint32_t Kilo, char KiloCh0, char KiloCh1> + inline int32_t prettify(char* _out, int32_t _count, uint64_t _value) { uint8_t idx = 0; - double size = double(_size); - while (_size != (_size&0x7ff) - && idx < 9) + double value = double(_value); + while (_value != (_value&0x7ff) + && idx < BX_COUNTOF(s_units) ) { - _size >>= 10; - size *= 1.0/1024.0; + _value /= Kilo; + value *= 1.0/double(Kilo); ++idx; } - snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0'); + return snprintf(_out, _count, "%0.2f %c%c%c", value + , s_units[idx] + , idx > 0 ? KiloCh0 : '\0' + , KiloCh1 + ); } - int32_t strlcpy(char* _dst, const char* _src, int32_t _max) + int32_t prettify(char* _out, int32_t _count, uint64_t _value, Units::Enum _units) { - return strlncpy(_dst, _max, _src); - } + if (Units::Kilo == _units) + { + return prettify<1000, 'B', '\0'>(_out, _count, _value); + } - int32_t strlcat(char* _dst, const char* _src, int32_t _max) - { - return strlncat(_dst, _max, _src); + return prettify<1024, 'i', 'B'>(_out, _count, _value); } } // namespace bx diff --git a/3rdparty/bx/src/thread.cpp b/3rdparty/bx/src/thread.cpp index 70ea4a0ecbe..fe7f3491dc2 100644 --- a/3rdparty/bx/src/thread.cpp +++ b/3rdparty/bx/src/thread.cpp @@ -3,11 +3,11 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/thread.h> #if BX_PLATFORM_ANDROID \ || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ @@ -21,7 +21,6 @@ # endif // BX_PLATFORM_ #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE # include <windows.h> # include <limits.h> @@ -37,11 +36,16 @@ using namespace Windows::System::Threading; namespace bx { + static AllocatorI* getAllocator() + { + static DefaultAllocator s_allocator; + return &s_allocator; + } + struct ThreadInternal { #if BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE static DWORD WINAPI threadFunc(LPVOID _arg); HANDLE m_handle; @@ -52,7 +56,9 @@ namespace bx #endif // BX_PLATFORM_ }; -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT DWORD WINAPI ThreadInternal::threadFunc(LPVOID _arg) { Thread* thread = (Thread*)_arg; @@ -76,8 +82,9 @@ namespace bx Thread::Thread() : m_fn(NULL) , m_userData(NULL) + , m_queue(getAllocator() ) , m_stackSize(0) - , m_exitCode(0 /*EXIT_SUCCESS*/) + , m_exitCode(kExitSuccess) , m_running(false) { BX_STATIC_ASSERT(sizeof(ThreadInternal) <= sizeof(m_internal) ); @@ -85,7 +92,6 @@ namespace bx ThreadInternal* ti = (ThreadInternal*)m_internal; #if BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE ti->m_handle = INVALID_HANDLE_VALUE; ti->m_threadId = UINT32_MAX; @@ -112,7 +118,8 @@ namespace bx m_running = true; ThreadInternal* ti = (ThreadInternal*)m_internal; -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE ti->m_handle = ::CreateThread(NULL , m_stackSize , (LPTHREAD_START_ROUTINE)ti->threadFunc @@ -163,7 +170,7 @@ namespace bx { BX_CHECK(m_running, "Not running!"); ThreadInternal* ti = (ThreadInternal*)m_internal; -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 +#if BX_PLATFORM_WINDOWS WaitForSingleObject(ti->m_handle, INFINITE); GetExitCodeThread(ti->m_handle, (DWORD*)&m_exitCode); CloseHandle(ti->m_handle); @@ -244,6 +251,17 @@ namespace bx #endif // BX_PLATFORM_ } + void Thread::push(void* _ptr) + { + m_queue.push(_ptr); + } + + void* Thread::pop() + { + void* ptr = m_queue.pop(); + return ptr; + } + int32_t Thread::entry() { #if BX_PLATFORM_WINDOWS @@ -252,7 +270,8 @@ namespace bx #endif // BX_PLATFORM_WINDOWS m_sem.post(); - return m_fn(m_userData); + int32_t result = m_fn(this, m_userData); + return result; } struct TlsDataInternal diff --git a/3rdparty/bx/src/timer.cpp b/3rdparty/bx/src/timer.cpp index 7f5403749d9..ad3bb1c32cb 100644 --- a/3rdparty/bx/src/timer.cpp +++ b/3rdparty/bx/src/timer.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/timer.h> #if BX_PLATFORM_ANDROID @@ -19,7 +20,9 @@ namespace bx { int64_t getHPCounter() { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT LARGE_INTEGER li; // Performance counter value may unexpectedly leap forward // http://support.microsoft.com/kb/274323 @@ -44,7 +47,9 @@ namespace bx int64_t getHPFrequency() { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT LARGE_INTEGER li; QueryPerformanceFrequency(&li); return li.QuadPart; diff --git a/3rdparty/bx/src/url.cpp b/3rdparty/bx/src/url.cpp new file mode 100644 index 00000000000..1dda39109bd --- /dev/null +++ b/3rdparty/bx/src/url.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bnet#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/url.h> + +namespace bx +{ + UrlView::UrlView() + { + } + + void UrlView::clear() + { + for (uint32_t ii = 0; ii < Count; ++ii) + { + m_tokens[ii].clear(); + } + } + + bool UrlView::parse(const StringView& _url) + { + clear(); + + const char* start = _url.getPtr(); + const char* term = _url.getTerm(); + const char* schemeEnd = strFind(StringView(start, term), "://"); + const char* hostStart = NULL != schemeEnd ? schemeEnd+3 : start; + const char* pathStart = strFind(StringView(hostStart, term), '/'); + + if (NULL == schemeEnd + && NULL == pathStart) + { + return false; + } + + if (NULL != schemeEnd + && (NULL == pathStart || pathStart > schemeEnd) ) + { + StringView scheme(start, schemeEnd); + + if (!isAlpha(scheme) ) + { + return false; + } + + m_tokens[Scheme].set(scheme); + } + + if (NULL != pathStart) + { + const char* queryStart = strFind(StringView(pathStart, term), '?'); + const char* fragmentStart = strFind(StringView(pathStart, term), '#'); + + if (NULL != fragmentStart + && fragmentStart < queryStart) + { + return false; + } + + m_tokens[Path].set(pathStart + , NULL != queryStart ? queryStart + : NULL != fragmentStart ? fragmentStart + : term + ); + + if (NULL != queryStart) + { + m_tokens[Query].set(queryStart+1 + , NULL != fragmentStart ? fragmentStart + : term + ); + } + + if (NULL != fragmentStart) + { + m_tokens[Fragment].set(fragmentStart+1, term); + } + + term = pathStart; + } + + const char* userPassEnd = strFind(StringView(hostStart, term), '@'); + const char* userPassStart = NULL != userPassEnd ? hostStart : NULL; + hostStart = NULL != userPassEnd ? userPassEnd+1 : hostStart; + const char* portStart = strFind(StringView(hostStart, term), ':'); + + m_tokens[Host].set(hostStart, NULL != portStart ? portStart : term); + + if (NULL != portStart) + { + m_tokens[Port].set(portStart+1, term); + } + + if (NULL != userPassStart) + { + const char* passStart = strFind(StringView(userPassStart, userPassEnd), ':'); + + m_tokens[UserName].set(userPassStart + , NULL != passStart ? passStart + : userPassEnd + ); + + if (NULL != passStart) + { + m_tokens[Password].set(passStart+1, userPassEnd); + } + } + + return true; + } + + const StringView& UrlView::get(Enum _token) const + { + return m_tokens[_token]; + } + + static char toHex(char _nible) + { + return "0123456789ABCDEF"[_nible&0xf]; + } + + // https://secure.wikimedia.org/wikipedia/en/wiki/URL_encoding + void urlEncode(char* _out, uint32_t _max, const StringView& _str) + { + _max--; // need space for zero terminator + + const char* str = _str.getPtr(); + const char* term = _str.getTerm(); + + uint32_t ii = 0; + for (char ch = *str++ + ; str <= term && ii < _max + ; ch = *str++ + ) + { + if (isAlphaNum(ch) + || ch == '-' + || ch == '_' + || ch == '.' + || ch == '~') + { + _out[ii++] = ch; + } + else if (ii+3 < _max) + { + _out[ii++] = '%'; + _out[ii++] = toHex(ch>>4); + _out[ii++] = toHex(ch); + } + } + + _out[ii] = '\0'; + } + +} // namespace bx diff --git a/3rdparty/bx/tests/atomic_test.cpp b/3rdparty/bx/tests/atomic_test.cpp new file mode 100644 index 00000000000..81b3318e8c0 --- /dev/null +++ b/3rdparty/bx/tests/atomic_test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "test.h" +#include <bx/cpu.h> + +TEST_CASE("atomic", "") +{ + uint32_t test = 1337; + uint32_t fetched; + + fetched = bx::atomicFetchAndAdd(&test, 52u); + REQUIRE(fetched == 1337); + REQUIRE(test == 1389); + + fetched = bx::atomicAddAndFetch(&test, 64u); + REQUIRE(fetched == 1453); + REQUIRE(test == 1453); + + fetched = bx::atomicFetchAndSub(&test, 64u); + REQUIRE(fetched == 1453); + REQUIRE(test == 1389); + + fetched = bx::atomicSubAndFetch(&test, 52u); + REQUIRE(fetched == 1337); + REQUIRE(test == 1337); + + fetched = bx::atomicFetchAndAddsat(&test, 52u, 1453u); + REQUIRE(fetched == 1337); + REQUIRE(test == 1389); + + fetched = bx::atomicFetchAndAddsat(&test, 1000u, 1453u); + REQUIRE(fetched == 1389); + REQUIRE(test == 1453); + + fetched = bx::atomicFetchAndSubsat(&test, 64u, 1337u); + REQUIRE(fetched == 1453); + REQUIRE(test == 1389); + + fetched = bx::atomicFetchAndSubsat(&test, 1000u, 1337u); + REQUIRE(fetched == 1389); + REQUIRE(test == 1337); + +} diff --git a/3rdparty/bx/tests/easing_test.cpp b/3rdparty/bx/tests/easing_test.cpp new file mode 100644 index 00000000000..9bf3c996798 --- /dev/null +++ b/3rdparty/bx/tests/easing_test.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "test.h" + +#include <bx/easing.h> +#include <bx/file.h> + +TEST_CASE("easing", "") +{ + bx::WriterI* writer = bx::getNullOut(); + + for (uint32_t ee = 0; ee < bx::Easing::Count; ++ee) + { + bx::writePrintf(writer, "\n\n%d\n", ee); + + const bx::EaseFn easing = bx::getEaseFunc(bx::Easing::Enum(ee) ); + + const int32_t nx = 64; + const int32_t ny = 10; + + bx::writePrintf(writer, "\t/// ^\n"); + + for (int32_t yy = ny+4; yy >= -5; --yy) + { + const float ys = float(yy )/float(ny); + const float ye = float(yy+1.0)/float(ny); + + bx::writePrintf(writer, "\t/// %c", yy != 0 ? '|' : '+'); + + for (int32_t xx = 0; xx < nx; ++xx) + { + int32_t jj = 0; + for (; jj < 10; ++jj) + { + const float tt = float(xx*10+jj)/10.0f/float(nx); + const float vv = easing(tt); + + if (vv >= ys + && vv < ye) + { + bx::writePrintf(writer, "*"); + break; + } + } + + if (jj == 10) + { + bx::writePrintf(writer, "%c", yy != 0 ? ' ' : '-'); + } + } + + bx::writePrintf(writer, "%s\n", yy != 0 ? "" : ">"); + } + } +} diff --git a/3rdparty/bx/tests/filepath_test.cpp b/3rdparty/bx/tests/filepath_test.cpp new file mode 100644 index 00000000000..5b743c66c23 --- /dev/null +++ b/3rdparty/bx/tests/filepath_test.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "test.h" +#include <bx/filepath.h> + +struct FilePathTest +{ + const char* filePath; + const char* expected; +}; + +FilePathTest s_filePathTest[] = +{ + // Already clean + {"", "."}, + {"abc", "abc"}, + {"abc/def", "abc/def"}, + {"a/b/c", "a/b/c"}, + {".", "."}, + {"..", ".."}, + {"../..", "../.."}, + {"../../abc", "../../abc"}, + {"/abc", "/abc"}, + {"/", "/"}, + + // Do not remove trailing slash + {"abc/", "abc/"}, + {"abc/def/", "abc/def/"}, + {"a/b/c/", "a/b/c/"}, + {"./", "./"}, + {"../", "../"}, + {"../../", "../../"}, + {"/abc/", "/abc/"}, + + // Remove doubled slash + {"abc//def//ghi", "abc/def/ghi"}, + {"//abc", "/abc"}, + {"///abc", "/abc"}, + {"//abc//", "/abc/"}, + {"abc//", "abc/"}, + + // Remove . elements + {"abc/./def", "abc/def"}, + {"/./abc/def", "/abc/def"}, + {"abc/.", "abc"}, + + // Remove .. elements + {"abc/def/ghi/../jkl", "abc/def/jkl"}, + {"abc/def/../ghi/../jkl", "abc/jkl"}, + {"abc/def/..", "abc"}, + {"abc/def/../..", "."}, + {"/abc/def/../..", "/"}, + {"abc/def/../../..", ".."}, + {"/abc/def/../../..", "/"}, + {"abc/def/../../../ghi/jkl/../../../mno", "../../mno"}, + + // Combinations + {"abc/./../def", "def"}, + {"abc//./../def", "def"}, + {"abc/../../././../def", "../../def"}, + + {"abc\\/../..\\/././../def", "../../def"}, + {"\\abc/def\\../..\\..", "/"}, +}; + +struct FilePathSplit +{ + const char* filePath; + bool absolute; + const char* path; + const char* fileName; + const char* baseName; + const char* extension; +}; + +static const FilePathSplit s_filePathSplit[] = +{ + { "\\abc/def\\../..\\../test.txt", true, "/", "test.txt", "test", ".txt" }, + { "/abv/gd/555/333/pod.mac", true, "/abv/gd/555/333/", "pod.mac", "pod", ".mac" }, + { "archive.tar.gz", false, "", "archive.tar.gz", "archive", ".tar.gz" }, + { "tmp/archive.tar.gz", false, "tmp/", "archive.tar.gz", "archive", ".tar.gz" }, + { "/tmp/archive.tar.gz", true, "/tmp/", "archive.tar.gz", "archive", ".tar.gz" }, + { "d:/tmp/archive.tar.gz", true, "D:/tmp/", "archive.tar.gz", "archive", ".tar.gz" }, + { "/tmp/abv/gd", true, "/tmp/abv/", "gd", "gd", "" }, + { "/tmp/abv/gd/", true, "/tmp/abv/gd/", "", "", "" }, +}; + +TEST_CASE("FilePath", "") +{ + bx::FilePath fp; + for (uint32_t ii = 0; ii < BX_COUNTOF(s_filePathTest); ++ii) + { + const FilePathTest& test = s_filePathTest[ii]; + + fp.set(test.filePath); + const bx::StringView result = fp.get(); + + REQUIRE(0 == bx::strCmp(test.expected, result) ); + } + + for (uint32_t ii = 0; ii < BX_COUNTOF(s_filePathSplit); ++ii) + { + const FilePathSplit& test = s_filePathSplit[ii]; + + fp.set(test.filePath); + const bx::StringView path = fp.getPath(); + const bx::StringView fileName = fp.getFileName(); + const bx::StringView baseName = fp.getBaseName(); + const bx::StringView ext = fp.getExt(); + + REQUIRE(0 == bx::strCmp(test.path, path) ); + REQUIRE(0 == bx::strCmp(test.fileName, fileName) ); + REQUIRE(0 == bx::strCmp(test.baseName, baseName) ); + REQUIRE(0 == bx::strCmp(test.extension, ext) ); + REQUIRE(test.absolute == fp.isAbsolute() ); + }; +} + +TEST_CASE("FilePath temp", "") +{ + bx::FilePath tmp(bx::Dir::Temp); + REQUIRE(0 != bx::strCmp(".", tmp.getPath().getPtr() ) ); + + bx::Error err; + tmp.join("test/abvgd/555333/test"); + REQUIRE(bx::makeAll(tmp, &err) ); + REQUIRE(err.isOk() ); + + tmp.set(bx::Dir::Temp); + tmp.join("test"); + REQUIRE(bx::removeAll(tmp, &err) ); + REQUIRE(err.isOk() ); +} diff --git a/3rdparty/bx/tests/handle_bench.cpp b/3rdparty/bx/tests/handle_bench.cpp index e8d8bee11cf..e5bd3007233 100644 --- a/3rdparty/bx/tests/handle_bench.cpp +++ b/3rdparty/bx/tests/handle_bench.cpp @@ -106,5 +106,5 @@ int main() extern void simd_bench(); simd_bench(); - return EXIT_SUCCESS; + return bx::kExitSuccess; } diff --git a/3rdparty/bx/tests/handle_test.cpp b/3rdparty/bx/tests/handle_test.cpp index b82e1da3174..05392922511 100644 --- a/3rdparty/bx/tests/handle_test.cpp +++ b/3rdparty/bx/tests/handle_test.cpp @@ -89,26 +89,26 @@ TEST_CASE("HandleHashTable", "") bx::StringView sv0("test0"); - bool ok = hm.insert(bx::hashMurmur2A(sv0), 0); + bool ok = hm.insert(bx::hash<bx::HashMurmur2A>(sv0), 0); REQUIRE(ok); - ok = hm.insert(bx::hashMurmur2A(sv0), 0); + ok = hm.insert(bx::hash<bx::HashMurmur2A>(sv0), 0); REQUIRE(!ok); REQUIRE(1 == hm.getNumElements() ); bx::StringView sv1("test1"); - ok = hm.insert(bx::hashMurmur2A(sv1), 0); + ok = hm.insert(bx::hash<bx::HashMurmur2A>(sv1), 0); REQUIRE(ok); REQUIRE(2 == hm.getNumElements() ); hm.removeByHandle(0); REQUIRE(0 == hm.getNumElements() ); - ok = hm.insert(bx::hashMurmur2A(sv0), 0); + ok = hm.insert(bx::hash<bx::HashMurmur2A>(sv0), 0); REQUIRE(ok); - hm.removeByKey(bx::hashMurmur2A(sv0) ); + hm.removeByKey(bx::hash<bx::HashMurmur2A>(sv0) ); REQUIRE(0 == hm.getNumElements() ); for (uint32_t ii = 0, num = hm.getMaxCapacity(); ii < num; ++ii) diff --git a/3rdparty/bx/tests/hash_test.cpp b/3rdparty/bx/tests/hash_test.cpp new file mode 100644 index 00000000000..8fbc542af94 --- /dev/null +++ b/3rdparty/bx/tests/hash_test.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "test.h" +#include <bx/hash.h> + +void makeCrcTable(uint32_t _poly) +{ + for (uint32_t ii = 0; ii < 256; ++ii) + { + uint32_t crc = ii; + for (uint32_t jj = 0; jj < 8; ++jj) + { + if (1 == (crc & 1) ) + { + crc = (crc >> 1) ^ _poly; + } + else + { + crc >>= 1; + } + } + + printf("0x%08x,%c", crc, 7 == (ii & 7) ? '\n' : ' '); + } +} + +struct HashTest +{ + uint32_t crc32; + uint32_t adler32; + const char* input; +}; + +const HashTest s_hashTest[] = +{ + { 0, 1, "" }, + { 0xe8b7be43, 0x00620062, "a" }, + { 0x9e83486d, 0x012600c4, "ab" }, + { 0xc340daab, 0x06060205, "abvgd" }, + { 0x07642fe2, 0x020a00d6, "1389" }, + { 0x26d75737, 0x04530139, "555333" }, +}; + +TEST_CASE("HashCrc32", "") +{ +#if 0 + makeCrcTable(0xedb88320); + printf("\n"); + makeCrcTable(0x82f63b78); + printf("\n"); + makeCrcTable(0xeb31d82e); +#endif // 0 + + for (uint32_t ii = 0; ii < BX_COUNTOF(s_hashTest); ++ii) + { + const HashTest& test = s_hashTest[ii]; + + bx::HashCrc32 hash; + hash.begin(); + hash.add(test.input, bx::strLen(test.input) ); + REQUIRE(test.crc32 == hash.end() ); + } +} + +TEST_CASE("HashAdler32", "") +{ + for (uint32_t ii = 0; ii < BX_COUNTOF(s_hashTest); ++ii) + { + const HashTest& test = s_hashTest[ii]; + + bx::HashAdler32 hash; + hash.begin(); + hash.add(test.input, bx::strLen(test.input) ); + REQUIRE(test.adler32 == hash.end() ); + } +} diff --git a/3rdparty/bx/tests/macros_test.cpp b/3rdparty/bx/tests/macros_test.cpp index bae4bb896cf..092bbd61726 100644 --- a/3rdparty/bx/tests/macros_test.cpp +++ b/3rdparty/bx/tests/macros_test.cpp @@ -61,5 +61,5 @@ TEST(macros) CHECK_EQUAL(5, BX_VA_ARGS_COUNT(1, 2, 3, 4, 5) ); CHECK_EQUAL(6, BX_VA_ARGS_COUNT(1, 2, 3, 4, 5, 6) ); - CHECK_EQUAL(0, bx::strncmp(BX_STRINGIZE(TEST 1234 %^&*), "TEST 1234 %^&*") ); + CHECK_EQUAL(0, bx::strCmp(BX_STRINGIZE(TEST 1234 %^&*), "TEST 1234 %^&*") ); } diff --git a/3rdparty/bx/tests/main_test.cpp b/3rdparty/bx/tests/main_test.cpp index b9d66db2fd6..261b62a2139 100644 --- a/3rdparty/bx/tests/main_test.cpp +++ b/3rdparty/bx/tests/main_test.cpp @@ -16,25 +16,6 @@ void ANativeActivity_onCreate(ANativeActivity*, void*, size_t) { exit(runAllTests(BX_COUNTOF(s_argv), s_argv) ); } -#elif BX_PLATFORM_NACL -# include <ppapi/c/pp_errors.h> -# include <ppapi/c/ppp.h> - -PP_EXPORT const void* PPP_GetInterface(const char* /*_name*/) -{ - return NULL; -} - -PP_EXPORT int32_t PPP_InitializeModule(PP_Module /*_module*/, PPB_GetInterface /*_interface*/) -{ - DBG("PPAPI version: %d", PPAPI_RELEASE); - runAllTests(BX_COUNTOF(s_argv), s_argv); - return PP_ERROR_NOINTERFACE; -} - -PP_EXPORT void PPP_ShutdownModule() -{ -} #else int main(int _argc, const char* _argv[]) { diff --git a/3rdparty/bx/tests/fpumath_test.cpp b/3rdparty/bx/tests/math_test.cpp index ae843872e43..2005a67908c 100644 --- a/3rdparty/bx/tests/fpumath_test.cpp +++ b/3rdparty/bx/tests/math_test.cpp @@ -4,7 +4,7 @@ */ #include "test.h" -#include <bx/fpumath.h> +#include <bx/math.h> #if !BX_COMPILER_MSVC || BX_COMPILER_MSVC >= 1800 #include <cmath> @@ -13,13 +13,25 @@ TEST_CASE("isFinite, isInfinite, isNan", "") for (uint64_t ii = 0; ii < UINT32_MAX; ii += rand()%(1<<13)+1) { union { uint32_t ui; float f; } u = { uint32_t(ii) }; - REQUIRE(std::isnan(u.f) == bx::isNan(u.f) ); + REQUIRE(std::isnan(u.f) == bx::isNan(u.f) ); REQUIRE(std::isfinite(u.f) == bx::isFinite(u.f) ); - REQUIRE(std::isinf(u.f) == bx::isInfinite(u.f) ); + REQUIRE(std::isinf(u.f) == bx::isInfinite(u.f) ); } } #endif // !BX_COMPILER_MSVC || BX_COMPILER_MSVC >= 1800 + +bool flog2_test(float _a) +{ + return bx::flog2(_a) == bx::flog(_a) * (1.0f / bx::flog(2.0f) ); +} + +TEST_CASE("flog2", "") +{ + flog2_test(0.0f); + flog2_test(256.0f); +} + TEST_CASE("ToBits", "") { REQUIRE(UINT32_C(0x12345678) == bx::floatToBits( bx::bitsToFloat( UINT32_C(0x12345678) ) ) ); @@ -65,9 +77,9 @@ TEST_CASE("quaternion", "") bx::mtxIdentity(mtx); mtxCheck(mtxQ, mtx); - float ax = bx::pi/27.0f; - float ay = bx::pi/13.0f; - float az = bx::pi/7.0f; + float ax = bx::kPi/27.0f; + float ay = bx::kPi/13.0f; + float az = bx::kPi/7.0f; bx::quatRotateX(quat, ax); bx::mtxQuat(mtxQ, quat); diff --git a/3rdparty/bx/tests/os_test.cpp b/3rdparty/bx/tests/os_test.cpp index e6aeb314fbe..1589416e543 100644 --- a/3rdparty/bx/tests/os_test.cpp +++ b/3rdparty/bx/tests/os_test.cpp @@ -5,6 +5,8 @@ #include "test.h" #include <bx/os.h> +#include <bx/semaphore.h> +#include <bx/timer.h> TEST_CASE("getProcessMemoryUsed", "") { @@ -12,9 +14,15 @@ TEST_CASE("getProcessMemoryUsed", "") // DBG("bx::getProcessMemoryUsed %d", bx::getProcessMemoryUsed() ); } -TEST_CASE("getTempPath", "") +TEST_CASE("semaphore_timeout", "") { - char tmpDir[512]; - uint32_t len = BX_COUNTOF(tmpDir); - REQUIRE(bx::getTempPath(tmpDir, &len) ); + bx::Semaphore sem; + + int64_t start = bx::getHPCounter(); + bool ok = sem.wait(900); + int64_t elapsed = bx::getHPCounter() - start; + int64_t frequency = bx::getHPFrequency(); + double ms = double(elapsed) / double(frequency) * 1000; + printf("%f\n", ms); + REQUIRE(!ok); } diff --git a/3rdparty/bx/tests/queue_test.cpp b/3rdparty/bx/tests/queue_test.cpp index 48fd270a274..81a2b44e676 100644 --- a/3rdparty/bx/tests/queue_test.cpp +++ b/3rdparty/bx/tests/queue_test.cpp @@ -21,14 +21,16 @@ uintptr_t ptrToBits(void* _ptr) TEST_CASE("SpSc", "") { - bx::SpScUnboundedQueue queue; + bx::DefaultAllocator allocator; + bx::SpScUnboundedQueue queue(&allocator); queue.push(bitsToPtr(0xdeadbeef) ); REQUIRE(0xdeadbeef == ptrToBits(queue.pop() ) ); } TEST_CASE("MpSc", "") { - bx::MpScUnboundedQueueT<void> queue; + bx::DefaultAllocator allocator; + bx::MpScUnboundedQueueT<void> queue(&allocator); queue.push(bitsToPtr(0xdeadbeef) ); REQUIRE(0xdeadbeef == ptrToBits(queue.pop() ) ); } diff --git a/3rdparty/bx/tests/rng_test.cpp b/3rdparty/bx/tests/rng_test.cpp new file mode 100644 index 00000000000..89fef3f05d7 --- /dev/null +++ b/3rdparty/bx/tests/rng_test.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "test.h" + +#include <bx/rng.h> +#include <bx/file.h> + +const uint32_t kMax = 10<<20; + +template<typename Ty> +void testRng(const char* _name, Ty* _rng) +{ + uint32_t histBits[32]; + uint32_t histUint8[256]; + + bx::memSet(histBits, 0, sizeof(histBits) ); + bx::memSet(histUint8, 0, sizeof(histUint8) ); + + for (uint32_t ii = 0; ii < kMax; ++ii) + { + uint32_t val = _rng->gen(); + + for (uint32_t shift = 0; shift < 32; ++shift) + { + const uint32_t mask = 1<<shift; + histBits[shift] += !!(0 != (val & mask) ); + } + + const uint32_t mf000 = (val & 0xff000000)>>24; + const uint32_t m0f00 = (val & 0x00ff0000)>>16; + const uint32_t m00f0 = (val & 0x0000ff00)>> 8; + const uint32_t m000f = (val & 0x000000ff)>> 0; + + histUint8[mf000]++; + histUint8[m0f00]++; + histUint8[m00f0]++; + histUint8[m000f]++; + } + + bx::WriterI* writer = bx::getNullOut(); + bx::writePrintf(writer, "%s\n", _name); + + { + bx::writePrintf(writer, "\tbits histogram:\n"); + uint32_t min = UINT32_MAX; + uint32_t max = 0; + + for (uint32_t ii = 0; ii < BX_COUNTOF(histBits); ++ii) + { + bx::writePrintf(writer, "\t\t%3d: %d\n", ii, histBits[ii]); + min = bx::min(min, histBits[ii]); + max = bx::max(max, histBits[ii]); + } + + bx::writePrintf(writer, "\tmin: %d, max: %d (diff: %d)\n", min, max, max-min); + + REQUIRE(max-min < 8000); + } + + { + bx::writePrintf(writer, "\tuint8_t histogram:\n"); + uint32_t min = UINT32_MAX; + uint32_t max = 0; + + for (uint32_t ii = 0; ii < BX_COUNTOF(histUint8); ++ii) + { + bx::writePrintf(writer, "\t\t%3d: %d\n", ii, histUint8[ii]); + min = bx::min(min, histUint8[ii]); + max = bx::max(max, histUint8[ii]); + } + + bx::writePrintf(writer, "\tmin: %d, max: %d (diff: %d)\n", min, max, max-min); + + REQUIRE(max-min < 8000); + } +} + +TEST_CASE("Rng", "") +{ + bx::RngMwc mwc; + testRng("RngMwc", &mwc); + + bx::RngShr3 shr3; + testRng("RngShr3", &shr3); +} diff --git a/3rdparty/bx/tests/settings_test.cpp b/3rdparty/bx/tests/settings_test.cpp new file mode 100644 index 00000000000..9f94cfd9fa8 --- /dev/null +++ b/3rdparty/bx/tests/settings_test.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "test.h" +#include <bx/settings.h> +#include <bx/file.h> + +TEST_CASE("Settings", "") +{ + bx::FilePath filePath; + filePath.set(bx::Dir::Temp); + filePath.join("settings.ini"); + + bx::DefaultAllocator allocator; + + bx::Settings settings(&allocator); + + settings.set("meh/podmac", "true"); + settings.set("test/foo/bar/abvgd", "1389"); + + bx::FileWriter writer; + if (bx::open(&writer, filePath) ) + { + bx::write(&writer, settings); + bx::close(&writer); + } + + REQUIRE(NULL == settings.get("meh") ); + REQUIRE(0 == bx::strCmp(settings.get("meh/podmac"), "true") ); + REQUIRE(0 == bx::strCmp(settings.get("test/foo/bar/abvgd"), "1389") ); + + settings.remove("meh/podmac"); + REQUIRE(NULL == settings.get("meh/podmac") ); + + settings.clear(); + + bx::FileReader reader; + if (bx::open(&reader, filePath) ) + { + bx::read(&reader, settings); + bx::close(&reader); + } + + REQUIRE(NULL == settings.get("meh") ); + REQUIRE(0 == bx::strCmp(settings.get("meh/podmac"), "true") ); + REQUIRE(0 == bx::strCmp(settings.get("test/foo/bar/abvgd"), "1389") ); +} diff --git a/3rdparty/bx/tests/simd_bench.cpp b/3rdparty/bx/tests/simd_bench.cpp index d8ace20c117..0f0c9c4671c 100644 --- a/3rdparty/bx/tests/simd_bench.cpp +++ b/3rdparty/bx/tests/simd_bench.cpp @@ -3,9 +3,9 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#include <bx/simd_t.h> +#include <bx/allocator.h> #include <bx/rng.h> -#include <bx/crtimpl.h> +#include <bx/simd_t.h> #include <bx/timer.h> #include <stdio.h> @@ -98,7 +98,7 @@ void simd_bench_pass(bx::simd128_t* _dst, bx::simd128_t* _src, uint32_t _numVert void simd_bench() { - bx::CrtAllocator allocator; + bx::DefaultAllocator allocator; bx::RngMwc rng; const uint32_t numVertices = 1024*1024; @@ -121,10 +121,10 @@ void simd_bench() for (uint32_t ii = 0; ii < numVertices; ++ii) { float* ptr = (float*)&src[ii]; - ptr[0] = bx::fabsolute(ptr[0]); - ptr[1] = bx::fabsolute(ptr[1]); - ptr[2] = bx::fabsolute(ptr[2]); - ptr[3] = bx::fabsolute(ptr[3]); + ptr[0] = bx::fabs(ptr[0]); + ptr[1] = bx::fabs(ptr[1]); + ptr[2] = bx::fabs(ptr[2]); + ptr[3] = bx::fabs(ptr[3]); } simd_bench_pass(dst, src, numVertices); diff --git a/3rdparty/bx/tests/simd_test.cpp b/3rdparty/bx/tests/simd_test.cpp index ca46fd00bc3..fcdc7a9cb1f 100644 --- a/3rdparty/bx/tests/simd_test.cpp +++ b/3rdparty/bx/tests/simd_test.cpp @@ -5,7 +5,7 @@ #include "test.h" #include <bx/simd_t.h> -#include <bx/fpumath.h> +#include <bx/math.h> #include <bx/string.h> #if 0 @@ -206,7 +206,7 @@ void simd_check_string(const char* _str, bx::simd128_t _a) SIMD_DBG("%s %s", _str, test); - CHECK(0 == bx::strncmp(_str, test) ); + CHECK(0 == bx::strCmp(_str, test) ); } TEST_CASE("simd_swizzle", "") @@ -235,13 +235,14 @@ TEST_CASE("simd_shuffle", "") const simd128_t ABCD = simd_ild(0x41414141, 0x42424242, 0x43434343, 0x44444444); simd_check_string("xyAB", simd_shuf_xyAB(xyzw, ABCD) ); simd_check_string("ABxy", simd_shuf_ABxy(xyzw, ABCD) ); - simd_check_string("zwCD", simd_shuf_zwCD(xyzw, ABCD) ); simd_check_string("CDzw", simd_shuf_CDzw(xyzw, ABCD) ); + simd_check_string("zwCD", simd_shuf_zwCD(xyzw, ABCD) ); simd_check_string("xAyB", simd_shuf_xAyB(xyzw, ABCD) ); + simd_check_string("AxBy", simd_shuf_AxBy(xyzw, ABCD) ); simd_check_string("zCwD", simd_shuf_zCwD(xyzw, ABCD) ); + simd_check_string("CzDw", simd_shuf_CzDw(xyzw, ABCD) ); simd_check_string("xAzC", simd_shuf_xAzC(xyzw, ABCD) ); simd_check_string("yBwD", simd_shuf_yBwD(xyzw, ABCD) ); - simd_check_string("CzDw", simd_shuf_CzDw(xyzw, ABCD) ); } TEST_CASE("simd_compare", "") diff --git a/3rdparty/bx/tests/sort_test.cpp b/3rdparty/bx/tests/sort_test.cpp index d271a3ffa03..0b078e23d90 100644 --- a/3rdparty/bx/tests/sort_test.cpp +++ b/3rdparty/bx/tests/sort_test.cpp @@ -23,13 +23,13 @@ TEST_CASE("quickSort", "") { const char* lhs = *(const char**)_lhs; const char* rhs = *(const char**)_rhs; - return bx::strncmp(lhs, rhs); + return bx::strCmp(lhs, rhs); }); - REQUIRE(0 == bx::strncmp(str[0], "jabuka") ); - REQUIRE(0 == bx::strncmp(str[1], "jagoda") ); - REQUIRE(0 == bx::strncmp(str[2], "kruska") ); - REQUIRE(0 == bx::strncmp(str[3], "malina") ); + REQUIRE(0 == bx::strCmp(str[0], "jabuka") ); + REQUIRE(0 == bx::strCmp(str[1], "jagoda") ); + REQUIRE(0 == bx::strCmp(str[2], "kruska") ); + REQUIRE(0 == bx::strCmp(str[3], "malina") ); int8_t byte[128]; bx::RngMwc rng; diff --git a/3rdparty/bx/tests/string_test.cpp b/3rdparty/bx/tests/string_test.cpp index 35e1dac4445..d848f3de142 100644 --- a/3rdparty/bx/tests/string_test.cpp +++ b/3rdparty/bx/tests/string_test.cpp @@ -4,9 +4,10 @@ */ #include "test.h" +#include <bx/filepath.h> #include <bx/string.h> -#include <bx/crtimpl.h> #include <bx/handlealloc.h> +#include <bx/sort.h> bx::AllocatorI* g_allocator; @@ -23,110 +24,185 @@ TEST_CASE("chars", "") } } -TEST_CASE("strnlen", "") +TEST_CASE("strLen", "") { const char* test = "test"; - REQUIRE(0 == bx::strnlen(test, 0) ); - REQUIRE(2 == bx::strnlen(test, 2) ); - REQUIRE(4 == bx::strnlen(test, INT32_MAX) ); + REQUIRE(0 == bx::strLen(test, 0) ); + REQUIRE(2 == bx::strLen(test, 2) ); + REQUIRE(4 == bx::strLen(test, INT32_MAX) ); } -TEST_CASE("strlncpy", "") +TEST_CASE("strCopy", "") { char dst[128]; size_t num; - num = bx::strlncpy(dst, 1, "blah"); + num = bx::strCopy(dst, 1, "blah"); REQUIRE(num == 0); - num = bx::strlncpy(dst, 3, "blah", 3); - REQUIRE(0 == bx::strncmp(dst, "bl") ); + num = bx::strCopy(dst, 3, "blah", 3); + REQUIRE(0 == bx::strCmp(dst, "bl") ); REQUIRE(num == 2); - num = bx::strlncpy(dst, sizeof(dst), "blah", 3); - REQUIRE(0 == bx::strncmp(dst, "bla") ); + num = bx::strCopy(dst, sizeof(dst), "blah", 3); + REQUIRE(0 == bx::strCmp(dst, "bla") ); REQUIRE(num == 3); - num = bx::strlncpy(dst, sizeof(dst), "blah"); - REQUIRE(0 == bx::strncmp(dst, "blah") ); + num = bx::strCopy(dst, sizeof(dst), "blah"); + REQUIRE(0 == bx::strCmp(dst, "bl", 2) ); + REQUIRE(0 == bx::strCmp(dst, "blah") ); REQUIRE(num == 4); } -TEST_CASE("strlncat", "") +TEST_CASE("strCat", "") { char dst[128] = { '\0' }; - REQUIRE(0 == bx::strlncat(dst, 1, "cat") ); + REQUIRE(0 == bx::strCat(dst, 1, "cat") ); - REQUIRE(4 == bx::strlncpy(dst, 5, "copy") ); - REQUIRE(3 == bx::strlncat(dst, 8, "cat") ); - REQUIRE(0 == bx::strncmp(dst, "copycat") ); + REQUIRE(4 == bx::strCopy(dst, 5, "copy") ); + REQUIRE(3 == bx::strCat(dst, 8, "cat") ); + REQUIRE(0 == bx::strCmp(dst, "copycat") ); + REQUIRE(0 == bx::strCmp(dst, "copy", 4) ); - REQUIRE(1 == bx::strlncat(dst, BX_COUNTOF(dst), "------", 1) ); - REQUIRE(3 == bx::strlncat(dst, BX_COUNTOF(dst), "cat") ); - REQUIRE(0 == bx::strncmp(dst, "copycat-cat") ); + REQUIRE(1 == bx::strCat(dst, BX_COUNTOF(dst), "------", 1) ); + REQUIRE(3 == bx::strCat(dst, BX_COUNTOF(dst), "cat") ); + REQUIRE(0 == bx::strCmp(dst, "copycat-cat") ); } -TEST_CASE("strincmp", "") +TEST_CASE("strCmp", "") { - REQUIRE(0 == bx::strincmp("test", "test") ); - REQUIRE(0 == bx::strincmp("test", "testestes", 4) ); - REQUIRE(0 == bx::strincmp("testestes", "test", 4) ); - REQUIRE(0 != bx::strincmp("preprocess", "platform") ); + REQUIRE(0 != bx::strCmp("meh", "meh/") ); +} + +TEST_CASE("strCmpI", "") +{ + REQUIRE(0 == bx::strCmpI("test", "test") ); + REQUIRE(0 == bx::strCmpI("test", "testestes", 4) ); + REQUIRE(0 == bx::strCmpI("testestes", "test", 4) ); + REQUIRE(0 != bx::strCmpI("preprocess", "platform") ); const char* abvgd = "abvgd"; const char* abvgx = "abvgx"; const char* empty = ""; - REQUIRE(0 == bx::strincmp(abvgd, abvgd) ); - REQUIRE(0 == bx::strincmp(abvgd, abvgx, 4) ); + REQUIRE(0 == bx::strCmpI(abvgd, abvgd) ); + REQUIRE(0 == bx::strCmpI(abvgd, abvgx, 4) ); + REQUIRE(0 == bx::strCmpI(empty, empty) ); - REQUIRE(0 > bx::strincmp(abvgd, abvgx) ); - REQUIRE(0 > bx::strincmp(empty, abvgd) ); + REQUIRE(0 > bx::strCmpI(abvgd, abvgx) ); + REQUIRE(0 > bx::strCmpI(empty, abvgd) ); - REQUIRE(0 < bx::strincmp(abvgx, abvgd) ); - REQUIRE(0 < bx::strincmp(abvgd, empty) ); + REQUIRE(0 < bx::strCmpI(abvgx, abvgd) ); + REQUIRE(0 < bx::strCmpI(abvgd, empty) ); } -TEST_CASE("strnchr", "") +TEST_CASE("strCmpV", "") { - const char* test = "test"; - REQUIRE(NULL == bx::strnchr(test, 's', 0) ); - REQUIRE(NULL == bx::strnchr(test, 's', 2) ); - REQUIRE(&test[2] == bx::strnchr(test, 's') ); + REQUIRE(0 == bx::strCmpV("test", "test") ); + REQUIRE(0 == bx::strCmpV("test", "testestes", 4) ); + REQUIRE(0 == bx::strCmpV("testestes", "test", 4) ); + REQUIRE(0 != bx::strCmpV("preprocess", "platform") ); + + const char* abvgd = "abvgd"; + const char* abvgx = "abvgx"; + const char* empty = ""; + REQUIRE(0 == bx::strCmpV(abvgd, abvgd) ); + REQUIRE(0 == bx::strCmpV(abvgd, abvgx, 4) ); + REQUIRE(0 == bx::strCmpV(empty, empty) ); + + REQUIRE(0 > bx::strCmpV(abvgd, abvgx) ); + REQUIRE(0 > bx::strCmpV(empty, abvgd) ); + + REQUIRE(0 < bx::strCmpV(abvgx, abvgd) ); + REQUIRE(0 < bx::strCmpV(abvgd, empty) ); +} + +static int32_t strCmpV(const void* _lhs, const void* _rhs) +{ + const char* lhs = *(const char**)_lhs; + const char* rhs = *(const char**)_rhs; + int32_t result = bx::strCmpV(lhs, rhs); + return result; +} + +TEST_CASE("strCmpV sort", "") +{ + const char* test[] = + { + "test_1.txt", + "test_10.txt", + "test_100.txt", + "test_15.txt", + "test_11.txt", + "test_23.txt", + "test_3.txt", + }; + + const char* expected[] = + { + "test_1.txt", + "test_3.txt", + "test_10.txt", + "test_11.txt", + "test_15.txt", + "test_23.txt", + "test_100.txt", + }; + + BX_STATIC_ASSERT(BX_COUNTOF(test) == BX_COUNTOF(expected) ); + + bx::quickSort(test, BX_COUNTOF(test), sizeof(const char*), strCmpV); + + for (uint32_t ii = 0; ii < BX_COUNTOF(test); ++ii) + { + REQUIRE(0 == bx::strCmp(test[ii], expected[ii]) ); + } } -TEST_CASE("strnrchr", "") +TEST_CASE("strRFind", "") { const char* test = "test"; - REQUIRE(NULL == bx::strnrchr(test, 's', 0) ); - REQUIRE(NULL == bx::strnrchr(test, 's', 1) ); - REQUIRE(&test[2] == bx::strnrchr(test, 's') ); + REQUIRE(NULL == bx::strRFind(bx::StringView(test, 0), 's') ); + REQUIRE(NULL == bx::strRFind(bx::StringView(test, 1), 's') ); + REQUIRE(&test[2] == bx::strRFind(test, 's') ); } -TEST_CASE("stristr", "") +TEST_CASE("strFindI", "") { const char* test = "The Quick Brown Fox Jumps Over The Lazy Dog."; - REQUIRE(NULL == bx::stristr(test, "quick", 8) ); - REQUIRE(NULL == bx::stristr(test, "quick1") ); - REQUIRE(&test[4] == bx::stristr(test, "quick", 9) ); - REQUIRE(&test[4] == bx::stristr(test, "quick") ); + REQUIRE(NULL == bx::strFindI(bx::StringView(test, 8), "quick") ); + REQUIRE(NULL == bx::strFindI(test, "quick1") ); + REQUIRE(&test[4] == bx::strFindI(bx::StringView(test, 9), "quick") ); + REQUIRE(&test[4] == bx::strFindI(test, "quick") ); } -TEST_CASE("strnstr", "") +TEST_CASE("strFind", "") { - const char* test = "The Quick Brown Fox Jumps Over The Lazy Dog."; + { + const char* test = "test"; - REQUIRE(NULL == bx::strnstr(test, "quick", 8) ); - REQUIRE(NULL == bx::strnstr(test, "quick1") ); - REQUIRE(NULL == bx::strnstr(test, "quick", 9) ); - REQUIRE(NULL == bx::strnstr(test, "quick") ); + REQUIRE(NULL == bx::strFind(bx::StringView(test, 0), 's') ); + REQUIRE(NULL == bx::strFind(bx::StringView(test, 2), 's') ); + REQUIRE(&test[2] == bx::strFind(test, 's') ); + } - REQUIRE(NULL == bx::strnstr(test, "Quick", 8) ); - REQUIRE(NULL == bx::strnstr(test, "Quick1") ); - REQUIRE(&test[4] == bx::strnstr(test, "Quick", 9) ); - REQUIRE(&test[4] == bx::strnstr(test, "Quick") ); + { + const char* test = "The Quick Brown Fox Jumps Over The Lazy Dog."; + + REQUIRE(NULL == bx::strFind(bx::StringView(test, 8), "quick") ); + REQUIRE(NULL == bx::strFind(test, "quick1") ); + REQUIRE(NULL == bx::strFind(bx::StringView(test, 9), "quick") ); + REQUIRE(NULL == bx::strFind(test, "quick") ); + + REQUIRE(NULL == bx::strFind(bx::StringView(test, 8), "Quick") ); + REQUIRE(NULL == bx::strFind(test, "Quick1") ); + REQUIRE(&test[4] == bx::strFind(bx::StringView(test, 9), "Quick") ); + REQUIRE(&test[4] == bx::strFind(test, "Quick") ); + + REQUIRE(NULL == bx::strFind("vgd", 'a') ); + } } template<typename Ty> @@ -134,8 +210,8 @@ static bool testToString(Ty _value, const char* _expected) { char tmp[1024]; int32_t num = bx::toString(tmp, BX_COUNTOF(tmp), _value); - int32_t len = (int32_t)bx::strnlen(_expected); - if (0 == bx::strncmp(tmp, _expected) + int32_t len = (int32_t)bx::strLen(_expected); + if (0 == bx::strCmp(tmp, _expected) && num == len) { return true; @@ -178,6 +254,86 @@ TEST_CASE("toString double", "") REQUIRE(testToString(1231231.23, "1231231.23") ); REQUIRE(testToString(0.000000000123123, "1.23123e-10") ); REQUIRE(testToString(0.0000000001, "1e-10") ); + REQUIRE(testToString(-270.000000, "-270.0") ); +} + +static bool testFromString(double _value, const char* _input) +{ + char tmp[1024]; + bx::toString(tmp, BX_COUNTOF(tmp), _value); + + double lhs; + bx::fromString(&lhs, tmp); + + double rhs; + bx::fromString(&rhs, _input); + + if (lhs == rhs) + { + return true; + } + + printf("result '%f', input '%s'\n", _value, _input); + return false; +} + +TEST_CASE("fromString double", "") +{ + REQUIRE(testFromString(0.0, "0.0") ); + REQUIRE(testFromString(-0.0, "-0.0") ); + REQUIRE(testFromString(1.0, "1.0") ); + REQUIRE(testFromString(-1.0, "-1.0") ); + REQUIRE(testFromString(1.2345, "1.2345") ); + REQUIRE(testFromString(1.2345678, "1.2345678") ); + REQUIRE(testFromString(0.123456789012, "0.123456789012") ); + REQUIRE(testFromString(1234567.8, "1234567.8") ); + REQUIRE(testFromString(-79.39773355813419, "-79.39773355813419") ); + REQUIRE(testFromString(0.000001, "0.000001") ); + REQUIRE(testFromString(0.0000001, "1e-7") ); + REQUIRE(testFromString(1e30, "1e30") ); + REQUIRE(testFromString(1.234567890123456e30, "1.234567890123456e30") ); + REQUIRE(testFromString(-5e-324, "-5e-324") ); + REQUIRE(testFromString(2.225073858507201e-308, "2.225073858507201e-308") ); + REQUIRE(testFromString(2.2250738585072014e-308, "2.2250738585072014e-308") ); + REQUIRE(testFromString(1.7976931348623157e308, "1.7976931348623157e308") ); + REQUIRE(testFromString(0.00000123123123, "0.00000123123123") ); + REQUIRE(testFromString(0.000000123123123, "1.23123123e-7") ); + REQUIRE(testFromString(123123.123, "123123.123") ); + REQUIRE(testFromString(1231231.23, "1231231.23") ); + REQUIRE(testFromString(0.000000000123123, "1.23123e-10") ); + REQUIRE(testFromString(0.0000000001, "1e-10") ); + REQUIRE(testFromString(-270.000000, "-270.0") ); +} + +static bool testFromString(int32_t _value, const char* _input) +{ + char tmp[1024]; + bx::toString(tmp, BX_COUNTOF(tmp), _value); + + double lhs; + bx::fromString(&lhs, tmp); + + double rhs; + bx::fromString(&rhs, _input); + + if (lhs == rhs) + { + return true; + } + + printf("result '%d', input '%s'\n", _value, _input); + return false; +} + +TEST_CASE("fromString int32_t", "") +{ + REQUIRE(testFromString(1389, "1389") ); + REQUIRE(testFromString(1389, " 1389") ); + REQUIRE(testFromString(1389, "+1389") ); + REQUIRE(testFromString(-1389, "-1389") ); + REQUIRE(testFromString(-1389, " -1389") ); + REQUIRE(testFromString(555333, "555333") ); + REQUIRE(testFromString(-21, "-021") ); } TEST_CASE("StringView", "") @@ -185,7 +341,7 @@ TEST_CASE("StringView", "") bx::StringView sv("test"); REQUIRE(4 == sv.getLength() ); - bx::CrtAllocator crt; + bx::DefaultAllocator crt; g_allocator = &crt; typedef bx::StringT<&g_allocator> String; @@ -196,10 +352,10 @@ TEST_CASE("StringView", "") st.append("test"); REQUIRE(8 == st.getLength() ); - st.append("test", 2); + st.append(bx::StringView("test", 2) ); REQUIRE(10 == st.getLength() ); - REQUIRE(0 == bx::strncmp(st.getPtr(), "testtestte") ); + REQUIRE(0 == bx::strCmp(st.getPtr(), "testtestte") ); st.clear(); REQUIRE(0 == st.getLength() ); @@ -211,3 +367,25 @@ TEST_CASE("StringView", "") sv.clear(); REQUIRE(0 == sv.getLength() ); } + +TEST_CASE("Trim", "") +{ + REQUIRE(0 == bx::strCmp(bx::strLTrim("abvgd", "ab"), "vgd") ); + REQUIRE(0 == bx::strCmp(bx::strLTrim("abvgd", "vagbd"), "") ); + REQUIRE(0 == bx::strCmp(bx::strLTrim("abvgd", "vgd"), "abvgd") ); + REQUIRE(0 == bx::strCmp(bx::strLTrim("/555333/podmac/", "/"), "555333/podmac/") ); + + REQUIRE(0 == bx::strCmp(bx::strRTrim("abvgd", "vagbd"), "") ); + REQUIRE(0 == bx::strCmp(bx::strRTrim("abvgd", "abv"), "abvgd") ); + REQUIRE(0 == bx::strCmp(bx::strRTrim("/555333/podmac/", "/"), "/555333/podmac") ); + + REQUIRE(0 == bx::strCmp(bx::strTrim("abvgd", "da"), "bvg") ); + REQUIRE(0 == bx::strCmp(bx::strTrim("<1389>", "<>"), "1389") ); + REQUIRE(0 == bx::strCmp(bx::strTrim("/555333/podmac/", "/"), "555333/podmac") ); + + REQUIRE(0 == bx::strCmp(bx::strTrim("abvgd", ""), "abvgd") ); + REQUIRE(0 == bx::strCmp(bx::strTrim(" \t a b\tv g d \t ", " \t"), "a b\tv g d") ); + + bx::FilePath uri("/555333/podmac/"); + REQUIRE(0 == bx::strCmp(bx::strTrim(uri.getPath(), "/"), "555333/podmac") ); +} diff --git a/3rdparty/bx/tests/thread_test.cpp b/3rdparty/bx/tests/thread_test.cpp index 8d099311835..713781956fb 100644 --- a/3rdparty/bx/tests/thread_test.cpp +++ b/3rdparty/bx/tests/thread_test.cpp @@ -6,17 +6,37 @@ #include "test.h" #include <bx/thread.h> -int32_t threadExit0(void*) +bx::DefaultAllocator s_allocator; +bx::MpScUnboundedBlockingQueue<void> s_mpsc(&s_allocator); + +int32_t threadExit0(bx::Thread* _thread, void*) { - return 0; + _thread->pop(); + + s_mpsc.push(reinterpret_cast<void*>(uintptr_t(0x1300) ) ); + + return bx::kExitSuccess; +} + +int32_t threadExit1(bx::Thread* _thread, void*) +{ + BX_UNUSED(_thread); + + s_mpsc.push(reinterpret_cast<void*>(uintptr_t(0x89) ) ); + + return bx::kExitFailure; } -int32_t threadExit1(void*) +TEST_CASE("Semaphore", "") { - return 1; + bx::Semaphore sem; + REQUIRE(!sem.wait(10) ); + + sem.post(1); + REQUIRE(sem.wait() ); } -TEST_CASE("thread", "") +TEST_CASE("Thread", "") { bx::Thread th; @@ -24,6 +44,7 @@ TEST_CASE("thread", "") th.init(threadExit0); REQUIRE(th.isRunning() ); + th.push(NULL); th.shutdown(); REQUIRE(!th.isRunning() ); @@ -36,3 +57,13 @@ TEST_CASE("thread", "") REQUIRE(!th.isRunning() ); REQUIRE(th.getExitCode() == 1); } + +TEST_CASE("MpScUnboundedBlockingQueue", "") +{ + void* p0 = s_mpsc.pop(); + void* p1 = s_mpsc.pop(); + + uintptr_t result = uintptr_t(p0) | uintptr_t(p1); + + REQUIRE(result == 0x1389); +} diff --git a/3rdparty/bx/tests/tokenizecmd_test.cpp b/3rdparty/bx/tests/tokenizecmd_test.cpp index d1495b28796..fece7ea2f25 100644 --- a/3rdparty/bx/tests/tokenizecmd_test.cpp +++ b/3rdparty/bx/tests/tokenizecmd_test.cpp @@ -15,12 +15,24 @@ TEST_CASE("commandLine", "") "--long", "--platform", "x", + "--num", "1389", + "--foo", + "--", // it should not parse arguments after argument terminator + "--bar", }; bx::CommandLine cmdLine(BX_COUNTOF(args), args); - REQUIRE(cmdLine.hasArg("long") ); - REQUIRE(cmdLine.hasArg('s') ); + REQUIRE( cmdLine.hasArg("long") ); + REQUIRE( cmdLine.hasArg('s') ); + + int32_t num; + REQUIRE(cmdLine.hasArg(num, '\0', "num") ); + REQUIRE(1389 == num); + + // test argument terminator + REQUIRE( cmdLine.hasArg("foo") ); + REQUIRE(!cmdLine.hasArg("bar") ); // non-existing argument REQUIRE(!cmdLine.hasArg('x') ); @@ -46,7 +58,7 @@ static bool test(const char* _input, int32_t _argc, ...) for (int32_t ii = 0; ii < _argc; ++ii) { const char* arg = va_arg(argList, const char*); - if (0 != bx::strncmp(argv[ii], arg) ) + if (0 != bx::strCmp(argv[ii], arg) ) { return false; } diff --git a/3rdparty/bx/tests/url_test.cpp b/3rdparty/bx/tests/url_test.cpp new file mode 100644 index 00000000000..504f4d2bc4d --- /dev/null +++ b/3rdparty/bx/tests/url_test.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "test.h" +#include <bx/string.h> +#include <bx/url.h> + +struct UrlTest +{ + bool result; + const char* url; + const char* tokens[bx::UrlView::Count]; +}; + +static const UrlTest s_urlTest[] = +{ + { true + , "scheme://username:password@host.rs:80/this/is/path/index.php?query=\"value\"#fragment", + { "scheme", "username", "password", "host.rs", "80", "/this/is/path/index.php", "query=\"value\"", "fragment" } + }, + { true + , "scheme://host.rs/", + { "scheme", "", "", "host.rs", "", "/", "", "" }, + }, + { true + , "scheme://host.rs:1389/", + { "scheme", "", "", "host.rs", "1389", "/", "", "" }, + }, + { true + , "host.rs/abvgd.html", + { "", "", "", "host.rs", "", "/abvgd.html", "", "" }, + }, + { true + , "https://192.168.0.1:8080/", + { "https", "", "", "192.168.0.1", "8080", "/", "", "" }, + }, + + { true + , "file:///d:/tmp/archive.tar.gz", + { "file", "", "", "", "", "/d:/tmp/archive.tar.gz", "", "" }, + }, +}; + +TEST_CASE("tokenizeUrl", "") +{ + bx::UrlView url; + + for (uint32_t ii = 0; ii < BX_COUNTOF(s_urlTest); ++ii) + { + const UrlTest& urlTest = s_urlTest[ii]; + + bool result = url.parse(urlTest.url); + REQUIRE(urlTest.result == result); + + if (result) + { + for (uint32_t token = 0; token < bx::UrlView::Count; ++token) + { +// char tmp[1024]; +// strCopy(tmp, BX_COUNTOF(tmp), url.get(bx::UrlView::Enum(token)) ); +// printf("`%s`, expected: `%s`\n", tmp, urlTest.tokens[token]); + + REQUIRE(0 == bx::strCmp(urlTest.tokens[token], url.get(bx::UrlView::Enum(token)) ) ); + } + } + } +} diff --git a/3rdparty/bx/tests/vsnprintf_test.cpp b/3rdparty/bx/tests/vsnprintf_test.cpp index 12aea7bbb25..8498ec39096 100644 --- a/3rdparty/bx/tests/vsnprintf_test.cpp +++ b/3rdparty/bx/tests/vsnprintf_test.cpp @@ -20,12 +20,12 @@ TEST_CASE("vsnprintf truncated", "Truncated output buffer.") char buffer[7]; REQUIRE(10 == bx::snprintf(buffer, BX_COUNTOF(buffer), "Ten chars!") ); - REQUIRE(0 == bx::strncmp(buffer, "Ten ch") ); + REQUIRE(0 == bx::strCmp(buffer, "Ten ch") ); } static bool test(const char* _expected, const char* _format, ...) { - int32_t max = (int32_t)bx::strnlen(_expected) + 1; + int32_t max = (int32_t)bx::strLen(_expected) + 1; char* temp = (char*)alloca(max); va_list argList; @@ -35,7 +35,7 @@ static bool test(const char* _expected, const char* _format, ...) bool result = true && len == max-1 - && 0 == bx::strncmp(_expected, temp) + && 0 == bx::strCmp(_expected, temp) ; if (!result) diff --git a/3rdparty/bx/tools/bin/darwin/genie b/3rdparty/bx/tools/bin/darwin/genie Binary files differindex 48552bab3e7..aa81010239b 100755 --- a/3rdparty/bx/tools/bin/darwin/genie +++ b/3rdparty/bx/tools/bin/darwin/genie diff --git a/3rdparty/bx/tools/bin/linux/genie b/3rdparty/bx/tools/bin/linux/genie Binary files differindex 021bc6ea4d2..6ad828c40ae 100755 --- a/3rdparty/bx/tools/bin/linux/genie +++ b/3rdparty/bx/tools/bin/linux/genie diff --git a/3rdparty/bx/tools/bin/windows/genie.exe b/3rdparty/bx/tools/bin/windows/genie.exe Binary files differindex b70a00cb408..71dbb2e11e9 100644 --- a/3rdparty/bx/tools/bin/windows/genie.exe +++ b/3rdparty/bx/tools/bin/windows/genie.exe diff --git a/3rdparty/bx/tools/bin2c/bin2c.cpp b/3rdparty/bx/tools/bin2c/bin2c.cpp index d33d9204bc9..414bce62a87 100644 --- a/3rdparty/bx/tools/bin2c/bin2c.cpp +++ b/3rdparty/bx/tools/bin2c/bin2c.cpp @@ -7,7 +7,7 @@ #include <vector> #include <bx/commandline.h> -#include <bx/crtimpl.h> +#include <bx/file.h> #include <bx/string.h> class Bin2cWriter : public bx::WriterI @@ -23,7 +23,7 @@ public: { } - virtual int32_t write(const void* _data, int32_t _size, bx::Error* /*_err*/ = NULL) BX_OVERRIDE + virtual int32_t write(const void* _data, int32_t _size, bx::Error* /*_err*/ = NULL) override { const char* data = (const char*)_data; m_buffer.insert(m_buffer.end(), data, data+_size); @@ -59,7 +59,7 @@ public: ascii[asciiPos] = '\0'; bx::writePrintf(m_writer, "\t" HEX_DUMP_FORMAT "// %s\n", hex, ascii); data += asciiPos; - hexPos = 0; + hexPos = 0; asciiPos = 0; } } @@ -80,7 +80,6 @@ public: } bx::WriterI* m_writer; - std::string m_filePath; std::string m_name; typedef std::vector<uint8_t> Buffer; Buffer m_buffer; @@ -88,18 +87,20 @@ public: void help(const char* _error = NULL) { + bx::WriterI* stdOut = bx::getStdOut(); + if (NULL != _error) { - fprintf(stderr, "Error:\n%s\n\n", _error); + bx::writePrintf(stdOut, "Error:\n%s\n\n", _error); } - fprintf(stderr + bx::writePrintf(stdOut , "bin2c, binary to C\n" "Copyright 2011-2017 Branimir Karadzic. All rights reserved.\n" "License: https://github.com/bkaradzic/bx#license-bsd-2-clause\n\n" ); - fprintf(stderr + bx::writePrintf(stdOut , "Usage: bin2c -f <in> -o <out> -n <name>\n" "\n" @@ -121,21 +122,21 @@ int main(int _argc, const char* _argv[]) if (cmdLine.hasArg('h', "help") ) { help(); - return EXIT_FAILURE; + return bx::kExitFailure; } const char* filePath = cmdLine.findOption('f'); if (NULL == filePath) { help("Input file name must be specified."); - return EXIT_FAILURE; + return bx::kExitFailure; } const char* outFilePath = cmdLine.findOption('o'); if (NULL == outFilePath) { help("Output file name must be specified."); - return EXIT_FAILURE; + return bx::kExitFailure; } const char* name = cmdLine.findOption('n'); @@ -147,14 +148,16 @@ int main(int _argc, const char* _argv[]) void* data = NULL; uint32_t size = 0; - bx::CrtFileReader fr; + bx::FileReader fr; if (bx::open(&fr, filePath) ) { size = uint32_t(bx::getSize(&fr) ); - data = malloc(size); + + bx::DefaultAllocator allocator; + data = BX_ALLOC(&allocator, size); bx::read(&fr, data, size); - bx::CrtFileWriter fw; + bx::FileWriter fw; if (bx::open(&fw, outFilePath) ) { Bin2cWriter writer(&fw, name); @@ -163,7 +166,7 @@ int main(int _argc, const char* _argv[]) bx::close(&fw); } - free(data); + BX_FREE(&allocator, data); } return 0; |