new: struct packer

new: vle,int,float,half packers
new: crc64(), arc4(), entropy()
chg: reordered endianness utils
main
Dominik Madarász 2023-10-09 08:07:17 +02:00
parent c984ac338e
commit 559b0ae2da
15 changed files with 7196 additions and 2662 deletions

Binary file not shown.

View File

@ -1937,58 +1937,33 @@ COMPRESS_ZLIB = (12<<4),
unsigned zencode(void *out, unsigned outlen, const void *in, unsigned inlen, unsigned flags);
unsigned zexcess(unsigned flags);
unsigned zdecode(void *out, unsigned outlen, const void *in, unsigned inlen, unsigned flags);
void *interleave( void *out, const void *list, int list_count, int sizeof_item, unsigned columns );
unsigned cobs_bounds(unsigned len);
unsigned cobs_encode(const void *in, unsigned inlen, void *out, unsigned outlen);
unsigned cobs_decode(const void *in, unsigned inlen, void *out, unsigned outlen);
uint64_t pack754(long double f, unsigned bits, unsigned expbits);
long double unpack754(uint64_t i, unsigned bits, unsigned expbits);
int msgpack(const char *fmt, ... );
bool msgunpack(const char *fmt, ... );
int msgpack_new(uint8_t *w, size_t l);
int msgpack_nil();
int msgpack_chr(bool n);
int msgpack_uns(uint64_t n);
int msgpack_int(int64_t n);
int msgpack_str(const char *s);
int msgpack_bin(const char *s, size_t n);
int msgpack_flt(double g);
int msgpack_ext(uint8_t key, void *val, size_t n);
int msgpack_arr(uint32_t n);
int msgpack_map(uint32_t n);
int msgpack_eof();
int msgpack_err();
bool msgunpack_new( const void *opaque_or_FILE, size_t bytes );
bool msgunpack_nil();
bool msgunpack_chr(bool *chr);
bool msgunpack_uns(uint64_t *uns);
bool msgunpack_int(int64_t *sig);
bool msgunpack_str(char **str);
bool msgunpack_bin(void **bin, uint64_t *len);
bool msgunpack_flt(float *flt);
bool msgunpack_dbl(double *dbl);
bool msgunpack_ext(uint8_t *key, void **val, uint64_t *len);
bool msgunpack_arr(uint64_t *len);
bool msgunpack_map(uint64_t *len);
bool msgunpack_eof();
bool msgunpack_err();
enum {
ERR,NIL,BOL,UNS,SIG,STR,BIN,FLT,EXT,ARR,MAP
};
typedef struct variant {
union {
uint8_t chr;
uint64_t uns;
int64_t sig;
uint8_t *str;
void *bin;
double flt;
uint32_t u32;
};
uint64_t sz;
uint16_t ext;
uint16_t type;
} variant;
bool msgunpack_var(struct variant *var);
unsigned base92_encode(const void *in, unsigned inlen, void* out, unsigned outlen);
unsigned base92_decode(const void *in, unsigned inlen, void* out, unsigned outlen);
unsigned base92_bounds(unsigned inlen);
unsigned netstring_bounds(unsigned inlen);
unsigned netstring_encode(const char *in, unsigned inlen, char *out, unsigned outlen);
unsigned netstring_decode(const char *in, unsigned inlen, char *out, unsigned outlen);
void delta8_encode(void *buffer, unsigned count);
void delta8_decode(void *buffer, unsigned count);
void delta16_encode(void *buffer, unsigned count);
void delta16_decode(void *buffer, unsigned count);
void delta32_encode(void *buffer, unsigned count);
void delta32_decode(void *buffer, unsigned count);
void delta64_encode(void *buffer, unsigned count);
void delta64_decode(void *buffer, unsigned count);
uint64_t zig64( int64_t value );
int64_t zag64( uint64_t value );
uint32_t enczig32u( int32_t n);
uint64_t enczig64u( int64_t n);
int32_t deczig32i(uint32_t n);
int64_t deczig64i(uint64_t n);
void *arc4( void *buffer, unsigned buflen, const void *pass, unsigned passlen );
uint64_t crc64(uint64_t h, const void *ptr, uint64_t len);
void entropy( void *buf, unsigned n );
typedef struct gjk_support {
int aid, bid;
vec3 a;
@ -2222,6 +2197,81 @@ uintptr_t id_make(void *ptr);
void * id_handle(uintptr_t id);
void id_dispose(uintptr_t id);
bool id_valid(uintptr_t id);
int is_big();
int is_little();
uint16_t swap16( uint16_t x );
uint32_t swap32( uint32_t x );
uint64_t swap64( uint64_t x );
float swap32f(float n);
double swap64f(double n);
uint16_t lil16(uint16_t n);
uint32_t lil32(uint32_t n);
uint64_t lil64(uint64_t n);
uint16_t big16(uint16_t n);
uint32_t big32(uint32_t n);
uint64_t big64(uint64_t n);
float lil32f(float n);
double lil64f(double n);
float big32f(float n);
double big64f(double n);
uint16_t* lil16p(void *p, int sz);
uint16_t* big16p(void *p, int sz);
uint32_t* lil32p(void *p, int sz);
uint32_t* big32p(void *p, int sz);
uint64_t* lil64p(void *p, int sz);
uint64_t* big64p(void *p, int sz);
float * lil32pf(void *p, int sz);
float * big32pf(void *p, int sz);
double * lil64pf(void *p, int sz);
double * big64pf(void *p, int sz);
typedef uint16_t half;
float half_to_float(half value);
half float_to_half(float value);
void pack16i(uint8_t *buf, uint16_t i, int swap);
void pack32i(uint8_t *buf, uint32_t i, int swap);
void pack64i(uint8_t *buf, uint64_t i, int swap);
int16_t unpack16i(const uint8_t *buf, int swap);
int32_t unpack32i(const uint8_t *buf, int swap);
int64_t unpack64i(const uint8_t *buf, int swap);
uint64_t pack754(long double f, unsigned bits, unsigned expbits);
long double unpack754(uint64_t i, unsigned bits, unsigned expbits);
uint64_t pack64uv( uint8_t *buffer, uint64_t value );
uint64_t unpack64uv( const uint8_t *buffer, uint64_t *value );
uint64_t pack64iv( uint8_t *buffer, int64_t value_ );
uint64_t unpack64iv( const uint8_t *buffer, int64_t *value );
int msgpack(const char *fmt, ... );
bool msgunpack(const char *fmt, ... );
int msgpack_new(uint8_t *w, size_t l);
int msgpack_nil();
int msgpack_chr(bool n);
int msgpack_uns(uint64_t n);
int msgpack_int(int64_t n);
int msgpack_str(const char *s);
int msgpack_bin(const char *s, size_t n);
int msgpack_flt(double g);
int msgpack_ext(uint8_t key, void *val, size_t n);
int msgpack_arr(uint32_t n);
int msgpack_map(uint32_t n);
int msgpack_eof();
int msgpack_err();
bool msgunpack_new( const void *opaque_or_FILE, size_t bytes );
bool msgunpack_nil();
bool msgunpack_chr(bool *chr);
bool msgunpack_uns(uint64_t *uns);
bool msgunpack_int(int64_t *sig);
bool msgunpack_str(char **str);
bool msgunpack_bin(void **bin, uint64_t *len);
bool msgunpack_flt(float *flt);
bool msgunpack_dbl(double *dbl);
bool msgunpack_ext(uint8_t *key, void **val, uint64_t *len);
bool msgunpack_arr(uint64_t *len);
bool msgunpack_map(uint64_t *len);
bool msgunpack_eof();
bool msgunpack_err();
int savef(FILE *file, const char *format, ...);
int saveb(unsigned char *buf, const char *format, ...);
int loadf(FILE *file, const char *format, ...);
int loadb(const unsigned char *buf, const char *format, ...);
int input_use( int controller_id );
float input( int vk );
vec2 input2( int vk );

File diff suppressed because it is too large Load Diff

View File

@ -137,6 +137,8 @@ for( int lock_ = (thread_mutex_lock( mutexptr ), 1); lock_; lock_ = (thread_mute
{{FILE:v4k_netsync.c}}
{{FILE:v4k_pack.c}}
{{FILE:v4k_render.c}}
{{FILE:v4k_renderdd.c}}

View File

@ -126,6 +126,8 @@ extern "C" {
{{FILE:v4k_id.h}}
{{FILE:v4k_pack.h}}
{{FILE:v4k_input.h}}
{{FILE:v4k_memory.h}}

File diff suppressed because it is too large Load Diff

View File

@ -23,84 +23,73 @@ API unsigned zexcess(unsigned flags);
API unsigned zdecode(void *out, unsigned outlen, const void *in, unsigned inlen, unsigned flags);
// ----------------------------------------------------------------------------
// cobs en/decoding
// array de/interleaving
// - rlyeh, public domain.
//
// results:
// R0G0B0 R1G1B1 R2G2B2... -> R0R1R2... B0B1B2... G0G1G2...
// R0G0B0A0 R1G1B1A1 R2G2B2A2... -> R0R1R2... A0A1A2... B0B1B2... G0G1G2...
API void *interleave( void *out, const void *list, int list_count, int sizeof_item, unsigned columns );
// ----------------------------------------------------------------------------
// cobs en/decoder
API unsigned cobs_bounds(unsigned len);
API unsigned cobs_encode(const void *in, unsigned inlen, void *out, unsigned outlen);
API unsigned cobs_decode(const void *in, unsigned inlen, void *out, unsigned outlen);
// ----------------------------------------------------------------------------
// float un/packing: 8 (micro), 16 (half), 32 (float), 64 (double) types
// base92 en/decoder
#define pack754_8(f) ( pack754((f), 8, 4))
#define pack754_16(f) ( pack754((f), 16, 5))
#define pack754_32(f) ( pack754((f), 32, 8))
#define pack754_64(f) ( pack754((f), 64, 11))
#define unpack754_8(u) (unpack754((u), 8, 4))
#define unpack754_16(u) (unpack754((u), 16, 5))
#define unpack754_32(u) (unpack754((u), 32, 8))
#define unpack754_64(u) (unpack754((u), 64, 11))
API uint64_t pack754(long double f, unsigned bits, unsigned expbits);
API long double unpack754(uint64_t i, unsigned bits, unsigned expbits);
API unsigned base92_encode(const void *in, unsigned inlen, void* out, unsigned outlen);
API unsigned base92_decode(const void *in, unsigned inlen, void* out, unsigned outlen);
API unsigned base92_bounds(unsigned inlen);
// ----------------------------------------------------------------------------
// msgpack v5, schema based struct/buffer bitpacking
// netstring en/decoder
// api v2
API unsigned netstring_bounds(unsigned inlen);
API unsigned netstring_encode(const char *in, unsigned inlen, char *out, unsigned outlen);
API unsigned netstring_decode(const char *in, unsigned inlen, char *out, unsigned outlen);
API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{"
API bool msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{"
// ----------------------------------------------------------------------------
// delta en/decoder
// api v1
API void delta8_encode(void *buffer, unsigned count);
API void delta8_decode(void *buffer, unsigned count);
API int msgpack_new(uint8_t *w, size_t l);
API int msgpack_nil(); // write null
API int msgpack_chr(bool n); // write boolean
API int msgpack_uns(uint64_t n); // write unsigned integer
API int msgpack_int(int64_t n); // write integer
API int msgpack_str(const char *s); // write string
API int msgpack_bin(const char *s, size_t n); // write binary pointer
API int msgpack_flt(double g); // write real
API int msgpack_ext(uint8_t key, void *val, size_t n); // write extension type
API int msgpack_arr(uint32_t n); // write array mark for next N items
API int msgpack_map(uint32_t n); // write map mark for next N pairs (N keys + N values)
API int msgpack_eof(); // write full?
API int msgpack_err(); // write error?
API void delta16_encode(void *buffer, unsigned count);
API void delta16_decode(void *buffer, unsigned count);
API bool msgunpack_new( const void *opaque_or_FILE, size_t bytes );
API bool msgunpack_nil();
API bool msgunpack_chr(bool *chr);
API bool msgunpack_uns(uint64_t *uns);
API bool msgunpack_int(int64_t *sig);
API bool msgunpack_str(char **str);
API bool msgunpack_bin(void **bin, uint64_t *len);
API bool msgunpack_flt(float *flt);
API bool msgunpack_dbl(double *dbl);
API bool msgunpack_ext(uint8_t *key, void **val, uint64_t *len);
API bool msgunpack_arr(uint64_t *len);
API bool msgunpack_map(uint64_t *len);
API bool msgunpack_eof();
API bool msgunpack_err();
API void delta32_encode(void *buffer, unsigned count);
API void delta32_decode(void *buffer, unsigned count);
// alt unpack api v1
API void delta64_encode(void *buffer, unsigned count);
API void delta64_decode(void *buffer, unsigned count);
enum {
ERR,NIL,BOL,UNS,SIG,STR,BIN,FLT,EXT,ARR,MAP
};
typedef struct variant {
union {
uint8_t chr;
uint64_t uns;
int64_t sig;
uint8_t *str;
void *bin;
double flt;
uint32_t u32;
};
uint64_t sz;
uint16_t ext;
uint16_t type; //[0..10]={err,nil,bol,uns,sig,str,bin,flt,ext,arr,map}
} variant;
// ----------------------------------------------------------------------------
// zigzag en/decoder
API bool msgunpack_var(struct variant *var);
API uint64_t zig64( int64_t value ); // convert sign|magnitude to magnitude|sign
API int64_t zag64( uint64_t value ); // convert magnitude|sign to sign|magnitude
API uint32_t enczig32u( int32_t n);
API uint64_t enczig64u( int64_t n);
API int32_t deczig32i(uint32_t n);
API int64_t deczig64i(uint64_t n);
// ----------------------------------------------------------------------------
// arc4 en/decryptor
API void *arc4( void *buffer, unsigned buflen, const void *pass, unsigned passlen );
// ----------------------------------------------------------------------------
// crc64
API uint64_t crc64(uint64_t h, const void *ptr, uint64_t len);
// ----------------------------------------------------------------------------
// entropy encoder
API void entropy( void *buf, unsigned n );

View File

@ -372,6 +372,76 @@ void* sha1_mem(const void *ptr, int inlen) { // 20bytes
sha1_done(&hs, hash);
return hash;
}
unsigned crc32_mem(unsigned h, const void *ptr_, unsigned len) {
// based on public domain code by Karl Malbrain
const uint8_t *ptr = (const uint8_t *)ptr_;
if (!ptr) return 0;
const unsigned tbl[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
for(h = ~h; len--; ) { uint8_t b = *ptr++; h = (h >> 4) ^ tbl[(h & 15) ^ (b & 15)]; h = (h >> 4) ^ tbl[(h & 15) ^ (b >> 4)]; }
return ~h;
}
uint64_t crc64_mem(uint64_t h, const void *ptr, uint64_t len) {
// based on public domain code by Lasse Collin
// also, use poly64 0xC96C5795D7870F42 for crc64-ecma
static uint64_t crc64_table[256];
static uint64_t poly64 = UINT64_C(0x95AC9329AC4BC9B5);
if( poly64 ) {
for( int b = 0; b < 256; ++b ) {
uint64_t r = b;
for( int i = 0; i < 8; ++i ) {
r = r & 1 ? (r >> 1) ^ poly64 : r >> 1;
}
crc64_table[ b ] = r;
//printf("%016llx\n", crc64_table[b]);
}
poly64 = 0;
}
const uint8_t *buf = (const uint8_t *)ptr;
uint64_t crc = ~h; // ~crc;
while( len != 0 ) {
crc = crc64_table[(uint8_t)crc ^ *buf++] ^ (crc >> 8);
--len;
}
return ~crc;
}
// https://en.wikipedia.org/wiki/MurmurHash
static inline uint32_t murmur3_scramble(uint32_t k) {
return k *= 0xcc9e2d51, k = (k << 15) | (k >> 17), k *= 0x1b873593;
}
uint32_t murmur3_mem(const uint8_t* key, size_t len, uint32_t seed) {
uint32_t h = seed;
uint32_t k;
/* Read in groups of 4. */
for (size_t i = len >> 2; i; i--) {
// Here is a source of differing results across endiannesses.
// A swap here has no effects on hash properties though.
k = *((uint32_t*)key);
key += sizeof(uint32_t);
h ^= murmur3_scramble(k);
h = (h << 13) | (h >> 19);
h = h * 5 + 0xe6546b64;
}
/* Read the rest. */
k = 0;
for (size_t i = len & 3; i; i--) {
k <<= 8;
k |= key[i - 1];
}
// A swap is *not* necessary here because the preceeding loop already
// places the low bytes in the low places according to whatever endianness
// we use. Swaps only apply when the memory is copied in a chunk.
h ^= murmur3_scramble(k);
/* Finalize. */
h ^= len;
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
#endif
// -----------------------------------------------------------------------------

View File

@ -8,11 +8,7 @@
// [ref] https://github.com/nlguillemot/dof/blob/master/viewer/packed_freelist.h
// [ref] https://gist.github.com/pervognsen/ffd89e45b5750e9ce4c6c8589fc7f253
#if is(ems)
#define id_t id_t2
#endif
typedef union id_t {
typedef union id64 {
uint64_t h;
struct {
#if (ID_INDEX_BITS+ID_COUNT_BITS) != 64
@ -21,15 +17,15 @@ typedef union id_t {
uint64_t index : ID_INDEX_BITS;
uint64_t count : ID_COUNT_BITS;
};
} id_t;
} id64;
typedef struct id_factory id_factory;
id_factory id_factory_create(uint64_t capacity /*= 256*/);
id_t id_factory_insert(id_factory *f, uint64_t data);
uint64_t id_factory_getvalue(id_factory *f, id_t handle);
void id_factory_setvalue(id_factory *f, id_t handle, uint64_t data);
void id_factory_erase(id_factory *f, id_t handle);
bool id_factory_isvalid(id_factory *f, id_t handle);
id64 id_factory_insert(id_factory *f, uint64_t data);
uint64_t id_factory_getvalue(id_factory *f, id64 handle);
void id_factory_setvalue(id_factory *f, id64 handle, uint64_t data);
void id_factory_erase(id_factory *f, id64 handle);
bool id_factory_isvalid(id_factory *f, id64 handle);
void id_factory_destroy(id_factory *f);
// ---
@ -72,46 +68,46 @@ void id_factory_destroy(id_factory *f) {
FREE(f->entries);
}
id_t id_factory_insert(id_factory *f, uint64_t data) {
id64 id_factory_insert(id_factory *f, uint64_t data) {
// pop element off the free list
assert(f->freelist != f->canary && "max alive capacity reached");
uint64_t index = f->freelist;
f->freelist = f->entries[f->freelist].data;
// create new id_t
// create new id64
f->entries[index].data = data;
id_t handle = {0};
id64 handle = {0};
handle.index = index;
handle.count = f->entries[index].count;
return handle;
}
void id_factory_erase(id_factory *f, id_t handle) {
// push id_t onto the freelist
void id_factory_erase(id_factory *f, id64 handle) {
// push id64 onto the freelist
uint64_t index = handle.index;
f->entries[index].data = f->freelist;
f->freelist = index;
// increment the count. this signifies a change in lifetime (this particular id_t is now dead)
// increment the count. this signifies a change in lifetime (this particular id64 is now dead)
// the next time this particular index is used in alloc, a new `count` will be used to uniquely identify
f->entries[index].count++;
}
uint64_t id_factory_getvalue(id_factory *f, id_t handle) {
uint64_t id_factory_getvalue(id_factory *f, id64 handle) {
uint64_t index = handle.index;
uint64_t count = handle.count;
assert(f->entries[index].count == count);
return f->entries[index].data;
}
void id_factory_setvalue(id_factory *f, id_t handle, uint64_t data) {
void id_factory_setvalue(id_factory *f, id64 handle, uint64_t data) {
uint64_t index = handle.index;
uint64_t count = handle.count;
assert(f->entries[index].count == count);
f->entries[index].data = data;
}
bool id_factory_isvalid(id_factory *f, id_t handle) {
bool id_factory_isvalid(id_factory *f, id64 handle) {
uint64_t index = handle.index;
uint64_t count = handle.count;
if (index >= f->capacity) return false;
@ -125,12 +121,12 @@ AUTORUN {
id_factory f = id_factory_create(optioni("--NUM",256));
array(id_t) ids = 0;
array(id64) ids = 0;
for( int i = 0 ; ; ++i, i &= ((1ULL << ID_INDEX_BITS) - 1) ) { // infinite wrap
printf("count_ids(%d) ", array_count(ids));
bool insert = randf() < 0.49; // biased against deletion
if( insert ) {
id_t h = id_factory_insert(&f, i);
id64 h = id_factory_insert(&f, i);
array_push(ids, h);
printf("add %llu.%llu\n", h.index, h.count);
} else {
@ -138,7 +134,7 @@ AUTORUN {
if( count ) {
int chosen = randi(0,count);
printf("del %d.\n", chosen);
id_t h = ids[chosen];
id64 h = ids[chosen];
id_factory_erase(&f, h);
array_erase(ids, chosen);
}
@ -154,18 +150,18 @@ static id_factory fid; // @fixme: threadsafe
uintptr_t id_make(void *ptr) {
do_once fid = id_factory_create(0), id_factory_insert(&fid, 0); // init and reserve id(0)
id_t newid = id_factory_insert(&fid, (uint64_t)(uintptr_t)ptr ); // 48-bit effective addr
id64 newid = id_factory_insert(&fid, (uint64_t)(uintptr_t)ptr ); // 48-bit effective addr
return newid.h;
}
void *id_handle(uintptr_t id) {
return (void *)(uintptr_t)id_factory_getvalue(&fid, ((id_t){ (uint64_t)id }) );
return (void *)(uintptr_t)id_factory_getvalue(&fid, ((id64){ (uint64_t)id }) );
}
void id_dispose(uintptr_t id) {
id_factory_erase(&fid, ((id_t){ (uint64_t)id }) );
id_factory_erase(&fid, ((id64){ (uint64_t)id }) );
}
bool id_valid(uintptr_t id) {
return id_factory_isvalid(&fid, ((id_t){ (uint64_t)id }) );
return id_factory_isvalid(&fid, ((id64){ (uint64_t)id }) );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,189 @@
// ----------------------------------------------------------------------------
// endianness
API int is_big();
API int is_little();
API uint16_t swap16( uint16_t x );
API uint32_t swap32( uint32_t x );
API uint64_t swap64( uint64_t x );
API float swap32f(float n);
API double swap64f(double n);
API uint16_t lil16(uint16_t n);
API uint32_t lil32(uint32_t n);
API uint64_t lil64(uint64_t n);
API uint16_t big16(uint16_t n);
API uint32_t big32(uint32_t n);
API uint64_t big64(uint64_t n);
API float lil32f(float n);
API double lil64f(double n);
API float big32f(float n);
API double big64f(double n);
API uint16_t* lil16p(void *p, int sz);
API uint16_t* big16p(void *p, int sz);
API uint32_t* lil32p(void *p, int sz);
API uint32_t* big32p(void *p, int sz);
API uint64_t* lil64p(void *p, int sz);
API uint64_t* big64p(void *p, int sz);
API float * lil32pf(void *p, int sz);
API float * big32pf(void *p, int sz);
API double * lil64pf(void *p, int sz);
API double * big64pf(void *p, int sz);
#if is(cl)
#define swap16 _byteswap_ushort
#define swap32 _byteswap_ulong
#define swap64 _byteswap_uint64
#elif is(gcc)
#define swap16 __builtin_bswap16
#define swap32 __builtin_bswap32
#define swap64 __builtin_bswap64
#endif
#define hton16 big16
#define ntoh16 big16
#define hton32 big32
#define ntoh32 big32
#define hton64 big64
#define ntoh64 big64
#define IS_BIG ((*(uint16_t *)"\0\1") == 1)
#define IS_LITTLE ((*(uint16_t *)"\0\1") != 1)
// ----------------------------------------------------------------------------
// half packing
typedef uint16_t half;
API float half_to_float(half value);
API half float_to_half(float value);
// ----------------------------------------------------------------------------
// int packing
// pack16i() -- store a 16-bit int into a char buffer (like htons())
// pack32i() -- store a 32-bit int into a char buffer (like htonl())
// pack64i() -- store a 64-bit int into a char buffer (like htonl())
API void pack16i(uint8_t *buf, uint16_t i, int swap);
API void pack32i(uint8_t *buf, uint32_t i, int swap);
API void pack64i(uint8_t *buf, uint64_t i, int swap);
// unpack16i() -- unpack a 16-bit int from a char buffer (like ntohs())
// unpack32i() -- unpack a 32-bit int from a char buffer (like ntohl())
// unpack64i() -- unpack a 64-bit int from a char buffer (like ntohl())
// changes unsigned numbers to signed if needed.
API int16_t unpack16i(const uint8_t *buf, int swap);
API int32_t unpack32i(const uint8_t *buf, int swap);
API int64_t unpack64i(const uint8_t *buf, int swap);
// ----------------------------------------------------------------------------
// float un/packing: 8 (micro), 16 (half), 32 (float), 64 (double) types
#define pack754_8(f) ( pack754((f), 8, 4))
#define pack754_16(f) ( pack754((f), 16, 5))
#define pack754_32(f) ( pack754((f), 32, 8))
#define pack754_64(f) ( pack754((f), 64, 11))
#define unpack754_8(u) (unpack754((u), 8, 4))
#define unpack754_16(u) (unpack754((u), 16, 5))
#define unpack754_32(u) (unpack754((u), 32, 8))
#define unpack754_64(u) (unpack754((u), 64, 11))
API uint64_t pack754(long double f, unsigned bits, unsigned expbits);
API long double unpack754(uint64_t i, unsigned bits, unsigned expbits);
// ----------------------------------------------------------------------------
// variable-length integer packing
API uint64_t pack64uv( uint8_t *buffer, uint64_t value );
API uint64_t unpack64uv( const uint8_t *buffer, uint64_t *value );
API uint64_t pack64iv( uint8_t *buffer, int64_t value_ );
API uint64_t unpack64iv( const uint8_t *buffer, int64_t *value );
// ----------------------------------------------------------------------------
// msgpack v5, schema based struct/buffer bitpacking
// api v2
API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{"
API bool msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{"
// api v1
API int msgpack_new(uint8_t *w, size_t l);
API int msgpack_nil(); // write null
API int msgpack_chr(bool n); // write boolean
API int msgpack_uns(uint64_t n); // write unsigned integer
API int msgpack_int(int64_t n); // write integer
API int msgpack_str(const char *s); // write string
API int msgpack_bin(const char *s, size_t n); // write binary pointer
API int msgpack_flt(double g); // write real
API int msgpack_ext(uint8_t key, void *val, size_t n); // write extension type
API int msgpack_arr(uint32_t n); // write array mark for next N items
API int msgpack_map(uint32_t n); // write map mark for next N pairs (N keys + N values)
API int msgpack_eof(); // write full?
API int msgpack_err(); // write error?
API bool msgunpack_new( const void *opaque_or_FILE, size_t bytes );
API bool msgunpack_nil();
API bool msgunpack_chr(bool *chr);
API bool msgunpack_uns(uint64_t *uns);
API bool msgunpack_int(int64_t *sig);
API bool msgunpack_str(char **str);
API bool msgunpack_bin(void **bin, uint64_t *len);
API bool msgunpack_flt(float *flt);
API bool msgunpack_dbl(double *dbl);
API bool msgunpack_ext(uint8_t *key, void **val, uint64_t *len);
API bool msgunpack_arr(uint64_t *len);
API bool msgunpack_map(uint64_t *len);
API bool msgunpack_eof();
API bool msgunpack_err();
// ----------------------------------------------------------------------------
// Based on code by Brian "Beej Jorgensen" Hall (public domain) [1].
// Based on code by Ginger Bill's half<->float (public domain) [2].
// - rlyeh, public domain.
//
// pack.c -- perl/python-ish pack/unpack functions
// like printf and scanf, but for binary data.
//
// format flags:
// (<) little endian (>) big endian (! also) (=) native endian
// (c) 8-bit char (b) 8-bit byte
// (h) 16-bit half (w) 16-bit word
// (i) 32-bit integer (u) 32-bit unsigned (f) 32-bit float
// (l) 64-bit long (q) 64-bit quad (d) 64-bit double
// (v) varint
// (s) string (64-bit varint length prepended)
// (S) string (32-bit fixed length prepended)
// (m) memblock (64-bit varint length prepended)
// (M) memblock (32-bit fixed length prepended)
// (z) memblock (zeroed)
// (#) number of arguments processed (only when unpacking)
//
// @todo:
// - (x) document & test flag
// @totest:
// - (s) string (64-bit variable length automatically prepended)
// - (S) string (32-bit fixed length automatically prepended)
// - (m) memblock (64-bit variable length automatically prepended)
// - (M) memblock (32-bit fixed length automatically prepended)
// - (z) memblock (zeroed)
// - (#) number of arguments processed (only when unpacking)
// - save data dictated by the format string from the buffer. return: number of bytes written, or 0 if error.
// if first argument is zero, returns number of bytes required for packing.
API int savef(FILE *file, const char *format, ...);
API int saveb(unsigned char *buf, const char *format, ...);
// - load data dictated by the format string into the buffer. return: number of bytes read, or 0 if error.
// if first argument is zero, returns number of bytes required for unpacking.
API int loadf(FILE *file, const char *format, ...);
API int loadb(const unsigned char *buf, const char *format, ...);

View File

@ -303,53 +303,6 @@ AUTORUN {
}
#endif
// endian ----------------------------------------------------------------------
#if is(cl)
#include <stdlib.h>
#define swap16 _byteswap_ushort
#define swap32 _byteswap_ulong
#define swap64 _byteswap_uint64
#elif is(gcc)
#define swap16 __builtin_bswap16
#define swap32 __builtin_bswap32
#define swap64 __builtin_bswap64
#else
uint16_t swap16( uint16_t x ) { return (x << 8) | (x >> 8); }
uint32_t swap32( uint32_t x ) { x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); return (x << 16) | (x >> 16); }
uint64_t swap64( uint64_t x ) { x = ((x << 8) & 0xff00ff00ff00ff00ULL) | ((x >> 8) & 0x00ff00ff00ff00ffULL); x = ((x << 16) & 0xffff0000ffff0000ULL) | ((x >> 16) & 0x0000ffff0000ffffULL); return (x << 32) | (x >> 32); }
#endif
float swap32f(float n) { union { float t; uint32_t i; } conv; conv.t = n; conv.i = swap32(conv.i); return conv.t; }
double swap64f(double n) { union { double t; uint64_t i; } conv; conv.t = n; conv.i = swap64(conv.i); return conv.t; }
#define is_big() ((*(uint16_t *)"\0\1") == 1)
#define is_little() ((*(uint16_t *)"\0\1") != 1)
uint16_t lil16(uint16_t n) { return is_big() ? swap16(n) : n; }
uint32_t lil32(uint32_t n) { return is_big() ? swap32(n) : n; }
uint64_t lil64(uint64_t n) { return is_big() ? swap64(n) : n; }
uint16_t big16(uint16_t n) { return is_little() ? swap16(n) : n; }
uint32_t big32(uint32_t n) { return is_little() ? swap32(n) : n; }
uint64_t big64(uint64_t n) { return is_little() ? swap64(n) : n; }
float lil32f(float n) { return is_big() ? swap32f(n) : n; }
double lil64f(double n) { return is_big() ? swap64f(n) : n; }
float big32f(float n) { return is_little() ? swap32f(n) : n; }
double big64f(double n) { return is_little() ? swap64f(n) : n; }
uint16_t* lil16p(void *p, int sz) { if(is_big() ) { uint16_t *n = (uint16_t *)p; for(int i = 0; i < sz; ++i) n[i] = swap16(n[i]); } return p; }
uint16_t* big16p(void *p, int sz) { if(is_little()) { uint16_t *n = (uint16_t *)p; for(int i = 0; i < sz; ++i) n[i] = swap16(n[i]); } return p; }
uint32_t* lil32p(void *p, int sz) { if(is_big() ) { uint32_t *n = (uint32_t *)p; for(int i = 0; i < sz; ++i) n[i] = swap32(n[i]); } return p; }
uint32_t* big32p(void *p, int sz) { if(is_little()) { uint32_t *n = (uint32_t *)p; for(int i = 0; i < sz; ++i) n[i] = swap32(n[i]); } return p; }
uint64_t* lil64p(void *p, int sz) { if(is_big() ) { uint64_t *n = (uint64_t *)p; for(int i = 0; i < sz; ++i) n[i] = swap64(n[i]); } return p; }
uint64_t* big64p(void *p, int sz) { if(is_little()) { uint64_t *n = (uint64_t *)p; for(int i = 0; i < sz; ++i) n[i] = swap64(n[i]); } return p; }
float * lil32pf(void *p, int sz) { if(is_big() ) { float *n = (float *)p; for(int i = 0; i < sz; ++i) n[i] = swap32f(n[i]); } return p; }
float * big32pf(void *p, int sz) { if(is_little()) { float *n = (float *)p; for(int i = 0; i < sz; ++i) n[i] = swap32f(n[i]); } return p; }
double * lil64pf(void *p, int sz) { if(is_big() ) { double *n = (double *)p; for(int i = 0; i < sz; ++i) n[i] = swap64f(n[i]); } return p; }
double * big64pf(void *p, int sz) { if(is_little()) { double *n = (double *)p; for(int i = 0; i < sz; ++i) n[i] = swap64f(n[i]); } return p; }
// cpu -------------------------------------------------------------------------
#if is(linux)

File diff suppressed because it is too large Load Diff

View File

@ -1537,87 +1537,76 @@ API unsigned zexcess(unsigned flags);
API unsigned zdecode(void *out, unsigned outlen, const void *in, unsigned inlen, unsigned flags);
// ----------------------------------------------------------------------------
// cobs en/decoding
// array de/interleaving
// - rlyeh, public domain.
//
// results:
// R0G0B0 R1G1B1 R2G2B2... -> R0R1R2... B0B1B2... G0G1G2...
// R0G0B0A0 R1G1B1A1 R2G2B2A2... -> R0R1R2... A0A1A2... B0B1B2... G0G1G2...
API void *interleave( void *out, const void *list, int list_count, int sizeof_item, unsigned columns );
// ----------------------------------------------------------------------------
// cobs en/decoder
API unsigned cobs_bounds(unsigned len);
API unsigned cobs_encode(const void *in, unsigned inlen, void *out, unsigned outlen);
API unsigned cobs_decode(const void *in, unsigned inlen, void *out, unsigned outlen);
// ----------------------------------------------------------------------------
// float un/packing: 8 (micro), 16 (half), 32 (float), 64 (double) types
// base92 en/decoder
#define pack754_8(f) ( pack754((f), 8, 4))
#define pack754_16(f) ( pack754((f), 16, 5))
#define pack754_32(f) ( pack754((f), 32, 8))
#define pack754_64(f) ( pack754((f), 64, 11))
#define unpack754_8(u) (unpack754((u), 8, 4))
#define unpack754_16(u) (unpack754((u), 16, 5))
#define unpack754_32(u) (unpack754((u), 32, 8))
#define unpack754_64(u) (unpack754((u), 64, 11))
API uint64_t pack754(long double f, unsigned bits, unsigned expbits);
API long double unpack754(uint64_t i, unsigned bits, unsigned expbits);
API unsigned base92_encode(const void *in, unsigned inlen, void* out, unsigned outlen);
API unsigned base92_decode(const void *in, unsigned inlen, void* out, unsigned outlen);
API unsigned base92_bounds(unsigned inlen);
// ----------------------------------------------------------------------------
// msgpack v5, schema based struct/buffer bitpacking
// netstring en/decoder
// api v2
API unsigned netstring_bounds(unsigned inlen);
API unsigned netstring_encode(const char *in, unsigned inlen, char *out, unsigned outlen);
API unsigned netstring_decode(const char *in, unsigned inlen, char *out, unsigned outlen);
API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{"
API bool msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{"
// ----------------------------------------------------------------------------
// delta en/decoder
// api v1
API void delta8_encode(void *buffer, unsigned count);
API void delta8_decode(void *buffer, unsigned count);
API int msgpack_new(uint8_t *w, size_t l);
API int msgpack_nil(); // write null
API int msgpack_chr(bool n); // write boolean
API int msgpack_uns(uint64_t n); // write unsigned integer
API int msgpack_int(int64_t n); // write integer
API int msgpack_str(const char *s); // write string
API int msgpack_bin(const char *s, size_t n); // write binary pointer
API int msgpack_flt(double g); // write real
API int msgpack_ext(uint8_t key, void *val, size_t n); // write extension type
API int msgpack_arr(uint32_t n); // write array mark for next N items
API int msgpack_map(uint32_t n); // write map mark for next N pairs (N keys + N values)
API int msgpack_eof(); // write full?
API int msgpack_err(); // write error?
API void delta16_encode(void *buffer, unsigned count);
API void delta16_decode(void *buffer, unsigned count);
API bool msgunpack_new( const void *opaque_or_FILE, size_t bytes );
API bool msgunpack_nil();
API bool msgunpack_chr(bool *chr);
API bool msgunpack_uns(uint64_t *uns);
API bool msgunpack_int(int64_t *sig);
API bool msgunpack_str(char **str);
API bool msgunpack_bin(void **bin, uint64_t *len);
API bool msgunpack_flt(float *flt);
API bool msgunpack_dbl(double *dbl);
API bool msgunpack_ext(uint8_t *key, void **val, uint64_t *len);
API bool msgunpack_arr(uint64_t *len);
API bool msgunpack_map(uint64_t *len);
API bool msgunpack_eof();
API bool msgunpack_err();
API void delta32_encode(void *buffer, unsigned count);
API void delta32_decode(void *buffer, unsigned count);
// alt unpack api v1
API void delta64_encode(void *buffer, unsigned count);
API void delta64_decode(void *buffer, unsigned count);
enum {
ERR,NIL,BOL,UNS,SIG,STR,BIN,FLT,EXT,ARR,MAP
};
typedef struct variant {
union {
uint8_t chr;
uint64_t uns;
int64_t sig;
uint8_t *str;
void *bin;
double flt;
uint32_t u32;
};
uint64_t sz;
uint16_t ext;
uint16_t type; //[0..10]={err,nil,bol,uns,sig,str,bin,flt,ext,arr,map}
} variant;
// ----------------------------------------------------------------------------
// zigzag en/decoder
API bool msgunpack_var(struct variant *var);
API uint64_t zig64( int64_t value ); // convert sign|magnitude to magnitude|sign
API int64_t zag64( uint64_t value ); // convert magnitude|sign to sign|magnitude
API uint32_t enczig32u( int32_t n);
API uint64_t enczig64u( int64_t n);
API int32_t deczig32i(uint32_t n);
API int64_t deczig64i(uint64_t n);
// ----------------------------------------------------------------------------
// arc4 en/decryptor
API void *arc4( void *buffer, unsigned buflen, const void *pass, unsigned passlen );
// ----------------------------------------------------------------------------
// crc64
API uint64_t crc64(uint64_t h, const void *ptr, uint64_t len);
// ----------------------------------------------------------------------------
// entropy encoder
API void entropy( void *buf, unsigned n );
#line 0
#line 1 "v4k_collide.h"
@ -2130,6 +2119,198 @@ bool id_valid(uintptr_t id);
#define ID_DATA_BITS (64-ID_COUNT_BITS)
#line 0
#line 1 "v4k_pack.h"
// ----------------------------------------------------------------------------
// endianness
API int is_big();
API int is_little();
API uint16_t swap16( uint16_t x );
API uint32_t swap32( uint32_t x );
API uint64_t swap64( uint64_t x );
API float swap32f(float n);
API double swap64f(double n);
API uint16_t lil16(uint16_t n);
API uint32_t lil32(uint32_t n);
API uint64_t lil64(uint64_t n);
API uint16_t big16(uint16_t n);
API uint32_t big32(uint32_t n);
API uint64_t big64(uint64_t n);
API float lil32f(float n);
API double lil64f(double n);
API float big32f(float n);
API double big64f(double n);
API uint16_t* lil16p(void *p, int sz);
API uint16_t* big16p(void *p, int sz);
API uint32_t* lil32p(void *p, int sz);
API uint32_t* big32p(void *p, int sz);
API uint64_t* lil64p(void *p, int sz);
API uint64_t* big64p(void *p, int sz);
API float * lil32pf(void *p, int sz);
API float * big32pf(void *p, int sz);
API double * lil64pf(void *p, int sz);
API double * big64pf(void *p, int sz);
#if is(cl)
#define swap16 _byteswap_ushort
#define swap32 _byteswap_ulong
#define swap64 _byteswap_uint64
#elif is(gcc)
#define swap16 __builtin_bswap16
#define swap32 __builtin_bswap32
#define swap64 __builtin_bswap64
#endif
#define hton16 big16
#define ntoh16 big16
#define hton32 big32
#define ntoh32 big32
#define hton64 big64
#define ntoh64 big64
#define IS_BIG ((*(uint16_t *)"\0\1") == 1)
#define IS_LITTLE ((*(uint16_t *)"\0\1") != 1)
// ----------------------------------------------------------------------------
// half packing
typedef uint16_t half;
API float half_to_float(half value);
API half float_to_half(float value);
// ----------------------------------------------------------------------------
// int packing
// pack16i() -- store a 16-bit int into a char buffer (like htons())
// pack32i() -- store a 32-bit int into a char buffer (like htonl())
// pack64i() -- store a 64-bit int into a char buffer (like htonl())
API void pack16i(uint8_t *buf, uint16_t i, int swap);
API void pack32i(uint8_t *buf, uint32_t i, int swap);
API void pack64i(uint8_t *buf, uint64_t i, int swap);
// unpack16i() -- unpack a 16-bit int from a char buffer (like ntohs())
// unpack32i() -- unpack a 32-bit int from a char buffer (like ntohl())
// unpack64i() -- unpack a 64-bit int from a char buffer (like ntohl())
// changes unsigned numbers to signed if needed.
API int16_t unpack16i(const uint8_t *buf, int swap);
API int32_t unpack32i(const uint8_t *buf, int swap);
API int64_t unpack64i(const uint8_t *buf, int swap);
// ----------------------------------------------------------------------------
// float un/packing: 8 (micro), 16 (half), 32 (float), 64 (double) types
#define pack754_8(f) ( pack754((f), 8, 4))
#define pack754_16(f) ( pack754((f), 16, 5))
#define pack754_32(f) ( pack754((f), 32, 8))
#define pack754_64(f) ( pack754((f), 64, 11))
#define unpack754_8(u) (unpack754((u), 8, 4))
#define unpack754_16(u) (unpack754((u), 16, 5))
#define unpack754_32(u) (unpack754((u), 32, 8))
#define unpack754_64(u) (unpack754((u), 64, 11))
API uint64_t pack754(long double f, unsigned bits, unsigned expbits);
API long double unpack754(uint64_t i, unsigned bits, unsigned expbits);
// ----------------------------------------------------------------------------
// variable-length integer packing
API uint64_t pack64uv( uint8_t *buffer, uint64_t value );
API uint64_t unpack64uv( const uint8_t *buffer, uint64_t *value );
API uint64_t pack64iv( uint8_t *buffer, int64_t value_ );
API uint64_t unpack64iv( const uint8_t *buffer, int64_t *value );
// ----------------------------------------------------------------------------
// msgpack v5, schema based struct/buffer bitpacking
// api v2
API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{"
API bool msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{"
// api v1
API int msgpack_new(uint8_t *w, size_t l);
API int msgpack_nil(); // write null
API int msgpack_chr(bool n); // write boolean
API int msgpack_uns(uint64_t n); // write unsigned integer
API int msgpack_int(int64_t n); // write integer
API int msgpack_str(const char *s); // write string
API int msgpack_bin(const char *s, size_t n); // write binary pointer
API int msgpack_flt(double g); // write real
API int msgpack_ext(uint8_t key, void *val, size_t n); // write extension type
API int msgpack_arr(uint32_t n); // write array mark for next N items
API int msgpack_map(uint32_t n); // write map mark for next N pairs (N keys + N values)
API int msgpack_eof(); // write full?
API int msgpack_err(); // write error?
API bool msgunpack_new( const void *opaque_or_FILE, size_t bytes );
API bool msgunpack_nil();
API bool msgunpack_chr(bool *chr);
API bool msgunpack_uns(uint64_t *uns);
API bool msgunpack_int(int64_t *sig);
API bool msgunpack_str(char **str);
API bool msgunpack_bin(void **bin, uint64_t *len);
API bool msgunpack_flt(float *flt);
API bool msgunpack_dbl(double *dbl);
API bool msgunpack_ext(uint8_t *key, void **val, uint64_t *len);
API bool msgunpack_arr(uint64_t *len);
API bool msgunpack_map(uint64_t *len);
API bool msgunpack_eof();
API bool msgunpack_err();
// ----------------------------------------------------------------------------
// Based on code by Brian "Beej Jorgensen" Hall (public domain) [1].
// Based on code by Ginger Bill's half<->float (public domain) [2].
// - rlyeh, public domain.
//
// pack.c -- perl/python-ish pack/unpack functions
// like printf and scanf, but for binary data.
//
// format flags:
// (<) little endian (>) big endian (! also) (=) native endian
// (c) 8-bit char (b) 8-bit byte
// (h) 16-bit half (w) 16-bit word
// (i) 32-bit integer (u) 32-bit unsigned (f) 32-bit float
// (l) 64-bit long (q) 64-bit quad (d) 64-bit double
// (v) varint
// (s) string (64-bit varint length prepended)
// (S) string (32-bit fixed length prepended)
// (m) memblock (64-bit varint length prepended)
// (M) memblock (32-bit fixed length prepended)
// (z) memblock (zeroed)
// (#) number of arguments processed (only when unpacking)
//
// @todo:
// - (x) document & test flag
// @totest:
// - (s) string (64-bit variable length automatically prepended)
// - (S) string (32-bit fixed length automatically prepended)
// - (m) memblock (64-bit variable length automatically prepended)
// - (M) memblock (32-bit fixed length automatically prepended)
// - (z) memblock (zeroed)
// - (#) number of arguments processed (only when unpacking)
// - save data dictated by the format string from the buffer. return: number of bytes written, or 0 if error.
// if first argument is zero, returns number of bytes required for packing.
API int savef(FILE *file, const char *format, ...);
API int saveb(unsigned char *buf, const char *format, ...);
// - load data dictated by the format string into the buffer. return: number of bytes read, or 0 if error.
// if first argument is zero, returns number of bytes required for unpacking.
API int loadf(FILE *file, const char *format, ...);
API int loadb(const unsigned char *buf, const char *format, ...);
#line 0
#line 1 "v4k_input.h"
// -----------------------------------------------------------------------------
// input framework

10
hello.c
View File

@ -1,4 +1,4 @@
// playground tests for V4K
// playground tests for FWK
// - rlyeh, public domain
//
// # quickstart
@ -96,15 +96,7 @@ int main() {
ui_section("Script");
if( ui_button("Test Lua") ) script_run("ui_notify(nil, \"Hello from Lua! Version: \" .. _VERSION)");
ui_section("Camera");
if( ui_float("Speed", &cam.speed) ) {}
if( ui_float3("Position", cam.position.v3) ) {}
ui_section("Audio");
static float bgm = 1, sfx = 1, master = 1;
if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm);
if( ui_slider2("SFX", &sfx, va("%.2f", sfx))) audio_volume_clip(sfx);
if( ui_slider2("Master", &master, va("%.2f", master))) audio_volume_master(master);
if( ui_label2_toolbar("BGM: Waterworld Map", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = BGM1, 0);
if( ui_label2_toolbar("BGM: Leisure Suit Larry", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = BGM2, 0);
if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(SFX1, 0);