292 lines
13 KiB
Lua
292 lines
13 KiB
Lua
local ffi = require( "ffi" )
|
|
|
|
local sokol_filename = _G.SOKOL_DLL or "sokol_dll"
|
|
local libs = ffi_sokol_libs or {
|
|
OSX = { x64 = sokol_filename..".so" },
|
|
Windows = { x64 = sokol_filename..".dll" },
|
|
Linux = { x64 = sokol_filename..".so", arm = sokol_filename..".so" },
|
|
BSD = { x64 = sokol_filename..".so" },
|
|
POSIX = { x64 = sokol_filename..".so" },
|
|
Other = { x64 = sokol_filename..".so" },
|
|
}
|
|
|
|
local lib = ffi_sokol_libs or libs[ ffi.os ][ ffi.arch ]
|
|
local sokol_libs = ffi.load( lib )
|
|
|
|
ffi.cdef[[
|
|
|
|
/********** sokol_args ****************************************************************/
|
|
|
|
/*
|
|
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_fn and free_fn function must be provided (e.g. it's not valid to
|
|
override one function but not the other).
|
|
*/
|
|
typedef struct sargs_allocator {
|
|
void* (*alloc_fn)(size_t size, void* user_data);
|
|
void (*free_fn)(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 */
|
|
void sargs_setup(const sargs_desc* desc);
|
|
/* shutdown sokol-args */
|
|
void sargs_shutdown(void);
|
|
/* true between sargs_setup() and sargs_shutdown() */
|
|
bool sargs_isvalid(void);
|
|
/* test if an argument exists by key name */
|
|
bool sargs_exists(const char* key);
|
|
/* get value by key name, return empty string if key doesn't exist or an existing key has no value */
|
|
const char* sargs_value(const char* key);
|
|
/* get value by key name, return provided default if key doesn't exist or has no value */
|
|
const char* sargs_value_def(const char* key, const char* def);
|
|
/* return true if val arg matches the value associated with key */
|
|
bool sargs_equals(const char* key, const char* val);
|
|
/* return true if key's value is "true", "yes", "on" or an existing key has no value */
|
|
bool sargs_boolean(const char* key);
|
|
/* get index of arg by key name, return -1 if not exists */
|
|
int sargs_find(const char* key);
|
|
/* get number of parsed arguments */
|
|
int sargs_num_args(void);
|
|
/* get key name of argument at index, or empty string */
|
|
const char* sargs_key_at(int index);
|
|
/* get value string of argument at index, or empty string */
|
|
const char* sargs_value_at(int index);
|
|
|
|
/********** sokol_audio ****************************************************************/
|
|
|
|
/*
|
|
saudio_logger
|
|
|
|
Used in saudio_desc to provide a custom logging and error reporting
|
|
callback to sokol-audio.
|
|
*/
|
|
typedef struct saudio_logger {
|
|
void (*func)(
|
|
const char* tag, // always "saudio"
|
|
uint32_t log_level, // 0=panic, 1=error, 2=warning, 3=info
|
|
uint32_t log_item_id, // SAUDIO_LOGITEM_*
|
|
const char* message_or_null, // a message string, may be nullptr in release mode
|
|
uint32_t line_nr, // line number in sokol_audio.h
|
|
const char* filename_or_null, // source filename, may be nullptr in release mode
|
|
void* user_data);
|
|
void* user_data;
|
|
} saudio_logger;
|
|
|
|
/*
|
|
saudio_allocator
|
|
|
|
Used in saudio_desc to provide custom memory-alloc and -free functions
|
|
to sokol_audio.h. If memory management should be overridden, both the
|
|
alloc_fn and free_fn function must be provided (e.g. it's not valid to
|
|
override one function but not the other).
|
|
*/
|
|
typedef struct saudio_allocator {
|
|
void* (*alloc_fn)(size_t size, void* user_data);
|
|
void (*free_fn)(void* ptr, void* user_data);
|
|
void* user_data;
|
|
} saudio_allocator;
|
|
|
|
typedef struct saudio_desc {
|
|
int sample_rate; // requested sample rate
|
|
int num_channels; // number of channels, default: 1 (mono)
|
|
int buffer_frames; // number of frames in streaming buffer
|
|
int packet_frames; // number of frames in a packet
|
|
int num_packets; // number of packets in packet queue
|
|
void (*stream_cb)(float* buffer, int num_frames, int num_channels); // optional streaming callback (no user data)
|
|
void (*stream_userdata_cb)(float* buffer, int num_frames, int num_channels, void* user_data); //... and with user data
|
|
void* user_data; // optional user data argument for stream_userdata_cb
|
|
saudio_allocator allocator; // optional allocation override functions
|
|
saudio_logger logger; // optional logging function (default: NO LOGGING!)
|
|
} saudio_desc;
|
|
|
|
/* setup sokol-audio */
|
|
void saudio_setup(const saudio_desc* desc);
|
|
/* shutdown sokol-audio */
|
|
void saudio_shutdown(void);
|
|
/* true after setup if audio backend was successfully initialized */
|
|
bool saudio_isvalid(void);
|
|
/* return the saudio_desc.user_data pointer */
|
|
void* saudio_userdata(void);
|
|
/* return a copy of the original saudio_desc struct */
|
|
saudio_desc saudio_query_desc(void);
|
|
/* actual sample rate */
|
|
int saudio_sample_rate(void);
|
|
/* return actual backend buffer size in number of frames */
|
|
int saudio_buffer_frames(void);
|
|
/* actual number of channels */
|
|
int saudio_channels(void);
|
|
/* return true if audio context is currently suspended (only in WebAudio backend, all other backends return false) */
|
|
bool saudio_suspended(void);
|
|
/* get current number of frames to fill packet queue */
|
|
int saudio_expect(void);
|
|
/* push sample frames from main thread, returns number of frames actually pushed */
|
|
int saudio_push(const float* frames, int num_frames);
|
|
|
|
/********** sokol_fetch ****************************************************************/
|
|
|
|
|
|
/*
|
|
sfetch_logger_t
|
|
|
|
Used in sfetch_desc_t to provide a custom logging and error reporting
|
|
callback to sokol-fetch.
|
|
*/
|
|
typedef struct sfetch_logger_t {
|
|
void (*func)(
|
|
const char* tag, // always "sfetch"
|
|
uint32_t log_level, // 0=panic, 1=error, 2=warning, 3=info
|
|
uint32_t log_item_id, // SFETCH_LOGITEM_*
|
|
const char* message_or_null, // a message string, may be nullptr in release mode
|
|
uint32_t line_nr, // line number in sokol_fetch.h
|
|
const char* filename_or_null, // source filename, may be nullptr in release mode
|
|
void* user_data);
|
|
void* user_data;
|
|
} sfetch_logger_t;
|
|
|
|
/*
|
|
sfetch_range_t
|
|
|
|
A pointer-size pair struct to pass memory ranges into and out of sokol-fetch.
|
|
When initialized from a value type (array or struct) you can use the
|
|
SFETCH_RANGE() helper macro to build an sfetch_range_t struct.
|
|
*/
|
|
typedef struct sfetch_range_t {
|
|
const void* ptr;
|
|
size_t size;
|
|
} sfetch_range_t;
|
|
|
|
/*
|
|
sfetch_allocator_t
|
|
|
|
Used in sfetch_desc_t to provide custom memory-alloc and -free functions
|
|
to sokol_fetch.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 sfetch_allocator_t {
|
|
void* (*alloc_fn)(size_t size, void* user_data);
|
|
void (*free_fn)(void* ptr, void* user_data);
|
|
void* user_data;
|
|
} sfetch_allocator_t;
|
|
|
|
/* configuration values for sfetch_setup() */
|
|
typedef struct sfetch_desc_t {
|
|
uint32_t max_requests; // max number of active requests across all channels (default: 128)
|
|
uint32_t num_channels; // number of channels to fetch requests in parallel (default: 1)
|
|
uint32_t num_lanes; // max number of requests active on the same channel (default: 1)
|
|
sfetch_allocator_t allocator; // optional memory allocation overrides (default: malloc/free)
|
|
sfetch_logger_t logger; // optional log function overrides (default: NO LOGGING!)
|
|
} sfetch_desc_t;
|
|
|
|
/* a request handle to identify an active fetch request, returned by sfetch_send() */
|
|
typedef struct sfetch_handle_t { uint32_t id; } sfetch_handle_t;
|
|
|
|
/* error codes */
|
|
typedef enum sfetch_error_t {
|
|
SFETCH_ERROR_NO_ERROR,
|
|
SFETCH_ERROR_FILE_NOT_FOUND,
|
|
SFETCH_ERROR_NO_BUFFER,
|
|
SFETCH_ERROR_BUFFER_TOO_SMALL,
|
|
SFETCH_ERROR_UNEXPECTED_EOF,
|
|
SFETCH_ERROR_INVALID_HTTP_STATUS,
|
|
SFETCH_ERROR_CANCELLED
|
|
} sfetch_error_t;
|
|
|
|
/* the response struct passed to the response callback */
|
|
typedef struct sfetch_response_t {
|
|
sfetch_handle_t handle; // request handle this response belongs to
|
|
bool dispatched; // true when request is in DISPATCHED state (lane has been assigned)
|
|
bool fetched; // true when request is in FETCHED state (fetched data is available)
|
|
bool paused; // request is currently in paused state
|
|
bool finished; // this is the last response for this request
|
|
bool failed; // request has failed (always set together with 'finished')
|
|
bool cancelled; // request was cancelled (always set together with 'finished')
|
|
sfetch_error_t error_code; // more detailed error code when failed is true
|
|
uint32_t channel; // the channel which processes this request
|
|
uint32_t lane; // the lane this request occupies on its channel
|
|
const char* path; // the original filesystem path of the request
|
|
void* user_data; // pointer to read/write user-data area
|
|
uint32_t data_offset; // current offset of fetched data chunk in the overall file data
|
|
sfetch_range_t data; // the fetched data as ptr/size pair (data.ptr == buffer.ptr, data.size <= buffer.size)
|
|
sfetch_range_t buffer; // the user-provided buffer which holds the fetched data
|
|
} sfetch_response_t;
|
|
|
|
/* request parameters passed to sfetch_send() */
|
|
typedef struct sfetch_request_t {
|
|
uint32_t channel; // index of channel this request is assigned to (default: 0)
|
|
const char* path; // filesystem path or HTTP URL (required)
|
|
void (*callback) (const sfetch_response_t*); // response callback function pointer (required)
|
|
uint32_t chunk_size; // number of bytes to load per stream-block (optional)
|
|
sfetch_range_t buffer; // a memory buffer where the data will be loaded into (optional)
|
|
sfetch_range_t user_data; // ptr/size of a POD user data block which will be memcpy'd (optional)
|
|
} sfetch_request_t;
|
|
|
|
|
|
/* setup sokol-fetch (can be called on multiple threads) */
|
|
void sfetch_setup(const sfetch_desc_t* desc);
|
|
/* discard a sokol-fetch context */
|
|
void sfetch_shutdown(void);
|
|
/* return true if sokol-fetch has been setup */
|
|
bool sfetch_valid(void);
|
|
/* get the desc struct that was passed to sfetch_setup() */
|
|
sfetch_desc_t sfetch_desc(void);
|
|
/* return the max userdata size in number of bytes (SFETCH_MAX_USERDATA_UINT64 * sizeof(uint64_t)) */
|
|
int sfetch_max_userdata_bytes(void);
|
|
/* return the value of the SFETCH_MAX_PATH implementation config value */
|
|
int sfetch_max_path(void);
|
|
|
|
/* send a fetch-request, get handle to request back */
|
|
sfetch_handle_t sfetch_send(const sfetch_request_t* request);
|
|
/* return true if a handle is valid *and* the request is alive */
|
|
bool sfetch_handle_valid(sfetch_handle_t h);
|
|
/* do per-frame work, moves requests into and out of IO threads, and invokes response-callbacks */
|
|
void sfetch_dowork(void);
|
|
|
|
/* bind a data buffer to a request (request must not currently have a buffer bound, must be called from response callback */
|
|
void sfetch_bind_buffer(sfetch_handle_t h, sfetch_range_t buffer);
|
|
/* clear the 'buffer binding' of a request, returns previous buffer pointer (can be 0), must be called from response callback */
|
|
void* sfetch_unbind_buffer(sfetch_handle_t h);
|
|
/* cancel a request that's in flight (will call response callback with .cancelled + .finished) */
|
|
void sfetch_cancel(sfetch_handle_t h);
|
|
/* pause a request (will call response callback each frame with .paused) */
|
|
void sfetch_pause(sfetch_handle_t h);
|
|
/* continue a paused request */
|
|
void sfetch_continue(sfetch_handle_t h);
|
|
|
|
/********** sokol_glue ****************************************************************/
|
|
|
|
sg_environment sglue_environment(void);
|
|
sg_swapchain sglue_swapchain(void);
|
|
|
|
/********** sokol_log ****************************************************************/
|
|
|
|
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_time ****************************************************************/
|
|
|
|
void stm_setup(void);
|
|
uint64_t stm_now(void);
|
|
uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks);
|
|
uint64_t stm_since(uint64_t start_ticks);
|
|
uint64_t stm_laptime(uint64_t* last_time);
|
|
uint64_t stm_round_to_common_refresh_rate(uint64_t frame_ticks);
|
|
double stm_sec(uint64_t ticks);
|
|
double stm_ms(uint64_t ticks);
|
|
double stm_us(uint64_t ticks);
|
|
double stm_ns(uint64_t ticks);
|
|
|
|
]]
|
|
|
|
return sokol_libs |