Selaa lähdekoodia

Language-binding-friendly API changes. (#458)

See: https://floooh.github.io/2021/02/07/sokol-api-overhaul.html
Andre Weissflog 4 vuotta sitten
vanhempi
commit
d2826d75c0
17 muutettua tiedostoa jossa 1082 lisäystä ja 793 poistoa
  1. 12 13
      README.md
  2. 11 11
      bindgen/gen_all.py
  3. 25 9
      bindgen/gen_ir.py
  4. 210 82
      bindgen/gen_zig.py
  5. 89 64
      sokol_app.h
  6. 2 2
      sokol_args.h
  7. 60 60
      sokol_audio.h
  8. 4 4
      sokol_fetch.h
  9. 301 239
      sokol_gfx.h
  10. 2 2
      sokol_time.h
  11. 75 54
      util/sokol_debugtext.h
  12. 16 22
      util/sokol_fontstash.h
  13. 138 123
      util/sokol_gfx_imgui.h
  14. 46 36
      util/sokol_gl.h
  15. 37 42
      util/sokol_imgui.h
  16. 1 1
      util/sokol_memtrack.h
  17. 53 29
      util/sokol_shape.h

+ 12 - 13
README.md

@@ -86,7 +86,7 @@ int main() {
     glfwInit();
     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
-    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
+    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
     GLFWwindow* w = glfwCreateWindow(640, 480, "Sokol Triangle GLFW", 0, 0);
     glfwMakeContextCurrent(w);
@@ -104,8 +104,7 @@ int main() {
         -0.5f, -0.5f, 0.5f,     0.0f, 0.0f, 1.0f, 1.0f
     };
     sg_buffer vbuf = sg_make_buffer(&(sg_buffer_desc){
-        .size = sizeof(vertices),
-        .content = vertices,
+        .data = SG_RANGE(vertices)
     });
 
     /* a shader */
@@ -140,7 +139,7 @@ int main() {
     });
 
     /* resource bindings */
-    sg_bindings binds = {
+    sg_bindings bind = {
         .vertex_buffers[0] = vbuf
     };
 
@@ -153,7 +152,7 @@ int main() {
         glfwGetFramebufferSize(w, &cur_width, &cur_height);
         sg_begin_default_pass(&pass_action, cur_width, cur_height);
         sg_apply_pipeline(pip);
-        sg_apply_bindings(&binds);
+        sg_apply_bindings(&bind);
         sg_draw(0, 3, 1);
         sg_end_pass();
         sg_commit();
@@ -183,9 +182,9 @@ A simple clear-loop sample using sokol_app.h and sokol_gfx.h (does not include
 separate sokol.c/.m implementation file which is necessary
 to split the Objective-C code from the C code of the sample):
 
-```cpp
-#include "sokol_app.h"
+```c
 #include "sokol_gfx.h"
+#include "sokol_app.h"
 #include "sokol_glue.h"
 
 sg_pass_action pass_action;
@@ -195,13 +194,13 @@ void init(void) {
         .context = sapp_sgcontext()
     });
     pass_action = (sg_pass_action) {
-        .colors[0] = { .action=SG_ACTION_CLEAR, .val={1.0f, 0.0f, 0.0f, 1.0f} }
+        .colors[0] = { .action=SG_ACTION_CLEAR, .value={1.0f, 0.0f, 0.0f, 1.0f} }
     };
 }
 
 void frame(void) {
-    float g = pass_action.colors[0].val[1] + 0.01f;
-    pass_action.colors[0].val[1] = (g > 1.0f) ? 0.0f : g;
+    float g = pass_action.colors[0].value.g + 0.01f;
+    pass_action.colors[0].value.g = (g > 1.0f) ? 0.0f : g;
     sg_begin_default_pass(&pass_action, sapp_width(), sapp_height());
     sg_end_pass();
     sg_commit();
@@ -218,7 +217,7 @@ sapp_desc sokol_main(int argc, char* argv[]) {
         .cleanup_cb = cleanup,
         .width = 400,
         .height = 300,
-        .window_title = "Clear (sokol app)",
+        .window_title = "Clear Sample",
     };
 }
 ```
@@ -240,7 +239,7 @@ A minimal audio-streaming API:
 
 A simple mono square-wave generator using the callback model:
 
-```cpp
+```c
 // the sample callback, running in audio thread
 static void stream_cb(float* buffer, int num_frames, int num_channels) {
     assert(1 == num_channels);
@@ -266,7 +265,7 @@ int main() {
 
 The same code using the push-model
 
-```cpp
+```c
 #define BUF_SIZE (32)
 int main() {
     // init sokol-audio with default params, no callback

+ 11 - 11
bindgen/gen_all.py

@@ -1,19 +1,19 @@
-import gen_ir, gen_zig
+import os, gen_zig
 
 tasks = [
-    [ '../sokol_gfx.h', 'sg_', 'gfx' ],
-    [ '../sokol_app.h', 'sapp_', 'app' ],
-    [ '../sokol_time.h', 'stm_', 'time' ],
-    [ '../sokol_audio.h', 'saudio_', 'audio' ]
+    [ '../sokol_gfx.h',            'sg_',       [] ],
+    [ '../sokol_app.h',            'sapp_',     [] ],
+    [ '../sokol_time.h',           'stm_',      [] ],
+    [ '../sokol_audio.h',          'saudio_',   [] ],
+    [ '../util/sokol_gl.h',        'sgl_',      ['sg_'] ],
+    [ '../util/sokol_debugtext.h', 'sdtx_',     ['sg_'] ],
+    [ '../util/sokol_shape.h',     'sshape_',   ['sg_'] ],
 ]
 
 # Zig
-print('> generating Zig bindings...')
 gen_zig.prepare()
 for task in tasks:
     c_header_path = task[0]
-    c_prefix = task[1]
-    module_name = task[2]
-    print(f'  {c_header_path} => {module_name}.zig')
-    ir = gen_ir.gen(c_header_path, module_name, c_prefix, ["-DSOKOL_ZIG_BINDINGS"])
-    gen_zig.gen(c_header_path, ir)
+    main_prefix = task[1]
+    dep_prefixes = task[2]
+    gen_zig.gen(c_header_path, main_prefix, dep_prefixes)

+ 25 - 9
bindgen/gen_ir.py

@@ -12,6 +12,18 @@ def is_api_decl(decl, prefix):
     else:
         return False
 
+def is_dep_decl(decl, dep_prefixes):
+    for prefix in dep_prefixes:
+        if is_api_decl(decl, prefix):
+            return True
+    return False
+
+def dep_prefix(decl, dep_prefixes):
+    for prefix in dep_prefixes:
+        if is_api_decl(decl, prefix):
+            return prefix
+    return None
+
 def filter_types(str):
     return str.replace('_Bool', 'bool')
 
@@ -67,7 +79,8 @@ def parse_func(decl):
     if 'inner' in decl:
         for param in decl['inner']:
             if param['kind'] != 'ParmVarDecl':
-                sys.exit(f"ERROR: func param kind must be 'ParmVarDecl' ({decl['name']})")
+                print(f"warning: ignoring func {decl['name']} (unsupported parameter type)")
+                return None
             outp_param = {}
             outp_param['name'] = param['name']
             outp_param['type'] = filter_types(param['type']['qualType'])
@@ -85,22 +98,25 @@ def parse_decl(decl):
     else:
         return None
 
-def clang(header_path, additional_options):
-    cmd = ['clang', '-Xclang', '-ast-dump=json' ]
-    cmd.extend(additional_options)
-    cmd.append(header_path)
+def clang(csrc_path):
+    cmd = ['clang', '-Xclang', '-ast-dump=json', '-c' ]
+    cmd.append(csrc_path)
     return subprocess.check_output(cmd)
 
-def gen(header_path, module, prefix, clang_options):
-    ast = clang(header_path, clang_options)
+def gen(header_path, source_path, module, main_prefix, dep_prefixes):
+    ast = clang(source_path)
     inp = json.loads(ast)
     outp = {}
     outp['module'] = module
-    outp['prefix'] = prefix
+    outp['prefix'] = main_prefix
+    outp['dep_prefixes'] = dep_prefixes
     outp['decls'] = []
     for decl in inp['inner']:
-        if is_api_decl(decl, prefix):
+        is_dep = is_dep_decl(decl, dep_prefixes)
+        if is_api_decl(decl, main_prefix) or is_dep:
             outp_decl = parse_decl(decl)
             if outp_decl is not None:
+                outp_decl['is_dep'] = is_dep
+                outp_decl['dep_prefix'] = dep_prefix(decl, dep_prefixes)
                 outp['decls'].append(outp_decl)
     return outp

+ 210 - 82
bindgen/gen_zig.py

@@ -6,29 +6,49 @@
 #   - functions are camelCase
 #   - otherwise snake_case
 #-------------------------------------------------------------------------------
+import gen_ir
 import json, re, os, shutil
 
-struct_types = []
-enum_types = []
-enum_items = {}
-out_lines = ''
+module_names = {
+    'sg_':      'gfx',
+    'sapp_':    'app',
+    'stm_':     'time',
+    'saudio_':  'audio',
+    'sgl_':     'gl',
+    'sdtx_':    'debugtext',
+    'sshape_':  'shape',
+}
 
-def reset_globals():
-    global struct_types
-    global enum_types
-    global enum_items
-    global out_lines
-    struct_types = []
-    enum_types = []
-    enum_items = {}
-    out_lines = ''
+c_source_paths = {
+    'sg_':      'sokol-zig/src/sokol/c/sokol_app_gfx.c',
+    'sapp_':    'sokol-zig/src/sokol/c/sokol_app_gfx.c',
+    'stm_':     'sokol-zig/src/sokol/c/sokol_time.c',
+    'saudio_':  'sokol-zig/src/sokol/c/sokol_audio.c',
+    'sgl_':     'sokol-zig/src/sokol/c/sokol_gl.c',
+    'sdtx_':    'sokol-zig/src/sokol/c/sokol_debugtext.c',
+    'sshape_':  'sokol-zig/src/sokol/c/sokol_shape.c',
+}
 
-re_1d_array = re.compile("^(?:const )?\w*\s\*?\[\d*\]$")
-re_2d_array = re.compile("^(?:const )?\w*\s\*?\[\d*\]\[\d*\]$")
+func_name_ignores = [
+    'sdtx_printf',
+    'sdtx_vprintf',
+]
+
+func_name_overrides = {
+    'sgl_error': 'sgl_get_error',   # 'error' is reserved in Zig
+    'sgl_deg': 'sgl_as_degrees',
+    'sgl_rad': 'sgl_as_radians'
+}
+
+struct_field_type_overrides = {
+    'sg_context_desc.color_format': 'int',
+    'sg_context_desc.depth_format': 'int',
+}
 
 prim_types = {
     'int':          'i32',
     'bool':         'bool',
+    'char':         'u8',
     'int8_t':       'i8',
     'uint8_t':      'u8',
     'int16_t':      'i16',
@@ -40,7 +60,8 @@ prim_types = {
     'float':        'f32',
     'double':       'f64',
     'uintptr_t':    'usize',
-    'intptr_t':     'isize'
+    'intptr_t':     'isize',
+    'size_t':       'usize'
 }
 
 prim_defaults = {
@@ -57,13 +78,27 @@ prim_defaults = {
     'float':        '0.0',
     'double':       '0.0',
     'uintptr_t':    '0',
-    'intptr_t':     '0'
+    'intptr_t':     '0',
+    'size_t':       '0'
 }
 
-struct_field_type_overrides = {
-    'sg_context_desc.color_format': 'int',
-    'sg_context_desc.depth_format': 'int',
-}
+struct_types = []
+enum_types = []
+enum_items = {}
+out_lines = ''
+
+def reset_globals():
+    global struct_types
+    global enum_types
+    global enum_items
+    global out_lines
+    struct_types = []
+    enum_types = []
+    enum_items = {}
+    out_lines = ''
+
+re_1d_array = re.compile("^(?:const )?\w*\s\*?\[\d*\]$")
+re_2d_array = re.compile("^(?:const )?\w*\s\*?\[\d*\]\[\d*\]$")
 
 def l(s):
     global out_lines
@@ -72,6 +107,24 @@ def l(s):
 def as_zig_prim_type(s):
     return prim_types[s]
 
+# prefix_bla_blub(_t) => (dep.)BlaBlub
+def as_zig_struct_type(s, prefix):
+    parts = s.lower().split('_')
+    outp = '' if s.startswith(prefix) else f'{parts[0]}.'
+    for part in parts[1:]:
+        if (part != 't'):
+            outp += part.capitalize()
+    return outp
+
+# prefix_bla_blub(_t) => (dep.)BlaBlub
+def as_zig_enum_type(s, prefix):
+    parts = s.lower().split('_')
+    outp = '' if s.startswith(prefix) else f'{parts[0]}.'
+    for part in parts[1:]:
+        if (part != 't'):
+            outp += part.capitalize()
+    return outp
+
 def check_struct_field_type_override(struct_name, field_name, orig_type):
     s = f"{struct_name}.{field_name}"
     if s in struct_field_type_overrides:
@@ -79,6 +132,15 @@ def check_struct_field_type_override(struct_name, field_name, orig_type):
     else:
         return orig_type
 
+def check_func_name_ignore(func_name):
+    return func_name in func_name_ignores
+
+def check_func_name_override(func_name):
+    if func_name in func_name_overrides:
+        return func_name_overrides[func_name]
+    else:
+        return func_name
+
 # PREFIX_BLA_BLUB to bla_blub
 def as_snake_case(s, prefix):
     outp = s.lower()
@@ -86,14 +148,6 @@ def as_snake_case(s, prefix):
         outp = outp[len(prefix):]
     return outp
 
-# prefix_bla_blub => BlaBlub
-def as_title_case(s):
-    parts = s.lower().split('_')[1:]
-    outp = ''
-    for part in parts:
-        outp += part.capitalize()
-    return outp
-
 # prefix_bla_blub => blaBlub
 def as_camel_case(s):
     parts = s.lower().split('_')[1:]
@@ -177,15 +231,15 @@ def extract_ptr_type(s):
     else:
         return tokens[0]
 
-def as_extern_c_arg_type(arg_type):
+def as_extern_c_arg_type(arg_type, prefix):
     if arg_type == "void":
         return "void"
     elif is_prim_type(arg_type):
         return as_zig_prim_type(arg_type)
     elif is_struct_type(arg_type):
-        return as_title_case(arg_type)
+        return as_zig_struct_type(arg_type, prefix)
     elif is_enum_type(arg_type):
-        return as_title_case(arg_type)
+        return as_zig_enum_type(arg_type, prefix)
     elif is_void_ptr(arg_type):
         return "?*c_void"
     elif is_const_void_ptr(arg_type):
@@ -193,7 +247,7 @@ def as_extern_c_arg_type(arg_type):
     elif is_string_ptr(arg_type):
         return "[*c]const u8"
     elif is_const_struct_ptr(arg_type):
-        return f"[*c]const {as_title_case(extract_ptr_type(arg_type))}"
+        return f"[*c]const {as_zig_struct_type(extract_ptr_type(arg_type), prefix)}"
     elif is_prim_ptr(arg_type):
         return f"[*c] {as_zig_prim_type(extract_ptr_type(arg_type))}"
     elif is_const_prim_ptr(arg_type):
@@ -201,7 +255,7 @@ def as_extern_c_arg_type(arg_type):
     else:
         return '??? (as_extern_c_arg_type)'
 
-def as_zig_arg_type(arg_prefix, arg_type):
+def as_zig_arg_type(arg_prefix, arg_type, prefix):
     # NOTE: if arg_prefix is None, the result is used as return value
     pre = "" if arg_prefix is None else arg_prefix
     if arg_type == "void":
@@ -212,18 +266,18 @@ def as_zig_arg_type(arg_prefix, arg_type):
     elif is_prim_type(arg_type):
         return pre + as_zig_prim_type(arg_type)
     elif is_struct_type(arg_type):
-        return pre + as_title_case(arg_type)
+        return pre + as_zig_struct_type(arg_type, prefix)
     elif is_enum_type(arg_type):
-        return pre + as_title_case(arg_type)
+        return pre + as_zig_enum_type(arg_type, prefix)
     elif is_void_ptr(arg_type):
         return pre + "?*c_void"
     elif is_const_void_ptr(arg_type):
         return pre + "?*const c_void"
     elif is_string_ptr(arg_type):
-        return pre + "[]const u8"
+        return pre + "[:0]const u8"
     elif is_const_struct_ptr(arg_type):
         # not a bug, pass const structs by value
-        return pre + f"{as_title_case(extract_ptr_type(arg_type))}"
+        return pre + f"{as_zig_struct_type(extract_ptr_type(arg_type), prefix)}"
     elif is_prim_ptr(arg_type):
         return pre + f"* {as_zig_prim_type(extract_ptr_type(arg_type))}"
     elif is_const_prim_ptr(arg_type):
@@ -232,14 +286,14 @@ def as_zig_arg_type(arg_prefix, arg_type):
         return arg_prefix + "??? (as_zig_arg_type)"
 
 # get C-style arguments of a function pointer as string
-def funcptr_args_c(field_type):
+def funcptr_args_c(field_type, prefix):
     tokens = field_type[field_type.index('(*)')+4:-1].split(',')
     s = ""
     for token in tokens:
-        arg_type = token.strip();
+        arg_type = token.strip()
         if s != "":
             s += ", "
-        c_arg = as_extern_c_arg_type(arg_type)
+        c_arg = as_extern_c_arg_type(arg_type, prefix)
         if (c_arg == "void"):
             return ""
         else:
@@ -256,43 +310,42 @@ def funcptr_res_c(field_type):
     else:
         return '???'
 
-def funcdecl_args_c(decl):
+def funcdecl_args_c(decl, prefix):
     s = ""
     for param_decl in decl['params']:
         if s != "":
             s += ", "
         arg_type = param_decl['type']
-        s += as_extern_c_arg_type(arg_type)
+        s += as_extern_c_arg_type(arg_type, prefix)
     return s
 
-def funcdecl_args_zig(decl):
+def funcdecl_args_zig(decl, prefix):
     s = ""
     for param_decl in decl['params']:
         if s != "":
             s += ", "
         arg_name = param_decl['name']
         arg_type = param_decl['type']
-        s += f"{as_zig_arg_type(f'{arg_name}: ', arg_type)}"
+        s += f"{as_zig_arg_type(f'{arg_name}: ', arg_type, prefix)}"
     return s
 
-def funcdecl_res_c(decl):
+def funcdecl_res_c(decl, prefix):
     decl_type = decl['type']
     res_type = decl_type[:decl_type.index('(')].strip()
-    return as_extern_c_arg_type(res_type)
+    return as_extern_c_arg_type(res_type, prefix)
 
-def funcdecl_res_zig(decl):
+def funcdecl_res_zig(decl, prefix):
     decl_type = decl['type']
     res_type = decl_type[:decl_type.index('(')].strip()
-    zig_res_type = as_zig_arg_type(None, res_type)
+    zig_res_type = as_zig_arg_type(None, res_type, prefix)
     if zig_res_type == "":
         zig_res_type = "void"
     return zig_res_type
 
 def gen_struct(decl, prefix, callconvc_funcptrs = True, use_raw_name=False, use_extern=True):
     struct_name = decl['name']
-    zig_type = struct_name if use_raw_name else as_title_case(struct_name)
+    zig_type = struct_name if use_raw_name else as_zig_struct_type(struct_name, prefix)
     l(f"pub const {zig_type} = {'extern ' if use_extern else ''}struct {{")
-    #l(f"    pub fn init(options: anytype) {zig_type} {{ var item: {zig_type} = .{{ }}; init_with(&item, options); return item; }}")
     for field in decl['fields']:
         field_name = field['name']
         field_type = field['type']
@@ -300,9 +353,9 @@ def gen_struct(decl, prefix, callconvc_funcptrs = True, use_raw_name=False, use_
         if is_prim_type(field_type):
             l(f"    {field_name}: {as_zig_prim_type(field_type)} = {type_default_value(field_type)},")
         elif is_struct_type(field_type):
-            l(f"    {field_name}: {as_title_case(field_type)} = .{{ }},")
+            l(f"    {field_name}: {as_zig_struct_type(field_type, prefix)} = .{{ }},")
         elif is_enum_type(field_type):
-            l(f"    {field_name}: {as_title_case(field_type)} = .{enum_default_item(field_type)},")
+            l(f"    {field_name}: {as_zig_enum_type(field_type, prefix)} = .{enum_default_item(field_type)},")
         elif is_string_ptr(field_type):
             l(f"    {field_name}: [*c]const u8 = null,")
         elif is_const_void_ptr(field_type):
@@ -313,9 +366,9 @@ def gen_struct(decl, prefix, callconvc_funcptrs = True, use_raw_name=False, use_
             l(f"    {field_name}: ?[*]const {as_zig_prim_type(extract_ptr_type(field_type))} = null,")
         elif is_func_ptr(field_type):
             if callconvc_funcptrs:
-                l(f"    {field_name}: ?fn({funcptr_args_c(field_type)}) callconv(.C) {funcptr_res_c(field_type)} = null,")
+                l(f"    {field_name}: ?fn({funcptr_args_c(field_type, prefix)}) callconv(.C) {funcptr_res_c(field_type)} = null,")
             else:
-                l(f"    {field_name}: ?fn({funcptr_args_c(field_type)}) {funcptr_res_c(field_type)} = null,")
+                l(f"    {field_name}: ?fn({funcptr_args_c(field_type, prefix)}) {funcptr_res_c(field_type)} = null,")
         elif is_1d_array_type(field_type):
             array_type = extract_array_type(field_type)
             array_nums = extract_array_nums(field_type)
@@ -323,9 +376,15 @@ def gen_struct(decl, prefix, callconvc_funcptrs = True, use_raw_name=False, use_
                 if is_prim_type(array_type):
                     zig_type = as_zig_prim_type(array_type)
                     def_val = type_default_value(array_type)
+                elif is_struct_type(array_type):
+                    zig_type = as_zig_struct_type(array_type, prefix)
+                    def_val = '.{}'
+                elif is_enum_type(array_type):
+                    zig_type = as_zig_enum_type(array_type, prefix)
+                    def_val = '.{}'
                 else:
-                    zig_type = as_title_case(array_type)
-                    def_val = ".{}"
+                    zig_type = '??? (array type)'
+                    def_val = '???'
                 t0 = f"[{array_nums[0]}]{zig_type}"
                 t0_slice = f"[]const {zig_type}"
                 t1 = f"[_]{zig_type}"
@@ -338,11 +397,16 @@ def gen_struct(decl, prefix, callconvc_funcptrs = True, use_raw_name=False, use_
             array_type = extract_array_type(field_type)
             array_nums = extract_array_nums(field_type)
             if is_prim_type(array_type):
-                l(f"// FIXME: 2D array with primitive type: {field_name}")
+                zig_type = as_zig_prim_type(array_type)
+                def_val = type_default_value(array_type)
             elif is_struct_type(array_type):
-                zig_type = as_title_case(array_type)
-                t0 = f"[{array_nums[0]}][{array_nums[1]}]{zig_type}"
-                l(f"    {field_name}: {t0} = [_][{array_nums[1]}]{zig_type}{{[_]{zig_type}{{ .{{ }} }}**{array_nums[1]}}}**{array_nums[0]},")
+                zig_type = as_zig_struct_type(array_type, prefix)
+                def_val = ".{ }"
+            else:
+                zig_type = "???"
+                def_val = "???"
+            t0 = f"[{array_nums[0]}][{array_nums[1]}]{zig_type}"
+            l(f"    {field_name}: {t0} = [_][{array_nums[1]}]{zig_type}{{[_]{zig_type}{{ {def_val} }}**{array_nums[1]}}}**{array_nums[0]},")
         else:
             l(f"// FIXME: {field_name}: {field_type};")
     l("};")
@@ -352,7 +416,7 @@ def gen_consts(decl, prefix):
         l(f"pub const {as_snake_case(item['name'], prefix)} = {item['value']};")
 
 def gen_enum(decl, prefix):
-    l(f"pub const {as_title_case(decl['name'])} = extern enum(i32) {{")
+    l(f"pub const {as_zig_enum_type(decl['name'], prefix)} = extern enum(i32) {{")
     for item in decl['items']:
         item_name = as_enum_item_name(item['name'])
         if item_name != "FORCE_U32":
@@ -363,13 +427,13 @@ def gen_enum(decl, prefix):
     l("};")
 
 def gen_func_c(decl, prefix):
-    l(f"pub extern fn {decl['name']}({funcdecl_args_c(decl)}) {funcdecl_res_c(decl)};")
+    l(f"pub extern fn {decl['name']}({funcdecl_args_c(decl, prefix)}) {funcdecl_res_c(decl, prefix)};")
 
 def gen_func_zig(decl, prefix):
     c_func_name = decl['name']
-    zig_func_name = as_camel_case(decl['name'])
-    zig_res_type = funcdecl_res_zig(decl)
-    l(f"pub fn {zig_func_name}({funcdecl_args_zig(decl)}) {funcdecl_res_zig(decl)} {{")
+    zig_func_name = as_camel_case(check_func_name_override(decl['name']))
+    zig_res_type = funcdecl_res_zig(decl, prefix)
+    l(f"pub inline fn {zig_func_name}({funcdecl_args_zig(decl, prefix)}) {funcdecl_res_zig(decl, prefix)} {{")
     if zig_res_type != 'void':
         s = f"    return {c_func_name}("
     else:
@@ -380,7 +444,9 @@ def gen_func_zig(decl, prefix):
         arg_name = param_decl['name']
         arg_type = param_decl['type']
         if is_const_struct_ptr(arg_type):
-            s += "&" + arg_name
+            s += f"&{arg_name}"
+        elif is_string_ptr(arg_type):
+            s += f"@ptrCast([*c]const u8,{arg_name})"
         else:
             s += arg_name
     s += ");"
@@ -401,31 +467,93 @@ def pre_parse(inp):
             for item in decl['items']:
                 enum_items[enum_name].append(as_enum_item_name(item['name']))
 
-def gen_module(inp):
+def gen_imports(inp, dep_prefixes):
+    for dep_prefix in dep_prefixes:
+        dep_module_name = module_names[dep_prefix]
+        l(f'const {dep_prefix[:-1]} = @import("{dep_module_name}.zig");')
+        l('')
+
+def gen_helpers(inp):
+    if inp['prefix'] in ['sg_', 'sdtx_', 'sshape_']:
+        l('// helper function to convert "anything" to a Range struct')
+        l('pub fn asRange(val: anytype) Range {')
+        l('    const type_info = @typeInfo(@TypeOf(val));')
+        l('    switch (type_info) {')
+        l('        .Pointer => {')
+        l('            switch (type_info.Pointer.size) {')
+        l('                .One => return .{ .ptr = val, .size = @sizeOf(type_info.Pointer.child) },')
+        l('                .Slice => return .{ .ptr = val.ptr, .size = @sizeOf(type_info.Pointer.child) * val.len },')
+        l('                else => @compileError("FIXME: Pointer type!"),')
+        l('            }')
+        l('        },')
+        l('        .Struct, .Array => {')
+        l('            return .{ .ptr = &val, .size = @sizeOf(@TypeOf(val)) };')
+        l('        },')
+        l('        else => {')
+        l('            @compileError("Cannot convert to range!");')
+        l('        }')
+        l('    }')
+        l('}')
+        l('')
+    if inp['prefix'] == 'sdtx_':
+        l('// std.fmt compatible Writer')
+        l('pub const Writer = struct {')
+        l('    pub const Error = error { };')
+        l('    pub fn writeAll(self: Writer, bytes: []const u8) Error!void {')
+        l('        for (bytes) |byte| {')
+        l('            putc(byte);')
+        l('        }')
+        l('    }')
+        l('    pub fn writeByteNTimes(self: Writer, byte: u8, n: u64) Error!void {')
+        l('        var i: u64 = 0;')
+        l('        while (i < n): (i += 1) {')
+        l('            putc(byte);')
+        l('        }')
+        l('    }')
+        l('};')
+        l('// std.fmt-style formatted print')
+        l('pub fn print(comptime fmt: anytype, args: anytype) void {')
+        l('    var writer: Writer = .{};')
+        l('    @import("std").fmt.format(writer, fmt, args) catch {};')
+        l('}')
+        l('')
+
+def gen_module(inp, dep_prefixes):
     l('// machine generated, do not edit')
     l('')
+    gen_imports(inp, dep_prefixes)
+    gen_helpers(inp)
     pre_parse(inp)
     prefix = inp['prefix']
     for decl in inp['decls']:
-        kind = decl['kind']
-        if kind == 'struct':
-            gen_struct(decl, prefix)
-        elif kind == 'consts':
-            gen_consts(decl, prefix)
-        elif kind == 'enum':
-            gen_enum(decl, prefix)
-        elif kind == 'func':
-            gen_func_c(decl, prefix)
-            gen_func_zig(decl, prefix)
+        if not decl['is_dep']:
+            kind = decl['kind']
+            if kind == 'struct':
+                gen_struct(decl, prefix)
+            elif kind == 'consts':
+                gen_consts(decl, prefix)
+            elif kind == 'enum':
+                gen_enum(decl, prefix)
+            elif kind == 'func':
+                if not check_func_name_ignore(decl['name']):
+                    gen_func_c(decl, prefix)
+                    gen_func_zig(decl, prefix)
 
 def prepare():
+    print('Generating zig bindings:')
     if not os.path.isdir('sokol-zig/src/sokol'):
         os.makedirs('sokol-zig/src/sokol')
+    if not os.path.isdir('sokol-zig/src/sokol/c'):
+        os.makedirs('sokol-zig/src/sokol/c')
 
-def gen(c_header_path, input_ir):
+def gen(c_header_path, c_prefix, dep_c_prefixes):
+    module_name = module_names[c_prefix]
+    c_source_path = c_source_paths[c_prefix]
+    print(f'  {c_header_path} => {module_name}')
     reset_globals()
-    gen_module(input_ir)
-    shutil.copyfile(c_header_path, f'sokol-zig/src/sokol/{os.path.basename(c_header_path)}')
-    output_path = f"sokol-zig/src/sokol/{input_ir['module']}.zig"
+    shutil.copyfile(c_header_path, f'sokol-zig/src/sokol/c/{os.path.basename(c_header_path)}')
+    ir = gen_ir.gen(c_header_path, c_source_path, module_name, c_prefix, dep_c_prefixes)
+    gen_module(ir, dep_c_prefixes)
+    output_path = f"sokol-zig/src/sokol/{ir['module']}.zig"
     with open(output_path, 'w', newline='\n') as f_outp:
         f_outp.write(out_lines)

+ 89 - 64
sokol_app.h

@@ -250,6 +250,13 @@
             this may change from one frame to the next, and it may be different
             from the initial size provided in the sapp_desc struct.
 
+        float sapp_widthf(void)
+        float sapp_heightf(void)
+            These are alternatives to sapp_width() and sapp_height() which return
+            the default framebuffer size as float values instead of integer. This
+            may help to prevent casting back and forth between int and float
+            in more strongly typed languages than C and C++.
+
         int sapp_color_format(void)
         int sapp_depth_format(void)
             The color and depth-stencil pixelformats of the default framebuffer,
@@ -340,6 +347,7 @@
             - the application was suspended or restored (on mobile platforms)
             - the user or application code has asked to quit the application
             - a string was pasted to the system clipboard
+            - one or more files have been dropped onto the application window
 
         To explicitly 'consume' an event and prevent that the event is
         forwarded for further handling to the operating system, call
@@ -1155,8 +1163,12 @@ extern sapp_desc sokol_main(int argc, char* argv[]);
 SOKOL_APP_API_DECL bool sapp_isvalid(void);
 /* returns the current framebuffer width in pixels */
 SOKOL_APP_API_DECL int sapp_width(void);
+/* same as sapp_width(), but returns float */
+SOKOL_APP_API_DECL float sapp_widthf(void);
 /* returns the current framebuffer height in pixels */
 SOKOL_APP_API_DECL int sapp_height(void);
+/* same as sapp_height(), but returns float */
+SOKOL_APP_API_DECL float sapp_heightf(void);
 /* get default framebuffer color pixel format */
 SOKOL_APP_API_DECL int sapp_color_format(void);
 /* get default framebuffer depth pixel format */
@@ -1277,7 +1289,8 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); }
 #ifdef SOKOL_APP_IMPL
 #define SOKOL_APP_IMPL_INCLUDED (1)
 
-#include <string.h> /* memset */
+#include <string.h> // memset
+#include <stddef.h> // size_t
 
 /* check if the config defines are alright */
 #if defined(__APPLE__)
@@ -2355,6 +2368,7 @@ typedef int  GLint;
     _SAPP_XMACRO(glUniform1i,                       void, (GLint location, GLint v0)) \
     _SAPP_XMACRO(glDisable,                         void, (GLenum cap)) \
     _SAPP_XMACRO(glColorMask,                       void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) \
+    _SAPP_XMACRO(glColorMaski,                      void, (GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) \
     _SAPP_XMACRO(glBindBuffer,                      void, (GLenum target, GLuint buffer)) \
     _SAPP_XMACRO(glDeleteVertexArrays,              void, (GLsizei n, const GLuint * arrays)) \
     _SAPP_XMACRO(glDepthMask,                       void, (GLboolean flag)) \
@@ -2555,14 +2569,14 @@ _SOKOL_PRIVATE void _sapp_init_state(const sapp_desc* desc) {
     _sapp.clipboard.enabled = _sapp.desc.enable_clipboard;
     if (_sapp.clipboard.enabled) {
         _sapp.clipboard.buf_size = _sapp.desc.clipboard_size;
-        _sapp.clipboard.buffer = (char*) SOKOL_CALLOC(1, _sapp.clipboard.buf_size);
+        _sapp.clipboard.buffer = (char*) SOKOL_CALLOC(1, (size_t)_sapp.clipboard.buf_size);
     }
     _sapp.drop.enabled = _sapp.desc.enable_dragndrop;
     if (_sapp.drop.enabled) {
         _sapp.drop.max_files = _sapp.desc.max_dropped_files;
         _sapp.drop.max_path_length = _sapp.desc.max_dropped_file_path_length;
         _sapp.drop.buf_size = _sapp.drop.max_files * _sapp.drop.max_path_length;
-        _sapp.drop.buffer = (char*) SOKOL_CALLOC(1, _sapp.drop.buf_size);
+        _sapp.drop.buffer = (char*) SOKOL_CALLOC(1, (size_t)_sapp.drop.buf_size);
     }
     _sapp_strcpy(_sapp.desc.window_title, _sapp.window_title, sizeof(_sapp.window_title));
     _sapp.desc.window_title = _sapp.window_title;
@@ -2615,7 +2629,7 @@ _SOKOL_PRIVATE sapp_keycode _sapp_translate_key(int scan_code) {
 _SOKOL_PRIVATE void _sapp_clear_drop_buffer(void) {
     if (_sapp.drop.enabled) {
         SOKOL_ASSERT(_sapp.drop.buffer);
-        memset(_sapp.drop.buffer, 0, _sapp.drop.buf_size);
+        memset(_sapp.drop.buffer, 0, (size_t)_sapp.drop.buf_size);
     }
 }
 
@@ -3009,7 +3023,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
         _sapp.macos.view.device = _sapp.macos.mtl_device;
         _sapp.macos.view.colorPixelFormat = MTLPixelFormatBGRA8Unorm;
         _sapp.macos.view.depthStencilPixelFormat = MTLPixelFormatDepth32Float_Stencil8;
-        _sapp.macos.view.sampleCount = _sapp.sample_count;
+        _sapp.macos.view.sampleCount = (NSUInteger) _sapp.sample_count;
         _sapp.macos.view.autoResizeDrawable = false;
         _sapp.macos.window.contentView = _sapp.macos.view;
         [_sapp.macos.window makeFirstResponder:_sapp.macos.view];
@@ -3027,7 +3041,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
         if (_sapp.sample_count > 1) {
             attrs[i++] = NSOpenGLPFAMultisample;
             attrs[i++] = NSOpenGLPFASampleBuffers; attrs[i++] = 1;
-            attrs[i++] = NSOpenGLPFASamples; attrs[i++] = _sapp.sample_count;
+            attrs[i++] = NSOpenGLPFASamples; attrs[i++] = (NSOpenGLPixelFormatAttribute)_sapp.sample_count;
         }
         else {
             attrs[i++] = NSOpenGLPFASampleBuffers; attrs[i++] = 0;
@@ -3162,7 +3176,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
         _sapp.drop.num_files = ((int)pboard.pasteboardItems.count > _sapp.drop.max_files) ? _sapp.drop.max_files : pboard.pasteboardItems.count;
         bool drop_failed = false;
         for (int i = 0; i < _sapp.drop.num_files; i++) {
-            NSURL *fileUrl = [NSURL fileURLWithPath:[pboard.pasteboardItems[i] stringForType:NSPasteboardTypeFileURL]];
+            NSURL *fileUrl = [NSURL fileURLWithPath:[pboard.pasteboardItems[(NSUInteger)i] stringForType:NSPasteboardTypeFileURL]];
             if (!_sapp_strcpy(fileUrl.standardizedURL.path.UTF8String, _sapp_dropped_file_path_ptr(i), _sapp.drop.max_path_length)) {
                 SOKOL_LOG("sokol_app.h: dropped file path too long (sapp_desc.max_dropped_file_path_length)\n");
                 drop_failed = true;
@@ -4297,7 +4311,7 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_key_cb(int emsc_type, const EmscriptenKeyboard
                 }
             }
             else {
-                _sapp.event.key_code = _sapp_translate_key(emsc_event->keyCode);
+                _sapp.event.key_code = _sapp_translate_key((int)emsc_event->keyCode);
                 /* Special hack for macOS: if the Super key is pressed, macOS doesn't
                     send keyUp events. As a workaround, to prevent keys from
                     "sticking", we'll send a keyup event following a keydown
@@ -4436,7 +4450,7 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_touch_cb(int emsc_type, const EmscriptenTouchE
             for (int i = 0; i < _sapp.event.num_touches; i++) {
                 const EmscriptenTouchPoint* src = &emsc_event->touches[i];
                 sapp_touchpoint* dst = &_sapp.event.touches[i];
-                dst->identifier = src->identifier;
+                dst->identifier = (uintptr_t)src->identifier;
                 dst->pos_x = src->targetX * _sapp.dpi_scale;
                 dst->pos_y = src->targetY * _sapp.dpi_scale;
                 dst->changed = src->isChanged;
@@ -4888,14 +4902,13 @@ _SOKOL_PRIVATE void _sapp_gl_init_fbconfig(_sapp_gl_fbconfig* fbconfig) {
     fbconfig->samples = -1;
 }
 
-_SOKOL_PRIVATE const _sapp_gl_fbconfig* _sapp_gl_choose_fbconfig(const _sapp_gl_fbconfig* desired, const _sapp_gl_fbconfig* alternatives, unsigned int count) {
-    unsigned int i;
-    unsigned int missing, least_missing = 1000000;
-    unsigned int color_diff, least_color_diff = 10000000;
-    unsigned int extra_diff, least_extra_diff = 10000000;
+_SOKOL_PRIVATE const _sapp_gl_fbconfig* _sapp_gl_choose_fbconfig(const _sapp_gl_fbconfig* desired, const _sapp_gl_fbconfig* alternatives, int count) {
+    int missing, least_missing = 1000000;
+    int color_diff, least_color_diff = 10000000;
+    int extra_diff, least_extra_diff = 10000000;
     const _sapp_gl_fbconfig* current;
-    const _sapp_gl_fbconfig* closest = NULL;
-    for (i = 0;  i < count;  i++) {
+    const _sapp_gl_fbconfig* closest = 0;
+    for (int i = 0;  i < count;  i++) {
         current = alternatives + i;
         if (desired->doublebuffer != current->doublebuffer) {
             continue;
@@ -4976,8 +4989,8 @@ _SOKOL_PRIVATE const _sapp_gl_fbconfig* _sapp_gl_choose_fbconfig(const _sapp_gl_
 #if defined(_SAPP_WIN32) || defined(_SAPP_UWP)
 _SOKOL_PRIVATE bool _sapp_win32_uwp_utf8_to_wide(const char* src, wchar_t* dst, int dst_num_bytes) {
     SOKOL_ASSERT(src && dst && (dst_num_bytes > 1));
-    memset(dst, 0, dst_num_bytes);
-    const int dst_chars = dst_num_bytes / sizeof(wchar_t);
+    memset(dst, 0, (size_t)dst_num_bytes);
+    const int dst_chars = dst_num_bytes / (int)sizeof(wchar_t);
     const int dst_needed = MultiByteToWideChar(CP_UTF8, 0, src, -1, 0, 0);
     if ((dst_needed > 0) && (dst_needed < dst_chars)) {
         MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, dst_chars);
@@ -5190,8 +5203,8 @@ static inline HRESULT _sapp_dxgi_Present(IDXGISwapChain* self, UINT SyncInterval
 
 _SOKOL_PRIVATE void _sapp_d3d11_create_device_and_swapchain(void) {
     DXGI_SWAP_CHAIN_DESC* sc_desc = &_sapp.d3d11.swap_chain_desc;
-    sc_desc->BufferDesc.Width = _sapp.framebuffer_width;
-    sc_desc->BufferDesc.Height = _sapp.framebuffer_height;
+    sc_desc->BufferDesc.Width = (UINT)_sapp.framebuffer_width;
+    sc_desc->BufferDesc.Height = (UINT)_sapp.framebuffer_height;
     sc_desc->BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
     sc_desc->BufferDesc.RefreshRate.Numerator = 60;
     sc_desc->BufferDesc.RefreshRate.Denominator = 1;
@@ -5208,7 +5221,7 @@ _SOKOL_PRIVATE void _sapp_d3d11_create_device_and_swapchain(void) {
     sc_desc->SampleDesc.Count = 1;
     sc_desc->SampleDesc.Quality = 0;
     sc_desc->BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
-    int create_flags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+    UINT create_flags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
     #if defined(SOKOL_DEBUG)
         create_flags |= D3D11_CREATE_DEVICE_DEBUG;
     #endif
@@ -5259,14 +5272,14 @@ _SOKOL_PRIVATE void _sapp_d3d11_create_default_render_target(void) {
     /* common desc for MSAA and depth-stencil texture */
     D3D11_TEXTURE2D_DESC tex_desc;
     memset(&tex_desc, 0, sizeof(tex_desc));
-    tex_desc.Width = _sapp.framebuffer_width;
-    tex_desc.Height = _sapp.framebuffer_height;
+    tex_desc.Width = (UINT)_sapp.framebuffer_width;
+    tex_desc.Height = (UINT)_sapp.framebuffer_height;
     tex_desc.MipLevels = 1;
     tex_desc.ArraySize = 1;
     tex_desc.Usage = D3D11_USAGE_DEFAULT;
     tex_desc.BindFlags = D3D11_BIND_RENDER_TARGET;
-    tex_desc.SampleDesc.Count = _sapp.sample_count;
-    tex_desc.SampleDesc.Quality = _sapp.sample_count > 1 ? D3D11_STANDARD_MULTISAMPLE_PATTERN : 0;
+    tex_desc.SampleDesc.Count = (UINT) _sapp.sample_count;
+    tex_desc.SampleDesc.Quality = (UINT) (_sapp.sample_count > 1 ? D3D11_STANDARD_MULTISAMPLE_PATTERN : 0);
 
     /* create MSAA texture and view if antialiasing requested */
     if (_sapp.sample_count > 1) {
@@ -5298,7 +5311,7 @@ _SOKOL_PRIVATE void _sapp_d3d11_destroy_default_render_target(void) {
 _SOKOL_PRIVATE void _sapp_d3d11_resize_default_render_target(void) {
     if (_sapp.d3d11.swap_chain) {
         _sapp_d3d11_destroy_default_render_target();
-        _sapp_dxgi_ResizeBuffers(_sapp.d3d11.swap_chain, _sapp.d3d11.swap_chain_desc.BufferCount, _sapp.framebuffer_width, _sapp.framebuffer_height, DXGI_FORMAT_B8G8R8A8_UNORM, 0);
+        _sapp_dxgi_ResizeBuffers(_sapp.d3d11.swap_chain, _sapp.d3d11.swap_chain_desc.BufferCount, (UINT)_sapp.framebuffer_width, (UINT)_sapp.framebuffer_height, DXGI_FORMAT_B8G8R8A8_UNORM, 0);
         _sapp_d3d11_create_default_render_target();
     }
 }
@@ -5310,7 +5323,7 @@ _SOKOL_PRIVATE void _sapp_d3d11_present(void) {
         SOKOL_ASSERT(_sapp.d3d11.msaa_rt);
         _sapp_d3d11_ResolveSubresource(_sapp.d3d11.device_context, (ID3D11Resource*)_sapp.d3d11.rt, 0, (ID3D11Resource*)_sapp.d3d11.msaa_rt, 0, DXGI_FORMAT_B8G8R8A8_UNORM);
     }
-    _sapp_dxgi_Present(_sapp.d3d11.swap_chain, _sapp.swap_interval, 0);
+    _sapp_dxgi_Present(_sapp.d3d11.swap_chain, (UINT)_sapp.swap_interval, 0);
 }
 
 #endif /* SOKOL_D3D11 */
@@ -5344,6 +5357,7 @@ _SOKOL_PRIVATE void _sapp_wgl_init(void) {
     if (!_sapp.wgl.msg_hwnd) {
         _sapp_fail("Win32: failed to create helper window!\n");
     }
+    SOKOL_ASSERT(_sapp.wgl.msg_hwnd);
     ShowWindow(_sapp.wgl.msg_hwnd, SW_HIDE);
     MSG msg;
     while (PeekMessageW(&msg, _sapp.wgl.msg_hwnd, 0, 0, PM_REMOVE)) {
@@ -5450,7 +5464,8 @@ _SOKOL_PRIVATE int _sapp_wgl_find_pixel_format(void) {
     const _sapp_gl_fbconfig* closest;
 
     int native_count = _sapp_wgl_attrib(1, WGL_NUMBER_PIXEL_FORMATS_ARB);
-    _sapp_gl_fbconfig* usable_configs = (_sapp_gl_fbconfig*) SOKOL_CALLOC(native_count, sizeof(_sapp_gl_fbconfig));
+    _sapp_gl_fbconfig* usable_configs = (_sapp_gl_fbconfig*) SOKOL_CALLOC((size_t)native_count, sizeof(_sapp_gl_fbconfig));
+    SOKOL_ASSERT(usable_configs);
     int usable_count = 0;
     for (int i = 0; i < native_count; i++) {
         const int n = i + 1;
@@ -5477,7 +5492,7 @@ _SOKOL_PRIVATE int _sapp_wgl_find_pixel_format(void) {
         if (_sapp.wgl.arb_multisample) {
             u->samples = _sapp_wgl_attrib(n, WGL_SAMPLES_ARB);
         }
-        u->handle = n;
+        u->handle = (uintptr_t)n;
         usable_count++;
     }
     SOKOL_ASSERT(usable_count > 0);
@@ -5563,7 +5578,7 @@ _SOKOL_PRIVATE void _sapp_wgl_swap_buffers(void) {
 
 _SOKOL_PRIVATE bool _sapp_win32_wide_to_utf8(const wchar_t* src, char* dst, int dst_num_bytes) {
     SOKOL_ASSERT(src && dst && (dst_num_bytes > 1));
-    memset(dst, 0, dst_num_bytes);
+    memset(dst, 0, (size_t)dst_num_bytes);
     const int bytes_needed = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
     if (bytes_needed <= dst_num_bytes) {
         WideCharToMultiByte(CP_UTF8, 0, src, -1, dst, dst_num_bytes, NULL, NULL);
@@ -5796,11 +5811,11 @@ _SOKOL_PRIVATE void _sapp_win32_files_dropped(HDROP hdrop) {
     bool drop_failed = false;
     const int count = (int) DragQueryFileW(hdrop, 0xffffffff, NULL, 0);
     _sapp.drop.num_files = (count > _sapp.drop.max_files) ? _sapp.drop.max_files : count;
-    for (int i = 0;  i < _sapp.drop.num_files;  i++) {
+    for (UINT i = 0;  i < (UINT)_sapp.drop.num_files;  i++) {
         const UINT num_chars = DragQueryFileW(hdrop, i, NULL, 0) + 1;
         WCHAR* buffer = (WCHAR*) SOKOL_CALLOC(num_chars, sizeof(WCHAR));
         DragQueryFileW(hdrop, i, buffer, num_chars);
-        if (!_sapp_win32_wide_to_utf8(buffer, _sapp_dropped_file_path_ptr(i), _sapp.drop.max_path_length)) {
+        if (!_sapp_win32_wide_to_utf8(buffer, _sapp_dropped_file_path_ptr((int)i), _sapp.drop.max_path_length)) {
             SOKOL_LOG("sokol_app.h: dropped file path too long (sapp_desc.max_dropped_file_path_length)\n");
             drop_failed = true;
         }
@@ -5931,7 +5946,8 @@ _SOKOL_PRIVATE LRESULT CALLBACK _sapp_win32_wndproc(HWND hWnd, UINT uMsg, WPARAM
                 if (_sapp.mouse.locked) {
                     HRAWINPUT ri = (HRAWINPUT) lParam;
                     UINT size = sizeof(_sapp.win32.raw_input_data);
-                    if (-1 == GetRawInputData(ri, RID_INPUT, &_sapp.win32.raw_input_data, &size, sizeof(RAWINPUTHEADER))) {
+                    // see: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdata
+                    if ((UINT)-1 == GetRawInputData(ri, RID_INPUT, &_sapp.win32.raw_input_data, &size, sizeof(RAWINPUTHEADER))) {
                         SOKOL_LOG("GetRawInputData() failed\n");
                         break;
                     }
@@ -6143,7 +6159,7 @@ _SOKOL_PRIVATE bool _sapp_win32_set_clipboard_string(const char* str) {
     SOKOL_ASSERT(_sapp.clipboard.enabled && (_sapp.clipboard.buf_size > 0));
 
     wchar_t* wchar_buf = 0;
-    const int wchar_buf_size = _sapp.clipboard.buf_size * sizeof(wchar_t);
+    const SIZE_T wchar_buf_size = (SIZE_T)_sapp.clipboard.buf_size * sizeof(wchar_t);
     HANDLE object = GlobalAlloc(GMEM_MOVEABLE, wchar_buf_size);
     if (!object) {
         goto error;
@@ -6152,7 +6168,7 @@ _SOKOL_PRIVATE bool _sapp_win32_set_clipboard_string(const char* str) {
     if (!wchar_buf) {
         goto error;
     }
-    if (!_sapp_win32_uwp_utf8_to_wide(str, wchar_buf, wchar_buf_size)) {
+    if (!_sapp_win32_uwp_utf8_to_wide(str, wchar_buf, (int)wchar_buf_size)) {
         goto error;
     }
     GlobalUnlock(wchar_buf);
@@ -6260,7 +6276,7 @@ _SOKOL_PRIVATE void _sapp_win32_run(const sapp_desc* desc) {
         #if defined(SOKOL_D3D11)
             _sapp_d3d11_present();
             if (IsIconic(_sapp.win32.hwnd)) {
-                Sleep(16 * _sapp.swap_interval);
+                Sleep((DWORD)(16 * _sapp.swap_interval));
             }
         #endif
         #if defined(SOKOL_GLCORE33)
@@ -6300,8 +6316,9 @@ _SOKOL_PRIVATE char** _sapp_win32_command_line_to_utf8_argv(LPWSTR w_command_lin
         _sapp_fail("Win32: failed to parse command line");
     } else {
         size_t size = wcslen(w_command_line) * 4;
-        argv = (char**) SOKOL_CALLOC(1, (argc + 1) * sizeof(char*) + size);
-        args = (char*)&argv[argc + 1];
+        argv = (char**) SOKOL_CALLOC(1, ((size_t)argc + 1) * sizeof(char*) + size);
+        SOKOL_ASSERT(argv);
+        args = (char*) &argv[argc + 1];
         int n;
         for (int i = 0; i < argc; ++i) {
             n = WideCharToMultiByte(CP_UTF8, 0, w_argv[i], -1, args, (int)size, NULL, NULL);
@@ -6310,7 +6327,7 @@ _SOKOL_PRIVATE char** _sapp_win32_command_line_to_utf8_argv(LPWSTR w_command_lin
                 break;
             }
             argv[i] = args;
-            size -= n;
+            size -= (size_t)n;
             args += n;
         }
         LocalFree(w_argv);
@@ -7595,19 +7612,19 @@ _SOKOL_PRIVATE bool _sapp_android_touch_event(const AInputEvent* e) {
     }
     int32_t idx = action_idx >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
     _sapp_init_event(type);
-    _sapp.event.num_touches = AMotionEvent_getPointerCount(e);
+    _sapp.event.num_touches = (int)AMotionEvent_getPointerCount(e);
     if (_sapp.event.num_touches > SAPP_MAX_TOUCHPOINTS) {
         _sapp.event.num_touches = SAPP_MAX_TOUCHPOINTS;
     }
     for (int32_t i = 0; i < _sapp.event.num_touches; i++) {
         sapp_touchpoint* dst = &_sapp.event.touches[i];
-        dst->identifier = AMotionEvent_getPointerId(e, i);
-        dst->pos_x = (AMotionEvent_getRawX(e, i) / _sapp.window_width) * _sapp.framebuffer_width;
-        dst->pos_y = (AMotionEvent_getRawY(e, i) / _sapp.window_height) * _sapp.framebuffer_height;
+        dst->identifier = (uintptr_t)AMotionEvent_getPointerId(e, (size_t)i);
+        dst->pos_x = (AMotionEvent_getRawX(e, (size_t)i) / _sapp.window_width) * _sapp.framebuffer_width;
+        dst->pos_y = (AMotionEvent_getRawY(e, (size_t)i) / _sapp.window_height) * _sapp.framebuffer_height;
 
         if (action == AMOTION_EVENT_ACTION_POINTER_DOWN ||
             action == AMOTION_EVENT_ACTION_POINTER_UP) {
-            dst->changed = i == idx;
+            dst->changed = (i == idx);
         } else {
             dst->changed = true;
         }
@@ -9053,7 +9070,7 @@ _SOKOL_PRIVATE GLXFBConfig _sapp_glx_choosefbconfig() {
         _sapp_fail("GLX: No GLXFBConfigs returned");
     }
 
-    usable_configs = (_sapp_gl_fbconfig*) SOKOL_CALLOC(native_count, sizeof(_sapp_gl_fbconfig));
+    usable_configs = (_sapp_gl_fbconfig*) SOKOL_CALLOC((size_t)native_count, sizeof(_sapp_gl_fbconfig));
     usable_count = 0;
     for (i = 0;  i < native_count;  i++) {
         const GLXFBConfig n = native_configs[i];
@@ -9233,7 +9250,7 @@ _SOKOL_PRIVATE void _sapp_x11_create_hidden_cursor(void) {
     SOKOL_ASSERT(img && (img->width == 16) && (img->height == 16) && img->pixels);
     img->xhot = 0;
     img->yhot = 0;
-    const size_t num_bytes = w * h * sizeof(XcursorPixel);
+    const size_t num_bytes = (size_t)(w * h) * sizeof(XcursorPixel);
     memset(img->pixels, 0, num_bytes);
     _sapp.x11.hidden_cursor = XcursorImageLoadCursor(_sapp.x11.display, img);
     XcursorImageDestroy(img);
@@ -9329,8 +9346,8 @@ _SOKOL_PRIVATE void _sapp_x11_create_window(Visual* visual, int depth) {
     _sapp.x11.window = XCreateWindow(_sapp.x11.display,
                                      _sapp.x11.root,
                                      0, 0,
-                                     _sapp.window_width,
-                                     _sapp.window_height,
+                                     (uint32_t)_sapp.window_width,
+                                     (uint32_t)_sapp.window_height,
                                      0,     /* border width */
                                      depth, /* color depth */
                                      InputOutput,
@@ -9420,7 +9437,7 @@ _SOKOL_PRIVATE int _sapp_x11_get_window_state(void) {
     } *state = NULL;
 
     if (_sapp_x11_get_window_property(_sapp.x11.window, _sapp.x11.WM_STATE, _sapp.x11.WM_STATE, (unsigned char**)&state) >= 2) {
-        result = state->state;
+        result = (int)state->state;
     }
     if (state) {
         XFree(state);
@@ -9428,7 +9445,7 @@ _SOKOL_PRIVATE int _sapp_x11_get_window_state(void) {
     return result;
 }
 
-_SOKOL_PRIVATE uint32_t _sapp_x11_mod(int x11_mods) {
+_SOKOL_PRIVATE uint32_t _sapp_x11_mod(uint32_t x11_mods) {
     uint32_t mods = 0;
     if (x11_mods & ShiftMask) {
         mods |= SAPP_MODIFIER_SHIFT;
@@ -9798,7 +9815,7 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) {
             break;
         case KeyPress:
             {
-                int keycode = event->xkey.keycode;
+                int keycode = (int)event->xkey.keycode;
                 const sapp_keycode key = _sapp_x11_translate_key(keycode);
                 bool repeat = _sapp_x11_keycodes[keycode & 0xFF];
                 _sapp_x11_keycodes[keycode & 0xFF] = true;
@@ -9816,7 +9833,7 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) {
             break;
         case KeyRelease:
             {
-                int keycode = event->xkey.keycode;
+                int keycode = (int)event->xkey.keycode;
                 const sapp_keycode key = _sapp_x11_translate_key(keycode);
                 _sapp_x11_keycodes[keycode & 0xFF] = false;
                 if (key != SAPP_KEYCODE_INVALID) {
@@ -9908,14 +9925,14 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) {
                 return;
             }
             if (event->xclient.message_type == _sapp.x11.WM_PROTOCOLS) {
-                const Atom protocol = event->xclient.data.l[0];
+                const Atom protocol = (Atom)event->xclient.data.l[0];
                 if (protocol == _sapp.x11.WM_DELETE_WINDOW) {
                     _sapp.quit_requested = true;
                 }
             }
             else if (event->xclient.message_type == _sapp.x11.xdnd.XdndEnter) {
                 const bool is_list = 0 != (event->xclient.data.l[1] & 1);
-                _sapp.x11.xdnd.source  = event->xclient.data.l[0];
+                _sapp.x11.xdnd.source  = (Window)event->xclient.data.l[0];
                 _sapp.x11.xdnd.version = event->xclient.data.l[1] >> 24;
                 _sapp.x11.xdnd.format  = None;
                 if (_sapp.x11.xdnd.version > _SAPP_X11_XDND_VERSION) {
@@ -9947,7 +9964,7 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) {
                 Time time = CurrentTime;
                 if (_sapp.x11.xdnd.format) {
                     if (_sapp.x11.xdnd.version >= 1) {
-                        time = event->xclient.data.l[2];
+                        time = (Time)event->xclient.data.l[2];
                     }
                     XConvertSelection(_sapp.x11.display,
                                       _sapp.x11.xdnd.XdndSelection,
@@ -9963,7 +9980,7 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) {
                     reply.xclient.window = _sapp.x11.window;
                     reply.xclient.message_type = _sapp.x11.xdnd.XdndFinished;
                     reply.xclient.format = 32;
-                    reply.xclient.data.l[0] = _sapp.x11.window;
+                    reply.xclient.data.l[0] = (long)_sapp.x11.window;
                     reply.xclient.data.l[1] = 0;    // drag was rejected
                     reply.xclient.data.l[2] = None;
                     XSendEvent(_sapp.x11.display, _sapp.x11.xdnd.source, False, NoEventMask, &reply);
@@ -9984,12 +10001,12 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) {
                 reply.xclient.window = _sapp.x11.xdnd.source;
                 reply.xclient.message_type = _sapp.x11.xdnd.XdndStatus;
                 reply.xclient.format = 32;
-                reply.xclient.data.l[0] = _sapp.x11.window;
+                reply.xclient.data.l[0] = (long)_sapp.x11.window;
                 if (_sapp.x11.xdnd.format) {
                     /* reply that we are ready to copy the dragged data */
                     reply.xclient.data.l[1] = 1;    // accept with no rectangle
                     if (_sapp.x11.xdnd.version >= 2) {
-                        reply.xclient.data.l[4] = _sapp.x11.xdnd.XdndActionCopy;
+                        reply.xclient.data.l[4] = (long)_sapp.x11.xdnd.XdndActionCopy;
                     }
                 }
                 XSendEvent(_sapp.x11.display, _sapp.x11.xdnd.source, False, NoEventMask, &reply);
@@ -10018,9 +10035,9 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) {
                     reply.xclient.window = _sapp.x11.window;
                     reply.xclient.message_type = _sapp.x11.xdnd.XdndFinished;
                     reply.xclient.format = 32;
-                    reply.xclient.data.l[0] = _sapp.x11.window;
+                    reply.xclient.data.l[0] = (long)_sapp.x11.window;
                     reply.xclient.data.l[1] = result;
-                    reply.xclient.data.l[2] = _sapp.x11.xdnd.XdndActionCopy;
+                    reply.xclient.data.l[2] = (long)_sapp.x11.xdnd.XdndActionCopy;
                     XSendEvent(_sapp.x11.display, _sapp.x11.xdnd.source, False, NoEventMask, &reply);
                     XFlush(_sapp.x11.display);
                 }
@@ -10164,6 +10181,18 @@ SOKOL_API_IMPL int sapp_width(void) {
     return (_sapp.framebuffer_width > 0) ? _sapp.framebuffer_width : 1;
 }
 
+SOKOL_API_IMPL float sapp_widthf(void) {
+    return (float)sapp_width();
+}
+
+SOKOL_API_IMPL int sapp_height(void) {
+    return (_sapp.framebuffer_height > 0) ? _sapp.framebuffer_height : 1;
+}
+
+SOKOL_API_IMPL float sapp_heightf(void) {
+    return (float)sapp_height();
+}
+
 SOKOL_API_IMPL int sapp_color_format(void) {
     #if defined(_SAPP_EMSCRIPTEN) && defined(SOKOL_WGPU)
         switch (_sapp.emsc.wgpu.render_format) {
@@ -10190,10 +10219,6 @@ SOKOL_API_IMPL int sapp_sample_count(void) {
     return _sapp.sample_count;
 }
 
-SOKOL_API_IMPL int sapp_height(void) {
-    return (_sapp.framebuffer_height > 0) ? _sapp.framebuffer_height : 1;
-}
-
 SOKOL_API_IMPL bool sapp_high_dpi(void) {
     return _sapp.desc.high_dpi && (_sapp.dpi_scale >= 1.5f);
 }

+ 2 - 2
sokol_args.h

@@ -665,8 +665,8 @@ SOKOL_API_IMPL void sargs_setup(const sargs_desc* desc) {
     _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*) SOKOL_CALLOC(_sargs.max_args, sizeof(_sargs_kvp_t));
-    _sargs.buf = (char*) SOKOL_CALLOC(_sargs.buf_size, sizeof(char));
+    _sargs.args = (_sargs_kvp_t*) SOKOL_CALLOC((size_t)_sargs.max_args, sizeof(_sargs_kvp_t));
+    _sargs.buf = (char*) SOKOL_CALLOC((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.valid = true;

+ 60 - 60
sokol_audio.h

@@ -440,7 +440,8 @@ inline void saudio_setup(const saudio_desc& desc) { return saudio_setup(&desc);
 /*=== IMPLEMENTATION =========================================================*/
 #ifdef SOKOL_AUDIO_IMPL
 #define SOKOL_AUDIO_IMPL_INCLUDED (1)
-#include <string.h> /* memset, memcpy */
+#include <string.h> // memset, memcpy
+#include <stddef.h> // size_t
 
 #ifndef SOKOL_API_IMPL
     #define SOKOL_API_IMPL
@@ -687,10 +688,10 @@ typedef struct { } _saudio_backend_t;
 
 /* a ringbuffer structure */
 typedef struct {
-    uint32_t head;  /* next slot to write to */
-    uint32_t tail;  /* next slot to read from */
-    uint32_t num;   /* number of slots in queue */
-    uint32_t queue[SAUDIO_RING_MAX_SLOTS];
+    int head;  // next slot to write to
+    int tail;  // next slot to read from
+    int num;   // number of slots in queue
+    int queue[SAUDIO_RING_MAX_SLOTS];
 } _saudio_ring_t;
 
 /* a packet FIFO structure */
@@ -787,11 +788,11 @@ _SOKOL_PRIVATE void _saudio_mutex_unlock(_saudio_mutex_t* m) { (void)m; }
 #endif
 
 /*=== RING-BUFFER QUEUE IMPLEMENTATION =======================================*/
-_SOKOL_PRIVATE uint16_t _saudio_ring_idx(_saudio_ring_t* ring, uint32_t i) {
-    return (uint16_t) (i % ring->num);
+_SOKOL_PRIVATE int _saudio_ring_idx(_saudio_ring_t* ring, int i) {
+    return (i % ring->num);
 }
 
-_SOKOL_PRIVATE void _saudio_ring_init(_saudio_ring_t* ring, uint32_t num_slots) {
+_SOKOL_PRIVATE void _saudio_ring_init(_saudio_ring_t* ring, int num_slots) {
     SOKOL_ASSERT((num_slots + 1) <= SAUDIO_RING_MAX_SLOTS);
     ring->head = 0;
     ring->tail = 0;
@@ -808,7 +809,7 @@ _SOKOL_PRIVATE bool _saudio_ring_empty(_saudio_ring_t* ring) {
 }
 
 _SOKOL_PRIVATE int _saudio_ring_count(_saudio_ring_t* ring) {
-    uint32_t count;
+    int count;
     if (ring->head >= ring->tail) {
         count = ring->head - ring->tail;
     }
@@ -819,15 +820,15 @@ _SOKOL_PRIVATE int _saudio_ring_count(_saudio_ring_t* ring) {
     return count;
 }
 
-_SOKOL_PRIVATE void _saudio_ring_enqueue(_saudio_ring_t* ring, uint32_t val) {
+_SOKOL_PRIVATE void _saudio_ring_enqueue(_saudio_ring_t* ring, int val) {
     SOKOL_ASSERT(!_saudio_ring_full(ring));
     ring->queue[ring->head] = val;
     ring->head = _saudio_ring_idx(ring, ring->head + 1);
 }
 
-_SOKOL_PRIVATE uint32_t _saudio_ring_dequeue(_saudio_ring_t* ring) {
+_SOKOL_PRIVATE int _saudio_ring_dequeue(_saudio_ring_t* ring) {
     SOKOL_ASSERT(!_saudio_ring_empty(ring));
-    uint32_t val = ring->queue[ring->tail];
+    int val = ring->queue[ring->tail];
     ring->tail = _saudio_ring_idx(ring, ring->tail + 1);
     return val;
 }
@@ -847,7 +848,7 @@ _SOKOL_PRIVATE void _saudio_fifo_init(_saudio_fifo_t* fifo, int packet_size, int
     SOKOL_ASSERT((packet_size > 0) && (num_packets > 0));
     fifo->packet_size = packet_size;
     fifo->num_packets = num_packets;
-    fifo->base_ptr = (uint8_t*) SOKOL_MALLOC(packet_size * num_packets);
+    fifo->base_ptr = (uint8_t*) SOKOL_MALLOC((size_t)(packet_size * num_packets));
     SOKOL_ASSERT(fifo->base_ptr);
     fifo->cur_packet = -1;
     fifo->cur_offset = 0;
@@ -907,7 +908,7 @@ _SOKOL_PRIVATE int _saudio_fifo_write(_saudio_fifo_t* fifo, const uint8_t* ptr,
                 to_copy = max_copy;
             }
             uint8_t* dst = fifo->base_ptr + fifo->cur_packet * fifo->packet_size + fifo->cur_offset;
-            memcpy(dst, ptr, to_copy);
+            memcpy(dst, ptr, (size_t)to_copy);
             ptr += to_copy;
             fifo->cur_offset += to_copy;
             all_to_copy -= to_copy;
@@ -949,7 +950,7 @@ _SOKOL_PRIVATE int _saudio_fifo_read(_saudio_fifo_t* fifo, uint8_t* ptr, int num
                 int packet_index = _saudio_ring_dequeue(&fifo->read_queue);
                 _saudio_ring_enqueue(&fifo->write_queue, packet_index);
                 const uint8_t* src = fifo->base_ptr + packet_index * fifo->packet_size;
-                memcpy(dst, src, fifo->packet_size);
+                memcpy(dst, src, (size_t)fifo->packet_size);
                 dst += fifo->packet_size;
                 num_bytes_copied += fifo->packet_size;
             }
@@ -963,7 +964,7 @@ _SOKOL_PRIVATE int _saudio_fifo_read(_saudio_fifo_t* fifo, uint8_t* ptr, int num
 /*=== DUMMY BACKEND IMPLEMENTATION ===========================================*/
 #if defined(SOKOL_DUMMY_BACKEND)
 _SOKOL_PRIVATE bool _saudio_backend_init(void) {
-    _saudio.bytes_per_frame = _saudio.num_channels * sizeof(float);
+    _saudio.bytes_per_frame = _saudio.num_channels * (int)sizeof(float);
     return true;
 };
 _SOKOL_PRIVATE void _saudio_backend_shutdown(void) { };
@@ -975,7 +976,7 @@ _SOKOL_PRIVATE void _saudio_backend_shutdown(void) { };
 _SOKOL_PRIVATE void _saudio_coreaudio_callback(void* user_data, AudioQueueRef queue, AudioQueueBufferRef buffer) {
     _SOKOL_UNUSED(user_data);
     if (_saudio_has_callback()) {
-        const int num_frames = buffer->mAudioDataByteSize / _saudio.bytes_per_frame;
+        const int num_frames = (int)buffer->mAudioDataByteSize / _saudio.bytes_per_frame;
         const int num_channels = _saudio.num_channels;
         _saudio_stream_callback((float*)buffer->mAudioData, num_frames, num_channels);
     }
@@ -984,7 +985,7 @@ _SOKOL_PRIVATE void _saudio_coreaudio_callback(void* user_data, AudioQueueRef qu
         int num_bytes = (int) buffer->mAudioDataByteSize;
         if (0 == _saudio_fifo_read(&_saudio.fifo, ptr, num_bytes)) {
             /* not enough read data available, fill the entire buffer with silence */
-            memset(ptr, 0, num_bytes);
+            memset(ptr, 0, (size_t)num_bytes);
         }
     }
     AudioQueueEnqueueBuffer(queue, buffer, 0, NULL);
@@ -1000,8 +1001,8 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
     fmt.mFormatID = kAudioFormatLinearPCM;
     fmt.mFormatFlags = kLinearPCMFormatFlagIsFloat | kAudioFormatFlagIsPacked;
     fmt.mFramesPerPacket = 1;
-    fmt.mChannelsPerFrame = _saudio.num_channels;
-    fmt.mBytesPerFrame = sizeof(float) * _saudio.num_channels;
+    fmt.mChannelsPerFrame = (uint32_t) _saudio.num_channels;
+    fmt.mBytesPerFrame = (uint32_t)sizeof(float) * (uint32_t)_saudio.num_channels;
     fmt.mBytesPerPacket = fmt.mBytesPerFrame;
     fmt.mBitsPerChannel = 32;
     OSStatus res = AudioQueueNewOutput(&fmt, _saudio_coreaudio_callback, 0, NULL, NULL, 0, &_saudio.backend.ca_audio_queue);
@@ -1010,7 +1011,7 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
     /* create 2 audio buffers */
     for (int i = 0; i < 2; i++) {
         AudioQueueBufferRef buf = NULL;
-        const uint32_t buf_byte_size = _saudio.buffer_frames * fmt.mBytesPerFrame;
+        const uint32_t buf_byte_size = (uint32_t)_saudio.buffer_frames * fmt.mBytesPerFrame;
         res = AudioQueueAllocateBuffer(_saudio.backend.ca_audio_queue, buf_byte_size, &buf);
         SOKOL_ASSERT((res == 0) && buf);
         buf->mAudioDataByteSize = buf_byte_size;
@@ -1019,7 +1020,7 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
     }
 
     /* init or modify actual playback parameters */
-    _saudio.bytes_per_frame = fmt.mBytesPerFrame;
+    _saudio.bytes_per_frame = (int)fmt.mBytesPerFrame;
 
     /* ...and start playback */
     res = AudioQueueStart(_saudio.backend.ca_audio_queue, NULL);
@@ -1042,7 +1043,7 @@ _SOKOL_PRIVATE void* _saudio_alsa_cb(void* param) {
     _SOKOL_UNUSED(param);
     while (!_saudio.backend.thread_stop) {
         /* snd_pcm_writei() will be blocking until it needs data */
-        int write_res = snd_pcm_writei(_saudio.backend.device, _saudio.backend.buffer, _saudio.backend.buffer_frames);
+        int write_res = snd_pcm_writei(_saudio.backend.device, _saudio.backend.buffer, (snd_pcm_uframes_t)_saudio.backend.buffer_frames);
         if (write_res < 0) {
             /* underrun occurred */
             snd_pcm_prepare(_saudio.backend.device);
@@ -1055,7 +1056,7 @@ _SOKOL_PRIVATE void* _saudio_alsa_cb(void* param) {
             else {
                 if (0 == _saudio_fifo_read(&_saudio.fifo, (uint8_t*)_saudio.backend.buffer, _saudio.backend.buffer_byte_size)) {
                     /* not enough read data available, fill the entire buffer with silence */
-                    memset(_saudio.backend.buffer, 0, _saudio.backend.buffer_byte_size);
+                    memset(_saudio.backend.buffer, 0, (size_t)_saudio.backend.buffer_byte_size);
                 }
             }
         }
@@ -1064,7 +1065,7 @@ _SOKOL_PRIVATE void* _saudio_alsa_cb(void* param) {
 }
 
 _SOKOL_PRIVATE bool _saudio_backend_init(void) {
-    int dir; unsigned int rate;
+    int dir; uint32_t rate;
     int rc = snd_pcm_open(&_saudio.backend.device, "default", SND_PCM_STREAM_PLAYBACK, 0);
     if (rc < 0) {
         SOKOL_LOG("sokol_audio.h: snd_pcm_open() failed");
@@ -1083,16 +1084,16 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
         SOKOL_LOG("sokol_audio.h: float samples not supported");
         goto error;
     }
-    if (0 > snd_pcm_hw_params_set_buffer_size(_saudio.backend.device, params, _saudio.buffer_frames)) {
+    if (0 > snd_pcm_hw_params_set_buffer_size(_saudio.backend.device, params, (snd_pcm_uframes_t)_saudio.buffer_frames)) {
         SOKOL_LOG("sokol_audio.h: requested buffer size not supported");
         goto error;
     }
-    if (0 > snd_pcm_hw_params_set_channels(_saudio.backend.device, params, _saudio.num_channels)) {
+    if (0 > snd_pcm_hw_params_set_channels(_saudio.backend.device, params, (uint32_t)_saudio.num_channels)) {
         SOKOL_LOG("sokol_audio.h: requested channel count not supported");
         goto error;
     }
     /* let ALSA pick a nearby sampling rate */
-    rate = _saudio.sample_rate;
+    rate = (uint32_t) _saudio.sample_rate;
     dir = 0;
     if (0 > snd_pcm_hw_params_set_rate_near(_saudio.backend.device, params, &rate, &dir)) {
         SOKOL_LOG("sokol_audio.h: snd_pcm_hw_params_set_rate_near() failed");
@@ -1104,14 +1105,14 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
     }
 
     /* read back actual sample rate and channels */
-    _saudio.sample_rate = rate;
-    _saudio.bytes_per_frame = _saudio.num_channels * sizeof(float);
+    _saudio.sample_rate = (int)rate;
+    _saudio.bytes_per_frame = _saudio.num_channels * (int)sizeof(float);
 
     /* allocate the streaming buffer */
     _saudio.backend.buffer_byte_size = _saudio.buffer_frames * _saudio.bytes_per_frame;
     _saudio.backend.buffer_frames = _saudio.buffer_frames;
-    _saudio.backend.buffer = (float*) SOKOL_MALLOC(_saudio.backend.buffer_byte_size);
-    memset(_saudio.backend.buffer, 0, _saudio.backend.buffer_byte_size);
+    _saudio.backend.buffer = (float*) SOKOL_MALLOC((size_t)_saudio.backend.buffer_byte_size);
+    memset(_saudio.backend.buffer, 0, (size_t)_saudio.backend.buffer_byte_size);
 
     /* create the buffer-streaming start thread */
     if (0 != pthread_create(&_saudio.backend.thread, 0, _saudio_alsa_cb, 0)) {
@@ -1190,12 +1191,12 @@ _SOKOL_PRIVATE void _saudio_wasapi_fill_buffer(void) {
     else {
         if (0 == _saudio_fifo_read(&_saudio.fifo, (uint8_t*)_saudio.backend.thread.src_buffer, _saudio.backend.thread.src_buffer_byte_size)) {
             /* not enough read data available, fill the entire buffer with silence */
-            memset(_saudio.backend.thread.src_buffer, 0, _saudio.backend.thread.src_buffer_byte_size);
+            memset(_saudio.backend.thread.src_buffer, 0, (size_t)_saudio.backend.thread.src_buffer_byte_size);
         }
     }
 }
 
-_SOKOL_PRIVATE void _saudio_wasapi_submit_buffer(UINT32 num_frames) {
+_SOKOL_PRIVATE void _saudio_wasapi_submit_buffer(int num_frames) {
     BYTE* wasapi_buffer = 0;
     if (FAILED(IAudioRenderClient_GetBuffer(_saudio.backend.render_client, num_frames, &wasapi_buffer))) {
         return;
@@ -1205,8 +1206,8 @@ _SOKOL_PRIVATE void _saudio_wasapi_submit_buffer(UINT32 num_frames) {
     /* convert float samples to int16_t, refill float buffer if needed */
     const int num_samples = num_frames * _saudio.num_channels;
     int16_t* dst = (int16_t*) wasapi_buffer;
-    uint32_t buffer_pos = _saudio.backend.thread.src_buffer_pos;
-    const uint32_t buffer_float_size = _saudio.backend.thread.src_buffer_byte_size / sizeof(float);
+    int buffer_pos = _saudio.backend.thread.src_buffer_pos;
+    const int buffer_float_size = _saudio.backend.thread.src_buffer_byte_size / (int)sizeof(float);
     float* src = _saudio.backend.thread.src_buffer;
     for (int i = 0; i < num_samples; i++) {
         if (0 == buffer_pos) {
@@ -1234,7 +1235,7 @@ _SOKOL_PRIVATE DWORD WINAPI _saudio_wasapi_thread_fn(LPVOID param) {
             continue;
         }
         SOKOL_ASSERT(_saudio.backend.thread.dst_buffer_frames >= padding);
-        UINT32 num_frames = _saudio.backend.thread.dst_buffer_frames - padding;
+        int num_frames = (int)_saudio.backend.thread.dst_buffer_frames - (int)padding;
         if (num_frames > 0) {
             _saudio_wasapi_submit_buffer(num_frames);
         }
@@ -1359,8 +1360,8 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
 #endif
     WAVEFORMATEX fmt;
     memset(&fmt, 0, sizeof(fmt));
-    fmt.nChannels = (WORD) _saudio.num_channels;
-    fmt.nSamplesPerSec = _saudio.sample_rate;
+    fmt.nChannels = (WORD)_saudio.num_channels;
+    fmt.nSamplesPerSec = (DWORD)_saudio.sample_rate;
     fmt.wFormatTag = WAVE_FORMAT_PCM;
     fmt.wBitsPerSample = 16;
     fmt.nBlockAlign = (fmt.nChannels * fmt.wBitsPerSample) / 8;
@@ -1390,13 +1391,13 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
         SOKOL_LOG("sokol_audio wasapi: audio client SetEventHandle failed");
         goto error;
     }
-    _saudio.backend.si16_bytes_per_frame = _saudio.num_channels * sizeof(int16_t);
-    _saudio.bytes_per_frame = _saudio.num_channels * sizeof(float);
+    _saudio.backend.si16_bytes_per_frame = _saudio.num_channels * (int)sizeof(int16_t);
+    _saudio.bytes_per_frame = _saudio.num_channels * (int)sizeof(float);
     _saudio.backend.thread.src_buffer_frames = _saudio.buffer_frames;
     _saudio.backend.thread.src_buffer_byte_size = _saudio.backend.thread.src_buffer_frames * _saudio.bytes_per_frame;
 
     /* allocate an intermediate buffer for sample format conversion */
-    _saudio.backend.thread.src_buffer = (float*) SOKOL_MALLOC(_saudio.backend.thread.src_buffer_byte_size);
+    _saudio.backend.thread.src_buffer = (float*) SOKOL_MALLOC((size_t)_saudio.backend.thread.src_buffer_byte_size);
     SOKOL_ASSERT(_saudio.backend.thread.src_buffer);
 
     /* create streaming thread */
@@ -1446,7 +1447,7 @@ EMSCRIPTEN_KEEPALIVE int _saudio_emsc_pull(int num_frames) {
             const int num_bytes = num_frames * _saudio.bytes_per_frame;
             if (0 == _saudio_fifo_read(&_saudio.fifo, _saudio.backend.buffer, num_bytes)) {
                 /* not enough read data available, fill the entire buffer with silence */
-                memset(_saudio.backend.buffer, 0, num_bytes);
+                memset(_saudio.backend.buffer, 0, (size_t)num_bytes);
             }
         }
         int res = (int) _saudio.backend.buffer;
@@ -1551,10 +1552,10 @@ EM_JS(int, saudio_js_buffer_frames, (void), {
 
 _SOKOL_PRIVATE bool _saudio_backend_init(void) {
     if (saudio_js_init(_saudio.sample_rate, _saudio.num_channels, _saudio.buffer_frames)) {
-        _saudio.bytes_per_frame = sizeof(float) * _saudio.num_channels;
+        _saudio.bytes_per_frame = (int)sizeof(float) * _saudio.num_channels;
         _saudio.sample_rate = saudio_js_sample_rate();
         _saudio.buffer_frames = saudio_js_buffer_frames();
-        const int buf_size = _saudio.buffer_frames * _saudio.bytes_per_frame;
+        const size_t buf_size = (size_t) (_saudio.buffer_frames * _saudio.bytes_per_frame);
         _saudio.backend.buffer = (uint8_t*) SOKOL_MALLOC(buf_size);
         return true;
     }
@@ -1637,10 +1638,10 @@ _SOKOL_PRIVATE void _saudio_opensles_fill_buffer(void) {
         _saudio_stream_callback(_saudio.backend.src_buffer, src_buffer_frames, _saudio.num_channels);
     }
     else {
-        const int src_buffer_byte_size = src_buffer_frames * _saudio.num_channels * sizeof(float);
+        const int src_buffer_byte_size = src_buffer_frames * _saudio.num_channels * (int)sizeof(float);
         if (0 == _saudio_fifo_read(&_saudio.fifo, (uint8_t*)_saudio.backend.src_buffer, src_buffer_byte_size)) {
             /* not enough read data available, fill the entire buffer with silence */
-            memset(_saudio.backend.src_buffer, 0x0, src_buffer_byte_size);
+            memset(_saudio.backend.src_buffer, 0x0, (size_t)src_buffer_byte_size);
         }
     }
 }
@@ -1662,8 +1663,8 @@ _SOKOL_PRIVATE void* _saudio_opensles_thread_fn(void* param) {
         int16_t* next_buffer = _saudio.backend.output_buffers[_saudio.backend.active_buffer];
 
         /* queue this buffer */
-        const int buffer_size_bytes = _saudio.buffer_frames * _saudio.num_channels * sizeof(short);
-        (*_saudio.backend.player_buffer_queue)->Enqueue(_saudio.backend.player_buffer_queue, out_buffer, buffer_size_bytes);
+        const int buffer_size_bytes = _saudio.buffer_frames * _saudio.num_channels * (int)sizeof(short);
+        (*_saudio.backend.player_buffer_queue)->Enqueue(_saudio.backend.player_buffer_queue, out_buffer, (SLuint32)buffer_size_bytes);
 
         /* fill the next buffer */
         _saudio_opensles_fill_buffer();
@@ -1701,23 +1702,22 @@ _SOKOL_PRIVATE void _saudio_backend_shutdown(void) {
 }
 
 _SOKOL_PRIVATE bool _saudio_backend_init(void) {
-    _saudio.bytes_per_frame = sizeof(float) * _saudio.num_channels;
+    _saudio.bytes_per_frame = (int)sizeof(float) * _saudio.num_channels;
 
     for (int i = 0; i < SAUDIO_NUM_BUFFERS; ++i) {
-        const int buffer_size_bytes = sizeof(int16_t) * _saudio.num_channels * _saudio.buffer_frames;
-        _saudio.backend.output_buffers[i] = (int16_t*) SOKOL_MALLOC(buffer_size_bytes);
+        const int buffer_size_bytes = (int)sizeof(int16_t) * _saudio.num_channels * _saudio.buffer_frames;
+        _saudio.backend.output_buffers[i] = (int16_t*) SOKOL_MALLOC((size_t)buffer_size_bytes);
         SOKOL_ASSERT(_saudio.backend.output_buffers[i]);
-        memset(_saudio.backend.output_buffers[i], 0x0, buffer_size_bytes);
+        memset(_saudio.backend.output_buffers[i], 0x0, (size_t)buffer_size_bytes);
     }
 
     {
         const int buffer_size_bytes = _saudio.bytes_per_frame * _saudio.buffer_frames;
-        _saudio.backend.src_buffer = (float*) SOKOL_MALLOC(buffer_size_bytes);
+        _saudio.backend.src_buffer = (float*) SOKOL_MALLOC((size_t)buffer_size_bytes);
         SOKOL_ASSERT(_saudio.backend.src_buffer);
-        memset(_saudio.backend.src_buffer, 0x0, buffer_size_bytes);
+        memset(_saudio.backend.src_buffer, 0x0, (size_t)buffer_size_bytes);
     }
 
-
     /* Create engine */
     const SLEngineOption opts[] = { SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE };
     if (slCreateEngine(&_saudio.backend.engine_obj, 1, opts, 0, NULL, NULL ) != SL_RESULT_SUCCESS) {
@@ -1758,8 +1758,8 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
     /* data format */
     SLDataFormat_PCM format;
     format.formatType = SL_DATAFORMAT_PCM;
-    format.numChannels = _saudio.num_channels;
-    format.samplesPerSec = _saudio.sample_rate * 1000;
+    format.numChannels = (SLuint32)_saudio.num_channels;
+    format.samplesPerSec = (SLuint32) (_saudio.sample_rate * 1000);
     format.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
     format.containerSize = 16;
     format.endianness = SL_BYTEORDER_LITTLEENDIAN;
@@ -1798,8 +1798,8 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) {
 
     /* begin */
     {
-        const int buffer_size_bytes = sizeof(int16_t) * _saudio.num_channels * _saudio.buffer_frames;
-        (*_saudio.backend.player_buffer_queue)->Enqueue(_saudio.backend.player_buffer_queue, _saudio.backend.output_buffers[0], buffer_size_bytes);
+        const int buffer_size_bytes = (int)sizeof(int16_t) * _saudio.num_channels * _saudio.buffer_frames;
+        (*_saudio.backend.player_buffer_queue)->Enqueue(_saudio.backend.player_buffer_queue, _saudio.backend.output_buffers[0], (SLuint32)buffer_size_bytes);
         _saudio.backend.active_buffer = (_saudio.backend.active_buffer + 1) % SAUDIO_NUM_BUFFERS;
 
         (*_saudio.backend.player)->RegisterCallback(_saudio.backend.player, _saudio_opensles_play_cb, NULL);

+ 4 - 4
sokol_fetch.h

@@ -1475,7 +1475,7 @@ _SOKOL_PRIVATE uint32_t _sfetch_file_size(_sfetch_file_handle_t h) {
 }
 
 _SOKOL_PRIVATE bool _sfetch_file_read(_sfetch_file_handle_t h, uint32_t offset, uint32_t num_bytes, void* ptr) {
-    fseek(h, offset, SEEK_SET);
+    fseek(h, (long)offset, SEEK_SET);
     return num_bytes == fread(ptr, 1, num_bytes, h);
 }
 
@@ -1615,8 +1615,8 @@ _SOKOL_PRIVATE void _sfetch_thread_dequeue_outgoing(_sfetch_thread_t* thread, _s
 #if _SFETCH_PLATFORM_WINDOWS
 _SOKOL_PRIVATE bool _sfetch_win32_utf8_to_wide(const char* src, wchar_t* dst, int dst_num_bytes) {
     SOKOL_ASSERT(src && dst && (dst_num_bytes > 1));
-    memset(dst, 0, dst_num_bytes);
-    const int dst_chars = dst_num_bytes / sizeof(wchar_t);
+    memset(dst, 0, (size_t)dst_num_bytes);
+    const int dst_chars = dst_num_bytes / (int)sizeof(wchar_t);
     const int dst_needed = MultiByteToWideChar(CP_UTF8, 0, src, -1, 0, 0);
     if ((dst_needed > 0) && (dst_needed < dst_chars)) {
         MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, dst_chars);
@@ -1935,7 +1935,7 @@ EM_JS(void, sfetch_js_send_head_request, (uint32_t slot_id, const char* path_cst
 });
 
 /* if bytes_to_read != 0, a range-request will be sent, otherwise a normal request */
-EM_JS(void, sfetch_js_send_get_request, (uint32_t slot_id, const char* path_cstr, int offset, int bytes_to_read, void* buf_ptr, int buf_size), {
+EM_JS(void, sfetch_js_send_get_request, (uint32_t slot_id, const char* path_cstr, uint32_t offset, uint32_t bytes_to_read, void* buf_ptr, uint32_t buf_size), {
     var path_str = UTF8ToString(path_cstr);
     var req = new XMLHttpRequest();
     req.open('GET', path_str);

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 301 - 239
sokol_gfx.h


+ 2 - 2
sokol_time.h

@@ -236,10 +236,10 @@ SOKOL_API_IMPL uint64_t stm_now(void) {
     #if defined(_WIN32)
         LARGE_INTEGER qpc_t;
         QueryPerformanceCounter(&qpc_t);
-        now = int64_muldiv(qpc_t.QuadPart - _stm.start.QuadPart, 1000000000, _stm.freq.QuadPart);
+        now = (uint64_t) 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 = int64_muldiv(mach_now, _stm.timebase.numer, _stm.timebase.denom);
+        now = (uint64_t) int64_muldiv((int64_t)mach_now, (int64_t)_stm.timebase.numer, (int64_t)_stm.timebase.denom);
     #elif defined(__EMSCRIPTEN__)
         double js_now = stm_js_perfnow() - _stm.start;
         SOKOL_ASSERT(js_now >= 0.0);

+ 75 - 54
util/sokol_debugtext.h

@@ -303,8 +303,10 @@
             .fonts = {
                 [0] = sdtx_font_kc853(),
                 [1] = {
-                    .ptr = my_font_data,
-                    .size = sizeof(my_font_data)
+                    .data = {
+                        .ptr = my_font_data,
+                        .size = sizeof(my_font_data)
+                    },
                     .first_char = ...,
                     .last_char = ...
                 }
@@ -330,14 +332,15 @@
     be rendered).
 
     If you provide such a complete font data array, you can drop the .first_char
-    and .last_char initialization parameters since those default to 0 and 255:
+    and .last_char initialization parameters since those default to 0 and 255,
+    note that you can also use the SDTX_RANGE() helper macro to build the
+    .data item:
 
         sdtx_setup(&sdtx_desc_t){
             .fonts = {
                 [0] = sdtx_font_kc853(),
                 [1] = {
-                    .ptr = my_font_data,
-                    .size = sizeof(my_font_data)
+                    .data = SDTX_RANGE(my_font_data)
                 }
             }
         });
@@ -352,8 +355,7 @@
             .fonts = {
                 [0] = sdtx_font_kc853(),
                 [1] = {
-                    .ptr = my_font_data,
-                    .size = sizeof(my_font_data)
+                    .data = SDTX_RANGE(my_font_data),
                     .first_char = 32,       // could also write ' '
                     .last_char = 90         // could also write 'Z'
                 }
@@ -391,6 +393,7 @@
 #define SOKOL_DEBUGTEXT_INCLUDED (1)
 #include <stdint.h>
 #include <stdbool.h>
+#include <stddef.h> // size_t
 #include <stdarg.h> // va_list
 
 #if !defined(SOKOL_GFX_INCLUDED)
@@ -426,6 +429,27 @@ typedef struct sdtx_context { uint32_t id; } sdtx_context;
 /* the default context handle */
 static const sdtx_context SDTX_DEFAULT_CONTEXT = { 0x00010001 };
 
+/*
+    sdtx_range is a pointer-size-pair struct used to pass memory
+    blobs into sokol-debugtext. When initialized from a value type
+    (array or struct), use the SDTX_RANGE() macro to build
+    an sdtx_range struct.
+*/
+typedef struct sdtx_range {
+    const void* ptr;
+    size_t size;
+} sdtx_range;
+
+// disabling this for every includer isn't great, but the warning is also quite pointless
+#if defined(_MSC_VER)
+#pragma warning(disable:4221)   /* /W4 only: nonstandard extension used: 'x': cannot be initialized using address of automatic variable 'y' */
+#endif
+#if defined(__cplusplus)
+#define SDTX_RANGE(x) sdtx_range{ &x, sizeof(x) }
+#else
+#define SDTX_RANGE(x) (sdtx_range){ &x, sizeof(x) }
+#endif
+
 /*
     sdtx_font_desc_t
 
@@ -450,8 +474,7 @@ static const sdtx_context SDTX_DEFAULT_CONTEXT = { 0x00010001 };
 #define SDTX_MAX_FONTS (8)
 
 typedef struct sdtx_font_desc_t {
-    const uint8_t* ptr;     // pointer to font pixel data
-    int16_t size;           // byte size of font pixel data
+    sdtx_range data;        // pointer to and size of font pixel data
     uint8_t first_char;     // first character index in font pixel data
     uint8_t last_char;      // last character index in font pixel data, inclusive (default: 255)
 } sdtx_font_desc_t;
@@ -3411,12 +3434,12 @@ static void _sdtx_init_pool(_sdtx_pool_t* pool, int num) {
     pool->size = num + 1;
     pool->queue_top = 0;
     /* generation counters indexable by pool slot index, slot 0 is reserved */
-    size_t gen_ctrs_size = sizeof(uint32_t) * pool->size;
+    size_t gen_ctrs_size = sizeof(uint32_t) * (size_t)pool->size;
     pool->gen_ctrs = (uint32_t*) SOKOL_MALLOC(gen_ctrs_size);
     SOKOL_ASSERT(pool->gen_ctrs);
     memset(pool->gen_ctrs, 0, gen_ctrs_size);
     /* it's not a bug to only reserve 'num' here */
-    pool->free_queue = (int*) SOKOL_MALLOC(sizeof(int)*num);
+    pool->free_queue = (int*) SOKOL_MALLOC(sizeof(int) * (size_t)num);
     SOKOL_ASSERT(pool->free_queue);
     /* never allocate the zero-th pool item since the invalid id is 0 */
     for (int i = pool->size-1; i >= 1; i--) {
@@ -3470,7 +3493,7 @@ static void _sdtx_setup_context_pool(const sdtx_desc_t* desc) {
     /* note: the pool will have an additional item, since slot 0 is reserved */
     SOKOL_ASSERT((desc->context_pool_size > 0) && (desc->context_pool_size < _SDTX_MAX_POOL_SIZE));
     _sdtx_init_pool(&_sdtx.context_pool.pool, desc->context_pool_size);
-    size_t pool_byte_size = sizeof(_sdtx_context_t) * _sdtx.context_pool.pool.size;
+    size_t pool_byte_size = sizeof(_sdtx_context_t) * (size_t)_sdtx.context_pool.pool.size;
     _sdtx.context_pool.contexts = (_sdtx_context_t*) SOKOL_MALLOC(pool_byte_size);
     SOKOL_ASSERT(_sdtx.context_pool.contexts);
     memset(_sdtx.context_pool.contexts, 0, pool_byte_size);
@@ -3557,6 +3580,9 @@ static sdtx_context_desc_t _sdtx_context_desc_defaults(const sdtx_context_desc_t
     res.canvas_height = _sdtx_def(res.canvas_height, _SDTX_DEFAULT_CANVAS_HEIGHT);
     res.tab_width = _sdtx_def(res.tab_width, _SDTX_DEFAULT_TAB_WIDTH);
     /* keep pixel format attrs are passed as is into pipeline creation */
+    SOKOL_ASSERT(res.char_buf_size > 0);
+    SOKOL_ASSERT(res.canvas_width > 0.0f);
+    SOKOL_ASSERT(res.canvas_height > 0.0f);
     return res;
 }
 
@@ -3567,11 +3593,9 @@ static void _sdtx_init_context(sdtx_context ctx_id, const sdtx_context_desc_t* i
     _sdtx_context_t* ctx = _sdtx_lookup_context(ctx_id.id);
     SOKOL_ASSERT(ctx);
     ctx->desc = _sdtx_context_desc_defaults(in_desc);
-    SOKOL_ASSERT(ctx->desc.canvas_width > 0.0f);
-    SOKOL_ASSERT(ctx->desc.canvas_height > 0.0f);
 
-    const uint32_t max_vertices = 6 * ctx->desc.char_buf_size;
-    const int vbuf_size = max_vertices * sizeof(_sdtx_vertex_t);
+    const int max_vertices = 6 * ctx->desc.char_buf_size;
+    const size_t vbuf_size = (size_t)max_vertices * sizeof(_sdtx_vertex_t);
     ctx->vertices = (_sdtx_vertex_t*) SOKOL_MALLOC(vbuf_size);
     SOKOL_ASSERT(ctx->vertices);
     ctx->cur_vertex_ptr = ctx->vertices;
@@ -3594,14 +3618,14 @@ static void _sdtx_init_context(sdtx_context ctx_id, const sdtx_context_desc_t* i
     pip_desc.layout.attrs[2].format = SG_VERTEXFORMAT_UBYTE4N;
     pip_desc.shader = _sdtx.shader;
     pip_desc.index_type = SG_INDEXTYPE_NONE;
-    pip_desc.blend.enabled = true;
-    pip_desc.blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA;
-    pip_desc.blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
-    pip_desc.blend.src_factor_alpha = SG_BLENDFACTOR_ZERO;
-    pip_desc.blend.dst_factor_alpha = SG_BLENDFACTOR_ONE;
-    pip_desc.blend.color_format = ctx->desc.color_format;
-    pip_desc.blend.depth_format = ctx->desc.depth_format;
-    pip_desc.rasterizer.sample_count = ctx->desc.sample_count;
+    pip_desc.sample_count = ctx->desc.sample_count;
+    pip_desc.depth.pixel_format = ctx->desc.depth_format;
+    pip_desc.colors[0].pixel_format = ctx->desc.color_format;
+    pip_desc.colors[0].blend.enabled = true;
+    pip_desc.colors[0].blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA;
+    pip_desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
+    pip_desc.colors[0].blend.src_factor_alpha = SG_BLENDFACTOR_ZERO;
+    pip_desc.colors[0].blend.dst_factor_alpha = SG_BLENDFACTOR_ONE;
     pip_desc.label = "sdtx-pipeline";
     ctx->pip = sg_make_pipeline(&pip_desc);
     SOKOL_ASSERT(SG_INVALID_ID != ctx->pip.id);
@@ -3640,11 +3664,11 @@ static bool _sdtx_is_default_context(sdtx_context ctx_id) {
 
 /* unpack linear 8x8 bits-per-pixel font data into 2D byte-per-pixel texture data */
 static void _sdtx_unpack_font(const sdtx_font_desc_t* font_desc, uint8_t* out_pixels) {
-    SOKOL_ASSERT(font_desc->ptr);
-    SOKOL_ASSERT((font_desc->size > 0) && ((font_desc->size % 8) == 0));
+    SOKOL_ASSERT(font_desc->data.ptr);
+    SOKOL_ASSERT((font_desc->data.size > 0) && ((font_desc->data.size % 8) == 0));
     SOKOL_ASSERT(font_desc->first_char <= font_desc->last_char);
-    SOKOL_ASSERT((((font_desc->last_char - font_desc->first_char) + 1) * 8) == font_desc->size);
-    const uint8_t* ptr = font_desc->ptr;
+    SOKOL_ASSERT((size_t)(((font_desc->last_char - font_desc->first_char) + 1) * 8) == font_desc->data.size);
+    const uint8_t* ptr = (const uint8_t*) font_desc->data.ptr;
     for (int chr = font_desc->first_char; chr <= font_desc->last_char; chr++) {
         for (int line = 0; line < 8; line++) {
             uint8_t bits = *ptr++;
@@ -3658,7 +3682,7 @@ static void _sdtx_unpack_font(const sdtx_font_desc_t* font_desc, uint8_t* out_pi
 static void _sdtx_setup_common(void) {
 
     /* common printf formatting buffer */
-    _sdtx.fmt_buf_size = _sdtx.desc.printf_buf_size + 1;
+    _sdtx.fmt_buf_size = (uint32_t) _sdtx.desc.printf_buf_size + 1;
     _sdtx.fmt_buf = (char*) SOKOL_MALLOC(_sdtx.fmt_buf_size);
     SOKOL_ASSERT(_sdtx.fmt_buf);
 
@@ -3678,7 +3702,7 @@ static void _sdtx_setup_common(void) {
     shd_desc.attrs[2].sem_name = "TEXCOORD";
     shd_desc.attrs[2].sem_index = 2;
     shd_desc.fs.images[0].name = "tex";
-    shd_desc.fs.images[0].type = SG_IMAGETYPE_2D;
+    shd_desc.fs.images[0].image_type = SG_IMAGETYPE_2D;
     shd_desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT;
     #if defined(SOKOL_GLCORE33)
         shd_desc.vs.source = _sdtx_vs_src_glcore33;
@@ -3691,16 +3715,12 @@ static void _sdtx_setup_common(void) {
         shd_desc.fs.entry = "main0";
         switch (sg_query_backend()) {
             case SG_BACKEND_METAL_MACOS:
-                shd_desc.vs.byte_code = _sdtx_vs_bytecode_metal_macos;
-                shd_desc.vs.byte_code_size = sizeof(_sdtx_vs_bytecode_metal_macos);
-                shd_desc.fs.byte_code = _sdtx_fs_bytecode_metal_macos;
-                shd_desc.fs.byte_code_size = sizeof(_sdtx_fs_bytecode_metal_macos);
+                shd_desc.vs.bytecode = SG_RANGE(_sdtx_vs_bytecode_metal_macos);
+                shd_desc.fs.bytecode = SG_RANGE(_sdtx_fs_bytecode_metal_macos);
                 break;
             case SG_BACKEND_METAL_IOS:
-                shd_desc.vs.byte_code = _sdtx_vs_bytecode_metal_ios;
-                shd_desc.vs.byte_code_size = sizeof(_sdtx_vs_bytecode_metal_ios);
-                shd_desc.fs.byte_code = _sdtx_fs_bytecode_metal_ios;
-                shd_desc.fs.byte_code_size = sizeof(_sdtx_fs_bytecode_metal_ios);
+                shd_desc.vs.bytecode = SG_RANGE(_sdtx_vs_bytecode_metal_ios);
+                shd_desc.fs.bytecode = SG_RANGE(_sdtx_fs_bytecode_metal_ios);
                 break;
             default:
                 shd_desc.vs.source = _sdtx_vs_src_metal_sim;
@@ -3708,10 +3728,8 @@ static void _sdtx_setup_common(void) {
                 break;
         }
     #elif defined(SOKOL_D3D11)
-        shd_desc.vs.byte_code = _sdtx_vs_bytecode_d3d11;
-        shd_desc.vs.byte_code_size = sizeof(_sdtx_vs_bytecode_d3d11);
-        shd_desc.fs.byte_code = _sdtx_fs_bytecode_d3d11;
-        shd_desc.fs.byte_code_size = sizeof(_sdtx_fs_bytecode_d3d11);
+        shd_desc.vs.bytecode = SG_RANGE(_sdtx_vs_bytecode_d3d11);
+        shd_desc.fs.bytecode = SG_RANGE(_sdtx_fs_bytecode_d3d11);
     #elif defined(SOKOL_WGPU)
         shd_desc.vs.byte_code = _sdtx_vs_bytecode_wgpu;
         shd_desc.vs.byte_code_size = sizeof(_sdtx_vs_bytecode_wgpu);
@@ -3728,7 +3746,7 @@ static void _sdtx_setup_common(void) {
     memset(_sdtx.font_pixels, 0xFF, sizeof(_sdtx.font_pixels));
     const int unpacked_font_size = 256 * 8 * 8;
     for (int i = 0; i < SDTX_MAX_FONTS; i++) {
-        if (_sdtx.desc.fonts[i].ptr) {
+        if (_sdtx.desc.fonts[i].data.ptr) {
             _sdtx_unpack_font(&_sdtx.desc.fonts[i], &_sdtx.font_pixels[i * unpacked_font_size]);
         }
     }
@@ -3743,8 +3761,7 @@ static void _sdtx_setup_common(void) {
     img_desc.mag_filter = SG_FILTER_NEAREST;
     img_desc.wrap_u = SG_WRAP_CLAMP_TO_EDGE;
     img_desc.wrap_v = SG_WRAP_CLAMP_TO_EDGE;
-    img_desc.content.subimage[0][0].ptr = _sdtx.font_pixels;
-    img_desc.content.subimage[0][0].size = sizeof(_sdtx.font_pixels);
+    img_desc.data.subimage[0][0] = SG_RANGE(_sdtx.font_pixels);
     _sdtx.font_img = sg_make_image(&img_desc);
     SOKOL_ASSERT(SG_INVALID_ID != _sdtx.font_img.id);
 
@@ -3837,7 +3854,7 @@ static inline void _sdtx_draw_char(_sdtx_context_t* ctx, uint8_t c) {
 }
 
 static inline void _sdtx_put_char(_sdtx_context_t* ctx, char c) {
-    uint8_t c_u8 = c;
+    uint8_t c_u8 = (uint8_t)c;
     if (c_u8 <= 32) {
         _sdtx_ctrl_char(ctx, c_u8);
     }
@@ -3851,11 +3868,14 @@ static sdtx_desc_t _sdtx_desc_defaults(const sdtx_desc_t* in_desc) {
     desc.context_pool_size = _sdtx_def(desc.context_pool_size, _SDTX_DEFAULT_CONTEXT_POOL_SIZE);
     desc.printf_buf_size = _sdtx_def(desc.printf_buf_size, _SDTX_DEFAULT_PRINTF_BUF_SIZE);
     for (int i = 0; i < SDTX_MAX_FONTS; i++) {
-        if (desc.fonts[i].ptr) {
+        if (desc.fonts[i].data.ptr) {
             desc.fonts[i].last_char = _sdtx_def(desc.fonts[i].last_char, 255);
         }
     }
     desc.context = _sdtx_context_desc_defaults(&desc.context);
+    SOKOL_ASSERT(desc.context_pool_size > 0);
+    SOKOL_ASSERT(desc.printf_buf_size > 0);
+    SOKOL_ASSERT(desc.context.char_buf_size > 0);
     return desc;
 }
 
@@ -3884,32 +3904,32 @@ SOKOL_API_IMPL void sdtx_shutdown(void) {
 }
 
 SOKOL_API_IMPL sdtx_font_desc_t sdtx_font_kc853(void) {
-    sdtx_font_desc_t desc = { _sdtx_font_kc853, sizeof(_sdtx_font_kc853), 0, 255 };
+    sdtx_font_desc_t desc = { { _sdtx_font_kc853, sizeof(_sdtx_font_kc853) }, 0, 255 };
     return desc;
 }
 
 SOKOL_API_IMPL sdtx_font_desc_t sdtx_font_kc854(void) {
-    sdtx_font_desc_t desc = { _sdtx_font_kc854, sizeof(_sdtx_font_kc854), 0, 255 };
+    sdtx_font_desc_t desc = { { _sdtx_font_kc854, sizeof(_sdtx_font_kc854) }, 0, 255 };
     return desc;
 }
 
 SOKOL_API_IMPL sdtx_font_desc_t sdtx_font_z1013(void) {
-    sdtx_font_desc_t desc = { _sdtx_font_z1013, sizeof(_sdtx_font_z1013), 0, 255 };
+    sdtx_font_desc_t desc = { { _sdtx_font_z1013, sizeof(_sdtx_font_z1013) }, 0, 255 };
     return desc;
 }
 
 SOKOL_API_IMPL sdtx_font_desc_t sdtx_font_cpc(void) {
-    sdtx_font_desc_t desc = { _sdtx_font_cpc, sizeof(_sdtx_font_cpc), 0, 255 };
+    sdtx_font_desc_t desc = { { _sdtx_font_cpc, sizeof(_sdtx_font_cpc) }, 0, 255 };
     return desc;
 }
 
 SOKOL_API_IMPL sdtx_font_desc_t sdtx_font_c64(void) {
-    sdtx_font_desc_t desc = { _sdtx_font_c64, sizeof(_sdtx_font_c64), 0, 255 };
+    sdtx_font_desc_t desc = { { _sdtx_font_c64, sizeof(_sdtx_font_c64) }, 0, 255 };
     return desc;
 }
 
 SOKOL_API_IMPL sdtx_font_desc_t sdtx_font_oric(void) {
-    sdtx_font_desc_t desc = { _sdtx_font_oric, sizeof(_sdtx_font_oric), 0, 255 };
+    sdtx_font_desc_t desc = { { _sdtx_font_oric, sizeof(_sdtx_font_oric) }, 0, 255 };
     return desc;
 }
 
@@ -4161,7 +4181,8 @@ SOKOL_API_IMPL void sdtx_draw(void) {
         if (num_verts > 0) {
             SOKOL_ASSERT((num_verts % 6) == 0);
             sg_push_debug_group("sokol-debugtext");
-            int vbuf_offset = sg_append_buffer(ctx->vbuf, ctx->vertices, num_verts * sizeof(_sdtx_vertex_t));
+            const sg_range range = { ctx->vertices, (size_t)num_verts * sizeof(_sdtx_vertex_t) };
+            int vbuf_offset = sg_append_buffer(ctx->vbuf, &range);
             sg_apply_pipeline(ctx->pip);
             sg_bindings bindings;
             memset(&bindings, 0, sizeof(bindings));

+ 16 - 22
util/sokol_fontstash.h

@@ -1610,7 +1610,7 @@ static int _sfons_render_create(void* user_ptr, int width, int height) {
         ub->uniforms[0].type = SG_UNIFORMTYPE_FLOAT4;
         ub->uniforms[0].array_count = 8;
         shd_desc.fs.images[0].name = "tex";
-        shd_desc.fs.images[0].type = SG_IMAGETYPE_2D;
+        shd_desc.fs.images[0].image_type = SG_IMAGETYPE_2D;
         shd_desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT;
         shd_desc.label = "sokol-fontstash-shader";
         #if defined(SOKOL_GLCORE33)
@@ -1624,16 +1624,12 @@ static int _sfons_render_create(void* user_ptr, int width, int height) {
             shd_desc.fs.entry = "main0";
             switch (sg_query_backend()) {
                 case SG_BACKEND_METAL_MACOS:
-                    shd_desc.vs.byte_code = _sfons_vs_bytecode_metal_macos;
-                    shd_desc.vs.byte_code_size = sizeof(_sfons_vs_bytecode_metal_macos);
-                    shd_desc.fs.byte_code = _sfons_fs_bytecode_metal_macos;
-                    shd_desc.fs.byte_code_size = sizeof(_sfons_fs_bytecode_metal_macos);
+                    shd_desc.vs.bytecode = SG_RANGE(_sfons_vs_bytecode_metal_macos);
+                    shd_desc.fs.bytecode = SG_RANGE(_sfons_fs_bytecode_metal_macos);
                     break;
                 case SG_BACKEND_METAL_IOS:
-                    shd_desc.vs.byte_code = _sfons_vs_bytecode_metal_ios;
-                    shd_desc.vs.byte_code_size = sizeof(_sfons_vs_bytecode_metal_ios);
-                    shd_desc.fs.byte_code = _sfons_fs_bytecode_metal_ios;
-                    shd_desc.fs.byte_code_size = sizeof(_sfons_fs_bytecode_metal_ios);
+                    shd_desc.vs.bytecode = SG_RANGE(_sfons_vs_bytecode_metal_ios);
+                    shd_desc.fs.bytecode = SG_RANGE(_sfons_fs_bytecode_metal_ios);
                     break;
                 default:
                     shd_desc.vs.source = _sfons_vs_source_metal_sim;
@@ -1641,10 +1637,8 @@ static int _sfons_render_create(void* user_ptr, int width, int height) {
                     break;
             }
         #elif defined(SOKOL_D3D11)
-            shd_desc.vs.byte_code = _sfons_vs_bytecode_hlsl4;
-            shd_desc.vs.byte_code_size = sizeof(_sfons_vs_bytecode_hlsl4);
-            shd_desc.fs.byte_code = _sfons_fs_bytecode_hlsl4;
-            shd_desc.fs.byte_code_size = sizeof(_sfons_fs_bytecode_hlsl4);
+            shd_desc.vs.bytecode = SG_RANGE(_sfons_vs_bytecode_hlsl4);
+            shd_desc.fs.bytecode = SG_RANGE(_sfons_fs_bytecode_hlsl4);
         #elif defined(SOKOL_WGPU)
             shd_desc.vs.byte_code = _sfons_vs_bytecode_wgpu;
             shd_desc.vs.byte_code_size = sizeof(_sfons_vs_bytecode_wgpu);
@@ -1663,9 +1657,9 @@ static int _sfons_render_create(void* user_ptr, int width, int height) {
         sg_pipeline_desc pip_desc;
         memset(&pip_desc, 0, sizeof(pip_desc));
         pip_desc.shader = sfons->shd;
-        pip_desc.blend.enabled = true;
-        pip_desc.blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA;
-        pip_desc.blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
+        pip_desc.colors[0].blend.enabled = true;
+        pip_desc.colors[0].blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA;
+        pip_desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
         sfons->pip = sgl_make_pipeline(&pip_desc);
     }
 
@@ -1776,16 +1770,16 @@ SOKOL_API_IMPL void sfons_flush(FONScontext* ctx) {
     _sfons_t* sfons = (_sfons_t*) ctx->params.userPtr;
     if (sfons->img_dirty) {
         sfons->img_dirty = false;
-        sg_image_content content;
-        memset(&content, 0, sizeof(content));
-        content.subimage[0][0].ptr = ctx->texData;
-        content.subimage[0][0].size = sfons->width * sfons->height;
-        sg_update_image(sfons->img, &content);
+        sg_image_data data;
+        memset(&data, 0, sizeof(data));
+        data.subimage[0][0].ptr = ctx->texData;
+        data.subimage[0][0].size = (size_t) (sfons->width * sfons->height);
+        sg_update_image(sfons->img, &data);
     }
 }
 
 SOKOL_API_IMPL uint32_t sfons_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
-    return (r) | (g<<8) | (b<<16) | (a<<24);
+    return ((uint32_t)r) | ((uint32_t)g<<8) | ((uint32_t)b<<16) | ((uint32_t)a<<24);
 }
 
 #endif /* SOKOL_FONTSTASH_IMPL */

+ 138 - 123
util/sokol_gfx_imgui.h

@@ -378,7 +378,7 @@ typedef struct {
 
 typedef struct {
     sg_buffer buffer;
-    int data_size;
+    size_t data_size;
 } sg_imgui_args_update_buffer_t;
 
 typedef struct {
@@ -387,7 +387,7 @@ typedef struct {
 
 typedef struct {
     sg_buffer buffer;
-    int data_size;
+    size_t data_size;
     int result;
 } sg_imgui_args_append_buffer_t;
 
@@ -423,10 +423,9 @@ typedef struct {
 typedef struct {
     sg_shader_stage stage;
     int ub_index;
-    const void* data;
-    int num_bytes;
+    size_t data_size;
     sg_pipeline pipeline;   /* the pipeline which was active at this call */
-    uint32_t ubuf_pos;      /* start of copied data in capture buffer */
+    size_t ubuf_pos;        /* start of copied data in capture buffer */
 } sg_imgui_args_apply_uniforms_t;
 
 typedef struct {
@@ -596,10 +595,10 @@ typedef struct {
 } sg_imgui_capture_item_t;
 
 typedef struct {
-    uint32_t ubuf_size;     /* size of uniform capture buffer in bytes */
-    uint32_t ubuf_pos;      /* current uniform buffer pos */
+    size_t ubuf_size;       /* size of uniform capture buffer in bytes */
+    size_t ubuf_pos;        /* current uniform buffer pos */
     uint8_t* ubuf;          /* buffer for capturing uniform updates */
-    uint32_t num_items;
+    int num_items;
     sg_imgui_capture_item_t items[SG_IMGUI_MAX_FRAMECAPTURE_ITEMS];
 } sg_imgui_capture_bucket_t;
 
@@ -608,8 +607,8 @@ typedef struct {
 */
 typedef struct {
     bool open;
-    uint32_t bucket_index;      /* which bucket to record to, 0 or 1 */
-    uint32_t sel_item;          /* currently selected capture item by index */
+    int bucket_index;      /* which bucket to record to, 0 or 1 */
+    int sel_item;          /* currently selected capture item by index */
     sg_imgui_capture_bucket_t bucket[2];
 } sg_imgui_capture_t;
 
@@ -806,7 +805,7 @@ _SOKOL_PRIVATE int _sg_imgui_uniform_size(sg_uniform_type type, int count) {
     }
 }
 
-_SOKOL_PRIVATE void* _sg_imgui_alloc(int size) {
+_SOKOL_PRIVATE void* _sg_imgui_alloc(size_t size) {
     SOKOL_ASSERT(size > 0);
     return SOKOL_MALLOC(size);
 }
@@ -817,7 +816,7 @@ _SOKOL_PRIVATE void _sg_imgui_free(void* ptr) {
     }
 }
 
-_SOKOL_PRIVATE void* _sg_imgui_realloc(void* old_ptr, int old_size, int new_size) {
+_SOKOL_PRIVATE void* _sg_imgui_realloc(void* old_ptr, size_t old_size, size_t new_size) {
     SOKOL_ASSERT((new_size > 0) && (new_size > old_size));
     void* new_ptr = SOKOL_MALLOC(new_size);
     SOKOL_ASSERT(new_ptr);
@@ -853,17 +852,17 @@ _SOKOL_PRIVATE sg_imgui_str_t _sg_imgui_make_str(const char* str) {
 
 _SOKOL_PRIVATE const char* _sg_imgui_str_dup(const char* src) {
     SOKOL_ASSERT(src);
-    int len = (int) strlen(src) + 1;
+    size_t len = strlen(src) + 1;
     char* dst = (char*) _sg_imgui_alloc(len);
     memcpy(dst, src, len);
     return (const char*) dst;
 }
 
-_SOKOL_PRIVATE const uint8_t* _sg_imgui_bin_dup(const uint8_t* src, int num_bytes) {
+_SOKOL_PRIVATE const void* _sg_imgui_bin_dup(const void* src, size_t num_bytes) {
     SOKOL_ASSERT(src && (num_bytes > 0));
-    uint8_t* dst = (uint8_t*) _sg_imgui_alloc(num_bytes);
+    void* dst = _sg_imgui_alloc(num_bytes);
     memcpy(dst, src, num_bytes);
-    return (const uint8_t*) dst;
+    return (const void*) dst;
 }
 
 _SOKOL_PRIVATE void _sg_imgui_snprintf(sg_imgui_str_t* dst, const char* fmt, ...) {
@@ -1155,7 +1154,7 @@ _SOKOL_PRIVATE const char* _sg_imgui_blendop_string(sg_blend_op op) {
     }
 }
 
-_SOKOL_PRIVATE const char* _sg_imgui_colormask_string(uint8_t m) {
+_SOKOL_PRIVATE const char* _sg_imgui_colormask_string(sg_color_mask m) {
     static const char* str[] = {
         "NONE",
         "R",
@@ -1206,6 +1205,11 @@ _SOKOL_PRIVATE const char* _sg_imgui_bool_string(bool b) {
     return b ? "true" : "false";
 }
 
+_SOKOL_PRIVATE const char* _sg_imgui_color_string(sg_imgui_str_t* dst_str, sg_color color) {
+    _sg_imgui_snprintf(dst_str, "%.3f %.3f %.3f %.3f", color.r, color.g, color.b, color.a);
+    return dst_str->buf;
+}
+
 _SOKOL_PRIVATE sg_imgui_str_t _sg_imgui_res_id_string(uint32_t res_id, const char* label) {
     SOKOL_ASSERT(label);
     sg_imgui_str_t res;
@@ -1353,14 +1357,14 @@ _SOKOL_PRIVATE void _sg_imgui_shader_created(sg_imgui_t* ctx, sg_shader res_id,
     if (shd->desc.vs.source) {
         shd->desc.vs.source = _sg_imgui_str_dup(shd->desc.vs.source);
     }
-    if (shd->desc.vs.byte_code) {
-        shd->desc.vs.byte_code = _sg_imgui_bin_dup(shd->desc.vs.byte_code, shd->desc.vs.byte_code_size);
+    if (shd->desc.vs.bytecode.ptr) {
+        shd->desc.vs.bytecode.ptr = _sg_imgui_bin_dup(shd->desc.vs.bytecode.ptr, shd->desc.vs.bytecode.size);
     }
     if (shd->desc.fs.source) {
         shd->desc.fs.source = _sg_imgui_str_dup(shd->desc.fs.source);
     }
-    if (shd->desc.fs.byte_code) {
-        shd->desc.fs.byte_code = _sg_imgui_bin_dup(shd->desc.fs.byte_code, shd->desc.fs.byte_code_size);
+    if (shd->desc.fs.bytecode.ptr) {
+        shd->desc.fs.bytecode.ptr = _sg_imgui_bin_dup(shd->desc.fs.bytecode.ptr, shd->desc.fs.bytecode.size);
     }
     for (int i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) {
         sg_shader_attr_desc* ad = &shd->desc.attrs[i];
@@ -1383,17 +1387,17 @@ _SOKOL_PRIVATE void _sg_imgui_shader_destroyed(sg_imgui_t* ctx, int slot_index)
         _sg_imgui_free((void*)shd->desc.vs.source);
         shd->desc.vs.source = 0;
     }
-    if (shd->desc.vs.byte_code) {
-        _sg_imgui_free((void*)shd->desc.vs.byte_code);
-        shd->desc.vs.byte_code = 0;
+    if (shd->desc.vs.bytecode.ptr) {
+        _sg_imgui_free((void*)shd->desc.vs.bytecode.ptr);
+        shd->desc.vs.bytecode.ptr = 0;
     }
     if (shd->desc.fs.source) {
         _sg_imgui_free((void*)shd->desc.fs.source);
         shd->desc.fs.source = 0;
     }
-    if (shd->desc.fs.byte_code) {
-        _sg_imgui_free((void*)shd->desc.fs.byte_code);
-        shd->desc.fs.byte_code = 0;
+    if (shd->desc.fs.bytecode.ptr) {
+        _sg_imgui_free((void*)shd->desc.fs.bytecode.ptr);
+        shd->desc.fs.bytecode.ptr = 0;
     }
 }
 
@@ -1432,7 +1436,7 @@ _SOKOL_PRIVATE void _sg_imgui_pass_destroyed(sg_imgui_t* ctx, int slot_index) {
 
 /*--- COMMAND CAPTURING ------------------------------------------------------*/
 _SOKOL_PRIVATE void _sg_imgui_capture_init(sg_imgui_t* ctx) {
-    const int ubuf_initial_size = 256 * 1024;
+    const size_t ubuf_initial_size = 256 * 1024;
     for (int i = 0; i < 2; i++) {
         sg_imgui_capture_bucket_t* bucket = &ctx->capture.bucket[i];
         bucket->ubuf_size = ubuf_initial_size;
@@ -1465,11 +1469,11 @@ _SOKOL_PRIVATE void _sg_imgui_capture_next_frame(sg_imgui_t* ctx) {
     bucket->ubuf_pos = 0;
 }
 
-_SOKOL_PRIVATE void _sg_imgui_capture_grow_ubuf(sg_imgui_t* ctx, uint32_t required_size) {
+_SOKOL_PRIVATE void _sg_imgui_capture_grow_ubuf(sg_imgui_t* ctx, size_t required_size) {
     sg_imgui_capture_bucket_t* bucket = _sg_imgui_capture_get_write_bucket(ctx);
     SOKOL_ASSERT(required_size > bucket->ubuf_size);
-    int old_size = bucket->ubuf_size;
-    int new_size = required_size + (required_size>>1);  /* allocate a bit ahead */
+    size_t old_size = bucket->ubuf_size;
+    size_t new_size = required_size + (required_size>>1);  /* allocate a bit ahead */
     bucket->ubuf_size = new_size;
     bucket->ubuf = (uint8_t*) _sg_imgui_realloc(bucket->ubuf, old_size, new_size);
 }
@@ -1485,27 +1489,27 @@ _SOKOL_PRIVATE sg_imgui_capture_item_t* _sg_imgui_capture_next_write_item(sg_img
     }
 }
 
-_SOKOL_PRIVATE uint32_t _sg_imgui_capture_num_read_items(sg_imgui_t* ctx) {
+_SOKOL_PRIVATE int _sg_imgui_capture_num_read_items(sg_imgui_t* ctx) {
     sg_imgui_capture_bucket_t* bucket = _sg_imgui_capture_get_read_bucket(ctx);
     return bucket->num_items;
 }
 
-_SOKOL_PRIVATE sg_imgui_capture_item_t* _sg_imgui_capture_read_item_at(sg_imgui_t* ctx, uint32_t index) {
+_SOKOL_PRIVATE sg_imgui_capture_item_t* _sg_imgui_capture_read_item_at(sg_imgui_t* ctx, int index) {
     sg_imgui_capture_bucket_t* bucket = _sg_imgui_capture_get_read_bucket(ctx);
     SOKOL_ASSERT(index < bucket->num_items);
     return &bucket->items[index];
 }
 
-_SOKOL_PRIVATE uint32_t _sg_imgui_capture_uniforms(sg_imgui_t* ctx, const void* data, int num_bytes) {
+_SOKOL_PRIVATE size_t _sg_imgui_capture_uniforms(sg_imgui_t* ctx, const sg_range* data) {
     sg_imgui_capture_bucket_t* bucket = _sg_imgui_capture_get_write_bucket(ctx);
-    const uint32_t required_size = bucket->ubuf_pos + num_bytes;
+    const size_t required_size = bucket->ubuf_pos + data->size;
     if (required_size > bucket->ubuf_size) {
         _sg_imgui_capture_grow_ubuf(ctx, required_size);
     }
     SOKOL_ASSERT(required_size <= bucket->ubuf_size);
-    memcpy(bucket->ubuf + bucket->ubuf_pos, data, num_bytes);
-    const uint32_t pos = bucket->ubuf_pos;
-    bucket->ubuf_pos += num_bytes;
+    memcpy(bucket->ubuf + bucket->ubuf_pos, data->ptr, data->size);
+    const size_t pos = bucket->ubuf_pos;
+    bucket->ubuf_pos += data->size;
     SOKOL_ASSERT(bucket->ubuf_pos <= bucket->ubuf_size);
     return pos;
 }
@@ -1590,7 +1594,7 @@ _SOKOL_PRIVATE sg_imgui_str_t _sg_imgui_capture_item_string(sg_imgui_t* ctx, int
         case SG_IMGUI_CMD_UPDATE_BUFFER:
             {
                 sg_imgui_str_t res_id = _sg_imgui_buffer_id_string(ctx, item->args.update_buffer.buffer);
-                _sg_imgui_snprintf(&str, "%d: sg_update_buffer(buf=%s, data_ptr=.., data_size=%d)",
+                _sg_imgui_snprintf(&str, "%d: sg_update_buffer(buf=%s, data.size=%d)",
                     index, res_id.buf,
                     item->args.update_buffer.data_size);
             }
@@ -1606,7 +1610,7 @@ _SOKOL_PRIVATE sg_imgui_str_t _sg_imgui_capture_item_string(sg_imgui_t* ctx, int
         case SG_IMGUI_CMD_APPEND_BUFFER:
             {
                 sg_imgui_str_t res_id = _sg_imgui_buffer_id_string(ctx, item->args.append_buffer.buffer);
-                _sg_imgui_snprintf(&str, "%d: sg_append_buffer(buf=%s, data_ptr=.., data_size=%d) => %d",
+                _sg_imgui_snprintf(&str, "%d: sg_append_buffer(buf=%s, data.size=%d) => %d",
                     index, res_id.buf,
                     item->args.append_buffer.data_size,
                     item->args.append_buffer.result);
@@ -1659,11 +1663,11 @@ _SOKOL_PRIVATE sg_imgui_str_t _sg_imgui_capture_item_string(sg_imgui_t* ctx, int
             break;
 
         case SG_IMGUI_CMD_APPLY_UNIFORMS:
-            _sg_imgui_snprintf(&str, "%d: sg_apply_uniforms(stage=%s, ub_index=%d, data=.., num_bytes=%d)",
+            _sg_imgui_snprintf(&str, "%d: sg_apply_uniforms(stage=%s, ub_index=%d, data.size=%d)",
                 index,
                 _sg_imgui_shaderstage_string(item->args.apply_uniforms.stage),
                 item->args.apply_uniforms.ub_index,
-                item->args.apply_uniforms.num_bytes);
+                item->args.apply_uniforms.data_size);
             break;
 
         case SG_IMGUI_CMD_DRAW:
@@ -2093,7 +2097,7 @@ _SOKOL_PRIVATE void _sg_imgui_destroy_pass(sg_pass pass, void* user_data) {
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_update_buffer(sg_buffer buf, const void* data_ptr, int data_size, void* user_data) {
+_SOKOL_PRIVATE void _sg_imgui_update_buffer(sg_buffer buf, const sg_range* data, void* user_data) {
     sg_imgui_t* ctx = (sg_imgui_t*) user_data;
     SOKOL_ASSERT(ctx);
     sg_imgui_capture_item_t* item = _sg_imgui_capture_next_write_item(ctx);
@@ -2101,14 +2105,14 @@ _SOKOL_PRIVATE void _sg_imgui_update_buffer(sg_buffer buf, const void* data_ptr,
         item->cmd = SG_IMGUI_CMD_UPDATE_BUFFER;
         item->color = _SG_IMGUI_COLOR_RSRC;
         item->args.update_buffer.buffer = buf;
-        item->args.update_buffer.data_size = data_size;
+        item->args.update_buffer.data_size = data->size;
     }
     if (ctx->hooks.update_buffer) {
-        ctx->hooks.update_buffer(buf, data_ptr, data_size, ctx->hooks.user_data);
+        ctx->hooks.update_buffer(buf, data, ctx->hooks.user_data);
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_update_image(sg_image img, const sg_image_content* data, void* user_data) {
+_SOKOL_PRIVATE void _sg_imgui_update_image(sg_image img, const sg_image_data* data, void* user_data) {
     sg_imgui_t* ctx = (sg_imgui_t*) user_data;
     SOKOL_ASSERT(ctx);
     sg_imgui_capture_item_t* item = _sg_imgui_capture_next_write_item(ctx);
@@ -2122,7 +2126,7 @@ _SOKOL_PRIVATE void _sg_imgui_update_image(sg_image img, const sg_image_content*
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_append_buffer(sg_buffer buf, const void* data_ptr, int data_size, int result, void* user_data) {
+_SOKOL_PRIVATE void _sg_imgui_append_buffer(sg_buffer buf, const sg_range* data, int result, void* user_data) {
     sg_imgui_t* ctx = (sg_imgui_t*) user_data;
     SOKOL_ASSERT(ctx);
     sg_imgui_capture_item_t* item = _sg_imgui_capture_next_write_item(ctx);
@@ -2130,11 +2134,11 @@ _SOKOL_PRIVATE void _sg_imgui_append_buffer(sg_buffer buf, const void* data_ptr,
         item->cmd = SG_IMGUI_CMD_APPEND_BUFFER;
         item->color = _SG_IMGUI_COLOR_RSRC;
         item->args.append_buffer.buffer = buf;
-        item->args.append_buffer.data_size = data_size;
+        item->args.append_buffer.data_size = data->size;
         item->args.append_buffer.result = result;
     }
     if (ctx->hooks.append_buffer) {
-        ctx->hooks.append_buffer(buf, data_ptr, data_size, result, ctx->hooks.user_data);
+        ctx->hooks.append_buffer(buf, data, result, ctx->hooks.user_data);
     }
 }
 
@@ -2237,9 +2241,10 @@ _SOKOL_PRIVATE void _sg_imgui_apply_bindings(const sg_bindings* bindings, void*
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_apply_uniforms(sg_shader_stage stage, int ub_index, const void* data, int num_bytes, void* user_data) {
+_SOKOL_PRIVATE void _sg_imgui_apply_uniforms(sg_shader_stage stage, int ub_index, const sg_range* data, void* user_data) {
     sg_imgui_t* ctx = (sg_imgui_t*) user_data;
     SOKOL_ASSERT(ctx);
+    SOKOL_ASSERT(data);
     sg_imgui_capture_item_t* item = _sg_imgui_capture_next_write_item(ctx);
     if (item) {
         item->cmd = SG_IMGUI_CMD_APPLY_UNIFORMS;
@@ -2247,13 +2252,12 @@ _SOKOL_PRIVATE void _sg_imgui_apply_uniforms(sg_shader_stage stage, int ub_index
         sg_imgui_args_apply_uniforms_t* args = &item->args.apply_uniforms;
         args->stage = stage;
         args->ub_index = ub_index;
-        args->data = data;
-        args->num_bytes = num_bytes;
+        args->data_size = data->size;
         args->pipeline = ctx->cur_pipeline;
-        args->ubuf_pos = _sg_imgui_capture_uniforms(ctx, data, num_bytes);
+        args->ubuf_pos = _sg_imgui_capture_uniforms(ctx, data);
     }
     if (ctx->hooks.apply_uniforms) {
-        ctx->hooks.apply_uniforms(stage, ub_index, data, num_bytes, ctx->hooks.user_data);
+        ctx->hooks.apply_uniforms(stage, ub_index, data, ctx->hooks.user_data);
     }
 }
 
@@ -2977,9 +2981,9 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pass_list(sg_imgui_t* ctx) {
 
 _SOKOL_PRIVATE void _sg_imgui_draw_capture_list(sg_imgui_t* ctx) {
     igBeginChildStr("capture_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
-    const uint32_t num_items = _sg_imgui_capture_num_read_items(ctx);
+    const int num_items = _sg_imgui_capture_num_read_items(ctx);
     uint64_t group_stack = 1;   /* bit set: group unfolded, cleared: folded */
-    for (uint32_t i = 0; i < num_items; i++) {
+    for (int i = 0; i < num_items; i++) {
         const sg_imgui_capture_item_t* item = _sg_imgui_capture_read_item_at(ctx, i);
         sg_imgui_str_t item_string = _sg_imgui_capture_item_string(ctx, i, item);
         igPushStyleColorU32(ImGuiCol_Text, item->color);
@@ -3035,7 +3039,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_buffer_panel(sg_imgui_t* ctx, sg_buffer buf)
                 igText("Update Frame Index: %d", info.update_frame_index);
                 igText("Append Frame Index: %d", info.append_frame_index);
                 igText("Append Pos:         %d", info.append_pos);
-                igText("Append Overflow:    %s", info.append_overflow ? "YES":"NO");
+                igText("Append Overflow:    %s", _sg_imgui_bool_string(info.append_overflow));
             }
         }
         else {
@@ -3080,7 +3084,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_image_panel(sg_imgui_t* ctx, sg_image img) {
             igSeparator();
             igText("Type:              %s", _sg_imgui_imagetype_string(desc->type));
             igText("Usage:             %s", _sg_imgui_usage_string(desc->usage));
-            igText("Render Target:     %s", desc->render_target ? "YES":"NO");
+            igText("Render Target:     %s", _sg_imgui_bool_string(desc->render_target));
             igText("Width:             %d", desc->width);
             igText("Height:            %d", desc->height);
             igText("Num Slices:        %d", desc->num_slices);
@@ -3124,7 +3128,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(const sg_shader_stage_desc* stag
     }
     int num_valid_images = 0;
     for (int i = 0; i < SG_MAX_SHADERSTAGE_IMAGES; i++) {
-        if (_SG_IMAGETYPE_DEFAULT != stage->images[i].type) {
+        if (_SG_IMAGETYPE_DEFAULT != stage->images[i].image_type) {
             num_valid_images++;
         }
         else {
@@ -3155,10 +3159,10 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(const sg_shader_stage_desc* stag
         if (igTreeNodeStr("Images")) {
             for (int i = 0; i < SG_MAX_SHADERSTAGE_IMAGES; i++) {
                 const sg_shader_image_desc* sid = &stage->images[i];
-                if (sid->type != _SG_IMAGETYPE_DEFAULT) {
-                    igText("slot: %d\n  name: %s\n  type: %s\n  sampler_type: %s",
+                if (sid->image_type != _SG_IMAGETYPE_DEFAULT) {
+                    igText("slot: %d\n  name: %s\n  image_type: %s\n  sampler_type: %s",
                         i, sid->name ? sid->name : "NONE",
-                        _sg_imgui_imagetype_string(sid->type),
+                        _sg_imgui_imagetype_string(sid->image_type),
                         _sg_imgui_samplertype_string(sid->sampler_type));
                 }
                 else {
@@ -3180,7 +3184,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(const sg_shader_stage_desc* stag
             igTreePop();
         }
     }
-    else if (stage->byte_code) {
+    else if (stage->bytecode.ptr) {
         if (igTreeNodeStr("Byte Code")) {
             igText("Byte-code display currently not supported.");
             igTreePop();
@@ -3252,53 +3256,54 @@ _SOKOL_PRIVATE void _sg_imgui_draw_vertex_layout(const sg_layout_desc* layout) {
     }
 }
 
+_SOKOL_PRIVATE void _sg_imgui_draw_stencil_face_state(const sg_stencil_face_state* sfs) {
+    igText("Fail Op:       %s", _sg_imgui_stencilop_string(sfs->fail_op));
+    igText("Depth Fail Op: %s", _sg_imgui_stencilop_string(sfs->depth_fail_op));
+    igText("Pass Op:       %s", _sg_imgui_stencilop_string(sfs->pass_op));
+    igText("Compare:       %s", _sg_imgui_comparefunc_string(sfs->compare));
+}
+
 _SOKOL_PRIVATE void _sg_imgui_draw_stencil_state(const sg_stencil_state* ss) {
-    igText("Fail Op:       %s", _sg_imgui_stencilop_string(ss->fail_op));
-    igText("Depth Fail Op: %s", _sg_imgui_stencilop_string(ss->depth_fail_op));
-    igText("Pass Op:       %s", _sg_imgui_stencilop_string(ss->pass_op));
-    igText("Compare Func:  %s", _sg_imgui_comparefunc_string(ss->compare_func));
-}
-
-_SOKOL_PRIVATE void _sg_imgui_draw_depth_stencil_state(const sg_depth_stencil_state* dss) {
-    igText("Depth Compare Func:  %s", _sg_imgui_comparefunc_string(dss->depth_compare_func));
-    igText("Depth Write Enabled: %s", dss->depth_write_enabled ? "YES":"NO");
-    igText("Stencil Enabled:     %s", dss->stencil_enabled ? "YES":"NO");
-    igText("Stencil Read Mask:   0x%02X", dss->stencil_read_mask);
-    igText("Stencil Write Mask:  0x%02X", dss->stencil_write_mask);
-    igText("Stencil Ref:         0x%02X", dss->stencil_ref);
-    if (igTreeNodeStr("Stencil Front")) {
-        _sg_imgui_draw_stencil_state(&dss->stencil_front);
+    igText("Enabled:    %s", _sg_imgui_bool_string(ss->enabled));
+    igText("Read Mask:  0x%02X", ss->read_mask);
+    igText("Write Mask: 0x%02X", ss->write_mask);
+    igText("Ref:        0x%02X", ss->ref);
+    if (igTreeNodeStr("Front")) {
+        _sg_imgui_draw_stencil_face_state(&ss->front);
         igTreePop();
     }
-    if (igTreeNodeStr("Stencil Back")) {
-        _sg_imgui_draw_stencil_state(&dss->stencil_back);
+    if (igTreeNodeStr("Back")) {
+        _sg_imgui_draw_stencil_face_state(&ss->back);
         igTreePop();
     }
 }
 
+_SOKOL_PRIVATE void _sg_imgui_draw_depth_state(const sg_depth_state* ds) {
+    igText("Pixel Format:  %s", _sg_imgui_pixelformat_string(ds->pixel_format));
+    igText("Compare:       %s", _sg_imgui_comparefunc_string(ds->compare));
+    igText("Write Enabled: %s", _sg_imgui_bool_string(ds->write_enabled));
+    igText("Bias:          %f", ds->bias);
+    igText("Bias Slope:    %f", ds->bias_slope_scale);
+    igText("Bias Clamp:    %f", ds->bias_clamp);
+}
+
 _SOKOL_PRIVATE void _sg_imgui_draw_blend_state(const sg_blend_state* bs) {
-    igText("Blend Enabled:    %s", bs->enabled ? "YES":"NO");
+    igText("Blend Enabled:    %s", _sg_imgui_bool_string(bs->enabled));
     igText("Src Factor RGB:   %s", _sg_imgui_blendfactor_string(bs->src_factor_rgb));
     igText("Dst Factor RGB:   %s", _sg_imgui_blendfactor_string(bs->dst_factor_rgb));
     igText("Op RGB:           %s", _sg_imgui_blendop_string(bs->op_rgb));
     igText("Src Factor Alpha: %s", _sg_imgui_blendfactor_string(bs->src_factor_alpha));
     igText("Dst Factor Alpha: %s", _sg_imgui_blendfactor_string(bs->dst_factor_alpha));
     igText("Op Alpha:         %s", _sg_imgui_blendop_string(bs->op_alpha));
-    igText("Color Write Mask: %s", _sg_imgui_colormask_string(bs->color_write_mask));
-    igText("Attachment Count: %d", bs->color_attachment_count);
-    igText("Color Format:     %s", _sg_imgui_pixelformat_string(bs->color_format));
-    igText("Depth Format:     %s", _sg_imgui_pixelformat_string(bs->depth_format));
-    igText("Blend Color:      %.3f %.3f %.3f %.3f", bs->blend_color[0], bs->blend_color[1], bs->blend_color[2], bs->blend_color[3]);
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_rasterizer_state(const sg_rasterizer_state* rs) {
-    igText("Alpha to Coverage: %s", rs->alpha_to_coverage_enabled ? "YES":"NO");
-    igText("Cull Mode:         %s", _sg_imgui_cullmode_string(rs->cull_mode));
-    igText("Face Winding:      %s", _sg_imgui_facewinding_string(rs->face_winding));
-    igText("Sample Count:      %d", rs->sample_count);
-    igText("Depth Bias:        %f", rs->depth_bias);
-    igText("Depth Bias Slope:  %f", rs->depth_bias_slope_scale);
-    igText("Depth Bias Clamp:  %f", rs->depth_bias_clamp);
+_SOKOL_PRIVATE void _sg_imgui_draw_color_state(const sg_color_state* cs) {
+    igText("Pixel Format:     %s", _sg_imgui_pixelformat_string(cs->pixel_format));
+    igText("Write Mask:       %s", _sg_imgui_colormask_string(cs->write_mask));
+    if (igTreeNodeStr("Blend State:")) {
+        _sg_imgui_draw_blend_state(&cs->blend);
+        igTreePop();
+    }
 }
 
 _SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, sg_pipeline pip) {
@@ -3314,24 +3319,35 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, sg_pipeline p
             if (_sg_imgui_draw_shader_link(ctx, pip_ui->desc.shader)) {
                 _sg_imgui_show_shader(ctx, pip_ui->desc.shader);
             }
-            igText("Prim Type:  %s", _sg_imgui_primitivetype_string(pip_ui->desc.primitive_type));
-            igText("Index Type: %s", _sg_imgui_indextype_string(pip_ui->desc.index_type));
             if (igTreeNodeStr("Vertex Layout")) {
                 _sg_imgui_draw_vertex_layout(&pip_ui->desc.layout);
                 igTreePop();
             }
-            if (igTreeNodeStr("Depth Stencil State")) {
-                _sg_imgui_draw_depth_stencil_state(&pip_ui->desc.depth_stencil);
+            if (igTreeNodeStr("Depth State")) {
+                _sg_imgui_draw_depth_state(&pip_ui->desc.depth);
                 igTreePop();
             }
-            if (igTreeNodeStr("Blend State")) {
-                _sg_imgui_draw_blend_state(&pip_ui->desc.blend);
+            if (igTreeNodeStr("Stencil State")) {
+                _sg_imgui_draw_stencil_state(&pip_ui->desc.stencil);
                 igTreePop();
             }
-            if (igTreeNodeStr("Rasterizer State")) {
-                _sg_imgui_draw_rasterizer_state(&pip_ui->desc.rasterizer);
-                igTreePop();
+            igText("Color Count: %d", pip_ui->desc.color_count);
+            for (int i = 0; i < pip_ui->desc.color_count; i++) {
+                sg_imgui_str_t str;
+                _sg_imgui_snprintf(&str, "Color %d", i);
+                if (igTreeNodeStr(str.buf)) {
+                    _sg_imgui_draw_color_state(&pip_ui->desc.colors[i]);
+                    igTreePop();
+                }
             }
+            igText("Prim Type:      %s", _sg_imgui_primitivetype_string(pip_ui->desc.primitive_type));
+            igText("Index Type:     %s", _sg_imgui_indextype_string(pip_ui->desc.index_type));
+            igText("Cull Mode:      %s", _sg_imgui_cullmode_string(pip_ui->desc.cull_mode));
+            igText("Face Winding:   %s", _sg_imgui_facewinding_string(pip_ui->desc.face_winding));
+            igText("Sample Count:   %d", pip_ui->desc.sample_count);
+            sg_imgui_str_t blend_color_str;
+            igText("Blend Color:    %.3f %.3f %.3f %.3f", _sg_imgui_color_string(&blend_color_str, pip_ui->desc.blend_color));
+            igText("Alpha To Coverage: %s", _sg_imgui_bool_string(pip_ui->desc.alpha_to_coverage_enabled));
         }
         else {
             igText("Pipeline 0x%08X not valid.", pip.id);
@@ -3340,7 +3356,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, sg_pipeline p
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_attachment(sg_imgui_t* ctx, const sg_attachment_desc* att, float* img_scale) {
+_SOKOL_PRIVATE void _sg_imgui_draw_pass_attachment(sg_imgui_t* ctx, const sg_pass_attachment_desc* att, float* img_scale) {
     igText("  Image: "); igSameLine(0,-1);
     if (_sg_imgui_draw_image_link(ctx, att->image)) {
         _sg_imgui_show_image(ctx, att->image);
@@ -3364,12 +3380,12 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pass_panel(sg_imgui_t* ctx, sg_pass pass) {
                 }
                 igSeparator();
                 igText("Color Attachment #%d:", i);
-                _sg_imgui_draw_attachment(ctx, &pass_ui->desc.color_attachments[i], &pass_ui->color_image_scale[i]);
+                _sg_imgui_draw_pass_attachment(ctx, &pass_ui->desc.color_attachments[i], &pass_ui->color_image_scale[i]);
             }
             if (pass_ui->desc.depth_stencil_attachment.image.id != SG_INVALID_ID) {
                 igSeparator();
                 igText("Depth-Stencil Attachemnt:");
-                _sg_imgui_draw_attachment(ctx, &pass_ui->desc.depth_stencil_attachment, &pass_ui->ds_image_scale);
+                _sg_imgui_draw_pass_attachment(ctx, &pass_ui->desc.depth_stencil_attachment, &pass_ui->ds_image_scale);
             }
         }
         else {
@@ -3454,14 +3470,14 @@ _SOKOL_PRIVATE void _sg_imgui_draw_uniforms_panel(sg_imgui_t* ctx, const sg_imgu
     const sg_shader_uniform_block_desc* ub_desc = (args->stage == SG_SHADERSTAGE_VS) ?
         &shd_ui->desc.vs.uniform_blocks[args->ub_index] :
         &shd_ui->desc.fs.uniform_blocks[args->ub_index];
-    SOKOL_ASSERT(args->num_bytes <= ub_desc->size);
+    SOKOL_ASSERT(args->data_size <= ub_desc->size);
     bool draw_dump = false;
     if (ub_desc->uniforms[0].type == SG_UNIFORMTYPE_INVALID) {
         draw_dump = true;
     }
 
     sg_imgui_capture_bucket_t* bucket = _sg_imgui_capture_get_read_bucket(ctx);
-    SOKOL_ASSERT((args->ubuf_pos + args->num_bytes) <= bucket->ubuf_size);
+    SOKOL_ASSERT((args->ubuf_pos + args->data_size) <= bucket->ubuf_size);
     const float* uptrf = (const float*) (bucket->ubuf + args->ubuf_pos);
     if (!draw_dump) {
         for (int i = 0; i < SG_MAX_UB_MEMBERS; i++) {
@@ -3504,12 +3520,12 @@ _SOKOL_PRIVATE void _sg_imgui_draw_uniforms_panel(sg_imgui_t* ctx, const sg_imgu
                         igText("???");
                         break;
                 }
-                uptrf += _sg_imgui_uniform_size(ud->type, 1) / sizeof(float);
+                uptrf += _sg_imgui_uniform_size(ud->type, 1) / (int)sizeof(float);
             }
         }
     }
     else {
-        const uint32_t num_floats = ub_desc->size / sizeof(float);
+        const size_t num_floats = ub_desc->size / sizeof(float);
         for (uint32_t i = 0; i < num_floats; i++) {
             igText("%.3f, ", uptrf[i]);
             if (((i + 1) % 4) != 0) {
@@ -3539,15 +3555,12 @@ _SOKOL_PRIVATE void _sg_imgui_draw_passaction_panel(sg_imgui_t* ctx, sg_pass pas
     for (int i = 0; i < num_color_atts; i++) {
         const sg_color_attachment_action* c_att = &action->colors[i];
         igText("  Color Attachment %d:", i);
+        sg_imgui_str_t color_str;
         switch (c_att->action) {
             case SG_ACTION_LOAD: igText("    SG_ACTION_LOAD"); break;
             case SG_ACTION_DONTCARE: igText("    SG_ACTION_DONTCARE"); break;
             default:
-                igText("    SG_ACTION_CLEAR: %.3f, %.3f, %.3f, %.3f",
-                    c_att->val[0],
-                    c_att->val[1],
-                    c_att->val[2],
-                    c_att->val[3]);
+                igText("    SG_ACTION_CLEAR: %s", _sg_imgui_color_string(&color_str, c_att->value));
                 break;
         }
     }
@@ -3556,19 +3569,19 @@ _SOKOL_PRIVATE void _sg_imgui_draw_passaction_panel(sg_imgui_t* ctx, sg_pass pas
     switch (d_att->action) {
         case SG_ACTION_LOAD: igText("    SG_ACTION_LOAD"); break;
         case SG_ACTION_DONTCARE: igText("    SG_ACTION_DONTCARE"); break;
-        default: igText("    SG_ACTION_CLEAR: %.3f", d_att->val); break;
+        default: igText("    SG_ACTION_CLEAR: %.3f", d_att->value); break;
     }
     const sg_stencil_attachment_action* s_att = &action->stencil;
     igText("  Stencil Attachment");
     switch (s_att->action) {
         case SG_ACTION_LOAD: igText("    SG_ACTION_LOAD"); break;
         case SG_ACTION_DONTCARE: igText("    SG_ACTION_DONTCARE"); break;
-        default: igText("    SG_ACTION_CLEAR: 0x%02X", s_att->val); break;
+        default: igText("    SG_ACTION_CLEAR: 0x%02X", s_att->value); break;
     }
 }
 
 _SOKOL_PRIVATE void _sg_imgui_draw_capture_panel(sg_imgui_t* ctx) {
-    uint32_t sel_item_index = ctx->capture.sel_item;
+    int sel_item_index = ctx->capture.sel_item;
     if (sel_item_index >= _sg_imgui_capture_num_read_items(ctx)) {
         return;
     }
@@ -3709,6 +3722,8 @@ _SOKOL_PRIVATE void _sg_imgui_draw_caps_panel(void) {
     igText("    imagetype_3d: %s", _sg_imgui_bool_string(f.imagetype_3d));
     igText("    imagetype_array: %s", _sg_imgui_bool_string(f.imagetype_array));
     igText("    image_clamp_to_border: %s", _sg_imgui_bool_string(f.image_clamp_to_border));
+    igText("    mrt_independent_blend_state: %s", _sg_imgui_bool_string(f.mrt_independent_blend_state));
+    igText("    mrt_independent_write_mask: %s", _sg_imgui_bool_string(f.mrt_independent_write_mask));
     sg_limits l = sg_query_limits();
     igText("\nLimits:\n");
     igText("    max_image_size_2d: %d", l.max_image_size_2d);
@@ -3815,27 +3830,27 @@ SOKOL_API_IMPL void sg_imgui_init(sg_imgui_t* ctx) {
     ctx->pipelines.num_slots = desc.pipeline_pool_size;
     ctx->passes.num_slots = desc.pass_pool_size;
 
-    const int buffer_pool_size = ctx->buffers.num_slots * sizeof(sg_imgui_buffer_t);
+    const size_t buffer_pool_size = (size_t)ctx->buffers.num_slots * sizeof(sg_imgui_buffer_t);
     ctx->buffers.slots = (sg_imgui_buffer_t*) _sg_imgui_alloc(buffer_pool_size);
     SOKOL_ASSERT(ctx->buffers.slots);
     memset(ctx->buffers.slots, 0, buffer_pool_size);
 
-    const int image_pool_size = ctx->images.num_slots * sizeof(sg_imgui_image_t);
+    const size_t image_pool_size = (size_t)ctx->images.num_slots * sizeof(sg_imgui_image_t);
     ctx->images.slots = (sg_imgui_image_t*) _sg_imgui_alloc(image_pool_size);
     SOKOL_ASSERT(ctx->images.slots);
     memset(ctx->images.slots, 0, image_pool_size);
 
-    const int shader_pool_size = ctx->shaders.num_slots * sizeof(sg_imgui_shader_t);
+    const size_t shader_pool_size = (size_t)ctx->shaders.num_slots * sizeof(sg_imgui_shader_t);
     ctx->shaders.slots = (sg_imgui_shader_t*) _sg_imgui_alloc(shader_pool_size);
     SOKOL_ASSERT(ctx->shaders.slots);
     memset(ctx->shaders.slots, 0, shader_pool_size);
 
-    const int pipeline_pool_size = ctx->pipelines.num_slots * sizeof(sg_imgui_pipeline_t);
+    const size_t pipeline_pool_size = (size_t)ctx->pipelines.num_slots * sizeof(sg_imgui_pipeline_t);
     ctx->pipelines.slots = (sg_imgui_pipeline_t*) _sg_imgui_alloc(pipeline_pool_size);
     SOKOL_ASSERT(ctx->pipelines.slots);
     memset(ctx->pipelines.slots, 0, pipeline_pool_size);
 
-    const int pass_pool_size = ctx->passes.num_slots * sizeof(sg_imgui_pass_t);
+    const size_t pass_pool_size = (size_t)ctx->passes.num_slots * sizeof(sg_imgui_pass_t);
     ctx->passes.slots = (sg_imgui_pass_t*) _sg_imgui_alloc(pass_pool_size);
     SOKOL_ASSERT(ctx->passes.slots);
     memset(ctx->passes.slots, 0, pass_pool_size);

+ 46 - 36
util/sokol_gl.h

@@ -206,6 +206,13 @@
             sgl_viewport(int x, int y, int w, int h, bool origin_top_left)
             sgl_scissor_rect(int x, int y, int w, int h, bool origin_top_left)
 
+        ...or call these alternatives which take float arguments (this might allow
+        to avoid casting between float and integer in more strongly typed languages
+        when floating point pixel coordinates are used):
+
+            sgl_viewportf(float x, float y, float w, float h, bool origin_top_left)
+            sgl_scissor_rectf(float x, float y, float w, float h, bool origin_top_left)
+
         ...these calls add a new command to the internal command queue, so
         that the viewport or scissor rect are set at the right time relative
         to other sokol-gl calls.
@@ -509,7 +516,9 @@ SOKOL_GL_API_DECL void sgl_destroy_pipeline(sgl_pipeline pip);
 
 /* render state functions */
 SOKOL_GL_API_DECL void sgl_viewport(int x, int y, int w, int h, bool origin_top_left);
+SOKOL_GL_API_DECL void sgl_viewportf(float x, float y, float w, float h, bool origin_top_left);
 SOKOL_GL_API_DECL void sgl_scissor_rect(int x, int y, int w, int h, bool origin_top_left);
+SOKOL_GL_API_DECL void sgl_scissor_rectf(float x, float y, float w, float h, bool origin_top_left);
 SOKOL_GL_API_DECL void sgl_enable_texture(void);
 SOKOL_GL_API_DECL void sgl_disable_texture(void);
 SOKOL_GL_API_DECL void sgl_texture(sg_image img);
@@ -2078,12 +2087,12 @@ static void _sgl_init_pool(_sgl_pool_t* pool, int num) {
     pool->size = num + 1;
     pool->queue_top = 0;
     /* generation counters indexable by pool slot index, slot 0 is reserved */
-    size_t gen_ctrs_size = sizeof(uint32_t) * pool->size;
+    size_t gen_ctrs_size = sizeof(uint32_t) * (size_t)pool->size;
     pool->gen_ctrs = (uint32_t*) SOKOL_MALLOC(gen_ctrs_size);
     SOKOL_ASSERT(pool->gen_ctrs);
     memset(pool->gen_ctrs, 0, gen_ctrs_size);
     /* it's not a bug to only reserve 'num' here */
-    pool->free_queue = (int*) SOKOL_MALLOC(sizeof(int)*num);
+    pool->free_queue = (int*) SOKOL_MALLOC(sizeof(int) * (size_t)num);
     SOKOL_ASSERT(pool->free_queue);
     /* never allocate the zero-th pool item since the invalid id is 0 */
     for (int i = pool->size-1; i >= 1; i--) {
@@ -2142,7 +2151,7 @@ static void _sgl_setup_pipeline_pool(const sgl_desc_t* desc) {
     /* note: the pools here will have an additional item, since slot 0 is reserved */
     SOKOL_ASSERT((desc->pipeline_pool_size > 0) && (desc->pipeline_pool_size < _SGL_MAX_POOL_SIZE));
     _sgl_init_pool(&_sgl.pip_pool.pool, desc->pipeline_pool_size);
-    size_t pool_byte_size = sizeof(_sgl_pipeline_t) * _sgl.pip_pool.pool.size;
+    size_t pool_byte_size = sizeof(_sgl_pipeline_t) * (size_t)_sgl.pip_pool.pool.size;
     _sgl.pip_pool.pips = (_sgl_pipeline_t*) SOKOL_MALLOC(pool_byte_size);
     SOKOL_ASSERT(_sgl.pip_pool.pips);
     memset(_sgl.pip_pool.pips, 0, pool_byte_size);
@@ -2245,14 +2254,14 @@ static void _sgl_init_pipeline(sgl_pipeline pip_id, const sg_pipeline_desc* in_d
         desc.shader = _sgl.shd;
     }
     desc.index_type = SG_INDEXTYPE_NONE;
-    desc.blend.color_format = _sgl.desc.color_format;
-    desc.blend.depth_format = _sgl.desc.depth_format;
-    desc.rasterizer.sample_count = _sgl.desc.sample_count;
-    if (desc.rasterizer.face_winding == _SG_FACEWINDING_DEFAULT) {
-        desc.rasterizer.face_winding = _sgl.desc.face_winding;
+    desc.sample_count = _sgl.desc.sample_count;
+    if (desc.face_winding == _SG_FACEWINDING_DEFAULT) {
+        desc.face_winding = _sgl.desc.face_winding;
     }
-    if (desc.blend.color_write_mask == _SG_COLORMASK_DEFAULT) {
-        desc.blend.color_write_mask = SG_COLORMASK_RGB;
+    desc.depth.pixel_format = _sgl.desc.depth_format;
+    desc.colors[0].pixel_format = _sgl.desc.color_format;
+    if (desc.colors[0].write_mask == _SG_COLORMASK_DEFAULT) {
+        desc.colors[0].write_mask = SG_COLORMASK_RGB;
     }
 
     _sgl_pipeline_t* pip = _sgl_lookup_pipeline(pip_id.id);
@@ -2647,11 +2656,11 @@ SOKOL_API_IMPL void sgl_setup(const sgl_desc_t* desc) {
     _sgl.num_vertices = _sgl.desc.max_vertices;
     _sgl.num_uniforms = _sgl.desc.max_commands;
     _sgl.num_commands = _sgl.num_uniforms;
-    _sgl.vertices = (_sgl_vertex_t*) SOKOL_MALLOC(_sgl.num_vertices * sizeof(_sgl_vertex_t));
+    _sgl.vertices = (_sgl_vertex_t*) SOKOL_MALLOC((size_t)_sgl.num_vertices * sizeof(_sgl_vertex_t));
     SOKOL_ASSERT(_sgl.vertices);
-    _sgl.uniforms = (_sgl_uniform_t*) SOKOL_MALLOC(_sgl.num_uniforms * sizeof(_sgl_uniform_t));
+    _sgl.uniforms = (_sgl_uniform_t*) SOKOL_MALLOC((size_t)_sgl.num_uniforms * sizeof(_sgl_uniform_t));
     SOKOL_ASSERT(_sgl.uniforms);
-    _sgl.commands = (_sgl_command_t*) SOKOL_MALLOC(_sgl.num_commands * sizeof(_sgl_command_t));
+    _sgl.commands = (_sgl_command_t*) SOKOL_MALLOC((size_t)_sgl.num_commands * sizeof(_sgl_command_t));
     SOKOL_ASSERT(_sgl.commands);
     _sgl_setup_pipeline_pool(&_sgl.desc);
 
@@ -2660,7 +2669,7 @@ SOKOL_API_IMPL void sgl_setup(const sgl_desc_t* desc) {
 
     sg_buffer_desc vbuf_desc;
     memset(&vbuf_desc, 0, sizeof(vbuf_desc));
-    vbuf_desc.size = _sgl.num_vertices * sizeof(_sgl_vertex_t);
+    vbuf_desc.size = (size_t)_sgl.num_vertices * sizeof(_sgl_vertex_t);
     vbuf_desc.type = SG_BUFFERTYPE_VERTEXBUFFER;
     vbuf_desc.usage = SG_USAGE_STREAM;
     vbuf_desc.label = "sgl-vertex-buffer";
@@ -2680,8 +2689,7 @@ SOKOL_API_IMPL void sgl_setup(const sgl_desc_t* desc) {
     img_desc.pixel_format = SG_PIXELFORMAT_RGBA8;
     img_desc.min_filter = SG_FILTER_NEAREST;
     img_desc.mag_filter = SG_FILTER_NEAREST;
-    img_desc.content.subimage[0][0].ptr = pixels;
-    img_desc.content.subimage[0][0].size = sizeof(pixels);
+    img_desc.data.subimage[0][0] = SG_RANGE(pixels);
     img_desc.label = "sgl-default-texture";
     _sgl.def_img = sg_make_image(&img_desc);
     SOKOL_ASSERT(SG_INVALID_ID != _sgl.def_img.id);
@@ -2704,7 +2712,7 @@ SOKOL_API_IMPL void sgl_setup(const sgl_desc_t* desc) {
     ub->uniforms[0].type = SG_UNIFORMTYPE_FLOAT4;
     ub->uniforms[0].array_count = 8;
     shd_desc.fs.images[0].name = "tex";
-    shd_desc.fs.images[0].type = SG_IMAGETYPE_2D;
+    shd_desc.fs.images[0].image_type = SG_IMAGETYPE_2D;
     shd_desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT;
     shd_desc.label = "sgl-shader";
     #if defined(SOKOL_GLCORE33)
@@ -2718,16 +2726,12 @@ SOKOL_API_IMPL void sgl_setup(const sgl_desc_t* desc) {
         shd_desc.fs.entry = "main0";
         switch (sg_query_backend()) {
             case SG_BACKEND_METAL_MACOS:
-                shd_desc.vs.byte_code = _sgl_vs_bytecode_metal_macos;
-                shd_desc.vs.byte_code_size = sizeof(_sgl_vs_bytecode_metal_macos);
-                shd_desc.fs.byte_code = _sgl_fs_bytecode_metal_macos;
-                shd_desc.fs.byte_code_size = sizeof(_sgl_fs_bytecode_metal_macos);
+                shd_desc.vs.bytecode = SG_RANGE(_sgl_vs_bytecode_metal_macos);
+                shd_desc.fs.bytecode = SG_RANGE(_sgl_fs_bytecode_metal_macos);
                 break;
             case SG_BACKEND_METAL_IOS:
-                shd_desc.vs.byte_code = _sgl_vs_bytecode_metal_ios;
-                shd_desc.vs.byte_code_size = sizeof(_sgl_vs_bytecode_metal_ios);
-                shd_desc.fs.byte_code = _sgl_fs_bytecode_metal_ios;
-                shd_desc.fs.byte_code_size = sizeof(_sgl_fs_bytecode_metal_ios);
+                shd_desc.vs.bytecode = SG_RANGE(_sgl_vs_bytecode_metal_ios);
+                shd_desc.fs.bytecode = SG_RANGE(_sgl_fs_bytecode_metal_ios);
                 break;
             default:
                 shd_desc.vs.source = _sgl_vs_source_metal_sim;
@@ -2735,15 +2739,11 @@ SOKOL_API_IMPL void sgl_setup(const sgl_desc_t* desc) {
                 break;
         }
     #elif defined(SOKOL_D3D11)
-        shd_desc.vs.byte_code = _sgl_vs_bytecode_hlsl4;
-        shd_desc.vs.byte_code_size = sizeof(_sgl_vs_bytecode_hlsl4);
-        shd_desc.fs.byte_code = _sgl_fs_bytecode_hlsl4;
-        shd_desc.fs.byte_code_size = sizeof(_sgl_fs_bytecode_hlsl4);
+        shd_desc.vs.bytecode = SG_RANGE(_sgl_vs_bytecode_hlsl4);
+        shd_desc.fs.bytecode = SG_RANGE(_sgl_fs_bytecode_hlsl4);
     #elif defined(SOKOL_WGPU)
-        shd_desc.vs.byte_code = _sgl_vs_bytecode_wgpu;
-        shd_desc.vs.byte_code_size = sizeof(_sgl_vs_bytecode_wgpu);
-        shd_desc.fs.byte_code = _sgl_fs_bytecode_wgpu;
-        shd_desc.fs.byte_code_size = sizeof(_sgl_fs_bytecode_wgpu);
+        shd_desc.vs.bytecode = SG_RANGE(_sgl_vs_bytecode_wgpu);
+        shd_desc.fs.bytecode = SG_RANGE(_sgl_fs_bytecode_wgpu);
     #else
         shd_desc.vs.source = _sgl_vs_src_dummy;
         shd_desc.fs.source = _sgl_fs_src_dummy;
@@ -2754,7 +2754,7 @@ SOKOL_API_IMPL void sgl_setup(const sgl_desc_t* desc) {
     /* create default pipeline object */
     sg_pipeline_desc def_pip_desc;
     memset(&def_pip_desc, 0, sizeof(def_pip_desc));
-    def_pip_desc.depth_stencil.depth_write_enabled = true;
+    def_pip_desc.depth.write_enabled = true;
     _sgl.def_pip = _sgl_make_pipeline(&def_pip_desc);
     sg_pop_debug_group();
 
@@ -2869,6 +2869,10 @@ SOKOL_API_IMPL void sgl_viewport(int x, int y, int w, int h, bool origin_top_lef
     }
 }
 
+SOKOL_API_IMPL void sgl_viewportf(float x, float y, float w, float h, bool origin_top_left) {
+    sgl_viewport((int)x, (int)y, (int)w, (int)h, origin_top_left);
+}
+
 SOKOL_API_IMPL void sgl_scissor_rect(int x, int y, int w, int h, bool origin_top_left) {
     SOKOL_ASSERT(_SGL_INIT_COOKIE == _sgl.init_cookie);
     SOKOL_ASSERT(!_sgl.in_begin);
@@ -2883,6 +2887,10 @@ SOKOL_API_IMPL void sgl_scissor_rect(int x, int y, int w, int h, bool origin_top
     }
 }
 
+SOKOL_API_IMPL void sgl_scissor_rectf(float x, float y, float w, float h, bool origin_top_left) {
+    sgl_scissor_rect((int)x, (int)y, (int)w, (int)h, origin_top_left);
+}
+
 SOKOL_API_IMPL void sgl_enable_texture(void) {
     SOKOL_ASSERT(_SGL_INIT_COOKIE == _sgl.init_cookie);
     SOKOL_ASSERT(!_sgl.in_begin);
@@ -3236,7 +3244,8 @@ SOKOL_API_IMPL void sgl_draw(void) {
         uint32_t cur_img_id = SG_INVALID_ID;
         int cur_uniform_index = -1;
         sg_push_debug_group("sokol-gl");
-        sg_update_buffer(_sgl.vbuf, _sgl.vertices, _sgl.cur_vertex * sizeof(_sgl_vertex_t));
+        const sg_range range = { _sgl.vertices, (size_t)_sgl.cur_vertex * sizeof(_sgl_vertex_t) };
+        sg_update_buffer(_sgl.vbuf, &range);
         _sgl.bind.vertex_buffers[0] = _sgl.vbuf;
         for (int i = 0; i < _sgl.cur_command; i++) {
             const _sgl_command_t* cmd = &_sgl.commands[i];
@@ -3269,7 +3278,8 @@ SOKOL_API_IMPL void sgl_draw(void) {
                             cur_img_id = args->img.id;
                         }
                         if (cur_uniform_index != args->uniform_index) {
-                            sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &_sgl.uniforms[args->uniform_index], sizeof(_sgl_uniform_t));
+                            const sg_range ub_range = { &_sgl.uniforms[args->uniform_index], sizeof(_sgl_uniform_t) };
+                            sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &ub_range);
                             cur_uniform_index = args->uniform_index;
                         }
                         /* FIXME: what if number of vertices doesn't match the primitive type? */

+ 37 - 42
util/sokol_imgui.h

@@ -1672,7 +1672,7 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
     sg_buffer_desc vb_desc;
     memset(&vb_desc, 0, sizeof(vb_desc));
     vb_desc.usage = SG_USAGE_STREAM;
-    vb_desc.size = _simgui.desc.max_vertices * sizeof(ImDrawVert);
+    vb_desc.size = (size_t)_simgui.desc.max_vertices * sizeof(ImDrawVert);
     vb_desc.label = "sokol-imgui-vertices";
     _simgui.vbuf = sg_make_buffer(&vb_desc);
 
@@ -1680,7 +1680,7 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
     memset(&ib_desc, 0, sizeof(ib_desc));
     ib_desc.type = SG_BUFFERTYPE_INDEXBUFFER;
     ib_desc.usage = SG_USAGE_STREAM;
-    ib_desc.size = _simgui.desc.max_vertices * 3 * sizeof(uint16_t);
+    ib_desc.size = (size_t)_simgui.desc.max_vertices * 3 * sizeof(uint16_t);
     ib_desc.label = "sokol-imgui-indices";
     _simgui.ibuf = sg_make_buffer(&ib_desc);
 
@@ -1703,8 +1703,8 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
         img_desc.wrap_v = SG_WRAP_CLAMP_TO_EDGE;
         img_desc.min_filter = SG_FILTER_LINEAR;
         img_desc.mag_filter = SG_FILTER_LINEAR;
-        img_desc.content.subimage[0][0].ptr = font_pixels;
-        img_desc.content.subimage[0][0].size = font_width * font_height * sizeof(uint32_t);
+        img_desc.data.subimage[0][0].ptr = font_pixels;
+        img_desc.data.subimage[0][0].size = (size_t)(font_width * font_height) * sizeof(uint32_t);
         img_desc.label = "sokol-imgui-font";
         _simgui.img = sg_make_image(&img_desc);
         io->Fonts->TexID = (ImTextureID)(uintptr_t) _simgui.img.id;
@@ -1728,7 +1728,7 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
     ub->uniforms[0].type = SG_UNIFORMTYPE_FLOAT4;
     ub->uniforms[0].array_count = 1;
     shd_desc.fs.images[0].name = "tex";
-    shd_desc.fs.images[0].type = SG_IMAGETYPE_2D;
+    shd_desc.fs.images[0].image_type = SG_IMAGETYPE_2D;
     shd_desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT;
     shd_desc.label = "sokol-imgui-shader";
     #if defined(SOKOL_GLCORE33)
@@ -1742,16 +1742,12 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
         shd_desc.fs.entry = "main0";
         switch (sg_query_backend()) {
             case SG_BACKEND_METAL_MACOS:
-                shd_desc.vs.byte_code = _simgui_vs_bytecode_metal_macos;
-                shd_desc.vs.byte_code_size = sizeof(_simgui_vs_bytecode_metal_macos);
-                shd_desc.fs.byte_code = _simgui_fs_bytecode_metal_macos;
-                shd_desc.fs.byte_code_size = sizeof(_simgui_fs_bytecode_metal_macos);
+                shd_desc.vs.bytecode = SG_RANGE(_simgui_vs_bytecode_metal_macos);
+                shd_desc.fs.bytecode = SG_RANGE(_simgui_fs_bytecode_metal_macos);
                 break;
             case SG_BACKEND_METAL_IOS:
-                shd_desc.vs.byte_code = _simgui_vs_bytecode_metal_ios;
-                shd_desc.vs.byte_code_size = sizeof(_simgui_vs_bytecode_metal_ios);
-                shd_desc.fs.byte_code = _simgui_fs_bytecode_metal_ios;
-                shd_desc.fs.byte_code_size = sizeof(_simgui_fs_bytecode_metal_ios);
+                shd_desc.vs.bytecode = SG_RANGE(_simgui_vs_bytecode_metal_ios);
+                shd_desc.fs.bytecode = SG_RANGE(_simgui_fs_bytecode_metal_ios);
                 break;
             default:
                 shd_desc.vs.source = _simgui_vs_source_metal_sim;
@@ -1759,15 +1755,11 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
                 break;
         }
     #elif defined(SOKOL_D3D11)
-        shd_desc.vs.byte_code = _simgui_vs_bytecode_hlsl4;
-        shd_desc.vs.byte_code_size = sizeof(_simgui_vs_bytecode_hlsl4);
-        shd_desc.fs.byte_code = _simgui_fs_bytecode_hlsl4;
-        shd_desc.fs.byte_code_size = sizeof(_simgui_fs_bytecode_hlsl4);
+        shd_desc.vs.bytecode = SG_RANGE(_simgui_vs_bytecode_hlsl4);
+        shd_desc.fs.bytecode = SG_RANGE(_simgui_fs_bytecode_hlsl4);
     #elif defined(SOKOL_WGPU)
-        shd_desc.vs.byte_code = _simgui_vs_bytecode_wgpu;
-        shd_desc.vs.byte_code_size = sizeof(_simgui_vs_bytecode_wgpu);
-        shd_desc.fs.byte_code = _simgui_fs_bytecode_wgpu;
-        shd_desc.fs.byte_code_size = sizeof(_simgui_fs_bytecode_wgpu);
+        shd_desc.vs.bytecode = SG_RANGE(_simgui_vs_bytecode_wgpu);
+        shd_desc.fs.bytecode = SG_RANGE(_simgui_fs_bytecode_wgpu);
     #else
         shd_desc.vs.source = _simgui_vs_src_dummy;
         shd_desc.fs.source = _simgui_fs_src_dummy;
@@ -1795,13 +1787,13 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
     }
     pip_desc.shader = _simgui.shd;
     pip_desc.index_type = SG_INDEXTYPE_UINT16;
-    pip_desc.blend.enabled = true;
-    pip_desc.blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA;
-    pip_desc.blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
-    pip_desc.blend.color_write_mask = SG_COLORMASK_RGB;
-    pip_desc.blend.color_format = _simgui.desc.color_format;
-    pip_desc.blend.depth_format = _simgui.desc.depth_format;
-    pip_desc.rasterizer.sample_count = _simgui.desc.sample_count;
+    pip_desc.sample_count = _simgui.desc.sample_count;
+    pip_desc.depth.pixel_format = _simgui.desc.depth_format;
+    pip_desc.colors[0].pixel_format = _simgui.desc.color_format;
+    pip_desc.colors[0].write_mask = SG_COLORMASK_RGB;
+    pip_desc.colors[0].blend.enabled = true;
+    pip_desc.colors[0].blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA;
+    pip_desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
     pip_desc.label = "sokol-imgui-pipeline";
     _simgui.pip = sg_make_pipeline(&pip_desc);
 
@@ -1907,37 +1899,40 @@ SOKOL_API_IMPL void simgui_render(void) {
 
     sg_apply_pipeline(_simgui.pip);
     _simgui_vs_params_t vs_params;
+    memset((void*)&vs_params, 0, sizeof(vs_params));
     vs_params.disp_size.x = io->DisplaySize.x;
     vs_params.disp_size.y = io->DisplaySize.y;
-    sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &vs_params, sizeof(vs_params));
+    sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(vs_params));
     sg_bindings bind;
-    memset(&bind, 0, sizeof(bind));
+    memset((void*)&bind, 0, sizeof(bind));
     bind.vertex_buffers[0] = _simgui.vbuf;
     bind.index_buffer = _simgui.ibuf;
     ImTextureID tex_id = io->Fonts->TexID;
     bind.fs_images[0].id = (uint32_t)(uintptr_t)tex_id;
-    uint32_t vb_offset = 0;
-    uint32_t ib_offset = 0;
+    int vb_offset = 0;
+    int ib_offset = 0;
     for (int cl_index = 0; cl_index < draw_data->CmdListsCount; cl_index++) {
         ImDrawList* cl = draw_data->CmdLists[cl_index];
 
         /* append vertices and indices to buffers, record start offsets in draw state */
         #if defined(__cplusplus)
-            const int vtx_size = cl->VtxBuffer.size() * sizeof(ImDrawVert);
-            const int idx_size = cl->IdxBuffer.size() * sizeof(ImDrawIdx);
+            const size_t vtx_size = cl->VtxBuffer.size() * sizeof(ImDrawVert);
+            const size_t idx_size = cl->IdxBuffer.size() * sizeof(ImDrawIdx);
             const ImDrawVert* vtx_ptr = &cl->VtxBuffer.front();
             const ImDrawIdx* idx_ptr = &cl->IdxBuffer.front();
         #else
-            const int vtx_size = cl->VtxBuffer.Size * sizeof(ImDrawVert);
-            const int idx_size = cl->IdxBuffer.Size * sizeof(ImDrawIdx);
+            const size_t vtx_size = (size_t)cl->VtxBuffer.Size * sizeof(ImDrawVert);
+            const size_t idx_size = (size_t)cl->IdxBuffer.Size * sizeof(ImDrawIdx);
             const ImDrawVert* vtx_ptr = cl->VtxBuffer.Data;
             const ImDrawIdx* idx_ptr = cl->IdxBuffer.Data;
         #endif
         if (vtx_ptr) {
-            vb_offset = sg_append_buffer(bind.vertex_buffers[0], vtx_ptr, vtx_size);
+            const sg_range vtx_range = { vtx_ptr, vtx_size };
+            vb_offset = sg_append_buffer(bind.vertex_buffers[0], &vtx_range);
         }
         if (idx_ptr) {
-            ib_offset = sg_append_buffer(bind.index_buffer, idx_ptr, idx_size);
+            const sg_range idx_range = { idx_ptr, idx_size };
+            ib_offset = sg_append_buffer(bind.index_buffer, &idx_range);
         }
         /* don't render anything if the buffer is in overflow state (this is also
             checked internally in sokol_gfx, draw calls that attempt to draw with
@@ -1966,7 +1961,7 @@ SOKOL_API_IMPL void simgui_render(void) {
                 // need to re-apply all state after calling a user callback
                 sg_apply_viewport(0, 0, fb_width, fb_height, true);
                 sg_apply_pipeline(_simgui.pip);
-                sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &vs_params, sizeof(vs_params));
+                sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(vs_params));
                 sg_apply_bindings(&bind);
             }
             else {
@@ -1974,7 +1969,7 @@ SOKOL_API_IMPL void simgui_render(void) {
                     tex_id = pcmd->TextureId;
                     vtx_offset = pcmd->VtxOffset;
                     bind.fs_images[0].id = (uint32_t)(uintptr_t)tex_id;
-                    bind.vertex_buffer_offsets[0] = vb_offset + pcmd->VtxOffset * sizeof(ImDrawVert);
+                    bind.vertex_buffer_offsets[0] = vb_offset + (int)(pcmd->VtxOffset * sizeof(ImDrawVert));
                     sg_apply_bindings(&bind);
                 }
                 const int scissor_x = (int) (pcmd->ClipRect.x * dpi_scale);
@@ -1982,9 +1977,9 @@ SOKOL_API_IMPL void simgui_render(void) {
                 const int scissor_w = (int) ((pcmd->ClipRect.z - pcmd->ClipRect.x) * dpi_scale);
                 const int scissor_h = (int) ((pcmd->ClipRect.w - pcmd->ClipRect.y) * dpi_scale);
                 sg_apply_scissor_rect(scissor_x, scissor_y, scissor_w, scissor_h, true);
-                sg_draw(base_element, pcmd->ElemCount, 1);
+                sg_draw(base_element, (int)pcmd->ElemCount, 1);
             }
-            base_element += pcmd->ElemCount;
+            base_element += (int)pcmd->ElemCount;
         }
     }
     sg_apply_viewport(0, 0, fb_width, fb_height, true);

+ 1 - 1
util/sokol_memtrack.h

@@ -74,7 +74,6 @@
         distribution.
 */
 #define SOKOL_MEMTRACK_INCLUDED (1)
-#include <stddef.h>
 #include <stdint.h>
 
 #if defined(SOKOL_API_DECL) && !defined(SOKOL_MEMTRACK_API_DECL)
@@ -111,6 +110,7 @@ SOKOL_MEMTRACK_API_DECL smemtrack_info_t smemtrack_info(void);
 #define SOKOL_MEMTRACK_IMPL_INCLUDED (1)
 #include <stdlib.h> /* malloc, free, calloc */
 #include <string.h> /* memset */
+#include <stddef.h> /* size_t */
 
 #ifndef SOKOL_API_IMPL
     #define SOKOL_API_IMPL

+ 53 - 29
util/sokol_shape.h

@@ -83,12 +83,10 @@
 
     sshape_buffer_t buf = {
         .vertices = {
-            .buffer_ptr = vertices,
-            .buffer_size = sizeof(vertices)
+            .buffer = SSHAPE_RANGE(vertices),
         },
         .indices = {
-            .buffer_ptr = indices,
-            .buffer_size = sizeof(indices)
+            .buffer = SSHAPE_RANGE(indices),
         }
     };
     ```
@@ -222,7 +220,7 @@
     ```c
     // create sokol-gfx vertex buffer
     sg_buffer_desc vbuf_desc = sshape_vertex_buffer_desc(&buf);
-    sg_buffer vbuf = sg_make_buffer(&vbuf_desc;
+    sg_buffer vbuf = sg_make_buffer(&vbuf_desc);
 
     // create sokol-gfx index buffer
     sg_buffer_desc ibuf_desc = sshape_index_buffer_desc(&buf);
@@ -267,8 +265,8 @@
     uint16_t indices[16];
 
     sshape_buffer_t buf = {
-        .vertices = { .buffer_ptr = vertices, .buffer_size = sizeof(vertices) },
-        .indices  = { .buffer_ptr = indices,  .buffer_size = sizeof(indices) }
+        .vertices.buffer = SSHAPE_RANGE(vertices),
+        .indices.buffer  = SSHAPE_RANGE(indices)
     };
 
     // first cube at pos x=-2.0 (with default size of 1x1x1)
@@ -312,8 +310,8 @@
     sshape_vertex_t vertices[128];
     uint16_t indices[16];
     sshape_buffer_t buf = {
-        .vertices = { .buffer_ptr = vertices, .buffer_size = sizeof(vertices) },
-        .indices  = { .buffer_ptr = indices,  .buffer_size = sizeof(indices) }
+        .vertices.buffer = SSHAPE_RANGE(vertices),
+        .indices.buffer = SSHAPE_RANGE(indices)
     };
 
     // build a red cube...
@@ -362,6 +360,7 @@
         distribution.
 */
 #define SOKOL_SHAPE_INCLUDED
+#include <stddef.h>     // size_t, offsetof
 #include <stdint.h>
 #include <stdbool.h>
 
@@ -386,6 +385,27 @@
 extern "C" {
 #endif
 
+/*
+    sshape_range is a pointer-size-pair struct used to pass memory
+    blobs into sokol-shape. When initialized from a value type
+    (array or struct), use the SSHAPE_RANGE() macro to build
+    an sshape_range struct.
+*/
+typedef struct sshape_range {
+    const void* ptr;
+    size_t size;
+} sshape_range;
+
+// disabling this for every includer isn't great, but the warning is also quite pointless
+#if defined(_MSC_VER)
+#pragma warning(disable:4221)   /* /W4 only: nonstandard extension used: 'x': cannot be initialized using address of automatic variable 'y' */
+#endif
+#if defined(__cplusplus)
+#define SSHAPE_RANGE(x) sshape_range{ &x, sizeof(x) }
+#else
+#define SSHAPE_RANGE(x) (sshape_range){ &x, sizeof(x) }
+#endif
+
 /* a 4x4 matrix wrapper struct */
 typedef struct sshape_mat4_t { float m[4][4]; } sshape_mat4_t;
 
@@ -401,12 +421,18 @@ typedef struct sshape_vertex_t {
 typedef struct sshape_element_range_t {
     int base_element;
     int num_elements;
+    #if defined(SOKOL_ZIG_BINDINGS)
+    uint32_t __pad[3];
+    #endif
 } sshape_element_range_t;
 
 /* number of elements and byte size of build actions */
 typedef struct sshape_sizes_item_t {
     uint32_t num;       // number of elements
     uint32_t size;      // the same as size in bytes
+    #if defined(SOKOL_ZIG_BINDINGS)
+    uint32_t __pad[3];
+    #endif
 } sshape_sizes_item_t;
 
 typedef struct sshape_sizes_t {
@@ -416,10 +442,9 @@ typedef struct sshape_sizes_t {
 
 /* in/out struct to keep track of mesh-build state */
 typedef struct sshape_buffer_item_t {
-    void* buffer_ptr;       // pointer to start of output buffer
-    uint32_t buffer_size;   // size in bytes of output buffer
-    uint32_t data_size;     // size in bytes of valid data in buffer
-    uint32_t shape_offset;  // data offset of the most recent shape
+    sshape_range buffer;    // pointer/size pair of output buffer
+    size_t data_size;       // size in bytes of valid data in buffer
+    size_t shape_offset;    // data offset of the most recent shape
 } sshape_buffer_item_t;
 
 typedef struct sshape_buffer_t {
@@ -526,7 +551,6 @@ SOKOL_SHAPE_API_DECL sshape_mat4_t sshape_mat4_transpose(const float m[16]);
 #define SOKOL_SHAPE_IMPL_INCLUDED (1)
 
 #include <string.h> // memcpy
-#include <stddef.h> // offsetof
 #include <math.h>   // sinf, cosf
 
 #ifdef __clang__
@@ -674,13 +698,13 @@ static uint32_t _sshape_torus_num_indices(uint32_t sides, uint32_t rings) {
 }
 
 static bool _sshape_validate_buffer_item(const sshape_buffer_item_t* item, uint32_t build_size) {
-    if (0 == item->buffer_ptr) {
+    if (0 == item->buffer.ptr) {
         return false;
     }
-    if (0 == item->buffer_size) {
+    if (0 == item->buffer.size) {
         return false;
     }
-    if ((item->data_size + build_size) > item->buffer_size) {
+    if ((item->data_size + build_size) > item->buffer.size) {
         return false;
     }
     if (item->shape_offset > item->data_size) {
@@ -761,10 +785,10 @@ static sshape_torus_t _sshape_torus_defaults(const sshape_torus_t* params) {
 }
 
 static void _sshape_add_vertex(sshape_buffer_t* buf, _sshape_vec4_t pos, _sshape_vec4_t norm, _sshape_vec2_t uv, uint32_t color) {
-    uint32_t offset = buf->vertices.data_size;
-    SOKOL_ASSERT((offset + sizeof(sshape_vertex_t)) <= buf->vertices.buffer_size);
+    size_t offset = buf->vertices.data_size;
+    SOKOL_ASSERT((offset + sizeof(sshape_vertex_t)) <= buf->vertices.buffer.size);
     buf->vertices.data_size += sizeof(sshape_vertex_t);
-    sshape_vertex_t* v_ptr = (sshape_vertex_t*) ((uint8_t*)buf->vertices.buffer_ptr + offset);
+    sshape_vertex_t* v_ptr = (sshape_vertex_t*) ((uint8_t*)buf->vertices.buffer.ptr + offset);
     v_ptr->x = pos.x;
     v_ptr->y = pos.y;
     v_ptr->z = pos.z;
@@ -775,10 +799,10 @@ static void _sshape_add_vertex(sshape_buffer_t* buf, _sshape_vec4_t pos, _sshape
 }
 
 static void _sshape_add_triangle(sshape_buffer_t* buf, uint16_t i0, uint16_t i1, uint16_t i2) {
-    uint32_t offset = buf->indices.data_size;
-    SOKOL_ASSERT((offset + 3*sizeof(uint16_t)) <= buf->indices.buffer_size);
+    size_t offset = buf->indices.data_size;
+    SOKOL_ASSERT((offset + 3*sizeof(uint16_t)) <= buf->indices.buffer.size);
     buf->indices.data_size += 3*sizeof(uint16_t);
-    uint16_t* i_ptr = (uint16_t*) ((uint8_t*)buf->indices.buffer_ptr + offset);
+    uint16_t* i_ptr = (uint16_t*) ((uint8_t*)buf->indices.buffer.ptr + offset);
     i_ptr[0] = i0;
     i_ptr[1] = i1;
     i_ptr[2] = i2;
@@ -1338,10 +1362,10 @@ SOKOL_API_IMPL sg_buffer_desc sshape_vertex_buffer_desc(const sshape_buffer_t* b
     SOKOL_ASSERT(buf && buf->valid);
     sg_buffer_desc desc = { 0 };
     if (buf->valid) {
-        desc.size = buf->vertices.data_size;
         desc.type = SG_BUFFERTYPE_VERTEXBUFFER;
         desc.usage = SG_USAGE_IMMUTABLE;
-        desc.content = buf->vertices.buffer_ptr;
+        desc.data.ptr = buf->vertices.buffer.ptr;
+        desc.data.size = buf->vertices.data_size;
     }
     return desc;
 }
@@ -1350,10 +1374,10 @@ SOKOL_API_IMPL sg_buffer_desc sshape_index_buffer_desc(const sshape_buffer_t* bu
     SOKOL_ASSERT(buf && buf->valid);
     sg_buffer_desc desc = { 0 };
     if (buf->valid) {
-        desc.size = buf->indices.data_size;
         desc.type = SG_BUFFERTYPE_INDEXBUFFER;
         desc.usage = SG_USAGE_IMMUTABLE;
-        desc.content = buf->indices.buffer_ptr;
+        desc.data.ptr = buf->indices.buffer.ptr;
+        desc.data.size = buf->indices.data_size;
     }
     return desc;
 }
@@ -1364,9 +1388,9 @@ SOKOL_SHAPE_API_DECL sshape_element_range_t sshape_element_range(const sshape_bu
     SOKOL_ASSERT(0 == (buf->indices.shape_offset & (sizeof(uint16_t) - 1)));
     SOKOL_ASSERT(0 == (buf->indices.data_size & (sizeof(uint16_t) - 1)));
     sshape_element_range_t range = { 0 };
-    range.base_element = buf->indices.shape_offset / sizeof(uint16_t);
+    range.base_element = (int) (buf->indices.shape_offset / sizeof(uint16_t));
     if (buf->valid) {
-        range.num_elements = (buf->indices.data_size - buf->indices.shape_offset) / sizeof(uint16_t);
+        range.num_elements = (int) ((buf->indices.data_size - buf->indices.shape_offset) / sizeof(uint16_t));
     }
     else {
         range.num_elements = 0;

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä