sokol
This commit is contained in:
parent
bbbfb97b60
commit
1408c05103
|
@ -145,13 +145,11 @@ static void scroll_cb(GLFWwindow *w, double xoffset, double yoffset)
|
|||
|
||||
static void mb_cb(GLFWwindow *w, int button, int action, int mods)
|
||||
{
|
||||
const char *act = NULL;
|
||||
const char *btn = NULL;
|
||||
JSValue argv[3];
|
||||
argv[0] = jsinput;
|
||||
switch (action) {
|
||||
case GLFW_PRESS:
|
||||
argv[3] = jsinputstate[2];
|
||||
argv[2] = jsinputstate[2];
|
||||
add_downkey(button);
|
||||
break;
|
||||
|
||||
|
@ -167,11 +165,6 @@ static void mb_cb(GLFWwindow *w, int button, int action, int mods)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!act || !btn) {
|
||||
YughError("Tried to call a mouse action that doesn't exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
argv[1] = input2js(keyname_extd(button,button));
|
||||
script_callee(pawn_callee,3,argv);
|
||||
}
|
||||
|
|
11473
source/engine/thirdparty/sokol/sokol_app.h
vendored
Normal file
11473
source/engine/thirdparty/sokol/sokol_app.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
845
source/engine/thirdparty/sokol/sokol_args.h
vendored
Normal file
845
source/engine/thirdparty/sokol/sokol_args.h
vendored
Normal file
|
@ -0,0 +1,845 @@
|
|||
#if defined(SOKOL_IMPL) && !defined(SOKOL_ARGS_IMPL)
|
||||
#define SOKOL_ARGS_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_ARGS_INCLUDED
|
||||
/*
|
||||
sokol_args.h -- cross-platform key/value arg-parsing for web and native
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_ARGS_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines with your own implementations:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_ARGS_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_ARGS_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_args.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_ARGS_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
sokol_args.h provides a simple unified argument parsing API for WebAssembly and
|
||||
native apps.
|
||||
|
||||
When running as WebAssembly app, arguments are taken from the page URL:
|
||||
|
||||
https://floooh.github.io/tiny8bit/kc85.html?type=kc85_3&mod=m022&snapshot=kc85/jungle.kcc
|
||||
|
||||
The same arguments provided to a command line app:
|
||||
|
||||
kc85 type=kc85_3 mod=m022 snapshot=kc85/jungle.kcc
|
||||
|
||||
ARGUMENT FORMATTING
|
||||
===================
|
||||
On the web platform, arguments must be formatted as a valid URL query string
|
||||
with 'percent encoding' used for special characters.
|
||||
|
||||
Strings are expected to be UTF-8 encoded (although sokol_args.h doesn't
|
||||
contain any special UTF-8 handling). See below on how to obtain
|
||||
UTF-8 encoded argc/argv values on Windows when using WinMain() as
|
||||
entry point.
|
||||
|
||||
On native platforms the following rules must be followed:
|
||||
|
||||
Arguments have the general form
|
||||
|
||||
key=value
|
||||
|
||||
Key/value pairs are separated by 'whitespace', valid whitespace
|
||||
characters are space and tab.
|
||||
|
||||
Whitespace characters in front and after the separating '=' character
|
||||
are ignored:
|
||||
|
||||
key = value
|
||||
|
||||
...is the same as
|
||||
|
||||
key=value
|
||||
|
||||
The 'key' string must be a simple string without escape sequences or whitespace.
|
||||
|
||||
Currently 'single keys' without values are not allowed, but may be
|
||||
in the future.
|
||||
|
||||
The 'value' string can be quoted, and quoted value strings can contain
|
||||
whitespace:
|
||||
|
||||
key = 'single-quoted value'
|
||||
key = "double-quoted value"
|
||||
|
||||
Single-quoted value strings can contain double quotes, and vice-versa:
|
||||
|
||||
key = 'single-quoted value "can contain double-quotes"'
|
||||
key = "double-quoted value 'can contain single-quotes'"
|
||||
|
||||
Note that correct quoting can be tricky on some shells, since command
|
||||
shells may remove quotes, unless they're escaped.
|
||||
|
||||
Value strings can contain a small selection of escape sequences:
|
||||
|
||||
\n - newline
|
||||
\r - carriage return
|
||||
\t - tab
|
||||
\\ - escaped backslash
|
||||
|
||||
(more escape codes may be added in the future).
|
||||
|
||||
CODE EXAMPLE
|
||||
============
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// initialize sokol_args with default parameters
|
||||
sargs_setup(&(sargs_desc){
|
||||
.argc = argc,
|
||||
.argv = argv
|
||||
});
|
||||
|
||||
// check if a key exists...
|
||||
if (sargs_exists("bla")) {
|
||||
...
|
||||
}
|
||||
|
||||
// get value string for key, if not found, return empty string ""
|
||||
const char* val0 = sargs_value("bla");
|
||||
|
||||
// get value string for key, or default string if key not found
|
||||
const char* val1 = sargs_value_def("bla", "default_value");
|
||||
|
||||
// check if a key matches expected value
|
||||
if (sargs_equals("type", "kc85_4")) {
|
||||
...
|
||||
}
|
||||
|
||||
// check if a key's value is "true", "yes" or "on"
|
||||
if (sargs_boolean("joystick_enabled")) {
|
||||
...
|
||||
}
|
||||
|
||||
// iterate over keys and values
|
||||
for (int i = 0; i < sargs_num_args(); i++) {
|
||||
printf("key: %s, value: %s\n", sargs_key_at(i), sargs_value_at(i));
|
||||
}
|
||||
|
||||
// lookup argument index by key string, will return -1 if key
|
||||
// is not found, sargs_key_at() and sargs_value_at() will return
|
||||
// an empty string for invalid indices
|
||||
int index = sargs_find("bla");
|
||||
printf("key: %s, value: %s\n", sargs_key_at(index), sargs_value_at(index));
|
||||
|
||||
// shutdown sokol-args
|
||||
sargs_shutdown();
|
||||
}
|
||||
|
||||
WINMAIN AND ARGC / ARGV
|
||||
=======================
|
||||
On Windows with WinMain() based apps, getting UTF8-encoded command line
|
||||
arguments is a bit more complicated:
|
||||
|
||||
First call GetCommandLineW(), this returns the entire command line
|
||||
as UTF-16 string. Then call CommandLineToArgvW(), this parses the
|
||||
command line string into the usual argc/argv format (but in UTF-16).
|
||||
Finally convert the UTF-16 strings in argv[] into UTF-8 via
|
||||
WideCharToMultiByte().
|
||||
|
||||
See the function _sapp_win32_command_line_to_utf8_argv() in sokol_app.h
|
||||
for example code how to do this (if you're using sokol_app.h, it will
|
||||
already convert the command line arguments to UTF-8 for you of course,
|
||||
so you can plug them directly into sokol_app.h).
|
||||
|
||||
API DOCUMENTATION
|
||||
=================
|
||||
void sargs_setup(const sargs_desc* desc)
|
||||
Initialize sokol_args, desc contains the following configuration
|
||||
parameters:
|
||||
int argc - the main function's argc parameter
|
||||
char** argv - the main function's argv parameter
|
||||
int max_args - max number of key/value pairs, default is 16
|
||||
int buf_size - size of the internal string buffer, default is 16384
|
||||
|
||||
Note that on the web, argc and argv will be ignored and the arguments
|
||||
will be taken from the page URL instead.
|
||||
|
||||
sargs_setup() will allocate 2 memory chunks: one for keeping track
|
||||
of the key/value args of size 'max_args*8', and a string buffer
|
||||
of size 'buf_size'.
|
||||
|
||||
void sargs_shutdown(void)
|
||||
Shutdown sokol-args and free any allocated memory.
|
||||
|
||||
bool sargs_isvalid(void)
|
||||
Return true between sargs_setup() and sargs_shutdown()
|
||||
|
||||
bool sargs_exists(const char* key)
|
||||
Test if a key arg exists.
|
||||
|
||||
const char* sargs_value(const char* key)
|
||||
Return value associated with key. Returns an empty
|
||||
string ("") if the key doesn't exist.
|
||||
|
||||
const char* sargs_value_def(const char* key, const char* default)
|
||||
Return value associated with key, or the provided default
|
||||
value if the value doesn't exist.
|
||||
|
||||
bool sargs_equals(const char* key, const char* val);
|
||||
Return true if the value associated with key matches
|
||||
the 'val' argument.
|
||||
|
||||
bool sargs_boolean(const char* key)
|
||||
Return true if the value string of 'key' is one
|
||||
of 'true', 'yes', 'on'.
|
||||
|
||||
int sargs_find(const char* key)
|
||||
Find argument by key name and return its index, or -1 if not found.
|
||||
|
||||
int sargs_num_args(void)
|
||||
Return number of key/value pairs.
|
||||
|
||||
const char* sargs_key_at(int index)
|
||||
Return the key name of argument at index. Returns empty string if
|
||||
is index is outside range.
|
||||
|
||||
const char* sargs_value_at(int index)
|
||||
Return the value of argument at index. Returns empty string
|
||||
if index is outside range.
|
||||
|
||||
|
||||
MEMORY ALLOCATION OVERRIDE
|
||||
==========================
|
||||
You can override the memory allocation functions at initialization time
|
||||
like this:
|
||||
|
||||
void* my_alloc(size_t size, void* user_data) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void my_free(void* ptr, void* user_data) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
...
|
||||
sargs_setup(&(sargs_desc){
|
||||
// ...
|
||||
.allocator = {
|
||||
.alloc = my_alloc,
|
||||
.free = my_free,
|
||||
.user_data = ...,
|
||||
}
|
||||
});
|
||||
...
|
||||
|
||||
If no overrides are provided, malloc and free will be used.
|
||||
|
||||
This only affects memory allocation calls done by sokol_args.h
|
||||
itself though, not any allocations in OS libraries.
|
||||
|
||||
TODO
|
||||
====
|
||||
- parsing errors?
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2018 Andre Weissflog
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the
|
||||
use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
#define SOKOL_ARGS_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_ARGS_API_DECL)
|
||||
#define SOKOL_ARGS_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_ARGS_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_ARGS_IMPL)
|
||||
#define SOKOL_ARGS_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_ARGS_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_ARGS_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
sargs_allocator
|
||||
|
||||
Used in sargs_desc to provide custom memory-alloc and -free functions
|
||||
to sokol_args.h. If memory management should be overridden, both the
|
||||
alloc and free function must be provided (e.g. it's not valid to
|
||||
override one function but not the other).
|
||||
*/
|
||||
typedef struct sargs_allocator {
|
||||
void* (*alloc)(size_t size, void* user_data);
|
||||
void (*free)(void* ptr, void* user_data);
|
||||
void* user_data;
|
||||
} sargs_allocator;
|
||||
|
||||
typedef struct sargs_desc {
|
||||
int argc;
|
||||
char** argv;
|
||||
int max_args;
|
||||
int buf_size;
|
||||
sargs_allocator allocator;
|
||||
} sargs_desc;
|
||||
|
||||
/* setup sokol-args */
|
||||
SOKOL_ARGS_API_DECL void sargs_setup(const sargs_desc* desc);
|
||||
/* shutdown sokol-args */
|
||||
SOKOL_ARGS_API_DECL void sargs_shutdown(void);
|
||||
/* true between sargs_setup() and sargs_shutdown() */
|
||||
SOKOL_ARGS_API_DECL bool sargs_isvalid(void);
|
||||
/* test if an argument exists by key name */
|
||||
SOKOL_ARGS_API_DECL bool sargs_exists(const char* key);
|
||||
/* get value by key name, return empty string if key doesn't exist */
|
||||
SOKOL_ARGS_API_DECL const char* sargs_value(const char* key);
|
||||
/* get value by key name, return provided default if key doesn't exist */
|
||||
SOKOL_ARGS_API_DECL const char* sargs_value_def(const char* key, const char* def);
|
||||
/* return true if val arg matches the value associated with key */
|
||||
SOKOL_ARGS_API_DECL bool sargs_equals(const char* key, const char* val);
|
||||
/* return true if key's value is "true", "yes" or "on" */
|
||||
SOKOL_ARGS_API_DECL bool sargs_boolean(const char* key);
|
||||
/* get index of arg by key name, return -1 if not exists */
|
||||
SOKOL_ARGS_API_DECL int sargs_find(const char* key);
|
||||
/* get number of parsed arguments */
|
||||
SOKOL_ARGS_API_DECL int sargs_num_args(void);
|
||||
/* get key name of argument at index, or empty string */
|
||||
SOKOL_ARGS_API_DECL const char* sargs_key_at(int index);
|
||||
/* get value string of argument at index, or empty string */
|
||||
SOKOL_ARGS_API_DECL const char* sargs_value_at(int index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
/* reference-based equivalents for c++ */
|
||||
inline void sargs_setup(const sargs_desc& desc) { return sargs_setup(&desc); }
|
||||
|
||||
#endif
|
||||
#endif // SOKOL_ARGS_INCLUDED
|
||||
|
||||
/*--- IMPLEMENTATION ---------------------------------------------------------*/
|
||||
#ifdef SOKOL_ARGS_IMPL
|
||||
#define SOKOL_ARGS_IMPL_INCLUDED (1)
|
||||
|
||||
#if defined(SOKOL_MALLOC) || defined(SOKOL_CALLOC) || defined(SOKOL_FREE)
|
||||
#error "SOKOL_MALLOC/CALLOC/FREE macros are no longer supported, please use sargs_desc.allocator to override memory allocation functions"
|
||||
#endif
|
||||
|
||||
#include <string.h> // memset, strcmp
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define SOKOL_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SOKOL_ASSERT
|
||||
#include <assert.h>
|
||||
#define SOKOL_ASSERT(c) assert(c)
|
||||
#endif
|
||||
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
#else
|
||||
#define _SOKOL_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define _sargs_def(val, def) (((val) == 0) ? (def) : (val))
|
||||
|
||||
#define _SARGS_MAX_ARGS_DEF (16)
|
||||
#define _SARGS_BUF_SIZE_DEF (16*1024)
|
||||
|
||||
/* parser state */
|
||||
#define _SARGS_EXPECT_KEY (1<<0)
|
||||
#define _SARGS_EXPECT_SEP (1<<1)
|
||||
#define _SARGS_EXPECT_VAL (1<<2)
|
||||
#define _SARGS_PARSING_KEY (1<<3)
|
||||
#define _SARGS_PARSING_VAL (1<<4)
|
||||
#define _SARGS_ERROR (1<<5)
|
||||
|
||||
/* a key/value pair struct */
|
||||
typedef struct {
|
||||
int key; /* index to start of key string in buf */
|
||||
int val; /* index to start of value string in buf */
|
||||
} _sargs_kvp_t;
|
||||
|
||||
/* sokol-args state */
|
||||
typedef struct {
|
||||
int max_args; /* number of key/value pairs in args array */
|
||||
int num_args; /* number of valid items in args array */
|
||||
_sargs_kvp_t* args; /* key/value pair array */
|
||||
int buf_size; /* size of buffer in bytes */
|
||||
int buf_pos; /* current buffer position */
|
||||
char* buf; /* character buffer, first char is reserved and zero for 'empty string' */
|
||||
bool valid;
|
||||
uint32_t parse_state;
|
||||
char quote; /* current quote char, 0 if not in a quote */
|
||||
bool in_escape; /* currently in an escape sequence */
|
||||
sargs_allocator allocator;
|
||||
} _sargs_state_t;
|
||||
static _sargs_state_t _sargs;
|
||||
|
||||
/*== PRIVATE IMPLEMENTATION FUNCTIONS ========================================*/
|
||||
_SOKOL_PRIVATE void _sargs_clear(void* ptr, size_t size) {
|
||||
SOKOL_ASSERT(ptr && (size > 0));
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void* _sargs_malloc(size_t size) {
|
||||
SOKOL_ASSERT(size > 0);
|
||||
void* ptr;
|
||||
if (_sargs.allocator.alloc) {
|
||||
ptr = _sargs.allocator.alloc(size, _sargs.allocator.user_data);
|
||||
}
|
||||
else {
|
||||
ptr = malloc(size);
|
||||
}
|
||||
SOKOL_ASSERT(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void* _sargs_malloc_clear(size_t size) {
|
||||
void* ptr = _sargs_malloc(size);
|
||||
_sargs_clear(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_free(void* ptr) {
|
||||
if (_sargs.allocator.free) {
|
||||
_sargs.allocator.free(ptr, _sargs.allocator.user_data);
|
||||
}
|
||||
else {
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_putc(char c) {
|
||||
if ((_sargs.buf_pos+2) < _sargs.buf_size) {
|
||||
_sargs.buf[_sargs.buf_pos++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE const char* _sargs_str(int index) {
|
||||
SOKOL_ASSERT((index >= 0) && (index < _sargs.buf_size));
|
||||
return &_sargs.buf[index];
|
||||
}
|
||||
|
||||
/*-- argument parser functions ------------------*/
|
||||
_SOKOL_PRIVATE void _sargs_expect_key(void) {
|
||||
_sargs.parse_state = _SARGS_EXPECT_KEY;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_key_expected(void) {
|
||||
return 0 != (_sargs.parse_state & _SARGS_EXPECT_KEY);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_expect_val(void) {
|
||||
_sargs.parse_state = _SARGS_EXPECT_VAL;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_val_expected(void) {
|
||||
return 0 != (_sargs.parse_state & _SARGS_EXPECT_VAL);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_expect_sep(void) {
|
||||
_sargs.parse_state = _SARGS_EXPECT_SEP;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_any_expected(void) {
|
||||
return 0 != (_sargs.parse_state & (_SARGS_EXPECT_KEY | _SARGS_EXPECT_VAL | _SARGS_EXPECT_SEP));
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_is_separator(char c) {
|
||||
return c == '=';
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_is_quote(char c) {
|
||||
if (0 == _sargs.quote) {
|
||||
return (c == '\'') || (c == '"');
|
||||
}
|
||||
else {
|
||||
return c == _sargs.quote;
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_begin_quote(char c) {
|
||||
_sargs.quote = c;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_end_quote(void) {
|
||||
_sargs.quote = 0;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_in_quotes(void) {
|
||||
return 0 != _sargs.quote;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_is_whitespace(char c) {
|
||||
return !_sargs_in_quotes() && ((c == ' ') || (c == '\t'));
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_start_key(void) {
|
||||
SOKOL_ASSERT(_sargs.num_args < _sargs.max_args);
|
||||
_sargs.parse_state = _SARGS_PARSING_KEY;
|
||||
_sargs.args[_sargs.num_args].key = _sargs.buf_pos;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_end_key(void) {
|
||||
SOKOL_ASSERT(_sargs.num_args < _sargs.max_args);
|
||||
_sargs_putc(0);
|
||||
_sargs.parse_state = 0;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_parsing_key(void) {
|
||||
return 0 != (_sargs.parse_state & _SARGS_PARSING_KEY);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_start_val(void) {
|
||||
SOKOL_ASSERT(_sargs.num_args < _sargs.max_args);
|
||||
_sargs.parse_state = _SARGS_PARSING_VAL;
|
||||
_sargs.args[_sargs.num_args].val = _sargs.buf_pos;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_end_val(void) {
|
||||
SOKOL_ASSERT(_sargs.num_args < _sargs.max_args);
|
||||
_sargs_putc(0);
|
||||
_sargs.num_args++;
|
||||
_sargs.parse_state = 0;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_is_escape(char c) {
|
||||
return '\\' == c;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_start_escape(void) {
|
||||
_sargs.in_escape = true;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_in_escape(void) {
|
||||
return _sargs.in_escape;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE char _sargs_escape(char c) {
|
||||
switch (c) {
|
||||
case 'n': return '\n';
|
||||
case 't': return '\t';
|
||||
case 'r': return '\r';
|
||||
case '\\': return '\\';
|
||||
default: return c;
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sargs_end_escape(void) {
|
||||
_sargs.in_escape = false;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_parsing_val(void) {
|
||||
return 0 != (_sargs.parse_state & _SARGS_PARSING_VAL);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_parse_carg(const char* src) {
|
||||
char c;
|
||||
while (0 != (c = *src++)) {
|
||||
if (_sargs_in_escape()) {
|
||||
c = _sargs_escape(c);
|
||||
_sargs_end_escape();
|
||||
}
|
||||
else if (_sargs_is_escape(c)) {
|
||||
_sargs_start_escape();
|
||||
continue;
|
||||
}
|
||||
if (_sargs_any_expected()) {
|
||||
if (!_sargs_is_whitespace(c)) {
|
||||
/* start of key, value or separator */
|
||||
if (_sargs_key_expected()) {
|
||||
/* start of new key */
|
||||
_sargs_start_key();
|
||||
}
|
||||
else if (_sargs_val_expected()) {
|
||||
/* start of value */
|
||||
if (_sargs_is_quote(c)) {
|
||||
_sargs_begin_quote(c);
|
||||
continue;
|
||||
}
|
||||
_sargs_start_val();
|
||||
}
|
||||
else {
|
||||
/* separator */
|
||||
if (_sargs_is_separator(c)) {
|
||||
_sargs_expect_val();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* skip white space */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (_sargs_parsing_key()) {
|
||||
if (_sargs_is_whitespace(c) || _sargs_is_separator(c)) {
|
||||
/* end of key string */
|
||||
_sargs_end_key();
|
||||
if (_sargs_is_separator(c)) {
|
||||
_sargs_expect_val();
|
||||
}
|
||||
else {
|
||||
_sargs_expect_sep();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (_sargs_parsing_val()) {
|
||||
if (_sargs_in_quotes()) {
|
||||
/* when in quotes, whitespace is a normal character
|
||||
and a matching quote ends the value string
|
||||
*/
|
||||
if (_sargs_is_quote(c)) {
|
||||
_sargs_end_quote();
|
||||
_sargs_end_val();
|
||||
_sargs_expect_key();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (_sargs_is_whitespace(c)) {
|
||||
/* end of value string (no quotes) */
|
||||
_sargs_end_val();
|
||||
_sargs_expect_key();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_sargs_putc(c);
|
||||
}
|
||||
if (_sargs_parsing_key()) {
|
||||
_sargs_end_key();
|
||||
_sargs_expect_sep();
|
||||
}
|
||||
else if (_sargs_parsing_val() && !_sargs_in_quotes()) {
|
||||
_sargs_end_val();
|
||||
_sargs_expect_key();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE bool _sargs_parse_cargs(int argc, const char** argv) {
|
||||
_sargs_expect_key();
|
||||
bool retval = true;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
retval &= _sargs_parse_carg(argv[i]);
|
||||
}
|
||||
_sargs.parse_state = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*-- EMSCRIPTEN IMPLEMENTATION -----------------------------------------------*/
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(EM_JS_DEPS)
|
||||
EM_JS_DEPS(sokol_audio, "$withStackSave,$allocateUTF8OnStack");
|
||||
#endif
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void _sargs_add_kvp(const char* key, const char* val) {
|
||||
SOKOL_ASSERT(_sargs.valid && key && val);
|
||||
if (_sargs.num_args >= _sargs.max_args) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy key string */
|
||||
char c;
|
||||
_sargs.args[_sargs.num_args].key = _sargs.buf_pos;
|
||||
const char* ptr = key;
|
||||
while (0 != (c = *ptr++)) {
|
||||
_sargs_putc(c);
|
||||
}
|
||||
_sargs_putc(0);
|
||||
|
||||
/* copy value string */
|
||||
_sargs.args[_sargs.num_args].val = _sargs.buf_pos;
|
||||
ptr = val;
|
||||
while (0 != (c = *ptr++)) {
|
||||
_sargs_putc(c);
|
||||
}
|
||||
_sargs_putc(0);
|
||||
|
||||
_sargs.num_args++;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
/* JS function to extract arguments from the page URL */
|
||||
EM_JS(void, sargs_js_parse_url, (void), {
|
||||
const params = new URLSearchParams(window.location.search).entries();
|
||||
for (let p = params.next(); !p.done; p = params.next()) {
|
||||
const key = p.value[0];
|
||||
const val = p.value[1];
|
||||
withStackSave(() => {
|
||||
const key_cstr = allocateUTF8OnStack(key);
|
||||
const val_cstr = allocateUTF8OnStack(val);
|
||||
__sargs_add_kvp(key_cstr, val_cstr)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
#endif /* EMSCRIPTEN */
|
||||
|
||||
/*== PUBLIC IMPLEMENTATION FUNCTIONS =========================================*/
|
||||
SOKOL_API_IMPL void sargs_setup(const sargs_desc* desc) {
|
||||
SOKOL_ASSERT(desc);
|
||||
_sargs_clear(&_sargs, sizeof(_sargs));
|
||||
_sargs.max_args = _sargs_def(desc->max_args, _SARGS_MAX_ARGS_DEF);
|
||||
_sargs.buf_size = _sargs_def(desc->buf_size, _SARGS_BUF_SIZE_DEF);
|
||||
SOKOL_ASSERT(_sargs.buf_size > 8);
|
||||
_sargs.args = (_sargs_kvp_t*) _sargs_malloc_clear((size_t)_sargs.max_args * sizeof(_sargs_kvp_t));
|
||||
_sargs.buf = (char*) _sargs_malloc_clear((size_t)_sargs.buf_size * sizeof(char));
|
||||
/* the first character in buf is reserved and always zero, this is the 'empty string' */
|
||||
_sargs.buf_pos = 1;
|
||||
_sargs.allocator = desc->allocator;
|
||||
_sargs.valid = true;
|
||||
|
||||
/* parse argc/argv */
|
||||
_sargs_parse_cargs(desc->argc, (const char**) desc->argv);
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
/* on emscripten, also parse the page URL*/
|
||||
sargs_js_parse_url();
|
||||
#endif
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL void sargs_shutdown(void) {
|
||||
SOKOL_ASSERT(_sargs.valid);
|
||||
if (_sargs.args) {
|
||||
_sargs_free(_sargs.args);
|
||||
_sargs.args = 0;
|
||||
}
|
||||
if (_sargs.buf) {
|
||||
_sargs_free(_sargs.buf);
|
||||
_sargs.buf = 0;
|
||||
}
|
||||
_sargs.valid = false;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL bool sargs_isvalid(void) {
|
||||
return _sargs.valid;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL int sargs_find(const char* key) {
|
||||
SOKOL_ASSERT(_sargs.valid && key);
|
||||
for (int i = 0; i < _sargs.num_args; i++) {
|
||||
if (0 == strcmp(_sargs_str(_sargs.args[i].key), key)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL int sargs_num_args(void) {
|
||||
SOKOL_ASSERT(_sargs.valid);
|
||||
return _sargs.num_args;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL const char* sargs_key_at(int index) {
|
||||
SOKOL_ASSERT(_sargs.valid);
|
||||
if ((index >= 0) && (index < _sargs.num_args)) {
|
||||
return _sargs_str(_sargs.args[index].key);
|
||||
}
|
||||
else {
|
||||
/* index 0 is always the empty string */
|
||||
return _sargs_str(0);
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL const char* sargs_value_at(int index) {
|
||||
SOKOL_ASSERT(_sargs.valid);
|
||||
if ((index >= 0) && (index < _sargs.num_args)) {
|
||||
return _sargs_str(_sargs.args[index].val);
|
||||
}
|
||||
else {
|
||||
/* index 0 is always the empty string */
|
||||
return _sargs_str(0);
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL bool sargs_exists(const char* key) {
|
||||
SOKOL_ASSERT(_sargs.valid && key);
|
||||
return -1 != sargs_find(key);
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL const char* sargs_value(const char* key) {
|
||||
SOKOL_ASSERT(_sargs.valid && key);
|
||||
return sargs_value_at(sargs_find(key));
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL const char* sargs_value_def(const char* key, const char* def) {
|
||||
SOKOL_ASSERT(_sargs.valid && key && def);
|
||||
int arg_index = sargs_find(key);
|
||||
if (-1 != arg_index) {
|
||||
return sargs_value_at(arg_index);
|
||||
}
|
||||
else {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL bool sargs_equals(const char* key, const char* val) {
|
||||
SOKOL_ASSERT(_sargs.valid && key && val);
|
||||
return 0 == strcmp(sargs_value(key), val);
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL bool sargs_boolean(const char* key) {
|
||||
const char* val = sargs_value(key);
|
||||
return (0 == strcmp("true", val)) ||
|
||||
(0 == strcmp("yes", val)) ||
|
||||
(0 == strcmp("on", val));
|
||||
}
|
||||
|
||||
#endif /* SOKOL_ARGS_IMPL */
|
2596
source/engine/thirdparty/sokol/sokol_audio.h
vendored
Normal file
2596
source/engine/thirdparty/sokol/sokol_audio.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
2802
source/engine/thirdparty/sokol/sokol_fetch.h
vendored
Normal file
2802
source/engine/thirdparty/sokol/sokol_fetch.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
16535
source/engine/thirdparty/sokol/sokol_gfx.h
vendored
Normal file
16535
source/engine/thirdparty/sokol/sokol_gfx.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
136
source/engine/thirdparty/sokol/sokol_glue.h
vendored
Normal file
136
source/engine/thirdparty/sokol/sokol_glue.h
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
#if defined(SOKOL_IMPL) && !defined(SOKOL_GLUE_IMPL)
|
||||
#define SOKOL_GLUE_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_GLUE_INCLUDED
|
||||
/*
|
||||
sokol_glue.h -- glue helper functions for sokol headers
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_GLUE_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
...optionally provide the following macros to override defaults:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_GLUE_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GLUE_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_glue.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_GLUE_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
The sokol core headers should not depend on each other, but sometimes
|
||||
it's useful to have a set of helper functions as "glue" between
|
||||
two or more sokol headers.
|
||||
|
||||
This is what sokol_glue.h is for. Simply include the header after other
|
||||
sokol headers (both for the implementation and declaration), and
|
||||
depending on what headers have been included before, sokol_glue.h
|
||||
will make available "glue functions".
|
||||
|
||||
PROVIDED FUNCTIONS
|
||||
==================
|
||||
|
||||
- if sokol_app.h and sokol_gfx.h is included:
|
||||
|
||||
sg_context_desc sapp_sgcontext(void):
|
||||
|
||||
Returns an initialized sg_context_desc function initialized
|
||||
by calling sokol_app.h functions.
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2018 Andre Weissflog
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the
|
||||
use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
#define SOKOL_GLUE_INCLUDED
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_GLUE_API_DECL)
|
||||
#define SOKOL_GLUE_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_GLUE_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_GLUE_IMPL)
|
||||
#define SOKOL_GLUE_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_GLUE_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_GLUE_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(SOKOL_GFX_INCLUDED) && defined(SOKOL_APP_INCLUDED)
|
||||
SOKOL_GLUE_API_DECL sg_context_desc sapp_sgcontext(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* SOKOL_GLUE_INCLUDED */
|
||||
|
||||
/*-- IMPLEMENTATION ----------------------------------------------------------*/
|
||||
#ifdef SOKOL_GLUE_IMPL
|
||||
#define SOKOL_GLUE_IMPL_INCLUDED (1)
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
|
||||
#if defined(SOKOL_GFX_INCLUDED) && defined(SOKOL_APP_INCLUDED)
|
||||
SOKOL_API_IMPL sg_context_desc sapp_sgcontext(void) {
|
||||
sg_context_desc desc;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.color_format = (sg_pixel_format) sapp_color_format();
|
||||
desc.depth_format = (sg_pixel_format) sapp_depth_format();
|
||||
desc.sample_count = sapp_sample_count();
|
||||
desc.metal.device = sapp_metal_get_device();
|
||||
desc.metal.renderpass_descriptor_cb = sapp_metal_get_renderpass_descriptor;
|
||||
desc.metal.drawable_cb = sapp_metal_get_drawable;
|
||||
desc.d3d11.device = sapp_d3d11_get_device();
|
||||
desc.d3d11.device_context = sapp_d3d11_get_device_context();
|
||||
desc.d3d11.render_target_view_cb = sapp_d3d11_get_render_target_view;
|
||||
desc.d3d11.depth_stencil_view_cb = sapp_d3d11_get_depth_stencil_view;
|
||||
desc.wgpu.device = sapp_wgpu_get_device();
|
||||
desc.wgpu.render_view_cb = sapp_wgpu_get_render_view;
|
||||
desc.wgpu.resolve_view_cb = sapp_wgpu_get_resolve_view;
|
||||
desc.wgpu.depth_stencil_view_cb = sapp_wgpu_get_depth_stencil_view;
|
||||
return desc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SOKOL_GLUE_IMPL */
|
343
source/engine/thirdparty/sokol/sokol_log.h
vendored
Normal file
343
source/engine/thirdparty/sokol/sokol_log.h
vendored
Normal file
|
@ -0,0 +1,343 @@
|
|||
#if defined(SOKOL_IMPL) && !defined(SOKOL_LOG_IMPL)
|
||||
#define SOKOL_LOG_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_LOG_INCLUDED
|
||||
/*
|
||||
sokol_log.h -- common logging callback for sokol headers
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Example code: https://github.com/floooh/sokol-samples
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_LOG_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines when building the implementation:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
|
||||
SOKOL_LOG_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GFX_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
Optionally define the following for verbose output:
|
||||
|
||||
SOKOL_DEBUG - by default this is defined if _DEBUG is defined
|
||||
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
sokol_log.h provides a default logging callback for other sokol headers.
|
||||
|
||||
To use the default log callback, just include sokol_log.h and provide
|
||||
a function pointer to the 'slog_func' function when setting up the
|
||||
sokol library:
|
||||
|
||||
For instance with sokol_audio.h:
|
||||
|
||||
#include "sokol_log.h"
|
||||
...
|
||||
saudio_setup(&(saudio_desc){ .logger.func = slog_func });
|
||||
|
||||
Logging output goes to stderr and/or a platform specific logging subsystem
|
||||
(which means that in some scenarios you might see logging messages duplicated):
|
||||
|
||||
- Windows: stderr + OutputDebugStringA()
|
||||
- macOS/iOS/Linux: stderr + syslog()
|
||||
- Emscripten: console.info()/warn()/error()
|
||||
- Android: __android_log_write()
|
||||
|
||||
On Windows with sokol_app.h also note the runtime config items to make
|
||||
stdout/stderr output visible on the console for WinMain() applications
|
||||
via sapp_desc.win32_console_attach or sapp_desc.win32_console_create,
|
||||
however when running in a debugger on Windows, the logging output should
|
||||
show up on the debug output UI panel.
|
||||
|
||||
In debug mode, a log message might look like this:
|
||||
|
||||
[sspine][error][id:12] /Users/floh/projects/sokol/util/sokol_spine.h:3472:0:
|
||||
SKELETON_DESC_NO_ATLAS: no atlas object provided in sspine_skeleton_desc.atlas
|
||||
|
||||
The source path and line number is formatted like compiler errors, in some IDEs (like VSCode)
|
||||
such error messages are clickable.
|
||||
|
||||
In release mode, logging is less verbose as to not bloat the executable with string data, but you still get
|
||||
enough information to identify the type and location of an error:
|
||||
|
||||
[sspine][error][id:12][line:3472]
|
||||
|
||||
RULES FOR WRITING YOUR OWN LOGGING FUNCTION
|
||||
===========================================
|
||||
- must be re-entrant because it might be called from different threads
|
||||
- must treat **all** provided string pointers as optional (can be null)
|
||||
- don't store the string pointers, copy the string data instead
|
||||
- must not return for log level panic
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2023 Andre Weissflog
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the
|
||||
use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
#define SOKOL_LOG_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_LOG_API_DECL)
|
||||
#define SOKOL_LOG_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_LOG_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_LOG_IMPL)
|
||||
#define SOKOL_LOG_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_LOG_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_LOG_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Plug this function into the 'logger.func' struct item when initializating any of the sokol
|
||||
headers. For instance for sokol_audio.h it would loom like this:
|
||||
|
||||
saudio_setup(&(saudio_desc){
|
||||
.logger = {
|
||||
.func = slog_func
|
||||
}
|
||||
});
|
||||
*/
|
||||
SOKOL_LOG_API_DECL void slog_func(const char* tag, uint32_t log_level, uint32_t log_item, const char* message, uint32_t line_nr, const char* filename, void* user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif // SOKOL_LOG_INCLUDED
|
||||
|
||||
// ██ ███ ███ ██████ ██ ███████ ███ ███ ███████ ███ ██ ████████ █████ ████████ ██ ██████ ███ ██
|
||||
// ██ ████ ████ ██ ██ ██ ██ ████ ████ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
|
||||
// ██ ██ ████ ██ ██████ ██ █████ ██ ████ ██ █████ ██ ██ ██ ██ ███████ ██ ██ ██ ██ ██ ██ ██
|
||||
// ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
// ██ ██ ██ ██ ███████ ███████ ██ ██ ███████ ██ ████ ██ ██ ██ ██ ██ ██████ ██ ████
|
||||
//
|
||||
// >>implementation
|
||||
#ifdef SOKOL_LOG_IMPL
|
||||
#define SOKOL_LOG_IMPL_INCLUDED (1)
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define SOKOL_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SOKOL_ASSERT
|
||||
#include <assert.h>
|
||||
#define SOKOL_ASSERT(c) assert(c)
|
||||
#endif
|
||||
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
#else
|
||||
#define _SOKOL_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _SOKOL_UNUSED
|
||||
#define _SOKOL_UNUSED(x) (void)(x)
|
||||
#endif
|
||||
|
||||
// platform detection
|
||||
#if defined(__APPLE__)
|
||||
#define _SLOG_APPLE (1)
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#define _SLOG_EMSCRIPTEN (1)
|
||||
#elif defined(_WIN32)
|
||||
#define _SLOG_WINDOWS (1)
|
||||
#elif defined(__ANDROID__)
|
||||
#define _SLOG_ANDROID (1)
|
||||
#elif defined(__linux__) || defined(__unix__)
|
||||
#define _SLOG_LINUX (1)
|
||||
#else
|
||||
#error "sokol_log.h: unknown platform"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> // abort
|
||||
#include <stdio.h> // fputs
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#if defined(_SLOG_EMSCRIPTEN)
|
||||
#include <emscripten/emscripten.h>
|
||||
#elif defined(_SLOG_WINDOWS)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif defined(_SLOG_ANDROID)
|
||||
#include <android/log.h>
|
||||
#elif defined(_SLOG_LINUX) || defined(_SLOG_APPLE)
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
// size of line buffer (on stack!) in bytes including terminating zero
|
||||
#define _SLOG_LINE_LENGTH (512)
|
||||
|
||||
_SOKOL_PRIVATE char* _slog_append(const char* str, char* dst, char* end) {
|
||||
if (str) {
|
||||
char c;
|
||||
while (((c = *str++) != 0) && (dst < (end - 1))) {
|
||||
*dst++ = c;
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE char* _slog_itoa(uint32_t x, char* buf, size_t buf_size) {
|
||||
const size_t max_digits_and_null = 11;
|
||||
if (buf_size < max_digits_and_null) {
|
||||
return 0;
|
||||
}
|
||||
char* p = buf + max_digits_and_null;
|
||||
*--p = 0;
|
||||
do {
|
||||
*--p = '0' + (x % 10);
|
||||
x /= 10;
|
||||
} while (x != 0);
|
||||
return p;
|
||||
}
|
||||
|
||||
#if defined(_SLOG_EMSCRIPTEN)
|
||||
EM_JS(void, slog_js_log, (uint32_t level, const char* c_str), {
|
||||
const str = UTF8ToString(c_str);
|
||||
switch (level) {
|
||||
case 0: console.error(str); break;
|
||||
case 1: console.error(str); break;
|
||||
case 2: console.warn(str); break;
|
||||
default: console.info(str); break;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
SOKOL_API_IMPL void slog_func(const char* tag, uint32_t log_level, uint32_t log_item, const char* message, uint32_t line_nr, const char* filename, void* user_data) {
|
||||
_SOKOL_UNUSED(user_data);
|
||||
|
||||
const char* log_level_str;
|
||||
switch (log_level) {
|
||||
case 0: log_level_str = "panic"; break;
|
||||
case 1: log_level_str = "error"; break;
|
||||
case 2: log_level_str = "warning"; break;
|
||||
default: log_level_str = "info"; break;
|
||||
}
|
||||
|
||||
// build log output line
|
||||
char line_buf[_SLOG_LINE_LENGTH];
|
||||
char* str = line_buf;
|
||||
char* end = line_buf + sizeof(line_buf);
|
||||
char num_buf[32];
|
||||
if (tag) {
|
||||
str = _slog_append("[", str, end);
|
||||
str = _slog_append(tag, str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
}
|
||||
str = _slog_append("[", str, end);
|
||||
str = _slog_append(log_level_str, str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
str = _slog_append("[id:", str, end);
|
||||
str = _slog_append(_slog_itoa(log_item, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
// if a filename is provided, build a clickable log message that's compatible with compiler error messages
|
||||
if (filename) {
|
||||
str = _slog_append(" ", str, end);
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC compiler error format
|
||||
str = _slog_append(filename, str, end);
|
||||
str = _slog_append("(", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("): ", str, end);
|
||||
#else
|
||||
// gcc/clang compiler error format
|
||||
str = _slog_append(filename, str, end);
|
||||
str = _slog_append(":", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append(":0: ", str, end);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
str = _slog_append("[line:", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("] ", str, end);
|
||||
}
|
||||
if (message) {
|
||||
str = _slog_append("\n\t", str, end);
|
||||
str = _slog_append(message, str, end);
|
||||
}
|
||||
str = _slog_append("\n\n", str, end);
|
||||
if (0 == log_level) {
|
||||
str = _slog_append("ABORTING because of [panic]\n", str, end);
|
||||
(void)str;
|
||||
}
|
||||
|
||||
// print to stderr?
|
||||
#if defined(_SLOG_LINUX) || defined(_SLOG_WINDOWS) || defined(_SLOG_APPLE)
|
||||
fputs(line_buf, stderr);
|
||||
#endif
|
||||
|
||||
// platform specific logging calls
|
||||
#if defined(_SLOG_WINDOWS)
|
||||
OutputDebugStringA(line_buf);
|
||||
#elif defined(_SLOG_ANDROID)
|
||||
int prio;
|
||||
switch (log_level) {
|
||||
case 0: prio = ANDROID_LOG_FATAL; break;
|
||||
case 1: prio = ANDROID_LOG_ERROR; break;
|
||||
case 2: prio = ANDROID_LOG_WARN; break;
|
||||
default: prio = ANDROID_LOG_INFO; break;
|
||||
}
|
||||
__android_log_write(prio, "SOKOL", line_buf);
|
||||
#elif defined(_SLOG_EMSCRIPTEN)
|
||||
slog_js_log(log_level, line_buf);
|
||||
#elif defined(_SLOG_LINUX) || defined(_SLOG_APPLE)
|
||||
int prio;
|
||||
switch (log_level) {
|
||||
case 0: prio = LOG_CRIT; break;
|
||||
case 1: prio = LOG_ERR; break;
|
||||
case 2: prio = LOG_WARNING; break;
|
||||
default: prio = LOG_INFO; break;
|
||||
}
|
||||
syslog(prio, "%s", line_buf);
|
||||
#endif
|
||||
if (0 == log_level) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif // SOKOL_LOG_IMPL
|
319
source/engine/thirdparty/sokol/sokol_time.h
vendored
Normal file
319
source/engine/thirdparty/sokol/sokol_time.h
vendored
Normal file
|
@ -0,0 +1,319 @@
|
|||
#if defined(SOKOL_IMPL) && !defined(SOKOL_TIME_IMPL)
|
||||
#define SOKOL_TIME_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_TIME_INCLUDED
|
||||
/*
|
||||
sokol_time.h -- simple cross-platform time measurement
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_TIME_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines with your own implementations:
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_TIME_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_TIME_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_time.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_TIME_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
void stm_setup();
|
||||
Call once before any other functions to initialize sokol_time
|
||||
(this calls for instance QueryPerformanceFrequency on Windows)
|
||||
|
||||
uint64_t stm_now();
|
||||
Get current point in time in unspecified 'ticks'. The value that
|
||||
is returned has no relation to the 'wall-clock' time and is
|
||||
not in a specific time unit, it is only useful to compute
|
||||
time differences.
|
||||
|
||||
uint64_t stm_diff(uint64_t new, uint64_t old);
|
||||
Computes the time difference between new and old. This will always
|
||||
return a positive, non-zero value.
|
||||
|
||||
uint64_t stm_since(uint64_t start);
|
||||
Takes the current time, and returns the elapsed time since start
|
||||
(this is a shortcut for "stm_diff(stm_now(), start)")
|
||||
|
||||
uint64_t stm_laptime(uint64_t* last_time);
|
||||
This is useful for measuring frame time and other recurring
|
||||
events. It takes the current time, returns the time difference
|
||||
to the value in last_time, and stores the current time in
|
||||
last_time for the next call. If the value in last_time is 0,
|
||||
the return value will be zero (this usually happens on the
|
||||
very first call).
|
||||
|
||||
uint64_t stm_round_to_common_refresh_rate(uint64_t duration)
|
||||
This oddly named function takes a measured frame time and
|
||||
returns the closest "nearby" common display refresh rate frame duration
|
||||
in ticks. If the input duration isn't close to any common display
|
||||
refresh rate, the input duration will be returned unchanged as a fallback.
|
||||
The main purpose of this function is to remove jitter/inaccuracies from
|
||||
measured frame times, and instead use the display refresh rate as
|
||||
frame duration.
|
||||
NOTE: for more robust frame timing, consider using the
|
||||
sokol_app.h function sapp_frame_duration()
|
||||
|
||||
Use the following functions to convert a duration in ticks into
|
||||
useful time units:
|
||||
|
||||
double stm_sec(uint64_t ticks);
|
||||
double stm_ms(uint64_t ticks);
|
||||
double stm_us(uint64_t ticks);
|
||||
double stm_ns(uint64_t ticks);
|
||||
Converts a tick value into seconds, milliseconds, microseconds
|
||||
or nanoseconds. Note that not all platforms will have nanosecond
|
||||
or even microsecond precision.
|
||||
|
||||
Uses the following time measurement functions under the hood:
|
||||
|
||||
Windows: QueryPerformanceFrequency() / QueryPerformanceCounter()
|
||||
MacOS/iOS: mach_absolute_time()
|
||||
emscripten: emscripten_get_now()
|
||||
Linux+others: clock_gettime(CLOCK_MONOTONIC)
|
||||
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2018 Andre Weissflog
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the
|
||||
use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
#define SOKOL_TIME_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_TIME_API_DECL)
|
||||
#define SOKOL_TIME_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_TIME_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_TIME_IMPL)
|
||||
#define SOKOL_TIME_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_TIME_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_TIME_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SOKOL_TIME_API_DECL void stm_setup(void);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_now(void);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_since(uint64_t start_ticks);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_laptime(uint64_t* last_time);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_round_to_common_refresh_rate(uint64_t frame_ticks);
|
||||
SOKOL_TIME_API_DECL double stm_sec(uint64_t ticks);
|
||||
SOKOL_TIME_API_DECL double stm_ms(uint64_t ticks);
|
||||
SOKOL_TIME_API_DECL double stm_us(uint64_t ticks);
|
||||
SOKOL_TIME_API_DECL double stm_ns(uint64_t ticks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif // SOKOL_TIME_INCLUDED
|
||||
|
||||
/*-- IMPLEMENTATION ----------------------------------------------------------*/
|
||||
#ifdef SOKOL_TIME_IMPL
|
||||
#define SOKOL_TIME_IMPL_INCLUDED (1)
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_ASSERT
|
||||
#include <assert.h>
|
||||
#define SOKOL_ASSERT(c) assert(c)
|
||||
#endif
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
#else
|
||||
#define _SOKOL_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
typedef struct {
|
||||
uint32_t initialized;
|
||||
LARGE_INTEGER freq;
|
||||
LARGE_INTEGER start;
|
||||
} _stm_state_t;
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#include <mach/mach_time.h>
|
||||
typedef struct {
|
||||
uint32_t initialized;
|
||||
mach_timebase_info_data_t timebase;
|
||||
uint64_t start;
|
||||
} _stm_state_t;
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#include <emscripten/emscripten.h>
|
||||
typedef struct {
|
||||
uint32_t initialized;
|
||||
double start;
|
||||
} _stm_state_t;
|
||||
#else /* anything else, this will need more care for non-Linux platforms */
|
||||
#ifdef ESP8266
|
||||
// On the ESP8266, clock_gettime ignores the first argument and CLOCK_MONOTONIC isn't defined
|
||||
#define CLOCK_MONOTONIC 0
|
||||
#endif
|
||||
#include <time.h>
|
||||
typedef struct {
|
||||
uint32_t initialized;
|
||||
uint64_t start;
|
||||
} _stm_state_t;
|
||||
#endif
|
||||
static _stm_state_t _stm;
|
||||
|
||||
/* prevent 64-bit overflow when computing relative timestamp
|
||||
see https://gist.github.com/jspohr/3dc4f00033d79ec5bdaf67bc46c813e3
|
||||
*/
|
||||
#if defined(_WIN32) || (defined(__APPLE__) && defined(__MACH__))
|
||||
_SOKOL_PRIVATE int64_t _stm_int64_muldiv(int64_t value, int64_t numer, int64_t denom) {
|
||||
int64_t q = value / denom;
|
||||
int64_t r = value % denom;
|
||||
return q * numer + r * numer / denom;
|
||||
}
|
||||
#endif
|
||||
|
||||
SOKOL_API_IMPL void stm_setup(void) {
|
||||
memset(&_stm, 0, sizeof(_stm));
|
||||
_stm.initialized = 0xABCDABCD;
|
||||
#if defined(_WIN32)
|
||||
QueryPerformanceFrequency(&_stm.freq);
|
||||
QueryPerformanceCounter(&_stm.start);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
mach_timebase_info(&_stm.timebase);
|
||||
_stm.start = mach_absolute_time();
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
_stm.start = emscripten_get_now();
|
||||
#else
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
_stm.start = (uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec;
|
||||
#endif
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_now(void) {
|
||||
SOKOL_ASSERT(_stm.initialized == 0xABCDABCD);
|
||||
uint64_t now;
|
||||
#if defined(_WIN32)
|
||||
LARGE_INTEGER qpc_t;
|
||||
QueryPerformanceCounter(&qpc_t);
|
||||
now = (uint64_t) _stm_int64_muldiv(qpc_t.QuadPart - _stm.start.QuadPart, 1000000000, _stm.freq.QuadPart);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
const uint64_t mach_now = mach_absolute_time() - _stm.start;
|
||||
now = (uint64_t) _stm_int64_muldiv((int64_t)mach_now, (int64_t)_stm.timebase.numer, (int64_t)_stm.timebase.denom);
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
double js_now = emscripten_get_now() - _stm.start;
|
||||
now = (uint64_t) (js_now * 1000000.0);
|
||||
#else
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
now = ((uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec) - _stm.start;
|
||||
#endif
|
||||
return now;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks) {
|
||||
if (new_ticks > old_ticks) {
|
||||
return new_ticks - old_ticks;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_since(uint64_t start_ticks) {
|
||||
return stm_diff(stm_now(), start_ticks);
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_laptime(uint64_t* last_time) {
|
||||
SOKOL_ASSERT(last_time);
|
||||
uint64_t dt = 0;
|
||||
uint64_t now = stm_now();
|
||||
if (0 != *last_time) {
|
||||
dt = stm_diff(now, *last_time);
|
||||
}
|
||||
*last_time = now;
|
||||
return dt;
|
||||
}
|
||||
|
||||
// first number is frame duration in ns, second number is tolerance in ns,
|
||||
// the resulting min/max values must not overlap!
|
||||
static const uint64_t _stm_refresh_rates[][2] = {
|
||||
{ 16666667, 1000000 }, // 60 Hz: 16.6667 +- 1ms
|
||||
{ 13888889, 250000 }, // 72 Hz: 13.8889 +- 0.25ms
|
||||
{ 13333333, 250000 }, // 75 Hz: 13.3333 +- 0.25ms
|
||||
{ 11764706, 250000 }, // 85 Hz: 11.7647 +- 0.25
|
||||
{ 11111111, 250000 }, // 90 Hz: 11.1111 +- 0.25ms
|
||||
{ 10000000, 500000 }, // 100 Hz: 10.0000 +- 0.5ms
|
||||
{ 8333333, 500000 }, // 120 Hz: 8.3333 +- 0.5ms
|
||||
{ 6944445, 500000 }, // 144 Hz: 6.9445 +- 0.5ms
|
||||
{ 4166667, 1000000 }, // 240 Hz: 4.1666 +- 1ms
|
||||
{ 0, 0 }, // keep the last element always at zero
|
||||
};
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_round_to_common_refresh_rate(uint64_t ticks) {
|
||||
uint64_t ns;
|
||||
int i = 0;
|
||||
while (0 != (ns = _stm_refresh_rates[i][0])) {
|
||||
uint64_t tol = _stm_refresh_rates[i][1];
|
||||
if ((ticks > (ns - tol)) && (ticks < (ns + tol))) {
|
||||
return ns;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// fallthough: didn't fit into any buckets
|
||||
return ticks;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL double stm_sec(uint64_t ticks) {
|
||||
return (double)ticks / 1000000000.0;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL double stm_ms(uint64_t ticks) {
|
||||
return (double)ticks / 1000000.0;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL double stm_us(uint64_t ticks) {
|
||||
return (double)ticks / 1000.0;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL double stm_ns(uint64_t ticks) {
|
||||
return (double)ticks;
|
||||
}
|
||||
#endif /* SOKOL_TIME_IMPL */
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
#include "yugine.h"
|
||||
|
||||
#define SOKOL_IMPL
|
||||
#define SOKOL_GLCORE33
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
|
||||
#include "render.h"
|
||||
|
||||
#include "camera.h"
|
||||
#include "window.h"
|
||||
#include "engine.h"
|
||||
|
@ -190,11 +196,6 @@ int main(int argc, char **args) {
|
|||
|
||||
#endif
|
||||
|
||||
FILE *gameinfo = NULL;
|
||||
gameinfo = fopen("game.info", "w");
|
||||
fprintf(gameinfo, "Yugine v. %s, sys %s.", VER, INFO);
|
||||
fclose(gameinfo);
|
||||
|
||||
engine_init();
|
||||
|
||||
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
|
@ -205,8 +206,6 @@ int main(int argc, char **args) {
|
|||
input_init();
|
||||
openglInit();
|
||||
|
||||
YughWarn("%d", __builtin_clz(500));
|
||||
|
||||
if (ed)
|
||||
script_dofile("scripts/editor.js");
|
||||
else
|
||||
|
|
|
@ -2576,6 +2576,7 @@ var limited_editor = {
|
|||
};
|
||||
|
||||
set_pawn(editor);
|
||||
Log.warn(`Total pawn count is ${Player.players[0].pawns.length}`);
|
||||
register_gui(editor.ed_gui, editor);
|
||||
Debug.register_call(editor.ed_debug, editor);
|
||||
|
||||
|
|
Loading…
Reference in a new issue