diff --git a/lib/c3/0.1/f32.facts b/lib/c3/0.1/f32.facts
new file mode 100644
index 0000000..a48256a
--- /dev/null
+++ b/lib/c3/0.1/f32.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {F32, :is_a, :module}
+replace {F32, :symbol, F32.cast}
+replace {F32.cast, :cfn, cfn F32 "f32_init_cast" (Result, Tag)}
diff --git a/lib/c3/0.1/f64.facts b/lib/c3/0.1/f64.facts
new file mode 100644
index 0000000..2b6ae72
--- /dev/null
+++ b/lib/c3/0.1/f64.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {F64, :is_a, :module}
+replace {F64, :symbol, F64.cast}
+replace {F64.cast, :cfn, cfn F64 "f64_init_cast" (Result, Tag)}
diff --git a/lib/c3/0.1/gl/object.facts b/lib/c3/0.1/gl/object.facts
new file mode 100644
index 0000000..4c6d92d
--- /dev/null
+++ b/lib/c3/0.1/gl/object.facts
@@ -0,0 +1,9 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {GL.Object, :is_a, :module}
+replace {GL.Object, :defstruct, [vertex: (GL.Vertex) {},
+ triangle: (GL.Triangle) {},
+ gl_mode: (U32) 0,
+ gl_vao: (U32) 0,
+ gl_vbo: (U32) 0,
+ gl_ebo: (U32) 0]}
diff --git a/lib/c3/0.1/gl/point2d.facts b/lib/c3/0.1/gl/point2d.facts
new file mode 100644
index 0000000..fa21d72
--- /dev/null
+++ b/lib/c3/0.1/gl/point2d.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {GL.Point2D, :is_a, :module}
+replace {GL.Point2D, :defstruct, [x: (F64) 0,
+ y: (F64) 0]}
diff --git a/lib/c3/0.1/gl/point3d.facts b/lib/c3/0.1/gl/point3d.facts
new file mode 100644
index 0000000..f5e9867
--- /dev/null
+++ b/lib/c3/0.1/gl/point3d.facts
@@ -0,0 +1,6 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {GL.Point3D, :is_a, :module}
+replace {GL.Point3D, :defstruct, [x: (F64) 0,
+ y: (F64) 0,
+ z: (F64) 0]}
diff --git a/lib/c3/0.1/gl/sphere.facts b/lib/c3/0.1/gl/sphere.facts
index 714fc2b..86f9b80 100644
--- a/lib/c3/0.1/gl/sphere.facts
+++ b/lib/c3/0.1/gl/sphere.facts
@@ -1,6 +1,6 @@
%{module: C3.Facts.Dump,
version: 1}
replace {GL.Sphere, :is_a, :module}
-replace {GL.Sphere, :defstruct, [segments_u: (Uw) 3,
- segments_v: (Uw) 2,
- vertex: (PtrFree) 0 ]}
+replace {GL.Sphere, :defstruct, [object: %GL.Object{},
+ segments_u: (Uw) 3,
+ segments_v: (Uw) 2]}
diff --git a/lib/c3/0.1/gl/triangle.facts b/lib/c3/0.1/gl/triangle.facts
new file mode 100644
index 0000000..273167d
--- /dev/null
+++ b/lib/c3/0.1/gl/triangle.facts
@@ -0,0 +1,6 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {GL.Triangle, :is_a, :module}
+replace {GL.Triangle, :defstruct, [a: (U32) 0,
+ b: (U32) 1,
+ c: (U32) 2]}
diff --git a/lib/c3/0.1/gl/vertex.facts b/lib/c3/0.1/gl/vertex.facts
new file mode 100644
index 0000000..08978d5
--- /dev/null
+++ b/lib/c3/0.1/gl/vertex.facts
@@ -0,0 +1,6 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {GL.Vertex, :is_a, :module}
+replace {GL.Vertex, :defstruct, [position: %GL.Point3D{},
+ normal: %GL.Point3D{},
+ tex_coord: %GL.Point2D{}]}
diff --git a/libc3/array.c b/libc3/array.c
index 2d0f41f..ebafd83 100644
--- a/libc3/array.c
+++ b/libc3/array.c
@@ -187,47 +187,42 @@ s_array * array_init (s_array *a, const s_sym *type, uw dimension,
assert(sym_is_module(type));
assert(dimension);
assert(dimensions);
- if (! dimension) {
- assert(! "array_init: zero dimension");
- errx(1, "array_init: zero dimension");
- return NULL;
- }
+ tmp.type = type;
+ if (dimension) {
#ifdef DEBUG
- while (i < dimension) {
- assert(dimensions[i]);
- i++;
- }
+ while (i < dimension) {
+ assert(dimensions[i]);
+ i++;
+ }
#endif
- tmp.dimension = dimension;
- tmp.dimensions = calloc(dimension, sizeof(s_array_dimension));
- i = 0;
- while (i < dimension) {
- tmp.dimensions[i].count = dimensions[i];
- count *= dimensions[i];
- i++;
- }
- i--;
- tmp.type = type;
- if (! sym_type_size(type, &item_size)) {
- free(tmp.dimensions);
- return NULL;
- }
- if (! item_size) {
- warnx("array_init: zero item size");
- assert(! "array_init: zero item size");
- return NULL;
- }
- tmp.dimensions[i].item_size = item_size;
- while (i > 0) {
+ tmp.dimension = dimension;
+ tmp.dimensions = calloc(dimension, sizeof(s_array_dimension));
+ i = 0;
+ while (i < dimension) {
+ tmp.dimensions[i].count = dimensions[i];
+ count *= dimensions[i];
+ i++;
+ }
i--;
- tmp.dimensions[i].item_size = tmp.dimensions[i + 1].count *
- tmp.dimensions[i + 1].item_size;
+ if (! sym_type_size(type, &item_size)) {
+ free(tmp.dimensions);
+ return NULL;
+ }
+ if (! item_size) {
+ warnx("array_init: zero item size");
+ assert(! "array_init: zero item size");
+ free(tmp.dimensions);
+ return NULL;
+ }
+ tmp.dimensions[i].item_size = item_size;
+ while (i > 0) {
+ i--;
+ tmp.dimensions[i].item_size = tmp.dimensions[i + 1].count *
+ tmp.dimensions[i + 1].item_size;
+ }
+ tmp.size = tmp.dimensions[0].count * tmp.dimensions[0].item_size;
+ tmp.count = count;
}
- tmp.size = tmp.dimensions[0].count * tmp.dimensions[0].item_size;
- tmp.count = count;
- tmp.data_free = NULL;
- tmp.data = NULL;
- tmp.tags = NULL;
*a = tmp;
return a;
}
diff --git a/libc3/c3.h b/libc3/c3.h
index 838c405..eaa3bd5 100644
--- a/libc3/c3.h
+++ b/libc3/c3.h
@@ -81,6 +81,7 @@
#include "sequence.h"
#include "str.h"
#include "struct.h"
+#include "struct_type.h"
#include "sw.h"
#include "tag.h"
#include "time.h"
diff --git a/libc3/env.c b/libc3/env.c
index ef43a3f..dba0213 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -837,6 +837,9 @@ s_list ** env_get_struct_type_spec (s_env *env, const s_sym *module,
s_tag tag_module;
s_tag tag_var;
s_tag tmp;
+ assert(env);
+ assert(module);
+ assert(dest);
tag_init_sym_1(&tag_defstruct, "defstruct");
tag_init_sym(&tag_module, module);
tag_init_var(&tag_var);
@@ -1157,6 +1160,26 @@ void env_push_unwind_protect (s_env *env,
env->unwind_protect = unwind_protect;
}
+bool env_struct_type_exists (s_env *env, const s_sym *module)
+{
+ s_facts_cursor cursor;
+ bool result;
+ s_tag tag_defstruct;
+ s_tag tag_module;
+ s_tag tag_var;
+ assert(env);
+ assert(module);
+ tag_init_sym_1(&tag_defstruct, "defstruct");
+ tag_init_sym(&tag_module, module);
+ tag_init_var(&tag_var);
+ env_module_maybe_reload(env, module, &env->facts);
+ facts_with_tags(&env->facts, &cursor, &tag_module,
+ &tag_defstruct, &tag_var);
+ result = facts_cursor_next(&cursor) ? true : false;
+ facts_cursor_clean(&cursor);
+ return result;
+}
+
bool env_tag_ident_is_bound (const s_env *env, const s_tag *tag,
s_facts *facts)
{
diff --git a/libc3/env.h b/libc3/env.h
index 6e412d0..8edddfa 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -77,6 +77,7 @@ s8 env_operator_precedence (s_env *env, const s_ident *op);
s_ident * env_operator_resolve (s_env *env, const s_ident *op,
u8 arity, s_ident *dest);
const s_sym * env_operator_symbol (s_env *env, const s_ident *op);
+bool env_struct_type_exists (s_env *env, const s_sym *module);
bool env_tag_ident_is_bound (const s_env *env,
const s_tag *tag, s_facts *facts);
diff --git a/libc3/hash.c b/libc3/hash.c
index 33826de..65a05ca 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -17,6 +17,7 @@
#include "hash.h"
#include "list.h"
#include "str.h"
+#include "tag.h"
#include "tag_type.h"
#define HASH_UPDATE_DEF(type) \
@@ -293,19 +294,36 @@ void hash_update_str (t_hash *hash, const s_str *str)
void hash_update_struct (t_hash *hash, const s_struct *s)
{
+ const void *data;
f_hash_update hash_update_value;
uw i = 0;
+ const s_sym *sym;
s8 type[] = "struct";
assert(hash);
assert(s);
hash_update(hash, type, sizeof(type));
+ hash_update_sym(hash, &s->type.module);
hash_update(hash, &s->type.map.count, sizeof(s->type.map.count));
while (i < s->type.map.count) {
hash_update_tag(hash, s->type.map.key + i);
if (! tag_type_to_hash_update(s->type.map.value[i].type,
&hash_update_value))
exit(1);
- hash_update_value(hash, (s8 *) s->data + s->type.offset[i]);
+ if (s->data)
+ data = (s8 *) s->data + s->type.offset[i];
+ else {
+ if (! tag_type(s->type.map.value + i, &sym))
+ exit(1);
+ if (s->tag) {
+ if (! tag_to_const_pointer(s->tag + i, sym, &data))
+ exit(1);
+ }
+ else {
+ if (! tag_to_const_pointer(s->type.map.value + i, sym, &data))
+ exit(1);
+ }
+ }
+ hash_update_value(hash, data);
i++;
}
}
diff --git a/libc3/list.c b/libc3/list.c
index 62c0285..2401c4f 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -218,20 +218,6 @@ s_list * list_new_copy (const s_tag *x, s_list *next)
return dest;
}
-/*
-s_list * list_new_f64 (f64 x, s_list *next)
-{
- s_list *dest;
- if ((dest = list_new(next))) {
- if (! tag_init_f64(&dest->tag, x)) {
- free(dest);
- return NULL;
- }
- }
- return dest;
-}
-*/
-
s_list * list_new_list (s_list *x, s_list *next)
{
s_list *dest;
@@ -244,31 +230,24 @@ s_list * list_new_list (s_list *x, s_list *next)
return dest;
}
-/*
-s_list * list_new_map (uw count, s_list *next)
-{
- s_list *dest;
- if ((dest = list_new(next))) {
- if (! tag_init_map(&dest->tag, count)) {
- free(dest);
- return NULL;
- }
- }
- return dest;
-}
-
-s_list * list_new_str_1 (s8 *x_free, const s8 *x, s_list *next)
+s_list ** list_remove_void (s_list **list)
{
- s_list *dest;
- if ((dest = list_new(next))) {
- if (! tag_init_str_1(&dest->tag, x_free, x)) {
- free(dest);
- return NULL;
- }
+ s_list *tmp;
+ s_list **l;
+ assert(list);
+ tmp = *list;
+ l = &tmp;
+ while (*l) {
+ if ((*l)->tag.type == TAG_VOID)
+ *l = list_delete(*l);
+ else if ((*l)->next.type == TAG_LIST)
+ l = &(*l)->next.data.list;
+ else
+ break;
}
- return dest;
+ *list = tmp;
+ return list;
}
-*/
s_array * list_to_array (const s_list *list, const s_sym *type,
s_array *dest)
@@ -345,22 +324,3 @@ s_array * list_to_array (const s_list *list, const s_sym *type,
free(tmp.dimensions);
return NULL;
}
-
-s_list ** list_remove_void (s_list **list)
-{
- s_list *tmp;
- s_list **l;
- assert(list);
- tmp = *list;
- l = &tmp;
- while (*l) {
- if ((*l)->tag.type == TAG_VOID)
- *l = list_delete(*l);
- else if ((*l)->next.type == TAG_LIST)
- l = &(*l)->next.data.list;
- else
- break;
- }
- *list = tmp;
- return list;
-}
diff --git a/libc3/struct.c b/libc3/struct.c
index 0118cb9..73bc16a 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -307,7 +307,8 @@ s_struct * struct_set (s_struct *s, const s_sym *key,
uw i;
f_init_copy init_copy;
uw size;
- e_tag_type type;
+ e_tag_type type;
+ const s_sym *type_sym;
assert(s);
assert(s->type.map.count);
assert(key);
@@ -318,10 +319,11 @@ s_struct * struct_set (s_struct *s, const s_sym *key,
s->type.map.key[i].data.sym == key) {
type = s->type.map.value[i].type;
if (! tag_type_to_clean(type, &clean) ||
- ! tag_type_to_init_copy(type, &init_copy))
+ ! tag_type_to_init_copy(type, &init_copy) ||
+ ! tag_type(s->type.map.value + i, &type_sym))
return NULL;
data = (s8 *) s->data + s->type.offset[i];
- if (! tag_to_const_pointer(value, tag_type_to_sym(type), &data_src))
+ if (! tag_to_const_pointer(value, type_sym, &data_src))
return NULL;
if (clean)
clean(data);
diff --git a/libc3/struct_type.c b/libc3/struct_type.c
index a4c0858..5eb0614 100644
--- a/libc3/struct_type.c
+++ b/libc3/struct_type.c
@@ -38,6 +38,11 @@ void struct_type_delete (s_struct_type *st)
free(st);
}
+bool struct_type_exists (const s_sym *module)
+{
+ return env_struct_type_exists(&g_c3_env, module);
+}
+
s_struct_type * struct_type_init (s_struct_type *st, const s_sym *module,
const s_list *spec)
{
diff --git a/libc3/struct_type.h b/libc3/struct_type.h
index c7332cb..1d05648 100644
--- a/libc3/struct_type.h
+++ b/libc3/struct_type.h
@@ -41,6 +41,8 @@ s_struct_type * struct_type_new (const s_sym *module,
const s_list *spec);
/* Utility functions. */
-uw struct_type_padding (uw offset, uw size);
+bool struct_type_exists (const s_sym *module);
+uw struct_type_padding (uw offset, uw size);
+
#endif /* LIBC3_STRUCT_TYPE_H */
diff --git a/libc3/sym.c b/libc3/sym.c
index e4ab9ed..032c527 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -331,6 +331,10 @@ bool sym_to_buf_inspect (const s_sym *type, f_buf_inspect *dest)
*dest = (f_buf_inspect) buf_inspect_var;
return true;
}
+ if (struct_type_exists(type)) {
+ *dest = (f_buf_inspect) buf_inspect_struct;
+ return true;
+ }
err_write_1("sym_to_buf_inspect: unknown type: ");
err_write_1(type->str.ptr.ps8);
err_write_1("\n");
@@ -435,7 +439,6 @@ bool sym_to_buf_inspect_size (const s_sym *type, f_buf_inspect_size *dest)
if (type == sym_1("PtrFree")) {
*dest = (f_buf_inspect_size) buf_inspect_ptr_free_size;
return true;
-
}
if (type == sym_1("Quote")) {
*dest = (f_buf_inspect_size) buf_inspect_quote_size;
@@ -461,6 +464,10 @@ bool sym_to_buf_inspect_size (const s_sym *type, f_buf_inspect_size *dest)
*dest = (f_buf_inspect_size) buf_inspect_void_size;
return true;
}
+ if (struct_type_exists(type)) {
+ *dest = (f_buf_inspect_size) buf_inspect_struct_size;
+ return true;
+ }
err_write_1("sym_to_buf_inspect_size: unknown type: ");
err_inspect_sym(&type);
err_write_1("\n");
@@ -594,6 +601,10 @@ bool sym_to_clean (const s_sym *type, f_clean *dest)
*dest = NULL;
return true;
}
+ if (struct_type_exists(type)) {
+ *dest = (f_clean) struct_clean;
+ return true;
+ }
err_write_1("sym_to_clean: unknown type: ");
err_inspect_sym(&type);
err_write_1("\n");
@@ -621,6 +632,14 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
*dest = &ffi_type_uint32;
return true;
}
+ if (sym == sym_1("F32")) {
+ *dest = &ffi_type_float;
+ return true;
+ }
+ if (sym == sym_1("F64")) {
+ *dest = &ffi_type_double;
+ return true;
+ }
if (sym == sym_1("Fn")) {
*dest = &ffi_type_pointer;
return true;
@@ -705,6 +724,10 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
*dest = &ffi_type_void;
return true;
}
+ if (struct_type_exists(sym)) {
+ *dest = &ffi_type_pointer;
+ return true;
+ }
err_write_1("sym_to_ffi_type: unknown type: ");
err_inspect_sym(&sym);
err_write_1("\n");
@@ -834,6 +857,10 @@ bool sym_to_init_cast (const s_sym *type, f_init_cast *dest)
*dest = NULL;
return true;
}
+ if (struct_type_exists(type)) {
+ *dest = (f_init_cast) struct_init_cast;
+ return true;
+ }
err_write_1("sym_to_init_cast: unknown type: ");
err_inspect_sym(&type);
err_write_1("\n");
@@ -963,6 +990,10 @@ bool sym_to_init_copy (const s_sym *type, f_init_copy *dest)
*dest = NULL;
return true;
}
+ if (struct_type_exists(type)) {
+ *dest = (f_init_copy) struct_init_copy;
+ return true;
+ }
err_write_1("sym_to_init_copy: unknown type: ");
err_inspect_sym(&type);
err_write_1("\n");
@@ -1052,6 +1083,10 @@ bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
*dest = TAG_STR;
return true;
}
+ if (sym == sym_1("Struct")) {
+ *dest = TAG_STRUCT;
+ return true;
+ }
if (sym == sym_1("Sw")) {
*dest = TAG_SW;
return true;
@@ -1088,6 +1123,10 @@ bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
*dest = TAG_UW;
return true;
}
+ if (struct_type_exists(sym)) {
+ *dest = TAG_STRUCT;
+ return true;
+ }
err_write_1("sym_to_tag_type: unknown type: ");
err_inspect_sym(&sym);
err_write_1("\n");
@@ -1097,6 +1136,7 @@ bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
bool sym_type_size (const s_sym *type, uw *dest)
{
+ s_struct_type st;
if (type == sym_1("Bool")) {
*dest = sizeof(bool);
return true;
@@ -1177,6 +1217,10 @@ bool sym_type_size (const s_sym *type, uw *dest)
*dest = sizeof(s_str);
return true;
}
+ if (type == sym_1("Struct")) {
+ *dest = sizeof(s_struct);
+ return true;
+ }
if (type == sym_1("Sw")) {
*dest = sizeof(sw);
return true;
@@ -1217,6 +1261,11 @@ bool sym_type_size (const s_sym *type, uw *dest)
*dest = 0;
return true;
}
+ if (struct_type_init_from_env(&st, type, &g_c3_env)) {
+ *dest = st.size;
+ struct_type_clean(&st);
+ return true;
+ }
err_write_1("sym_type_size: unknown type: ");
err_inspect_sym(&type);
err_write_1("\n");
diff --git a/libc3/tag.c b/libc3/tag.c
index 73c2c09..a2a2066 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -750,7 +750,7 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
}
goto invalid_cast;
case TAG_F64:
- if (type == sym_1("f64")) {
+ if (type == sym_1("F64")) {
*dest = &tag->data.f64;
return true;
}
@@ -891,6 +891,10 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
*dest = &tag->data.struct_;
return true;
}
+ if (type == tag->data.struct_.type.module) {
+ *dest = tag->data.struct_.data;
+ return true;
+ }
goto invalid_cast;
case TAG_SYM:
if (type == sym_1("Sym")) {
@@ -981,6 +985,13 @@ const s_sym ** tag_type (const s_tag *tag, const s_sym **dest)
{
assert(tag);
assert(dest);
+ switch (tag->type) {
+ case TAG_STRUCT:
+ *dest = tag->data.struct_.type.module;
+ return dest;
+ default:
+ break;
+ }
*dest = tag_type_to_sym(tag->type);
return dest;
}
diff --git a/libc3/tag_type.c b/libc3/tag_type.c
index 19c08a6..bea730c 100644
--- a/libc3/tag_type.c
+++ b/libc3/tag_type.c
@@ -336,38 +336,38 @@ bool tag_type_to_ffi_type (e_tag_type type, ffi_type **dest)
{
switch (type) {
case TAG_ARRAY: *dest = &ffi_type_pointer; return true;
- case TAG_BOOL: *dest = &ffi_type_uint8; return true;
+ case TAG_BOOL: *dest = &ffi_type_uint8; return true;
case TAG_CALL: *dest = &ffi_type_pointer; return true;
case TAG_CFN: *dest = &ffi_type_pointer; return true;
- case TAG_CHARACTER: *dest = &ffi_type_schar; return true;
- case TAG_F32: *dest = &ffi_type_float; return true;
- case TAG_F64: *dest = &ffi_type_double; return true;
+ case TAG_CHARACTER: *dest = &ffi_type_schar; return true;
+ case TAG_F32: *dest = &ffi_type_float; return true;
+ case TAG_F64: *dest = &ffi_type_double; return true;
case TAG_FACT: *dest = &ffi_type_pointer; return true;
case TAG_FN: *dest = &ffi_type_pointer; return true;
case TAG_IDENT: *dest = &ffi_type_pointer; return true;
- case TAG_INTEGER: *dest = &ffi_type_sint; return true;
+ case TAG_INTEGER: *dest = &ffi_type_sint; return true;
case TAG_LIST: *dest = &ffi_type_pointer; return true;
case TAG_MAP: *dest = &ffi_type_pointer; return true;
case TAG_PTAG: *dest = &ffi_type_pointer; return true;
- case TAG_PTR:
+ case TAG_PTR: *dest = &ffi_type_pointer; return true;
case TAG_PTR_FREE: *dest = &ffi_type_pointer; return true;
case TAG_QUOTE: *dest = &ffi_type_pointer; return true;
- case TAG_S8: *dest = &ffi_type_sint8; return true;
- case TAG_S16: *dest = &ffi_type_sint16; return true;
- case TAG_S32: *dest = &ffi_type_sint32; return true;
- case TAG_S64: *dest = &ffi_type_sint64; return true;
- case TAG_SW: *dest = &ffi_type_slong; return true;
+ case TAG_S8: *dest = &ffi_type_sint8; return true;
+ case TAG_S16: *dest = &ffi_type_sint16; return true;
+ case TAG_S32: *dest = &ffi_type_sint32; return true;
+ case TAG_S64: *dest = &ffi_type_sint64; return true;
+ case TAG_SW: *dest = &ffi_type_slong; return true;
case TAG_STR: *dest = &ffi_type_pointer; return true;
case TAG_STRUCT: *dest = &ffi_type_pointer; return true;
case TAG_SYM: *dest = &ffi_type_pointer; return true;
case TAG_TUPLE: *dest = &ffi_type_pointer; return true;
- case TAG_U8: *dest = &ffi_type_uint8; return true;
- case TAG_U16: *dest = &ffi_type_uint16; return true;
- case TAG_U32: *dest = &ffi_type_uint32; return true;
- case TAG_U64: *dest = &ffi_type_uint64; return true;
- case TAG_UW: *dest = &ffi_type_ulong; return true;
+ case TAG_U8: *dest = &ffi_type_uint8; return true;
+ case TAG_U16: *dest = &ffi_type_uint16; return true;
+ case TAG_U32: *dest = &ffi_type_uint32; return true;
+ case TAG_U64: *dest = &ffi_type_uint64; return true;
+ case TAG_UW: *dest = &ffi_type_ulong; return true;
case TAG_VAR: *dest = &ffi_type_pointer; return true;
- case TAG_VOID: *dest = &ffi_type_void; return true;
+ case TAG_VOID: *dest = &ffi_type_void; return true;
}
warnx("tag_type_to_ffi_type: unknown tag type: %d", type);
assert(! "tag_type_to_ffi_type: unknown tag type");
diff --git a/libc3/window/sdl2/gl_object.c b/libc3/window/sdl2/gl_object.c
index c798428..a811a81 100644
--- a/libc3/window/sdl2/gl_object.c
+++ b/libc3/window/sdl2/gl_object.c
@@ -13,11 +13,25 @@
#include <libc3/c3.h>
#include "gl_object.h"
+s_gl_object * gl_object_allocate (s_gl_object *object, uw vertex_count,
+ uw triangle_count)
+{
+ assert(object);
+ assert(vertex_count);
+ assert(triangle_count);
+ if (! array_init(&object->vertex, sym_1("GL.Vertex"), 1,
+ &vertex_count) ||
+ ! array_init(&object->triangle, sym_1("GL.Triangle"), 1,
+ &triangle_count))
+ return NULL;
+ return object;
+}
+
void gl_object_clean (s_gl_object *object)
{
assert(object);
array_clean(&object->vertex);
- array_clean(&object->index);
+ array_clean(&object->triangle);
glDeleteVertexArrays(1, &object->gl_vao);
glDeleteBuffers(1, &object->gl_vbo);
glDeleteBuffers(1, &object->gl_ebo);
@@ -33,18 +47,6 @@ s_gl_object * gl_object_init (s_gl_object *object)
return object;
}
-s_gl_object * gl_object_allocate (s_gl_object *object, uw vertex_count,
- uw index_count)
-{
- assert(object);
- assert(vertex_count);
- assert(index_count);
- assert(index_count % 3 == 0);
- array_init(&object->vertex, sym_1("GL.Vertex"), 1, &vertex_count);
- array_init(&object->index, sym_1("U32"), 1, &index_count);
- return object;
-}
-
void gl_object_render (const s_gl_object *object)
{
assert(object);
@@ -65,8 +67,8 @@ bool gl_object_update (s_gl_object *object)
glBufferData(GL_ARRAY_BUFFER, object->vertex.size,
object->vertex.data, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->gl_ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, object->index.size,
- object->index.data, GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, object->triangle.size,
+ object->triangle.data, GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
diff --git a/libc3/window/sdl2/gl_sphere.c b/libc3/window/sdl2/gl_sphere.c
index 20c1086..b4dba94 100644
--- a/libc3/window/sdl2/gl_sphere.c
+++ b/libc3/window/sdl2/gl_sphere.c
@@ -37,6 +37,7 @@ s_gl_sphere * gl_sphere_init (s_gl_sphere *sphere, uw seg_u, uw seg_v)
s_gl_vertex *vertex;
f64 r;
s_gl_sphere tmp = {0};
+ s_gl_triangle *triangle;
f64 z;
assert(sphere);
if (seg_u < 3)
@@ -46,7 +47,7 @@ s_gl_sphere * gl_sphere_init (s_gl_sphere *sphere, uw seg_u, uw seg_v)
tmp.segments_u = seg_u;
tmp.segments_v = seg_v;
if (! gl_object_allocate(&tmp.object, seg_u * (seg_v + 2),
- 6 * (seg_u + 1) * (seg_v + 2)))
+ 2 * seg_u * (seg_v + 1)))
return NULL;
vertex = tmp.object.vertex.data;
i = 0;
@@ -68,6 +69,24 @@ s_gl_sphere * gl_sphere_init (s_gl_sphere *sphere, uw seg_u, uw seg_v)
}
i++;
}
+ triangle = tmp.object.triangle.data;
+ i = 0;
+ while (i < seg_v + 1) {
+ j = 0;
+ while (j < seg_u) {
+ triangle->a = i * seg_u + j;
+ triangle->b = (i + 1) * seg_u + j;
+ triangle->c = (i + 1) * seg_u + (j + 1) % seg_u;
+ triangle++;
+ triangle->a = i * seg_u + j;
+ triangle->b = (i + 1) * seg_u + (j + 1) % seg_u;
+ triangle->c = i * seg_u + (j + 1) % seg_u;
+ triangle++;
+ j++;
+ }
+ i++;
+ }
+
*sphere = tmp;
return sphere;
}
diff --git a/libc3/window/sdl2/types.h b/libc3/window/sdl2/types.h
index f63b883..00ff063 100644
--- a/libc3/window/sdl2/types.h
+++ b/libc3/window/sdl2/types.h
@@ -38,6 +38,7 @@ typedef struct gl_object s_gl_object;
typedef struct gl_point_2d s_gl_point_2d;
typedef struct gl_point_3d s_gl_point_3d;
typedef struct gl_sphere s_gl_sphere;
+typedef struct gl_triangle s_gl_triangle;
typedef struct gl_vertex s_gl_vertex;
typedef struct sdl2_font s_sdl2_font;
typedef struct sdl2_sprite s_sdl2_sprite;
@@ -120,6 +121,21 @@ struct gl_matrix_4d {
f64 tt;
};
+struct gl_object {
+ s_array vertex;
+ s_array triangle;
+ u32 gl_mode;
+ u32 gl_vao;
+ u32 gl_vbo;
+ u32 gl_ebo;
+};
+
+struct gl_triangle {
+ u32 a;
+ u32 b;
+ u32 c;
+};
+
struct rgb {
f64 r;
f64 g;
@@ -141,21 +157,6 @@ struct sdl2_font {
s_str real_path;
};
-struct gl_vertex {
- s_gl_point_3d position;
- s_gl_point_3d normal;
- s_gl_point_2d tex_coord;
-};
-
-struct gl_object {
- s_array vertex;
- s_array index;
- u32 gl_mode;
- u32 gl_vao;
- u32 gl_vbo;
- u32 gl_ebo;
-};
-
/* Subtype of s_window. See libc3/window/types.h */
struct window_sdl2 {
sw x;
@@ -208,6 +209,12 @@ struct gl_sphere {
uw segments_v;
};
+struct gl_vertex {
+ s_gl_point_3d position;
+ s_gl_point_3d normal;
+ s_gl_point_2d tex_coord;
+};
+
struct sdl2_sprite {
s_gl_object object;
s_str path;