diff --git a/libc3/array.c b/libc3/array.c
index 4c789ac..e8e1c34 100644
--- a/libc3/array.c
+++ b/libc3/array.c
@@ -22,6 +22,7 @@
#include "call.h"
#include "cfn.h"
#include "character.h"
+#include "clean.h"
#include "env.h"
#include "f32.h"
#include "f64.h"
@@ -65,21 +66,18 @@ s_array * array_allocate (s_array *a)
void array_clean (s_array *a)
{
- f_clean clean;
u8 *data;
uw i;
uw size;
assert(a);
free(a->dimensions);
if (a->data) {
- if (sym_to_clean(a->type, &clean) &&
- clean &&
- sym_type_size(a->type, &size) &&
+ if (sym_type_size(a->type, &size) &&
size) {
data = a->data;
i = 0;
while (i < a->count) {
- clean(data);
+ clean(a->type, data);
data += size;
i++;
}
@@ -285,7 +283,6 @@ s_array * array_init_cast (s_array *array, const s_tag *tag)
s_array * array_init_copy (s_array *a, const s_array *src)
{
- f_clean clean;
f_init_copy init_copy;
u8 *data_tmp;
u8 *data_src;
@@ -350,10 +347,10 @@ s_array * array_init_copy (s_array *a, const s_array *src)
*a = tmp;
return a;
ko_data:
- if (i && sym_to_clean(src->type, &clean) && clean) {
+ if (i) {
while (--i) {
data_tmp -= item_size;
- clean(data_tmp);
+ clean(src->type, data_tmp);
}
}
free(tmp.data);
diff --git a/libc3/clean.c b/libc3/clean.c
new file mode 100644
index 0000000..173601c
--- /dev/null
+++ b/libc3/clean.c
@@ -0,0 +1,140 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include "c3.h"
+
+bool clean (const s_sym *type, void *data)
+{
+ assert(type);
+ if (type == sym_1("Array")) {
+ array_clean(data);
+ return true;
+ }
+ if (type == sym_1("Bool")) {
+ return true;
+ }
+ if (type == sym_1("Call")) {
+ call_clean(data);
+ return true;
+ }
+ if (type == sym_1("Cfn")) {
+ cfn_clean(data);
+ return true;
+ }
+ if (type == sym_1("Character")) {
+ return true;
+ }
+ if (type == sym_1("F32")) {
+ return true;
+ }
+ if (type == sym_1("F64")) {
+ return true;
+ }
+ if (type == sym_1("Fact")) {
+ return true;
+ }
+ if (type == sym_1("Fn")) {
+ fn_clean(data);
+ return true;
+ }
+ if (type == sym_1("Ident")) {
+ return true;
+ }
+ if (type == sym_1("Integer")) {
+ integer_clean(data);
+ return true;
+ }
+ if (type == sym_1("List")) {
+ list_f_clean(data);
+ return true;
+ }
+ if (type == sym_1("Map")) {
+ map_clean(data);
+ return true;
+ }
+ if (type == sym_1("Ptag")) {
+ return true;
+ }
+ if (type == sym_1("Ptr")) {
+ return true;
+ }
+ if (type == sym_1("PtrFree")) {
+ ptr_free_clean(data);
+ return true;
+ }
+ if (type == sym_1("Quote")) {
+ quote_clean(data);
+ return true;
+ }
+ if (type == sym_1("S8")) {
+ return true;
+ }
+ if (type == sym_1("S16")) {
+ return true;
+ }
+ if (type == sym_1("S32")) {
+ return true;
+ }
+ if (type == sym_1("S64")) {
+ return true;
+ }
+ if (type == sym_1("Str")) {
+ str_clean(data);
+ return true;
+ }
+ if (type == sym_1("Struct")) {
+ struct_clean(data);
+ return true;
+ }
+ if (type == sym_1("Sw")) {
+ return true;
+ }
+ if (type == sym_1("Sym")) {
+ return true;
+ }
+ if (type == sym_1("Tuple")) {
+ tuple_clean(data);
+ return true;
+ }
+ if (type == sym_1("U8")) {
+ return true;
+ }
+ if (type == sym_1("U16")) {
+ return true;
+ }
+ if (type == sym_1("U32")) {
+ return true;
+ }
+ if (type == sym_1("U64")) {
+ return true;
+ }
+ if (type == sym_1("Uw")) {
+ return true;
+ }
+ if (type == sym_1("Var")) {
+ return true;
+ }
+ if (type == sym_1("Void")) {
+ return true;
+ }
+ if (struct_type_exists(type)) {
+ s_struct s = {0};
+ struct_init_with_data(&s, type, false, data);
+ struct_clean(&s);
+ return true;
+ }
+ err_write_1("sym_to_clean: unknown type: ");
+ err_inspect_sym(&type);
+ err_write_1("\n");
+ assert(! "sym_to_clean: unknown type");
+ return false;
+}
diff --git a/libc3/clean.h b/libc3/clean.h
new file mode 100644
index 0000000..3121888
--- /dev/null
+++ b/libc3/clean.h
@@ -0,0 +1,26 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/**
+ * @file clean.h
+ * @brief Generic clean-up operations.
+ *
+ * Functions to manage clean-up code.
+ */
+#ifndef LIBC3_CLEAN_H
+#define LIBC3_CLEAN_H
+
+#include "types.h"
+
+void clean (const s_sym *type, void *data);
+
+#endif /* LIBC3_CLEAN_H */
diff --git a/libc3/list.c b/libc3/list.c
index 619a731..96ddbae 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -17,6 +17,7 @@
#include "buf.h"
#include "buf_inspect.h"
#include "buf_parse.h"
+#include "clean.h"
#include "list.h"
#include "sym.h"
#include "tag.h"
@@ -252,7 +253,6 @@ s_list ** list_remove_void (s_list **list)
s_array * list_to_array (const s_list *list, const s_sym *type,
s_array *dest)
{
- f_clean clean;
s8 *data;
const void *data_list;
f_init_copy init_copy;
@@ -316,11 +316,9 @@ s_array * list_to_array (const s_list *list, const s_sym *type,
*dest = tmp;
return dest;
ko:
- if (sym_to_clean(type, &clean) && clean) {
- while (data > (s8 *) tmp.data) {
- data -= size;
- clean(data);
- }
+ while (data > (s8 *) tmp.data) {
+ data -= size;
+ clean(type, data);
}
free(tmp.data);
free(tmp.dimensions);
diff --git a/libc3/sources.mk b/libc3/sources.mk
index e919ccb..a736b62 100644
--- a/libc3/sources.mk
+++ b/libc3/sources.mk
@@ -77,6 +77,7 @@ HEADERS = \
"ceiling.h" \
"cfn.h" \
"character.h" \
+ "clean.h" \
"compare.h" \
"config.h" \
"env.h" \
@@ -223,6 +224,7 @@ SOURCES = \
"ceiling.c" \
"cfn.c" \
"character.c" \
+ "clean.c" \
"compare.c" \
"env.c" \
"error.c" \
@@ -301,6 +303,103 @@ SOURCES = \
"void.c" \
LO_SOURCES = \
+ "" \
+ "../libtommath/bn_cutoffs.c" \
+ "../libtommath/bn_mp_2expt.c" \
+ "../libtommath/bn_mp_abs.c" \
+ "../libtommath/bn_mp_add.c" \
+ "../libtommath/bn_mp_add_d.c" \
+ "../libtommath/bn_mp_and.c" \
+ "../libtommath/bn_mp_clamp.c" \
+ "../libtommath/bn_mp_clear.c" \
+ "../libtommath/bn_mp_clear_multi.c" \
+ "../libtommath/bn_mp_cmp.c" \
+ "../libtommath/bn_mp_cmp_d.c" \
+ "../libtommath/bn_mp_cmp_mag.c" \
+ "../libtommath/bn_mp_cnt_lsb.c" \
+ "../libtommath/bn_mp_complement.c" \
+ "../libtommath/bn_mp_copy.c" \
+ "../libtommath/bn_mp_count_bits.c" \
+ "../libtommath/bn_mp_div.c" \
+ "../libtommath/bn_mp_div_2.c" \
+ "../libtommath/bn_mp_div_2d.c" \
+ "../libtommath/bn_mp_div_3.c" \
+ "../libtommath/bn_mp_div_d.c" \
+ "../libtommath/bn_mp_dr_is_modulus.c" \
+ "../libtommath/bn_mp_dr_reduce.c" \
+ "../libtommath/bn_mp_dr_setup.c" \
+ "../libtommath/bn_mp_error_to_string.c" \
+ "../libtommath/bn_mp_exch.c" \
+ "../libtommath/bn_mp_exptmod.c" \
+ "../libtommath/bn_mp_gcd.c" \
+ "../libtommath/bn_mp_get_double.c" \
+ "../libtommath/bn_mp_get_i32.c" \
+ "../libtommath/bn_mp_get_i64.c" \
+ "../libtommath/bn_mp_get_mag_u32.c" \
+ "../libtommath/bn_mp_get_mag_u64.c" \
+ "../libtommath/bn_mp_grow.c" \
+ "../libtommath/bn_mp_init.c" \
+ "../libtommath/bn_mp_init_copy.c" \
+ "../libtommath/bn_mp_init_multi.c" \
+ "../libtommath/bn_mp_init_size.c" \
+ "../libtommath/bn_mp_invmod.c" \
+ "../libtommath/bn_mp_lcm.c" \
+ "../libtommath/bn_mp_lshd.c" \
+ "../libtommath/bn_mp_mod.c" \
+ "../libtommath/bn_mp_mod_2d.c" \
+ "../libtommath/bn_mp_montgomery_calc_normalization.c" \
+ "../libtommath/bn_mp_montgomery_reduce.c" \
+ "../libtommath/bn_mp_montgomery_setup.c" \
+ "../libtommath/bn_mp_mul.c" \
+ "../libtommath/bn_mp_mul_2.c" \
+ "../libtommath/bn_mp_mul_2d.c" \
+ "../libtommath/bn_mp_mul_d.c" \
+ "../libtommath/bn_mp_mulmod.c" \
+ "../libtommath/bn_mp_neg.c" \
+ "../libtommath/bn_mp_or.c" \
+ "../libtommath/bn_mp_radix_size.c" \
+ "../libtommath/bn_mp_reduce.c" \
+ "../libtommath/bn_mp_reduce_2k.c" \
+ "../libtommath/bn_mp_reduce_2k_l.c" \
+ "../libtommath/bn_mp_reduce_2k_setup.c" \
+ "../libtommath/bn_mp_reduce_2k_setup_l.c" \
+ "../libtommath/bn_mp_reduce_is_2k.c" \
+ "../libtommath/bn_mp_reduce_is_2k_l.c" \
+ "../libtommath/bn_mp_reduce_setup.c" \
+ "../libtommath/bn_mp_rshd.c" \
+ "../libtommath/bn_mp_set.c" \
+ "../libtommath/bn_mp_set_double.c" \
+ "../libtommath/bn_mp_set_i32.c" \
+ "../libtommath/bn_mp_set_i64.c" \
+ "../libtommath/bn_mp_set_l.c" \
+ "../libtommath/bn_mp_set_u32.c" \
+ "../libtommath/bn_mp_set_u64.c" \
+ "../libtommath/bn_mp_set_ul.c" \
+ "../libtommath/bn_mp_sqr.c" \
+ "../libtommath/bn_mp_sqrt.c" \
+ "../libtommath/bn_mp_sub.c" \
+ "../libtommath/bn_mp_sub_d.c" \
+ "../libtommath/bn_mp_xor.c" \
+ "../libtommath/bn_mp_zero.c" \
+ "../libtommath/bn_s_mp_add.c" \
+ "../libtommath/bn_s_mp_balance_mul.c" \
+ "../libtommath/bn_s_mp_exptmod.c" \
+ "../libtommath/bn_s_mp_exptmod_fast.c" \
+ "../libtommath/bn_s_mp_invmod_fast.c" \
+ "../libtommath/bn_s_mp_invmod_slow.c" \
+ "../libtommath/bn_s_mp_karatsuba_mul.c" \
+ "../libtommath/bn_s_mp_karatsuba_sqr.c" \
+ "../libtommath/bn_s_mp_montgomery_reduce_fast.c" \
+ "../libtommath/bn_s_mp_mul_digs.c" \
+ "../libtommath/bn_s_mp_mul_digs_fast.c" \
+ "../libtommath/bn_s_mp_mul_high_digs.c" \
+ "../libtommath/bn_s_mp_mul_high_digs_fast.c" \
+ "../libtommath/bn_s_mp_rand_platform.c" \
+ "../libtommath/bn_s_mp_sqr.c" \
+ "../libtommath/bn_s_mp_sqr_fast.c" \
+ "../libtommath/bn_s_mp_sub.c" \
+ "../libtommath/bn_s_mp_toom_mul.c" \
+ "../libtommath/bn_s_mp_toom_sqr.c" \
"abs.c" \
"arg.c" \
"array.c" \
@@ -376,6 +475,7 @@ LO_SOURCES = \
"ceiling.c" \
"cfn.c" \
"character.c" \
+ "clean.c" \
"compare.c" \
"env.c" \
"error.c" \
@@ -452,101 +552,4 @@ LO_SOURCES = \
"uw.c" \
"var.c" \
"void.c" \
- "../libtommath/bn_cutoffs.c" \
- "../libtommath/bn_mp_2expt.c" \
- "../libtommath/bn_mp_abs.c" \
- "../libtommath/bn_mp_add.c" \
- "../libtommath/bn_mp_add_d.c" \
- "../libtommath/bn_mp_and.c" \
- "../libtommath/bn_mp_clamp.c" \
- "../libtommath/bn_mp_clear.c" \
- "../libtommath/bn_mp_clear_multi.c" \
- "../libtommath/bn_mp_cmp.c" \
- "../libtommath/bn_mp_cmp_d.c" \
- "../libtommath/bn_mp_cmp_mag.c" \
- "../libtommath/bn_mp_cnt_lsb.c" \
- "../libtommath/bn_mp_complement.c" \
- "../libtommath/bn_mp_copy.c" \
- "../libtommath/bn_mp_count_bits.c" \
- "../libtommath/bn_mp_div.c" \
- "../libtommath/bn_mp_div_2.c" \
- "../libtommath/bn_mp_div_2d.c" \
- "../libtommath/bn_mp_div_3.c" \
- "../libtommath/bn_mp_div_d.c" \
- "../libtommath/bn_mp_dr_is_modulus.c" \
- "../libtommath/bn_mp_dr_reduce.c" \
- "../libtommath/bn_mp_dr_setup.c" \
- "../libtommath/bn_mp_error_to_string.c" \
- "../libtommath/bn_mp_exch.c" \
- "../libtommath/bn_mp_exptmod.c" \
- "../libtommath/bn_mp_gcd.c" \
- "../libtommath/bn_mp_get_double.c" \
- "../libtommath/bn_mp_get_i32.c" \
- "../libtommath/bn_mp_get_i64.c" \
- "../libtommath/bn_mp_get_mag_u32.c" \
- "../libtommath/bn_mp_get_mag_u64.c" \
- "../libtommath/bn_mp_grow.c" \
- "../libtommath/bn_mp_init.c" \
- "../libtommath/bn_mp_init_copy.c" \
- "../libtommath/bn_mp_init_multi.c" \
- "../libtommath/bn_mp_init_size.c" \
- "../libtommath/bn_mp_invmod.c" \
- "../libtommath/bn_mp_lcm.c" \
- "../libtommath/bn_mp_lshd.c" \
- "../libtommath/bn_mp_mod.c" \
- "../libtommath/bn_mp_mod_2d.c" \
- "../libtommath/bn_mp_montgomery_calc_normalization.c" \
- "../libtommath/bn_mp_montgomery_reduce.c" \
- "../libtommath/bn_mp_montgomery_setup.c" \
- "../libtommath/bn_mp_mul.c" \
- "../libtommath/bn_mp_mul_2.c" \
- "../libtommath/bn_mp_mul_2d.c" \
- "../libtommath/bn_mp_mul_d.c" \
- "../libtommath/bn_mp_mulmod.c" \
- "../libtommath/bn_mp_neg.c" \
- "../libtommath/bn_mp_or.c" \
- "../libtommath/bn_mp_radix_size.c" \
- "../libtommath/bn_mp_reduce.c" \
- "../libtommath/bn_mp_reduce_2k.c" \
- "../libtommath/bn_mp_reduce_2k_l.c" \
- "../libtommath/bn_mp_reduce_2k_setup.c" \
- "../libtommath/bn_mp_reduce_2k_setup_l.c" \
- "../libtommath/bn_mp_reduce_is_2k.c" \
- "../libtommath/bn_mp_reduce_is_2k_l.c" \
- "../libtommath/bn_mp_reduce_setup.c" \
- "../libtommath/bn_mp_rshd.c" \
- "../libtommath/bn_mp_set.c" \
- "../libtommath/bn_mp_set_double.c" \
- "../libtommath/bn_mp_set_i32.c" \
- "../libtommath/bn_mp_set_i64.c" \
- "../libtommath/bn_mp_set_l.c" \
- "../libtommath/bn_mp_set_u32.c" \
- "../libtommath/bn_mp_set_u64.c" \
- "../libtommath/bn_mp_set_ul.c" \
- "../libtommath/bn_mp_sqr.c" \
- "../libtommath/bn_mp_sqrt.c" \
- "../libtommath/bn_mp_sub.c" \
- "../libtommath/bn_mp_sub_d.c" \
- "../libtommath/bn_mp_xor.c" \
- "../libtommath/bn_mp_zero.c" \
- "../libtommath/bn_s_mp_add.c" \
- "../libtommath/bn_s_mp_balance_mul.c" \
- "../libtommath/bn_s_mp_exptmod.c" \
- "../libtommath/bn_s_mp_exptmod_fast.c" \
- "../libtommath/bn_s_mp_invmod_fast.c" \
- "../libtommath/bn_s_mp_invmod_slow.c" \
- "../libtommath/bn_s_mp_karatsuba_mul.c" \
- "../libtommath/bn_s_mp_karatsuba_sqr.c" \
- "../libtommath/bn_s_mp_montgomery_reduce_fast.c" \
- "../libtommath/bn_s_mp_mul_digs.c" \
- "../libtommath/bn_s_mp_mul_digs_fast.c" \
- "../libtommath/bn_s_mp_mul_high_digs.c" \
- "../libtommath/bn_s_mp_mul_high_digs_fast.c" \
- "../libtommath/bn_s_mp_rand_platform.c" \
- "../libtommath/bn_s_mp_sqr.c" \
- "../libtommath/bn_s_mp_sqr_fast.c" \
- "../libtommath/bn_s_mp_sub.c" \
- "../libtommath/bn_s_mp_toom_mul.c" \
- "../libtommath/bn_s_mp_toom_sqr.c" \
- "" \
diff --git a/libc3/sources.sh b/libc3/sources.sh
index 48646c4..e48bb0e 100644
--- a/libc3/sources.sh
+++ b/libc3/sources.sh
@@ -1,4 +1,4 @@
# sources.sh generated by update_sources
-HEADERS='abs.h arg.h array.h assert.h binding.h bool.h buf.h buf_file.h buf_inspect.h buf_inspect_s16.h buf_inspect_s16_binary.h buf_inspect_s16_decimal.h buf_inspect_s16_hexadecimal.h buf_inspect_s16_octal.h buf_inspect_s32.h buf_inspect_s32_binary.h buf_inspect_s32_decimal.h buf_inspect_s32_hexadecimal.h buf_inspect_s32_octal.h buf_inspect_s64.h buf_inspect_s64_binary.h buf_inspect_s64_decimal.h buf_inspect_s64_hexadecimal.h buf_inspect_s64_octal.h buf_inspect_s8.h buf_inspect_s8_binary.h buf_inspect_s8_decimal.h buf_inspect_s8_hexadecimal.h buf_inspect_s8_octal.h buf_inspect_sw.h buf_inspect_sw_binary.h buf_inspect_sw_decimal.h buf_inspect_sw_hexadecimal.h buf_inspect_sw_octal.h buf_inspect_u16.h buf_inspect_u16_binary.h buf_inspect_u16_decimal.h buf_inspect_u16_hexadecimal.h buf_inspect_u16_octal.h buf_inspect_u32.h buf_inspect_u32_binary.h buf_inspect_u32_decimal.h buf_inspect_u32_hexadecimal.h buf_inspect_u32_octal.h buf_inspect_u64.h buf_inspect_u64_binary.h buf_inspect_u64_decimal.h buf_inspect_u64_hexadecimal.h buf_inspect_u64_octal.h buf_inspect_u8.h buf_inspect_u8_binary.h buf_inspect_u8_decimal.h buf_inspect_u8_hexadecimal.h buf_inspect_u8_octal.h buf_inspect_uw.h buf_inspect_uw_binary.h buf_inspect_uw_decimal.h buf_inspect_uw_hexadecimal.h buf_inspect_uw_octal.h buf_parse.h buf_parse_s16.h buf_parse_s32.h buf_parse_s64.h buf_parse_s8.h buf_parse_sw.h buf_parse_u16.h buf_parse_u32.h buf_parse_u64.h buf_parse_u8.h buf_parse_uw.h buf_save.h c3.h c3_main.h call.h ceiling.h cfn.h character.h compare.h config.h env.h error.h error_handler.h eval.h f32.h f64.h fact.h facts.h facts_cursor.h facts_spec.h facts_spec_cursor.h facts_with.h facts_with_cursor.h file.h float.h fn.h fn_clause.h frame.h hash.h ident.h integer.h io.h list.h list_init.h log.h map.h module.h operator.h ptag.h ptr.h ptr_free.h quote.h s16.h s32.h s64.h s8.h sequence.h set__fact.h set__tag.h set_cursor__fact.h set_cursor__tag.h set_item__fact.h set_item__tag.h sha1.h sign.h skiplist__fact.h skiplist_node__fact.h str.h struct.h struct_type.h sw.h sym.h tag.h tag_init.h tag_type.h time.h tuple.h type.h types.h u16.h u32.h u64.h u8.h ucd.h uw.h var.h void.h '
-SOURCES='abs.c arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_inspect_s16.c buf_inspect_s16_binary.c buf_inspect_s16_decimal.c buf_inspect_s16_hexadecimal.c buf_inspect_s16_octal.c buf_inspect_s32.c buf_inspect_s32_binary.c buf_inspect_s32_decimal.c buf_inspect_s32_hexadecimal.c buf_inspect_s32_octal.c buf_inspect_s64.c buf_inspect_s64_binary.c buf_inspect_s64_decimal.c buf_inspect_s64_hexadecimal.c buf_inspect_s64_octal.c buf_inspect_s8.c buf_inspect_s8_binary.c buf_inspect_s8_decimal.c buf_inspect_s8_hexadecimal.c buf_inspect_s8_octal.c buf_inspect_sw.c buf_inspect_sw_binary.c buf_inspect_sw_decimal.c buf_inspect_sw_hexadecimal.c buf_inspect_sw_octal.c buf_inspect_u16.c buf_inspect_u16_binary.c buf_inspect_u16_decimal.c buf_inspect_u16_hexadecimal.c buf_inspect_u16_octal.c buf_inspect_u32.c buf_inspect_u32_binary.c buf_inspect_u32_decimal.c buf_inspect_u32_hexadecimal.c buf_inspect_u32_octal.c buf_inspect_u64.c buf_inspect_u64_binary.c buf_inspect_u64_decimal.c buf_inspect_u64_hexadecimal.c buf_inspect_u64_octal.c buf_inspect_u8.c buf_inspect_u8_binary.c buf_inspect_u8_decimal.c buf_inspect_u8_hexadecimal.c buf_inspect_u8_octal.c buf_inspect_uw.c buf_inspect_uw_binary.c buf_inspect_uw_decimal.c buf_inspect_uw_hexadecimal.c buf_inspect_uw_octal.c buf_parse.c buf_parse_s16.c buf_parse_s32.c buf_parse_s64.c buf_parse_s8.c buf_parse_sw.c buf_parse_u16.c buf_parse_u32.c buf_parse_u64.c buf_parse_u8.c buf_parse_uw.c buf_save.c c3.c call.c ceiling.c cfn.c character.c compare.c env.c error.c error_handler.c eval.c f32.c f64.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c file.c fn.c fn_clause.c frame.c hash.c ident.c integer.c io.c license.c list.c list_init.c log.c map.c module.c operator.c ptag.c ptr.c ptr_free.c quote.c s16.c s32.c s64.c s8.c sequence.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c sign.c skiplist__fact.c skiplist_node__fact.c str.c struct.c struct_type.c sw.c sym.c tag.c tag_add.c tag_band.c tag_bor.c tag_bxor.c tag_div.c tag_init.c tag_mod.c tag_mul.c tag_shift_left.c tag_shift_right.c tag_sub.c tag_type.c time.c tuple.c type.c u16.c u32.c u64.c u8.c ucd.c uw.c var.c void.c '
-LO_SOURCES='abs.c arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_inspect_s16.c buf_inspect_s16_binary.c buf_inspect_s16_decimal.c buf_inspect_s16_hexadecimal.c buf_inspect_s16_octal.c buf_inspect_s32.c buf_inspect_s32_binary.c buf_inspect_s32_decimal.c buf_inspect_s32_hexadecimal.c buf_inspect_s32_octal.c buf_inspect_s64.c buf_inspect_s64_binary.c buf_inspect_s64_decimal.c buf_inspect_s64_hexadecimal.c buf_inspect_s64_octal.c buf_inspect_s8.c buf_inspect_s8_binary.c buf_inspect_s8_decimal.c buf_inspect_s8_hexadecimal.c buf_inspect_s8_octal.c buf_inspect_sw.c buf_inspect_sw_binary.c buf_inspect_sw_decimal.c buf_inspect_sw_hexadecimal.c buf_inspect_sw_octal.c buf_inspect_u16.c buf_inspect_u16_binary.c buf_inspect_u16_decimal.c buf_inspect_u16_hexadecimal.c buf_inspect_u16_octal.c buf_inspect_u32.c buf_inspect_u32_binary.c buf_inspect_u32_decimal.c buf_inspect_u32_hexadecimal.c buf_inspect_u32_octal.c buf_inspect_u64.c buf_inspect_u64_binary.c buf_inspect_u64_decimal.c buf_inspect_u64_hexadecimal.c buf_inspect_u64_octal.c buf_inspect_u8.c buf_inspect_u8_binary.c buf_inspect_u8_decimal.c buf_inspect_u8_hexadecimal.c buf_inspect_u8_octal.c buf_inspect_uw.c buf_inspect_uw_binary.c buf_inspect_uw_decimal.c buf_inspect_uw_hexadecimal.c buf_inspect_uw_octal.c buf_parse.c buf_parse_s16.c buf_parse_s32.c buf_parse_s64.c buf_parse_s8.c buf_parse_sw.c buf_parse_u16.c buf_parse_u32.c buf_parse_u64.c buf_parse_u8.c buf_parse_uw.c buf_save.c c3.c call.c ceiling.c cfn.c character.c compare.c env.c error.c error_handler.c eval.c f32.c f64.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c file.c fn.c fn_clause.c frame.c hash.c ident.c integer.c io.c license.c list.c list_init.c log.c map.c module.c operator.c ptag.c ptr.c ptr_free.c quote.c s16.c s32.c s64.c s8.c sequence.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c sign.c skiplist__fact.c skiplist_node__fact.c str.c struct.c struct_type.c sw.c sym.c tag.c tag_add.c tag_band.c tag_bor.c tag_bxor.c tag_div.c tag_init.c tag_mod.c tag_mul.c tag_shift_left.c tag_shift_right.c tag_sub.c tag_type.c time.c tuple.c type.c u16.c u32.c u64.c u8.c ucd.c uw.c var.c void.c ../libtommath/bn_cutoffs.c ../libtommath/bn_mp_2expt.c ../libtommath/bn_mp_abs.c ../libtommath/bn_mp_add.c ../libtommath/bn_mp_add_d.c ../libtommath/bn_mp_and.c ../libtommath/bn_mp_clamp.c ../libtommath/bn_mp_clear.c ../libtommath/bn_mp_clear_multi.c ../libtommath/bn_mp_cmp.c ../libtommath/bn_mp_cmp_d.c ../libtommath/bn_mp_cmp_mag.c ../libtommath/bn_mp_cnt_lsb.c ../libtommath/bn_mp_complement.c ../libtommath/bn_mp_copy.c ../libtommath/bn_mp_count_bits.c ../libtommath/bn_mp_div.c ../libtommath/bn_mp_div_2.c ../libtommath/bn_mp_div_2d.c ../libtommath/bn_mp_div_3.c ../libtommath/bn_mp_div_d.c ../libtommath/bn_mp_dr_is_modulus.c ../libtommath/bn_mp_dr_reduce.c ../libtommath/bn_mp_dr_setup.c ../libtommath/bn_mp_error_to_string.c ../libtommath/bn_mp_exch.c ../libtommath/bn_mp_exptmod.c ../libtommath/bn_mp_gcd.c ../libtommath/bn_mp_get_double.c ../libtommath/bn_mp_get_i32.c ../libtommath/bn_mp_get_i64.c ../libtommath/bn_mp_get_mag_u32.c ../libtommath/bn_mp_get_mag_u64.c ../libtommath/bn_mp_grow.c ../libtommath/bn_mp_init.c ../libtommath/bn_mp_init_copy.c ../libtommath/bn_mp_init_multi.c ../libtommath/bn_mp_init_size.c ../libtommath/bn_mp_invmod.c ../libtommath/bn_mp_lcm.c ../libtommath/bn_mp_lshd.c ../libtommath/bn_mp_mod.c ../libtommath/bn_mp_mod_2d.c ../libtommath/bn_mp_montgomery_calc_normalization.c ../libtommath/bn_mp_montgomery_reduce.c ../libtommath/bn_mp_montgomery_setup.c ../libtommath/bn_mp_mul.c ../libtommath/bn_mp_mul_2.c ../libtommath/bn_mp_mul_2d.c ../libtommath/bn_mp_mul_d.c ../libtommath/bn_mp_mulmod.c ../libtommath/bn_mp_neg.c ../libtommath/bn_mp_or.c ../libtommath/bn_mp_radix_size.c ../libtommath/bn_mp_reduce.c ../libtommath/bn_mp_reduce_2k.c ../libtommath/bn_mp_reduce_2k_l.c ../libtommath/bn_mp_reduce_2k_setup.c ../libtommath/bn_mp_reduce_2k_setup_l.c ../libtommath/bn_mp_reduce_is_2k.c ../libtommath/bn_mp_reduce_is_2k_l.c ../libtommath/bn_mp_reduce_setup.c ../libtommath/bn_mp_rshd.c ../libtommath/bn_mp_set.c ../libtommath/bn_mp_set_double.c ../libtommath/bn_mp_set_i32.c ../libtommath/bn_mp_set_i64.c ../libtommath/bn_mp_set_l.c ../libtommath/bn_mp_set_u32.c ../libtommath/bn_mp_set_u64.c ../libtommath/bn_mp_set_ul.c ../libtommath/bn_mp_sqr.c ../libtommath/bn_mp_sqrt.c ../libtommath/bn_mp_sub.c ../libtommath/bn_mp_sub_d.c ../libtommath/bn_mp_xor.c ../libtommath/bn_mp_zero.c ../libtommath/bn_s_mp_add.c ../libtommath/bn_s_mp_balance_mul.c ../libtommath/bn_s_mp_exptmod.c ../libtommath/bn_s_mp_exptmod_fast.c ../libtommath/bn_s_mp_invmod_fast.c ../libtommath/bn_s_mp_invmod_slow.c ../libtommath/bn_s_mp_karatsuba_mul.c ../libtommath/bn_s_mp_karatsuba_sqr.c ../libtommath/bn_s_mp_montgomery_reduce_fast.c ../libtommath/bn_s_mp_mul_digs.c ../libtommath/bn_s_mp_mul_digs_fast.c ../libtommath/bn_s_mp_mul_high_digs.c ../libtommath/bn_s_mp_mul_high_digs_fast.c ../libtommath/bn_s_mp_rand_platform.c ../libtommath/bn_s_mp_sqr.c ../libtommath/bn_s_mp_sqr_fast.c ../libtommath/bn_s_mp_sub.c ../libtommath/bn_s_mp_toom_mul.c ../libtommath/bn_s_mp_toom_sqr.c '
+HEADERS='abs.h arg.h array.h assert.h binding.h bool.h buf.h buf_file.h buf_inspect.h buf_inspect_s16.h buf_inspect_s16_binary.h buf_inspect_s16_decimal.h buf_inspect_s16_hexadecimal.h buf_inspect_s16_octal.h buf_inspect_s32.h buf_inspect_s32_binary.h buf_inspect_s32_decimal.h buf_inspect_s32_hexadecimal.h buf_inspect_s32_octal.h buf_inspect_s64.h buf_inspect_s64_binary.h buf_inspect_s64_decimal.h buf_inspect_s64_hexadecimal.h buf_inspect_s64_octal.h buf_inspect_s8.h buf_inspect_s8_binary.h buf_inspect_s8_decimal.h buf_inspect_s8_hexadecimal.h buf_inspect_s8_octal.h buf_inspect_sw.h buf_inspect_sw_binary.h buf_inspect_sw_decimal.h buf_inspect_sw_hexadecimal.h buf_inspect_sw_octal.h buf_inspect_u16.h buf_inspect_u16_binary.h buf_inspect_u16_decimal.h buf_inspect_u16_hexadecimal.h buf_inspect_u16_octal.h buf_inspect_u32.h buf_inspect_u32_binary.h buf_inspect_u32_decimal.h buf_inspect_u32_hexadecimal.h buf_inspect_u32_octal.h buf_inspect_u64.h buf_inspect_u64_binary.h buf_inspect_u64_decimal.h buf_inspect_u64_hexadecimal.h buf_inspect_u64_octal.h buf_inspect_u8.h buf_inspect_u8_binary.h buf_inspect_u8_decimal.h buf_inspect_u8_hexadecimal.h buf_inspect_u8_octal.h buf_inspect_uw.h buf_inspect_uw_binary.h buf_inspect_uw_decimal.h buf_inspect_uw_hexadecimal.h buf_inspect_uw_octal.h buf_parse.h buf_parse_s16.h buf_parse_s32.h buf_parse_s64.h buf_parse_s8.h buf_parse_sw.h buf_parse_u16.h buf_parse_u32.h buf_parse_u64.h buf_parse_u8.h buf_parse_uw.h buf_save.h c3.h c3_main.h call.h ceiling.h cfn.h character.h clean.h compare.h config.h env.h error.h error_handler.h eval.h f32.h f64.h fact.h facts.h facts_cursor.h facts_spec.h facts_spec_cursor.h facts_with.h facts_with_cursor.h file.h float.h fn.h fn_clause.h frame.h hash.h ident.h integer.h io.h list.h list_init.h log.h map.h module.h operator.h ptag.h ptr.h ptr_free.h quote.h s16.h s32.h s64.h s8.h sequence.h set__fact.h set__tag.h set_cursor__fact.h set_cursor__tag.h set_item__fact.h set_item__tag.h sha1.h sign.h skiplist__fact.h skiplist_node__fact.h str.h struct.h struct_type.h sw.h sym.h tag.h tag_init.h tag_type.h time.h tuple.h type.h types.h u16.h u32.h u64.h u8.h ucd.h uw.h var.h void.h '
+SOURCES='abs.c arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_inspect_s16.c buf_inspect_s16_binary.c buf_inspect_s16_decimal.c buf_inspect_s16_hexadecimal.c buf_inspect_s16_octal.c buf_inspect_s32.c buf_inspect_s32_binary.c buf_inspect_s32_decimal.c buf_inspect_s32_hexadecimal.c buf_inspect_s32_octal.c buf_inspect_s64.c buf_inspect_s64_binary.c buf_inspect_s64_decimal.c buf_inspect_s64_hexadecimal.c buf_inspect_s64_octal.c buf_inspect_s8.c buf_inspect_s8_binary.c buf_inspect_s8_decimal.c buf_inspect_s8_hexadecimal.c buf_inspect_s8_octal.c buf_inspect_sw.c buf_inspect_sw_binary.c buf_inspect_sw_decimal.c buf_inspect_sw_hexadecimal.c buf_inspect_sw_octal.c buf_inspect_u16.c buf_inspect_u16_binary.c buf_inspect_u16_decimal.c buf_inspect_u16_hexadecimal.c buf_inspect_u16_octal.c buf_inspect_u32.c buf_inspect_u32_binary.c buf_inspect_u32_decimal.c buf_inspect_u32_hexadecimal.c buf_inspect_u32_octal.c buf_inspect_u64.c buf_inspect_u64_binary.c buf_inspect_u64_decimal.c buf_inspect_u64_hexadecimal.c buf_inspect_u64_octal.c buf_inspect_u8.c buf_inspect_u8_binary.c buf_inspect_u8_decimal.c buf_inspect_u8_hexadecimal.c buf_inspect_u8_octal.c buf_inspect_uw.c buf_inspect_uw_binary.c buf_inspect_uw_decimal.c buf_inspect_uw_hexadecimal.c buf_inspect_uw_octal.c buf_parse.c buf_parse_s16.c buf_parse_s32.c buf_parse_s64.c buf_parse_s8.c buf_parse_sw.c buf_parse_u16.c buf_parse_u32.c buf_parse_u64.c buf_parse_u8.c buf_parse_uw.c buf_save.c c3.c call.c ceiling.c cfn.c character.c clean.c compare.c env.c error.c error_handler.c eval.c f32.c f64.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c file.c fn.c fn_clause.c frame.c hash.c ident.c integer.c io.c license.c list.c list_init.c log.c map.c module.c operator.c ptag.c ptr.c ptr_free.c quote.c s16.c s32.c s64.c s8.c sequence.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c sign.c skiplist__fact.c skiplist_node__fact.c str.c struct.c struct_type.c sw.c sym.c tag.c tag_add.c tag_band.c tag_bor.c tag_bxor.c tag_div.c tag_init.c tag_mod.c tag_mul.c tag_shift_left.c tag_shift_right.c tag_sub.c tag_type.c time.c tuple.c type.c u16.c u32.c u64.c u8.c ucd.c uw.c var.c void.c '
+LO_SOURCES=' ../libtommath/bn_cutoffs.c ../libtommath/bn_mp_2expt.c ../libtommath/bn_mp_abs.c ../libtommath/bn_mp_add.c ../libtommath/bn_mp_add_d.c ../libtommath/bn_mp_and.c ../libtommath/bn_mp_clamp.c ../libtommath/bn_mp_clear.c ../libtommath/bn_mp_clear_multi.c ../libtommath/bn_mp_cmp.c ../libtommath/bn_mp_cmp_d.c ../libtommath/bn_mp_cmp_mag.c ../libtommath/bn_mp_cnt_lsb.c ../libtommath/bn_mp_complement.c ../libtommath/bn_mp_copy.c ../libtommath/bn_mp_count_bits.c ../libtommath/bn_mp_div.c ../libtommath/bn_mp_div_2.c ../libtommath/bn_mp_div_2d.c ../libtommath/bn_mp_div_3.c ../libtommath/bn_mp_div_d.c ../libtommath/bn_mp_dr_is_modulus.c ../libtommath/bn_mp_dr_reduce.c ../libtommath/bn_mp_dr_setup.c ../libtommath/bn_mp_error_to_string.c ../libtommath/bn_mp_exch.c ../libtommath/bn_mp_exptmod.c ../libtommath/bn_mp_gcd.c ../libtommath/bn_mp_get_double.c ../libtommath/bn_mp_get_i32.c ../libtommath/bn_mp_get_i64.c ../libtommath/bn_mp_get_mag_u32.c ../libtommath/bn_mp_get_mag_u64.c ../libtommath/bn_mp_grow.c ../libtommath/bn_mp_init.c ../libtommath/bn_mp_init_copy.c ../libtommath/bn_mp_init_multi.c ../libtommath/bn_mp_init_size.c ../libtommath/bn_mp_invmod.c ../libtommath/bn_mp_lcm.c ../libtommath/bn_mp_lshd.c ../libtommath/bn_mp_mod.c ../libtommath/bn_mp_mod_2d.c ../libtommath/bn_mp_montgomery_calc_normalization.c ../libtommath/bn_mp_montgomery_reduce.c ../libtommath/bn_mp_montgomery_setup.c ../libtommath/bn_mp_mul.c ../libtommath/bn_mp_mul_2.c ../libtommath/bn_mp_mul_2d.c ../libtommath/bn_mp_mul_d.c ../libtommath/bn_mp_mulmod.c ../libtommath/bn_mp_neg.c ../libtommath/bn_mp_or.c ../libtommath/bn_mp_radix_size.c ../libtommath/bn_mp_reduce.c ../libtommath/bn_mp_reduce_2k.c ../libtommath/bn_mp_reduce_2k_l.c ../libtommath/bn_mp_reduce_2k_setup.c ../libtommath/bn_mp_reduce_2k_setup_l.c ../libtommath/bn_mp_reduce_is_2k.c ../libtommath/bn_mp_reduce_is_2k_l.c ../libtommath/bn_mp_reduce_setup.c ../libtommath/bn_mp_rshd.c ../libtommath/bn_mp_set.c ../libtommath/bn_mp_set_double.c ../libtommath/bn_mp_set_i32.c ../libtommath/bn_mp_set_i64.c ../libtommath/bn_mp_set_l.c ../libtommath/bn_mp_set_u32.c ../libtommath/bn_mp_set_u64.c ../libtommath/bn_mp_set_ul.c ../libtommath/bn_mp_sqr.c ../libtommath/bn_mp_sqrt.c ../libtommath/bn_mp_sub.c ../libtommath/bn_mp_sub_d.c ../libtommath/bn_mp_xor.c ../libtommath/bn_mp_zero.c ../libtommath/bn_s_mp_add.c ../libtommath/bn_s_mp_balance_mul.c ../libtommath/bn_s_mp_exptmod.c ../libtommath/bn_s_mp_exptmod_fast.c ../libtommath/bn_s_mp_invmod_fast.c ../libtommath/bn_s_mp_invmod_slow.c ../libtommath/bn_s_mp_karatsuba_mul.c ../libtommath/bn_s_mp_karatsuba_sqr.c ../libtommath/bn_s_mp_montgomery_reduce_fast.c ../libtommath/bn_s_mp_mul_digs.c ../libtommath/bn_s_mp_mul_digs_fast.c ../libtommath/bn_s_mp_mul_high_digs.c ../libtommath/bn_s_mp_mul_high_digs_fast.c ../libtommath/bn_s_mp_rand_platform.c ../libtommath/bn_s_mp_sqr.c ../libtommath/bn_s_mp_sqr_fast.c ../libtommath/bn_s_mp_sub.c ../libtommath/bn_s_mp_toom_mul.c ../libtommath/bn_s_mp_toom_sqr.c abs.c arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_inspect_s16.c buf_inspect_s16_binary.c buf_inspect_s16_decimal.c buf_inspect_s16_hexadecimal.c buf_inspect_s16_octal.c buf_inspect_s32.c buf_inspect_s32_binary.c buf_inspect_s32_decimal.c buf_inspect_s32_hexadecimal.c buf_inspect_s32_octal.c buf_inspect_s64.c buf_inspect_s64_binary.c buf_inspect_s64_decimal.c buf_inspect_s64_hexadecimal.c buf_inspect_s64_octal.c buf_inspect_s8.c buf_inspect_s8_binary.c buf_inspect_s8_decimal.c buf_inspect_s8_hexadecimal.c buf_inspect_s8_octal.c buf_inspect_sw.c buf_inspect_sw_binary.c buf_inspect_sw_decimal.c buf_inspect_sw_hexadecimal.c buf_inspect_sw_octal.c buf_inspect_u16.c buf_inspect_u16_binary.c buf_inspect_u16_decimal.c buf_inspect_u16_hexadecimal.c buf_inspect_u16_octal.c buf_inspect_u32.c buf_inspect_u32_binary.c buf_inspect_u32_decimal.c buf_inspect_u32_hexadecimal.c buf_inspect_u32_octal.c buf_inspect_u64.c buf_inspect_u64_binary.c buf_inspect_u64_decimal.c buf_inspect_u64_hexadecimal.c buf_inspect_u64_octal.c buf_inspect_u8.c buf_inspect_u8_binary.c buf_inspect_u8_decimal.c buf_inspect_u8_hexadecimal.c buf_inspect_u8_octal.c buf_inspect_uw.c buf_inspect_uw_binary.c buf_inspect_uw_decimal.c buf_inspect_uw_hexadecimal.c buf_inspect_uw_octal.c buf_parse.c buf_parse_s16.c buf_parse_s32.c buf_parse_s64.c buf_parse_s8.c buf_parse_sw.c buf_parse_u16.c buf_parse_u32.c buf_parse_u64.c buf_parse_u8.c buf_parse_uw.c buf_save.c c3.c call.c ceiling.c cfn.c character.c clean.c compare.c env.c error.c error_handler.c eval.c f32.c f64.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c file.c fn.c fn_clause.c frame.c hash.c ident.c integer.c io.c license.c list.c list_init.c log.c map.c module.c operator.c ptag.c ptr.c ptr_free.c quote.c s16.c s32.c s64.c s8.c sequence.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c sign.c skiplist__fact.c skiplist_node__fact.c str.c struct.c struct_type.c sw.c sym.c tag.c tag_add.c tag_band.c tag_bor.c tag_bxor.c tag_div.c tag_init.c tag_mod.c tag_mul.c tag_shift_left.c tag_shift_right.c tag_sub.c tag_type.c time.c tuple.c type.c u16.c u32.c u64.c u8.c ucd.c uw.c var.c void.c '
diff --git a/libc3/struct.c b/libc3/struct.c
index c223397..05849ec 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -14,6 +14,7 @@
#include <err.h>
#include <stdlib.h>
#include <string.h>
+#include "clean.h"
#include "env.h"
#include "list.h"
#include "map.h"
@@ -42,17 +43,14 @@ s_struct * struct_allocate (s_struct *s)
void struct_clean (s_struct *s)
{
- f_clean clean;
uw i;
const s_sym *sym;
assert(s);
if (s->data) {
i = 0;
while (i < s->type.map.count) {
- if (tag_type(s->type.map.value + i, &sym) &&
- sym_to_clean(sym, &clean) &&
- clean)
- clean((s8 *) s->data + s->type.offset[i]);
+ if (tag_type(s->type.map.value + i, &sym))
+ clean(sym, (s8 *) s->data + s->type.offset[i]);
i++;
}
if (s->free_data)
@@ -300,7 +298,6 @@ s_struct * struct_new_copy (const s_struct *src)
s_struct * struct_set (s_struct *s, const s_sym *key,
const s_tag *value)
{
- f_clean clean;
void *data;
const void *data_src;
uw i;
@@ -317,15 +314,13 @@ s_struct * struct_set (s_struct *s, const s_sym *key,
if (s->type.map.key[i].type == TAG_SYM &&
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) ||
+ if (! 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, type_sym, &data_src))
return NULL;
- if (clean)
- clean(data);
+ clean(type_sym, data);
if (init_copy) {
if (! init_copy(data, data_src))
return NULL;
diff --git a/libc3/sym.c b/libc3/sym.c
index 40d82e1..6a469cf 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -490,152 +490,6 @@ bool sym_to_buf_inspect_size (const s_sym *type, f_buf_inspect_size *dest)
assert(! "sym_to_buf_inspect_size: unknown type");
return false;
}
-
-bool sym_to_clean (const s_sym *type, f_clean *dest)
-{
- if (type == sym_1("Array")) {
- *dest = (f_clean) array_clean;
- return true;
- }
- if (type == sym_1("Bool")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Call")) {
- *dest = (f_clean) call_clean;
- return true;
- }
- if (type == sym_1("Cfn")) {
- *dest = (f_clean) cfn_clean;
- return true;
- }
- if (type == sym_1("Character")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("F32")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("F64")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Fact")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Fn")) {
- *dest = (f_clean) fn_clean;
- return true;
- }
- if (type == sym_1("Ident")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Integer")) {
- *dest = (f_clean) integer_clean;
- return true;
- }
- if (type == sym_1("List")) {
- *dest = (f_clean) list_f_clean;
- return true;
- }
- if (type == sym_1("Map")) {
- *dest = (f_clean) map_clean;
- return true;
- }
- if (type == sym_1("Ptag")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Ptr")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("PtrFree")) {
- *dest = (f_clean) ptr_free_clean;
- return true;
- }
- if (type == sym_1("Quote")) {
- *dest = (f_clean) quote_clean;
- return true;
- }
- if (type == sym_1("S8")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("S16")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("S32")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("S64")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Str")) {
- *dest = (f_clean) str_clean;
- return true;
- }
- if (type == sym_1("Struct")) {
- *dest = (f_clean) struct_clean;
- return true;
- }
- if (type == sym_1("Sw")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Sym")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Tuple")) {
- *dest = (f_clean) tuple_clean;
- return true;
- }
- if (type == sym_1("U8")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("U16")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("U32")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("U64")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Uw")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Var")) {
- *dest = NULL;
- return true;
- }
- if (type == sym_1("Void")) {
- *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");
- assert(! "sym_to_clean: unknown type");
- return false;
-}
-
bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
ffi_type **dest)
{
diff --git a/libc3/sym.h b/libc3/sym.h
index 019e639..c5937d2 100644
--- a/libc3/sym.h
+++ b/libc3/sym.h
@@ -48,7 +48,6 @@ bool sym_to_buf_inspect (const s_sym *type,
f_buf_inspect *dest);
bool sym_to_buf_inspect_size (const s_sym *type,
f_buf_inspect_size *dest);
-bool sym_to_clean (const s_sym *type, f_clean *dest);
bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
ffi_type **dest);
bool sym_to_init_cast (const s_sym *type, f_init_cast *dest);
diff --git a/libc3/tag_type.c b/libc3/tag_type.c
index bea730c..fc90f98 100644
--- a/libc3/tag_type.c
+++ b/libc3/tag_type.c
@@ -248,48 +248,6 @@ bool tag_type_to_buf_parse (e_tag_type type, f_buf_parse *p)
return false;
}
-bool tag_type_to_clean (e_tag_type type, f_clean *dest)
-{
- switch (type) {
- case TAG_ARRAY: *dest = (f_clean) array_clean; return true;
- case TAG_BOOL: *dest = NULL; return true;
- case TAG_CALL: *dest = (f_clean) call_clean; return true;
- case TAG_CFN: *dest = (f_clean) cfn_clean; return true;
- case TAG_CHARACTER:
- case TAG_F32:
- case TAG_F64:
- case TAG_FACT: *dest = NULL; return true;
- case TAG_FN: *dest = (f_clean) fn_clean; return true;
- case TAG_IDENT: *dest = NULL; return true;
- case TAG_INTEGER: *dest = (f_clean) integer_clean; return true;
- case TAG_SW:
- case TAG_S64:
- case TAG_S32:
- case TAG_S16:
- case TAG_S8:
- case TAG_U8:
- case TAG_U16:
- case TAG_U32:
- case TAG_U64:
- case TAG_UW: *dest = NULL; return true;
- case TAG_LIST: *dest = (f_clean) list_f_clean; return true;
- case TAG_MAP: *dest = (f_clean) map_clean; return true;
- case TAG_PTAG:
- case TAG_PTR: *dest = NULL; return true;
- case TAG_PTR_FREE: *dest = (f_clean) ptr_free_clean; return true;
- case TAG_QUOTE: *dest = (f_clean) quote_clean; return true;
- case TAG_STR: *dest = (f_clean) str_clean; return true;
- case TAG_STRUCT: *dest = (f_clean) struct_clean; return true;
- case TAG_SYM: *dest = NULL; return true;
- case TAG_TUPLE: *dest = (f_clean) tuple_clean; return true;
- case TAG_VAR:
- case TAG_VOID: *dest = NULL; return true;
- }
- warnx("tag_type_to_clean: invalid tag type: %d", type);
- assert(! "tag_type_to_clean: invalid tag type");
- return false;
-}
-
bool tag_type_to_env_eval (e_tag_type type, f_env_eval *dest)
{
switch (type) {
diff --git a/libc3/tag_type.h b/libc3/tag_type.h
index 2797809..0bd9ef1 100644
--- a/libc3/tag_type.h
+++ b/libc3/tag_type.h
@@ -28,7 +28,6 @@ bool tag_type_to_buf_inspect_size (e_tag_type type,
f_buf_inspect_size *dest);
bool tag_type_to_buf_parse (e_tag_type type,
f_buf_parse *dest);
-bool tag_type_to_clean (e_tag_type type, f_clean *dest);
bool tag_type_to_env_eval (e_tag_type type, f_env_eval *dest);
bool tag_type_to_hash_update (e_tag_type type,
f_hash_update *dest);
diff --git a/libc3/types.h b/libc3/types.h
index 94a7879..c0f4803 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -182,7 +182,6 @@ typedef u64 t_skiplist_height;
typedef sw (* f_buf_inspect) (s_buf *buf, const void *x);
typedef sw (* f_buf_inspect_size) (const void *x);
typedef sw (* f_buf_parse) (s_buf *buf, void *dest);
-typedef void (* f_clean) (void *x);
typedef bool (* f_env_eval) (s_env *env, const void *x, s_tag *dest);
typedef void (* f_hash_update) (t_hash *hash, const void *x);
typedef void * (* f_init_cast) (void *x, const s_tag *tag);
diff --git a/libc3/window/sdl2/demo/earth.c b/libc3/window/sdl2/demo/earth.c
index c080b9a..79171b4 100644
--- a/libc3/window/sdl2/demo/earth.c
+++ b/libc3/window/sdl2/demo/earth.c
@@ -13,7 +13,7 @@
#include <math.h>
#include <libc3/c3.h>
#include "../window_sdl2.h"
-#include "../sdl2_sprite.h"
+#include "../gl_sprite.h"
#include "../gl_camera.h"
#include "../gl_sphere.h"
#include "earth.h"
@@ -22,7 +22,7 @@
#define EARTH_SEGMENTS_U 200
#define EARTH_SEGMENTS_V 100
-s_sdl2_sprite g_sprite_earth = {0};
+s_gl_sprite g_sprite_earth = {0};
bool earth_load (s_sequence *seq,
s_window_sdl2 *window)
@@ -83,11 +83,17 @@ bool earth_render (s_sequence *seq, s_window_sdl2 *window,
*camera_rot_x_speed *= -1.0;
camera->rotation.z += seq->dt * EARTH_CAMERA_ROTATION_Z_SPEED *
360.0;
+ assert(glGetError() == GL_NO_ERROR);
gl_camera_render(camera);
+ assert(glGetError() == GL_NO_ERROR);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ assert(glGetError() == GL_NO_ERROR);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
+ assert(glGetError() == GL_NO_ERROR);
+ //glEnable(GL_LIGHTING);
+ assert(glGetError() == GL_NO_ERROR);
+ //glEnable(GL_LIGHT0);
+ assert(glGetError() == GL_NO_ERROR);
f32 ambiant[4] = {0.1f, 0.1f, 0.1f, 1.0f};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambiant);
f32 diffuse[4] = {1.0f, 0.92f, 0.83f, 1.0f};
@@ -98,14 +104,20 @@ bool earth_render (s_sequence *seq, s_window_sdl2 *window,
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1f);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f);
+ assert(glGetError() == GL_NO_ERROR);
glEnable(GL_DEPTH_TEST);
+ assert(glGetError() == GL_NO_ERROR);
glPushMatrix(); {
sphere_radius = 5.0;
+ assert(glGetError() == GL_NO_ERROR);
glScalef(sphere_radius, sphere_radius, sphere_radius);
+ assert(glGetError() == GL_NO_ERROR);
glEnable(GL_TEXTURE_2D);
+ assert(glGetError() == GL_NO_ERROR);
+ gl_sprite_bind(&g_sprite_earth, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
- sdl2_sprite_bind(&g_sprite_earth, 0);
+ assert(glGetError() == GL_NO_ERROR);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gl_sphere_render(sphere);
/*
diff --git a/libc3/window/sdl2/demo/earth.h b/libc3/window/sdl2/demo/earth.h
index 9c573f0..0bf6ac4 100644
--- a/libc3/window/sdl2/demo/earth.h
+++ b/libc3/window/sdl2/demo/earth.h
@@ -16,8 +16,8 @@
#include "../types.h"
#include "window_sdl2_demo.h"
-extern s_sdl2_sprite g_sprite_earth;
-extern s_sdl2_sprite g_sprite_earth_night;
+extern s_gl_sprite g_sprite_earth;
+extern s_gl_sprite g_sprite_earth_night;
bool earth_load (s_sequence *seq, s_window_sdl2 *window);
bool earth_render (s_sequence *seq, s_window_sdl2 *window,
diff --git a/libc3/window/sdl2/demo/flies.c b/libc3/window/sdl2/demo/flies.c
index 7469afb..8c1db4d 100644
--- a/libc3/window/sdl2/demo/flies.c
+++ b/libc3/window/sdl2/demo/flies.c
@@ -14,7 +14,7 @@
#include <libc3/c3.h>
#include "../gl_font.h"
#include "../gl_text.h"
-#include "../sdl2_sprite.h"
+#include "../gl_sprite.h"
#include "../window_sdl2.h"
#include "flies.h"
@@ -33,8 +33,8 @@ static const u8 g_board_item_block = BOARD_ITEM_BLOCK;
static const u8 g_board_item_fly = BOARD_ITEM_FLY;
static const u8 g_board_item_dead_fly = BOARD_ITEM_DEAD_FLY;
s_gl_font g_font_flies = {0};
-s_sdl2_sprite g_sprite_dead_fly = {0};
-s_sdl2_sprite g_sprite_fly = {0};
+s_gl_sprite g_sprite_dead_fly = {0};
+s_gl_sprite g_sprite_fly = {0};
s_gl_text g_text_flies_in = {0};
s_gl_text g_text_flies_out = {0};
static const f64 g_xy_ratio = 0.666;
@@ -238,7 +238,7 @@ bool flies_render (s_sequence *seq, s_window_sdl2 *window,
glPushMatrix(); {
glTranslated(-board_item_w / 2.0, -board_item_h / 2.0, 0.0);
glScaled(fly_scale, fly_scale, 1.0);
- sdl2_sprite_render(&g_sprite_fly, 0);
+ gl_sprite_render(&g_sprite_fly, 0);
} glPopMatrix();
if (address[0] == BOARD_SIZE / 2 &&
address[1] == BOARD_SIZE - 1) {
@@ -311,7 +311,7 @@ bool flies_render (s_sequence *seq, s_window_sdl2 *window,
glTranslated(-board_item_w / 2.0, -board_item_h / 2.0,
0.0);
glScaled(dead_fly_scale, dead_fly_scale, 1.0);
- sdl2_sprite_render(&g_sprite_dead_fly, 0);
+ gl_sprite_render(&g_sprite_dead_fly, 0);
} glPopMatrix();
break;
}
diff --git a/libc3/window/sdl2/demo/flies.h b/libc3/window/sdl2/demo/flies.h
index 9b3adc3..1de8081 100644
--- a/libc3/window/sdl2/demo/flies.h
+++ b/libc3/window/sdl2/demo/flies.h
@@ -16,9 +16,9 @@
#include "../types.h"
#include "window_sdl2_demo.h"
-extern s_gl_font g_font_flies;
-extern s_sdl2_sprite g_sprite_dead_fly;
-extern s_sdl2_sprite g_sprite_fly;
+extern s_gl_font g_font_flies;
+extern s_gl_sprite g_sprite_dead_fly;
+extern s_gl_sprite g_sprite_fly;
bool flies_load (s_sequence *seq, s_window_sdl2 *window);
bool flies_render (s_sequence *seq, s_window_sdl2 *window,
diff --git a/libc3/window/sdl2/demo/lightspeed.c b/libc3/window/sdl2/demo/lightspeed.c
index 83e90af..1e9cffc 100644
--- a/libc3/window/sdl2/demo/lightspeed.c
+++ b/libc3/window/sdl2/demo/lightspeed.c
@@ -11,10 +11,14 @@
* THIS SOFTWARE.
*/
#include <libc3/c3.h>
+#include "../gl_lines.h"
+#include "../gl_matrix_4d.h"
+#include "../gl_ortho.h"
+#include "../gl_point_3d.h"
+#include "window_sdl2_demo.h"
#include "lightspeed.h"
-#define LIGHTSPEED_STAR_MAX (1024 * 1024)
-#define LIGHTSPEED_STAR_PROBABILITY 0.005
+s_gl_lines g_lines_stars = {0};
static void star_init (s_tag *star)
{
@@ -33,7 +37,7 @@ static void star_init (s_tag *star)
tag_init_f64(star->data.map.value + 2, 2.0 * y - 1.0);
}
-static void star_render (s_tag *star, s_sequence *seq)
+static void star_render (s_tag *star, s_sequence *seq, s_gl_vertex *v)
{
f64 q;
f64 *speed;
@@ -44,14 +48,16 @@ static void star_render (s_tag *star, s_sequence *seq)
speed = &star->data.map.value[0].data.f64;
x = &star->data.map.value[1].data.f64;
y = &star->data.map.value[2].data.f64;
- glVertex2d(*x, *y);
+ gl_point_3d_init(&v[0].position, *x, *y, 0.0);
q = (1 + *speed / 20);
- glVertex2d(*x * q, *y * q);
+ gl_point_3d_init(&v[1].position, *x * q, *y * q, 0.0);
q = (1 + *speed / 100);
*x = *x * q;
*y = *y * q;
*speed += seq->dt;
- if (*x < -1.0 || *x > 1.0 || *y < -1.0 || *y > 1.0)
+ if ((*x == 0.0 && *y == 0.0) ||
+ *x < -1.0 || *x > 1.0 ||
+ *y < -1.0 || *y > 1.0)
star_init(star);
}
@@ -77,31 +83,46 @@ bool lightspeed_render (s_sequence *seq, s_window_sdl2 *window,
{
uw i;
uw star_count;
+ s_gl_vertex *v;
(void) window;
(void) context;
- glDisable(GL_TEXTURE_2D);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- //glScale2d(window->w / 2.0, window->h / 2.0);
- //glTranslatef(1.0f, 1.0f, 0.0f);
- glClearColor(0, 0, 0, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- glLineWidth(2);
- glColor4f(1, 1, 1, 0.7f);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_LINE_SMOOTH);
- glBegin(GL_LINES);
+ gl_matrix_4d_init_identity(&g_ortho.model_matrix);
+ /*
+ gl_matrix_4d_scale(&g_ortho.model_matrix, window->w / 2.0,
+ window->h / 2.0, 1);
+ gl_matrix_4d_translate(&g_ortho.model_matrix, 1, 1, 0);
+ */
+ gl_ortho_update_model_matrix(&g_ortho);
star_count = window->w * window->h * LIGHTSPEED_STAR_PROBABILITY;
if (star_count > LIGHTSPEED_STAR_MAX)
star_count = LIGHTSPEED_STAR_MAX;
+ v = g_lines_stars.vertex.data;
i = 0;
while (i < star_count) {
- star_render(seq->tag.data.tuple.tag + i, seq);
+ star_render(seq->tag.data.tuple.tag + i, seq, v);
+ v += 2;
i++;
}
- glEnd();
+ assert(glGetError() == GL_NO_ERROR);
+ gl_lines_update(&g_lines_stars, star_count);
+ assert(glGetError() == GL_NO_ERROR);
+ glDisable(GL_DEPTH_TEST);
+ assert(glGetError() == GL_NO_ERROR);
+ glClearColor(0, 0, 0, 1);
+ assert(glGetError() == GL_NO_ERROR);
+ glClear(GL_COLOR_BUFFER_BIT);
+ assert(glGetError() == GL_NO_ERROR);
+ glLineWidth(2);
+ assert(glGetError() == GL_NO_ERROR);
+ glBlendColor(1, 1, 1, 0.7f);
+ assert(glGetError() == GL_NO_ERROR);
+ glEnable(GL_BLEND);
+ assert(glGetError() == GL_NO_ERROR);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ assert(glGetError() == GL_NO_ERROR);
+ glEnable(GL_LINE_SMOOTH);
+ assert(glGetError() == GL_NO_ERROR);
+ gl_lines_render(&g_lines_stars, star_count);
+ assert(glGetError() == GL_NO_ERROR);
return true;
}
diff --git a/libc3/window/sdl2/demo/lightspeed.h b/libc3/window/sdl2/demo/lightspeed.h
index acaaf1b..6a889ad 100644
--- a/libc3/window/sdl2/demo/lightspeed.h
+++ b/libc3/window/sdl2/demo/lightspeed.h
@@ -15,6 +15,11 @@
#include "../types.h"
+#define LIGHTSPEED_STAR_MAX (1024 * 1024)
+#define LIGHTSPEED_STAR_PROBABILITY 0.005
+
+extern s_gl_lines g_lines_stars;
+
bool lightspeed_load (s_sequence *seq, s_window_sdl2 *window);
bool lightspeed_render (s_sequence *seq, s_window_sdl2 *window,
void *context);
diff --git a/libc3/window/sdl2/demo/toasters.c b/libc3/window/sdl2/demo/toasters.c
index 9543772..0491655 100644
--- a/libc3/window/sdl2/demo/toasters.c
+++ b/libc3/window/sdl2/demo/toasters.c
@@ -12,7 +12,7 @@
*/
#include <math.h>
#include <libc3/c3.h>
-#include "../sdl2_sprite.h"
+#include "../gl_sprite.h"
#include "toasters.h"
#define TOASTERS_SCALE_TOAST 0.52
@@ -22,8 +22,8 @@
static const f64 g_speed_x = 80.0;
static const f64 g_speed_y = -40.0;
-s_sdl2_sprite g_sprite_toast = {0};
-s_sdl2_sprite g_sprite_toaster = {0};
+s_gl_sprite g_sprite_toast = {0};
+s_gl_sprite g_sprite_toaster = {0};
static bool toasters_render_toasters (s_list **toasters,
s_window_sdl2 *window,
@@ -61,7 +61,7 @@ static void toast_render (s_tag *toast, s_window_sdl2 *window,
glPushMatrix();
glTranslated(*x, *y + g_sprite_toast.h, 0.0);
glScalef(TOASTERS_SCALE_TOAST, -TOASTERS_SCALE_TOAST, 1);
- sdl2_sprite_render(&g_sprite_toast, 0);
+ gl_sprite_render(&g_sprite_toast, 0);
glPopMatrix();
}
}
@@ -94,9 +94,9 @@ static void toaster_render (s_tag *toaster, s_window_sdl2 *window,
glPushMatrix();
glTranslated(*x, *y + g_sprite_toaster.h, 0.0);
glScalef(TOASTERS_SCALE_TOASTER, -TOASTERS_SCALE_TOASTER, 1);
- sdl2_sprite_render(&g_sprite_toaster,
- fmod(seq->t * g_sprite_toaster.frame_count,
- g_sprite_toaster.frame_count));
+ gl_sprite_render(&g_sprite_toaster,
+ fmod(seq->t * g_sprite_toaster.frame_count,
+ g_sprite_toaster.frame_count));
glPopMatrix();
}
}
diff --git a/libc3/window/sdl2/demo/toasters.h b/libc3/window/sdl2/demo/toasters.h
index 162192c..e6c9c15 100644
--- a/libc3/window/sdl2/demo/toasters.h
+++ b/libc3/window/sdl2/demo/toasters.h
@@ -15,8 +15,8 @@
#include "../types.h"
-extern s_sdl2_sprite g_sprite_toast;
-extern s_sdl2_sprite g_sprite_toaster;
+extern s_gl_sprite g_sprite_toast;
+extern s_gl_sprite g_sprite_toaster;
bool toasters_load (s_sequence *seq, s_window_sdl2 *window);
bool toasters_render (s_sequence *seq, s_window_sdl2 *window,
diff --git a/libc3/window/sdl2/demo/window_sdl2_demo.c b/libc3/window/sdl2/demo/window_sdl2_demo.c
index 84f504c..cd75c40 100644
--- a/libc3/window/sdl2/demo/window_sdl2_demo.c
+++ b/libc3/window/sdl2/demo/window_sdl2_demo.c
@@ -15,10 +15,12 @@
#include <libc3/c3.h>
#include "../../window.h"
#include "../gl_font.h"
+#include "../gl_lines.h"
#include "../gl_matrix_4d.h"
#include "../gl_ortho.h"
+#include "../gl_square.h"
#include "../gl_text.h"
-#include "../sdl2_sprite.h"
+#include "../gl_sprite.h"
#include "../window_sdl2.h"
#include "bg_rect.h"
#include "lightspeed.h"
@@ -28,11 +30,12 @@
#define WINDOW_SDL2_DEMO_SEQUENCE_COUNT 5
-//s_gl_font g_font_computer_modern = {0};
-s_gl_font g_font_courier_new = {0};
-s_gl_ortho g_ortho = {0};
-s_gl_text g_text_fps = {0};
-s_gl_text g_text_seq_title = {0};
+//s_gl_font g_font_computer_modern = {0};
+s_gl_font g_font_courier_new = {0};
+s_gl_ortho g_ortho = {0};
+s_gl_square g_square = {0};
+s_gl_text g_text_fps = {0};
+s_gl_text g_text_seq_title = {0};
static bool window_sdl2_demo_button (s_window_sdl2 *window, u8 button,
sw x, sw y);
@@ -80,7 +83,7 @@ int main (int argc, char **argv)
}
bool window_sdl2_demo_button (s_window_sdl2 *window, u8 button,
- sw x, sw y)
+ sw x, sw y)
{
assert(window);
(void) window;
@@ -151,7 +154,7 @@ bool window_sdl2_demo_load (s_window_sdl2 *window)
return false;
gl_ortho_resize(&g_ortho, 0, window->w, 0, window->h, -1, 1);
if (! gl_font_init(&g_font_courier_new,
- "fonts/Courier New/Courier New.ttf"))
+ "fonts/Courier New/Courier New.ttf"))
return false;
if (! gl_text_init_1(&g_text_seq_title, &g_font_courier_new, ""))
return false;
@@ -160,32 +163,35 @@ bool window_sdl2_demo_load (s_window_sdl2 *window)
window_sdl2_sequence_init(window->sequence, 8.0,
"01. Background rectangles",
bg_rect_load, bg_rect_render);
+ if (! gl_lines_init(&g_lines_stars) ||
+ ! gl_lines_allocate(&g_lines_stars, LIGHTSPEED_STAR_MAX))
+ return false;
window_sdl2_sequence_init(window->sequence + 1, 20.0,
"02. Lightspeed",
lightspeed_load, lightspeed_render);
- if (! sdl2_sprite_init(&g_sprite_toaster, "img/flaps.256.png",
- 4, 1, 4))
+ if (! gl_sprite_init(&g_sprite_toaster, "img/flaps.256.png",
+ 4, 1, 4))
return false;
- if (! sdl2_sprite_init(&g_sprite_toast, "img/toast.128.png",
- 1, 1, 1))
+ if (! gl_sprite_init(&g_sprite_toast, "img/toast.128.png",
+ 1, 1, 1))
return false;
window_sdl2_sequence_init(window->sequence + 2, 60.0,
"03. Toasters",
toasters_load, toasters_render);
if (! gl_font_init(&g_font_flies,
- "fonts/Courier New/Courier New.ttf"))
+ "fonts/Courier New/Courier New.ttf"))
return false;
- if (! sdl2_sprite_init(&g_sprite_fly, "img/fly-noto.png",
- 1, 1, 1))
+ if (! gl_sprite_init(&g_sprite_fly, "img/fly-noto.png",
+ 1, 1, 1))
return false;
- if (! sdl2_sprite_init(&g_sprite_dead_fly, "img/fly-dead.png",
- 1, 1, 1))
+ if (! gl_sprite_init(&g_sprite_dead_fly, "img/fly-dead.png",
+ 1, 1, 1))
return false;
window_sdl2_sequence_init(window->sequence + 3, 60.0,
"04. Flies",
flies_load, flies_render);
- if (! sdl2_sprite_init(&g_sprite_earth, "img/earth.png",
- 1, 1, 1))
+ if (! gl_sprite_init(&g_sprite_earth, "img/earth.png",
+ 1, 1, 1))
return false;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
assert(glGetError() == GL_NO_ERROR);
@@ -195,7 +201,7 @@ bool window_sdl2_demo_load (s_window_sdl2 *window)
"05. Earth",
earth_load, earth_render);
assert(glGetError() == GL_NO_ERROR);
- window_set_sequence_pos((s_window *) window, 0);
+ window_set_sequence_pos((s_window *) window, 0);
assert(glGetError() == GL_NO_ERROR);
return true;
}
@@ -260,10 +266,15 @@ bool window_sdl2_demo_render (s_window_sdl2 *window, void *context)
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ assert(glGetError() == GL_NO_ERROR);
if (! seq->render(seq, window, context))
return false;
+ assert(glGetError() == GL_NO_ERROR);
/* 2D */
glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
+ GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
assert(glGetError() == GL_NO_ERROR);
gl_font_set_size(&g_font_courier_new, 20,
(f64) window->gl_h / window->h);
@@ -272,19 +283,34 @@ bool window_sdl2_demo_render (s_window_sdl2 *window, void *context)
/* progress bar */
glDisable(GL_BLEND);
assert(glGetError() == GL_NO_ERROR);
- glBlendColor(1.0f, 1.0f, 1.0f, 1.0f);
assert(glGetError() == GL_NO_ERROR);
glBindTexture(GL_TEXTURE_2D, 0);
assert(glGetError() == GL_NO_ERROR);
+ glBlendColor(1.0f, 1.0f, 1.0f, 1.0f);
+ gl_matrix_4d_init_identity(&g_ortho.model_matrix);
+ gl_matrix_4d_translate(&g_ortho.model_matrix, 19.0, 11.0, 0);
+ gl_matrix_4d_scale(&g_ortho.model_matrix,
+ (window->w - 40.0) * seq->t / seq->duration + 2.0,
+ 4.0, 0);
+ gl_ortho_update_model_matrix(&g_ortho);
+ gl_square_render(&g_square);
/*
- glRectd(19, 11,
- 19 + (window->w - 40.0) * seq->t / seq->duration + 2,
- 11 + 4);
+ glRectd(19, 11,
+ 19 + (window->w - 40.0) * seq->t / seq->duration + 2,
+ 11 + 4);
+ */
glBlendColor(0.0f, 0.0f, 0.0f, 1.0f);
- glRectd(20, 12,
- 20 + (window->w - 40.0) * seq->t / seq->duration,
- 12 + 2);
- assert(glGetError() == GL_NO_ERROR);
+ gl_matrix_4d_init_identity(&g_ortho.model_matrix);
+ gl_matrix_4d_translate(&g_ortho.model_matrix, 20.0, 12.0, 0);
+ gl_matrix_4d_scale(&g_ortho.model_matrix,
+ (window->w - 40.0) * seq->t / seq->duration,
+ 2.0, 0);
+ gl_ortho_update_model_matrix(&g_ortho);
+ gl_square_render(&g_square);
+ /*
+ glRectd(20, 12,
+ 20 + (window->w - 40.0) * seq->t / seq->duration,
+ 12 + 2);
*/
/* fps */
s8 fps[32];
@@ -313,10 +339,10 @@ void window_sdl2_demo_unload (s_window_sdl2 *window)
(void) window;
gl_ortho_clean(&g_ortho);
gl_font_clean(&g_font_courier_new);
- sdl2_sprite_clean(&g_sprite_toaster);
- sdl2_sprite_clean(&g_sprite_toast);
+ gl_sprite_clean(&g_sprite_toaster);
+ gl_sprite_clean(&g_sprite_toast);
gl_font_clean(&g_font_flies);
- sdl2_sprite_clean(&g_sprite_fly);
- sdl2_sprite_clean(&g_sprite_dead_fly);
- sdl2_sprite_clean(&g_sprite_earth);
+ gl_sprite_clean(&g_sprite_fly);
+ gl_sprite_clean(&g_sprite_dead_fly);
+ gl_sprite_clean(&g_sprite_earth);
}
diff --git a/libc3/window/sdl2/demo/window_sdl2_demo.h b/libc3/window/sdl2/demo/window_sdl2_demo.h
index 371e1a9..3093d27 100644
--- a/libc3/window/sdl2/demo/window_sdl2_demo.h
+++ b/libc3/window/sdl2/demo/window_sdl2_demo.h
@@ -15,7 +15,8 @@
#include "../types.h"
-extern s_gl_font g_font_computer_modern;
-extern s_gl_font g_font_courier_new;
+extern s_gl_font g_font_computer_modern;
+extern s_gl_font g_font_courier_new;
+extern s_gl_ortho g_ortho;
#endif /* LIBC3_WINDOW_SDL2_DEMO_H */
diff --git a/libc3/window/sdl2/gl_lines.c b/libc3/window/sdl2/gl_lines.c
new file mode 100644
index 0000000..d6703fc
--- /dev/null
+++ b/libc3/window/sdl2/gl_lines.c
@@ -0,0 +1,93 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <libc3/c3.h>
+#include "gl_lines.h"
+
+s_gl_lines * gl_lines_allocate (s_gl_lines *lines, uw lines_count)
+{
+ uw vertex_count;
+ assert(lines);
+ assert(lines_count);
+ vertex_count = lines_count * 2;
+ if (! array_init(&lines->vertex, sym_1("GL.Vertex"), 1,
+ &vertex_count) ||
+ ! array_allocate(&lines->vertex))
+ return NULL;
+ return lines;
+}
+
+void gl_lines_clean (s_gl_lines *lines)
+{
+ assert(lines);
+ array_clean(&lines->vertex);
+ glDeleteVertexArrays(1, &lines->gl_vao);
+ glDeleteBuffers(1, &lines->gl_vbo);
+}
+
+s_gl_lines * gl_lines_init (s_gl_lines *lines)
+{
+ s_gl_lines tmp = {0};
+ assert(glGetError() == GL_NO_ERROR);
+ glGenVertexArrays(1, &tmp.gl_vao);
+ glGenBuffers(1, &tmp.gl_vbo);
+ assert(glGetError() == GL_NO_ERROR);
+ *lines = tmp;
+ return lines;
+}
+
+void gl_lines_render (const s_gl_lines *lines, uw lines_count)
+{
+ assert(lines);
+ if (lines_count > lines->vertex.count / 2)
+ lines_count = lines->vertex.count / 2;
+ assert(glGetError() == GL_NO_ERROR);
+ glBindVertexArray(lines->gl_vao);
+ assert(glGetError() == GL_NO_ERROR);
+ glDrawArrays(GL_LINES, 0, lines_count * 2);
+ assert(glGetError() == GL_NO_ERROR);
+}
+
+bool gl_lines_update (s_gl_lines *lines, uw lines_count)
+{
+ //GLenum gl_error;
+ assert(lines);
+ assert(lines->gl_vao);
+ assert(lines->gl_vbo);
+ assert(lines->vertex.data);
+ assert(glGetError() == GL_NO_ERROR);
+ if (lines_count > lines->vertex.count / 2)
+ lines_count = lines->vertex.count / 2;
+ glBindVertexArray(lines->gl_vao);
+ assert(glGetError() == GL_NO_ERROR);
+ glBindBuffer(GL_ARRAY_BUFFER, lines->gl_vbo);
+ assert(glGetError() == GL_NO_ERROR);
+ glBufferData(GL_ARRAY_BUFFER, lines_count * 2 * sizeof(s_gl_vertex),
+ lines->vertex.data, GL_DYNAMIC_DRAW);
+ assert(glGetError() == GL_NO_ERROR);
+ glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, sizeof(s_gl_vertex),
+ (void *) 0);
+ assert(glGetError() == GL_NO_ERROR);
+ glEnableVertexAttribArray(0);
+ assert(glGetError() == GL_NO_ERROR);
+ glVertexAttribPointer(1, 3, GL_DOUBLE, GL_FALSE, sizeof(s_gl_vertex),
+ (void *) (3 * sizeof(double)));
+ assert(glGetError() == GL_NO_ERROR);
+ glEnableVertexAttribArray(1);
+ assert(glGetError() == GL_NO_ERROR);
+ glVertexAttribPointer(2, 2, GL_DOUBLE, GL_FALSE, sizeof(s_gl_vertex),
+ (void *) (6 * sizeof(double)));
+ assert(glGetError() == GL_NO_ERROR);
+ glEnableVertexAttribArray(2);
+ assert(glGetError() == GL_NO_ERROR);
+ return true;
+}
diff --git a/libc3/window/sdl2/gl_lines.h b/libc3/window/sdl2/gl_lines.h
new file mode 100644
index 0000000..e0fbcce
--- /dev/null
+++ b/libc3/window/sdl2/gl_lines.h
@@ -0,0 +1,36 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef GL_LINES_H
+#define GL_LINES_H
+
+#include "types.h"
+
+/* Stack-allocation compatible functions, call gl_lines_clean
+ after use. */
+void gl_lines_clean (s_gl_lines *lines);
+s_gl_lines * gl_lines_init (s_gl_lines *lines);
+
+/* Heap-allocation functions, call gl_lines_delete after use. */
+void gl_lines_delete (s_gl_lines *lines);
+s_gl_lines * gl_lines_new ();
+
+/* Operators. */
+s_gl_lines * gl_lines_allocate (s_gl_lines *lines, uw lines_count);
+bool gl_lines_update (s_gl_lines *lines, uw lines_count);
+
+/* Observers. */
+void gl_lines_render (const s_gl_lines *lines, uw lines_count);
+void gl_lines_render_wireframe (const s_gl_lines *lines,
+ uw lines_count);
+
+#endif /* GL_LINES_H */
diff --git a/libc3/window/sdl2/gl_matrix_4d.c b/libc3/window/sdl2/gl_matrix_4d.c
index d96bd5e..f0fe807 100644
--- a/libc3/window/sdl2/gl_matrix_4d.c
+++ b/libc3/window/sdl2/gl_matrix_4d.c
@@ -15,6 +15,32 @@
#include "gl_matrix_4d.h"
#include "gl_point_3d.h"
+sw gl_matrix_4d_buf_inspect (s_buf *buf, const s_gl_matrix_4d *matrix)
+{
+ u8 i;
+ sw r;
+ sw result = 0;
+ assert(buf);
+ assert(matrix);
+ const f64 *m;
+ if ((r = buf_write_1(buf, "(F64) {")) < 0)
+ return r;
+ result += r;
+ m = &matrix->xx;
+ i = 0;
+ while (i < 16) {
+ if ((r = buf_inspect_f64(buf, m)) < 0)
+ return r;
+ result += r;
+ m++;
+ i++;
+ }
+ if ((r = buf_write_1(buf, "}")) < 0)
+ return r;
+ result += r;
+ return result;
+}
+
s_gl_matrix_4d * gl_matrix_4d_init_copy (s_gl_matrix_4d *m,
const s_gl_matrix_4d *src)
{
@@ -125,13 +151,13 @@ s_gl_matrix_4d * gl_matrix_4d_ortho (s_gl_matrix_4d *m, f64 x1, f64 x2,
assert(m);
dx = x2 - x1;
dy = y2 - y1;
- dz = clip_z_far - clip_z_near;
+ dz = clip_z_near - clip_z_far;
ortho.xx = 2.0 / dx;
ortho.yy = 2.0 / dy;
- ortho.zz = -2.0 / dz;
- ortho.tx = -(x1 + x2) / dx;
- ortho.ty = -(y1 + y2) / dy;
- ortho.tz = -(clip_z_near + clip_z_far) / dz;
+ ortho.zz = 2.0 / dz;
+ ortho.xt = -(x1 + x2) / dx;
+ ortho.yt = -(y1 + y2) / dy;
+ ortho.zt = (clip_z_near + clip_z_far) / dz;
ortho.tt = 1.0;
gl_matrix_4d_product(m, &ortho);
return m;
@@ -167,6 +193,18 @@ s_gl_matrix_4d * gl_matrix_4d_product (s_gl_matrix_4d *m,
return m;
}
+s_gl_matrix_4d * gl_matrix_4d_scale (s_gl_matrix_4d *m, f64 x, f64 y,
+ f64 z)
+{
+ s_gl_matrix_4d s = {0};
+ s.xx = x;
+ s.yy = y;
+ s.zz = z;
+ s.tt = 1.0;
+ gl_matrix_4d_product(m, &s);
+ return m;
+}
+
s_gl_matrix_4d * gl_matrix_4d_translate (s_gl_matrix_4d *m, f64 x,
f64 y, f64 z)
{
diff --git a/libc3/window/sdl2/gl_object.c b/libc3/window/sdl2/gl_object.c
index cf75f1d..57da027 100644
--- a/libc3/window/sdl2/gl_object.c
+++ b/libc3/window/sdl2/gl_object.c
@@ -12,6 +12,7 @@
*/
#include <libc3/c3.h>
#include "gl_object.h"
+#include "gl_vertex.h"
s_gl_object * gl_object_allocate (s_gl_object *object, uw vertex_count,
uw triangle_count)
@@ -55,14 +56,43 @@ void gl_object_render (const s_gl_object *object)
{
assert(object);
assert(glGetError() == GL_NO_ERROR);
+ glBindBuffer(GL_ARRAY_BUFFER, object->gl_vbo);
+ assert(glGetError() == GL_NO_ERROR);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->gl_ebo);
+ assert(glGetError() == GL_NO_ERROR);
+ glDrawArrays(GL_TRIANGLES, object->triangle.count * 3,
+ GL_UNSIGNED_INT);
+ assert(glGetError() == GL_NO_ERROR);
+}
+
+void gl_object_render_wireframe (const s_gl_object *object)
+{
+ assert(object);
+ assert(glGetError() == GL_NO_ERROR);
glBindVertexArray(object->gl_vao);
assert(glGetError() == GL_NO_ERROR);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->gl_ebo);
assert(glGetError() == GL_NO_ERROR);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ glDrawElements(GL_LINE_LOOP, object->triangle.count * 3, GL_UNSIGNED_INT, 0);
assert(glGetError() == GL_NO_ERROR);
}
+void gl_object_transform (s_gl_object *object,
+ const s_gl_matrix_4d *matrix)
+{
+ uw i;
+ s_gl_vertex *vertex;
+ assert(object);
+ assert(matrix);
+ vertex = object->vertex.data;
+ i = 0;
+ while (i < object->vertex.count) {
+ gl_vertex_transform(vertex, matrix);
+ vertex++;
+ i++;
+ }
+}
+
bool gl_object_update (s_gl_object *object)
{
//GLenum gl_error;
diff --git a/libc3/window/sdl2/gl_object.h b/libc3/window/sdl2/gl_object.h
index 8c6126b..b4bd54c 100644
--- a/libc3/window/sdl2/gl_object.h
+++ b/libc3/window/sdl2/gl_object.h
@@ -31,5 +31,6 @@ bool gl_object_update (s_gl_object *object);
/* Observers. */
void gl_object_render (const s_gl_object *object);
+void gl_object_render_wireframe (const s_gl_object *object);
#endif /* GL_OBJECT_H */
diff --git a/libc3/window/sdl2/gl_ortho.c b/libc3/window/sdl2/gl_ortho.c
index 3422cf2..08ddbc1 100644
--- a/libc3/window/sdl2/gl_ortho.c
+++ b/libc3/window/sdl2/gl_ortho.c
@@ -17,6 +17,10 @@
static const s8 * g_gl_ortho_vertex_shader_src = "#version 460 core\n"
"layout (location = 0) in dvec3 aPos;\n"
+ "layout (location = 1) in dvec3 aNorm;\n"
+ "layout (location = 2) in dvec2 aTexCoord;\n"
+ "out vec3 FragNormal;\n"
+ "out vec2 TexCoord;\n"
"uniform dmat4 projection_matrix;\n"
"uniform dmat4 view_matrix;\n"
"uniform dmat4 model_matrix;\n"
@@ -24,6 +28,8 @@ static const s8 * g_gl_ortho_vertex_shader_src = "#version 460 core\n"
"void main() {\n"
" gl_Position = vec4(projection_matrix * view_matrix * \n"
" model_matrix * dvec4(aPos, 1.0));\n"
+ " FragNormal = vec3(dmat3(transpose(inverse(model_matrix))) * aNorm);\n"
+ " TexCoord = vec2(aTexCoord);\n"
"}\n";
void gl_ortho_clean (s_gl_ortho *ortho)
@@ -72,8 +78,6 @@ s_gl_ortho * gl_ortho_init (s_gl_ortho *ortho)
assert(glGetError() == GL_NO_ERROR);
glDeleteShader(vertex_shader);
assert(glGetError() == GL_NO_ERROR);
- glUseProgram(ortho->gl_shader_program);
- assert(glGetError() == GL_NO_ERROR);
ortho->gl_projection_matrix_loc =
glGetUniformLocation(ortho->gl_shader_program, "projection_matrix");
assert(glGetError() == GL_NO_ERROR);
@@ -83,8 +87,6 @@ s_gl_ortho * gl_ortho_init (s_gl_ortho *ortho)
ortho->gl_model_matrix_loc =
glGetUniformLocation(ortho->gl_shader_program, "model_matrix");
assert(glGetError() == GL_NO_ERROR);
- glUseProgram(0);
- assert(glGetError() == GL_NO_ERROR);
return ortho;
}
@@ -130,14 +132,9 @@ void gl_ortho_resize (s_gl_ortho *ortho, f64 x1, f64 x2, f64 y1, f64 y2,
f64 clip_z_near, f64 clip_z_far)
{
assert(ortho);
- assert(glGetError() == GL_NO_ERROR);
gl_matrix_4d_init_identity(&ortho->projection_matrix);
gl_matrix_4d_ortho(&ortho->projection_matrix, x1, x2, y1, y2,
clip_z_near, clip_z_far);
- glUseProgram(ortho->gl_shader_program);
- glUniformMatrix4dv(ortho->gl_projection_matrix_loc, 1, GL_FALSE,
- &ortho->projection_matrix.xx);
- assert(glGetError() == GL_NO_ERROR);
}
void gl_ortho_render_end (s_gl_ortho *ortho)
diff --git a/libc3/window/sdl2/gl_point_3d.c b/libc3/window/sdl2/gl_point_3d.c
index 7821b22..91f1def 100644
--- a/libc3/window/sdl2/gl_point_3d.c
+++ b/libc3/window/sdl2/gl_point_3d.c
@@ -130,3 +130,23 @@ f64 gl_point_3d_norm (const s_gl_point_3d *p)
assert(p);
return sqrt(p->x * p->x + p->y * p->y + p->z * p->z);
}
+
+void gl_point_3d_normalize (s_gl_point_3d *p)
+{
+ f64 inv_norm;
+ assert(p);
+ inv_norm = 1.0 / gl_point_3d_norm(p);
+ p->x *= inv_norm;
+ p->y *= inv_norm;
+ p->z *= inv_norm;
+}
+
+void gl_point_3d_transform (s_gl_point_3d *p,
+ const s_gl_matrix_4d *matrix)
+{
+ s_gl_point_3d tmp;
+ assert(p);
+ assert(matrix);
+ gl_point_3d_init_product(&tmp, matrix, p);
+ *p = tmp;
+}
diff --git a/libc3/window/sdl2/gl_point_3d.h b/libc3/window/sdl2/gl_point_3d.h
index 63e0c5f..6a8a902 100644
--- a/libc3/window/sdl2/gl_point_3d.h
+++ b/libc3/window/sdl2/gl_point_3d.h
@@ -37,8 +37,9 @@ s_gl_point_3d * gl_point_3d_new_product (const s_gl_matrix_4d *m,
s_gl_point_3d * gl_point_3d_new_zero (void);
/* Operators. */
-s_gl_point_3d * gl_point_3d_product (s_gl_point_3d *p,
- const s_gl_matrix_4d *m);
+void gl_point_3d_normalize (s_gl_point_3d *p);
+void gl_point_3d_transform (s_gl_point_3d *p,
+ const s_gl_matrix_4d *matrix);
/* Observers. */
f64 gl_point_3d_norm (const s_gl_point_3d *p);
diff --git a/libc3/window/sdl2/gl_sphere.c b/libc3/window/sdl2/gl_sphere.c
index c57f359..5357d96 100644
--- a/libc3/window/sdl2/gl_sphere.c
+++ b/libc3/window/sdl2/gl_sphere.c
@@ -87,7 +87,6 @@ s_gl_sphere * gl_sphere_init (s_gl_sphere *sphere, uw seg_u, uw seg_v)
}
i++;
}
- gl_object_update(&sphere->object);
*sphere = tmp;
return sphere;
}
diff --git a/libc3/window/sdl2/gl_sprite.c b/libc3/window/sdl2/gl_sprite.c
new file mode 100644
index 0000000..b87c764
--- /dev/null
+++ b/libc3/window/sdl2/gl_sprite.c
@@ -0,0 +1,383 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <libc3/c3.h>
+#include "gl_object.h"
+#include "gl_point_2d.h"
+#include "gl_point_3d.h"
+#include "gl_sprite.h"
+#include "gl_triangle.h"
+
+void gl_sprite_bind (const s_gl_sprite *sprite, uw frame)
+{
+ assert(sprite);
+ assert(frame < sprite->frame_count);
+ frame %= sprite->frame_count;
+ assert(glGetError() == GL_NO_ERROR);
+ glBindTexture(GL_TEXTURE_2D, sprite->texture[frame]);
+ assert(glGetError() == GL_NO_ERROR);
+}
+
+void gl_sprite_clean (s_gl_sprite *sprite)
+{
+ assert(sprite);
+ gl_object_clean(&sprite->object);
+ str_clean(&sprite->path);
+ str_clean(&sprite->real_path);
+ glDeleteTextures(sprite->frame_count, sprite->texture);
+ free(sprite->texture);
+}
+
+static bool png_info_to_gl_info (s32 png_color_type,
+ s32 png_bit_depth,
+ GLenum *gl_format,
+ GLint *gl_internal_format,
+ GLenum *gl_type,
+ u8 *components)
+{
+ switch (png_bit_depth) {
+ case 8: *gl_type = GL_UNSIGNED_BYTE; break;
+ case 16: *gl_type = GL_UNSIGNED_SHORT; break;
+ default: *gl_type = 0; return false;
+ }
+ switch (png_color_type) {
+ case PNG_COLOR_TYPE_GRAY:
+ *components = 1;
+ *gl_format = GL_RED;
+ switch (png_bit_depth) {
+ case 8: *gl_internal_format = GL_RED; break;
+ case 16: *gl_internal_format = GL_RED; break;
+ default: *gl_internal_format = 0; return false;
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ *components = 2;
+ *gl_format = GL_RG;
+ switch (png_bit_depth) {
+ case 8: *gl_internal_format = GL_RG; break;
+ case 16: *gl_internal_format = GL_RG; break;
+ default: *gl_internal_format = 0; return false;
+ }
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ *components = 3;
+ *gl_format = GL_RGB;
+ switch (png_bit_depth) {
+ case 8: *gl_internal_format = GL_RGB; break;
+ case 16: *gl_internal_format = GL_RGB; break;
+ default: *gl_internal_format = 0; return false;
+ }
+ break;
+ case PNG_COLOR_TYPE_RGBA:
+ *components = 4;
+ *gl_format = GL_RGBA;
+ switch (png_bit_depth) {
+ case 8: *gl_internal_format = GL_RGBA8; break;
+ case 16: *gl_internal_format = GL_RGBA16; break;
+ default: *gl_internal_format = 0; return false;
+ }
+ break;
+ default:
+ *components = 0;
+ *gl_format = 0;
+ *gl_internal_format = 0;
+ return false;
+ }
+ return true;
+}
+
+s_gl_sprite * gl_sprite_init (s_gl_sprite *sprite, const s8 *path,
+ uw dim_x, uw dim_y, uw frame_count)
+{
+ u8 *data;
+ FILE *fp;
+ GLenum gl_format;
+ GLint gl_internal_format;
+ GLenum gl_type;
+ uw i;
+ s32 png_bit_depth;
+ s32 png_color_type;
+ u8 png_components;
+ png_bytep png_data;
+ u32 png_h;
+ u8 png_header[8]; // maximum size is 8
+ png_infop png_info;
+ uw png_pixel_size;
+ png_structp png_read;
+ png_bytep *png_row;
+ u32 png_w;
+ u8 *sprite_data;
+ uw sprite_stride;
+ uw x;
+ uw y;
+ uw v;
+ uw dimension;
+ s_gl_sprite tmp = {0};
+ s_gl_triangle *triangle;
+ s_gl_vertex *vertex;
+ assert(sprite);
+ assert(path);
+ assert(dim_x);
+ assert(dim_y);
+ assert(glGetError() == GL_NO_ERROR);
+ tmp.frame_count = (frame_count > 0) ? frame_count :
+ (dim_x * dim_y);
+ str_init_copy_1(&tmp.path, path);
+ if (! file_search(&tmp.path, sym_1("r"), &tmp.real_path)) {
+ err_write_1("sdl2_sprite_init: file not found: ");
+ err_puts(path);
+ str_clean(&tmp.path);
+ return NULL;
+ }
+ fp = fopen(tmp.real_path.ptr.ps8, "rb");
+ if (! fp) {
+ err_write_1("sdl2_sprite_init: fopen: ");
+ err_puts(tmp.real_path.ptr.ps8);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ if (fread(png_header, 1, sizeof(png_header), fp) !=
+ sizeof(png_header)) {
+ err_write_1("sdl2_sprite_init: fread: ");
+ err_puts(tmp.real_path.ptr.ps8);
+ fclose(fp);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ if (png_sig_cmp(png_header, 0, sizeof(png_header))) {
+ err_write_1("sdl2_sprite_init: not a png: ");
+ err_puts(tmp.real_path.ptr.ps8);
+ fclose(fp);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ png_read = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
+ NULL);
+ if (! png_read) {
+ err_write_1("sdl2_sprite_init: png_create_read_struct: ");
+ err_puts(tmp.real_path.ptr.ps8);
+ fclose(fp);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ png_info = png_create_info_struct(png_read);
+ if (! png_info) {
+ err_write_1("sdl2_sprite_init: png_create_info_struct: ");
+ err_puts(tmp.real_path.ptr.ps8);
+ png_destroy_read_struct(&png_read, NULL, NULL);
+ fclose(fp);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ gl_internal_format = 0;
+ gl_format = 0;
+ gl_type = 0;
+ png_components = 0;
+ if (setjmp(png_jmpbuf(png_read))) {
+ png_destroy_read_struct(&png_read, &png_info, NULL);
+ fclose(fp);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ png_set_sig_bytes(png_read, sizeof(png_header));
+ png_init_io(png_read, fp);
+ png_read_info(png_read, png_info);
+ png_get_IHDR(png_read, png_info, &png_w, &png_h,
+ &png_bit_depth, &png_color_type,
+ NULL, NULL, NULL);
+ if (png_color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_palette_to_rgb(png_read);
+ if (! png_info_to_gl_info(png_color_type, png_bit_depth, &gl_format,
+ &gl_internal_format, &gl_type,
+ &png_components)) {
+ if (! gl_format || ! png_components) {
+ err_write_1("sdl2_sprite_init: unknown PNG color type ");
+ err_inspect_s32(&png_color_type);
+ err_write_1(": ");
+ err_puts(tmp.real_path.ptr.ps8);
+ }
+ if (! gl_internal_format) {
+ err_write_1("sdl2_sprite_init: unknown OpenGL internal format: ");
+ err_puts(tmp.real_path.ptr.ps8);
+ }
+ if (! gl_type) {
+ err_write_1("sdl2_sprite_init: unknown OpenGL type: ");
+ err_puts(tmp.real_path.ptr.ps8);
+ }
+ png_destroy_read_struct(&png_read, &png_info, NULL);
+ fclose(fp);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ png_pixel_size = (png_bit_depth / 8) * png_components;
+ if (! png_pixel_size)
+ png_error(png_read, "unknown png pixel size");
+ if (png_h > PNG_SIZE_MAX / (png_w * png_pixel_size))
+ png_error(png_read, "image_data buffer would be too large");
+ png_data = png_malloc(png_read, png_h * png_w * png_pixel_size);
+ png_row = png_malloc(png_read, png_h * sizeof(png_bytep));
+ i = 0;
+ while (i < png_h) {
+ png_row[i] = png_data + i * png_w * png_pixel_size;
+ i++;
+ }
+ if (png_bit_depth < 8)
+ png_set_packing(png_read);
+ png_read_image(png_read, png_row);
+ png_destroy_read_struct(&png_read, &png_info, NULL);
+ fclose(fp);
+ tmp.total_w = png_w;
+ tmp.total_h = png_h;
+ tmp.dim_x = dim_x;
+ tmp.dim_y = dim_y;
+ tmp.w = tmp.total_w / dim_x;
+ tmp.h = tmp.total_h / dim_y;
+ tmp.texture = calloc(tmp.frame_count, sizeof(GLuint));
+ if (! tmp.texture) {
+ err_puts("sdl2_sprite_init: tmp.texture:"
+ " failed to allocate memory");
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ glGenTextures(tmp.frame_count, tmp.texture);
+ GLenum gl_error = glGetError();
+ if (gl_error != GL_NO_ERROR) {
+ err_write_1("sdl2_sprite_init: ");
+ err_inspect_str(&tmp.real_path);
+ err_write_1(": glGenTextures: ");
+ err_puts((const s8 *) gluErrorString(gl_error));
+ free(tmp.texture);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ sprite_stride = tmp.w * png_pixel_size;
+ data = malloc(tmp.h * sprite_stride);
+ if (! data) {
+ err_write_1("sdl2_sprite_init: failed to allocate memory: ");
+ err_puts(tmp.real_path.ptr.ps8);
+ free(tmp.texture);
+ str_clean(&tmp.path);
+ str_clean(&tmp.real_path);
+ return NULL;
+ }
+ i = 0;
+ y = 0;
+ while (i < tmp.frame_count && y < dim_y) {
+ x = 0;
+ while (i < tmp.frame_count && x < dim_x) {
+ sprite_data = data + sprite_stride * tmp.h;
+ v = 0;
+ while (v < tmp.h) {
+ sprite_data -= sprite_stride;
+ memcpy(sprite_data,
+ png_row[y * tmp.h + v] + x * sprite_stride,
+ sprite_stride);
+ v++;
+ }
+ glBindTexture(GL_TEXTURE_2D, tmp.texture[i]);
+ gl_error = glGetError();
+ if (gl_error != GL_NO_ERROR) {
+ err_write_1("sdl2_sprite_init: ");
+ err_inspect_str(&tmp.real_path);
+ err_write_1(": glBindTexture: ");
+ err_puts((const s8 *) gluErrorString(gl_error));
+ return NULL;
+ }
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+ GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+ GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl_error = glGetError();
+ if (gl_error != GL_NO_ERROR) {
+ err_write_1("sdl2_sprite_init: ");
+ err_inspect_str(&tmp.real_path);
+ err_write_1(": glTexParameteri: ");
+ err_puts((const s8 *) gluErrorString(gl_error));
+ return NULL;
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, gl_format, tmp.w, tmp.h,
+ 0, gl_format, gl_type, data);
+ //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmp.w, tmp.h,
+ // 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ gl_error = glGetError();
+ if (gl_error != GL_NO_ERROR) {
+ err_write_1("sdl2_sprite_init: ");
+ err_inspect_str(&tmp.real_path);
+ err_write_1(": glTexImage2D: ");
+ err_puts((const s8 *) gluErrorString(gl_error));
+ return NULL;
+ }
+ glGenerateMipmap(GL_TEXTURE_2D);
+ assert(glGetError() == GL_NO_ERROR);
+ i++;
+ x++;
+ }
+ y++;
+ }
+ glBindTexture(GL_TEXTURE_2D, 0);
+ free(data);
+ free(png_data);
+ free(png_row);
+ assert(glGetError() == GL_NO_ERROR);
+ gl_object_init(&tmp.object);
+ dimension = 4;
+ array_init(&tmp.object.vertex, sym_1("GL.Vertex"), 1,
+ &dimension);
+ array_allocate(&tmp.object.vertex);
+ dimension = 2;
+ array_init(&tmp.object.triangle, sym_1("GL.Triangle"), 1,
+ &dimension);
+ array_allocate(&tmp.object.triangle);
+ vertex = tmp.object.vertex.data;
+ gl_point_3d_init(&vertex[0].position, 0.0, tmp.h, 0.0);
+ gl_point_3d_init(&vertex[0].normal, 0.0, 0.0, -1.0);
+ gl_point_2d_init(&vertex[0].tex_coord, 0.0, 1.0);
+ gl_point_3d_init(&vertex[1].position, 0.0, 0.0, 0.0);
+ gl_point_3d_init(&vertex[1].normal, 0.0, 0.0, -1.0);
+ gl_point_2d_init(&vertex[1].tex_coord, 0.0, 0.0);
+ gl_point_3d_init(&vertex[2].position, tmp.w, tmp.h, 0.0);
+ gl_point_3d_init(&vertex[2].normal, 0.0, 0.0, -1.0);
+ gl_point_2d_init(&vertex[2].tex_coord, 1.0, 1.0);
+ gl_point_3d_init(&vertex[3].position, tmp.w, 0.0, 0.0);
+ gl_point_3d_init(&vertex[3].normal, 0.0, 0.0, -1.0);
+ gl_point_2d_init(&vertex[3].tex_coord, 1.0, 0.0);
+ triangle = tmp.object.triangle.data;
+ gl_triangle_init(triangle + 0, 0, 1, 2);
+ gl_triangle_init(triangle + 1, 1, 3, 2);
+ gl_object_update(&tmp.object);
+ *sprite = tmp;
+ return sprite;
+}
+
+void gl_sprite_render (const s_gl_sprite *sprite, uw frame)
+{
+ assert(sprite);
+ assert(glGetError() == GL_NO_ERROR);
+ gl_sprite_bind(sprite, frame);
+ assert(glGetError() == GL_NO_ERROR);
+ gl_object_render(&sprite->object);
+ assert(glGetError() == GL_NO_ERROR);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ assert(glGetError() == GL_NO_ERROR);
+}
diff --git a/libc3/window/sdl2/gl_sprite.h b/libc3/window/sdl2/gl_sprite.h
new file mode 100644
index 0000000..22d7283
--- /dev/null
+++ b/libc3/window/sdl2/gl_sprite.h
@@ -0,0 +1,28 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef GL_SPRITE_H
+#define GL_SPRITE_H
+
+#include "types.h"
+
+/* Stack-allocation compatible functions, call gl_sprite_clean
+ after use. */
+void gl_sprite_clean (s_gl_sprite *sprite);
+s_gl_sprite * gl_sprite_init (s_gl_sprite *sprite, const s8 *path,
+ uw dim_x, uw dim_y, uw frame_count);
+
+/* Observers. */
+void gl_sprite_bind (const s_gl_sprite *sprite, uw frame);
+void gl_sprite_render (const s_gl_sprite *sprite, uw frame);
+
+#endif /* GL_SPRITE_H */
diff --git a/libc3/window/sdl2/gl_square.c b/libc3/window/sdl2/gl_square.c
new file mode 100644
index 0000000..d549e35
--- /dev/null
+++ b/libc3/window/sdl2/gl_square.c
@@ -0,0 +1,115 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <math.h>
+#include <libc3/c3.h>
+#include "gl_object.h"
+#include "gl_point_3d.h"
+#include "gl_square.h"
+
+void gl_square_clean (s_gl_square *square)
+{
+ assert(square);
+ gl_object_clean(&square->object);
+}
+
+void gl_square_delete (s_gl_square *square)
+{
+ assert(square);
+ gl_square_clean(square);
+ free(square);
+}
+
+s_gl_square * gl_square_init (s_gl_square *square, uw seg_u, uw seg_v)
+{
+ uw i;
+ uw j;
+ s_gl_point_3d normal;
+ s_gl_square tmp = {0};
+ s_gl_triangle *triangle;
+ s_gl_vertex *vertex;
+ f64 y;
+ assert(square);
+ if (seg_u < 2)
+ seg_u = 2;
+ if (seg_v < 2)
+ seg_v = 2;
+ tmp.segments_u = seg_u;
+ tmp.segments_v = seg_v;
+ if (! gl_object_init(&tmp.object) ||
+ ! gl_object_allocate(&tmp.object, seg_u * seg_v,
+ 2 * (seg_u - 1) * (seg_v - 1)))
+ return NULL;
+ gl_point_3d_init(&normal, 0.0, 0.0, 1.0);
+ vertex = tmp.object.vertex.data;
+ i = 0;
+ while (i < seg_v) {
+ y = (f64) i / seg_v;
+ j = 0;
+ while (j < seg_u) {
+ vertex->tex_coord.x = vertex->position.x = (f64) j / seg_u;
+ vertex->tex_coord.y = vertex->position.y = y;
+ vertex->position.z = 0.0;
+ vertex->normal = normal;
+ vertex++;
+ j++;
+ }
+ i++;
+ }
+ triangle = tmp.object.triangle.data;
+ i = 0;
+ while (i < seg_v - 1) {
+ j = 0;
+ while (j < seg_u - 1) {
+ triangle->a = i * seg_u + j;
+ triangle->b = (i + 1) * seg_u + j;
+ triangle->c = (i + 1) * seg_u + j + 1;
+ triangle++;
+ triangle->a = i * seg_u + j;
+ triangle->b = (i + 1) * seg_u + j + 1;
+ triangle->c = i * seg_u + j + 1;
+ triangle++;
+ j++;
+ }
+ i++;
+ }
+ gl_object_update(&square->object);
+ *square = tmp;
+ return square;
+}
+
+s_gl_square * gl_square_new (uw segments_u, uw segments_v)
+{
+ s_gl_square *square;
+ square = calloc(1, sizeof(s_gl_square));
+ if (! square) {
+ err_puts("gl_square_new: failed to allocate memory");
+ return NULL;
+ }
+ if (! gl_square_init(square, segments_u, segments_v)) {
+ free(square);
+ return NULL;
+ }
+ return square;
+}
+
+void gl_square_render (const s_gl_square *square)
+{
+ assert(square);
+ gl_object_render(&square->object);
+}
+
+void gl_square_render_wireframe (const s_gl_square *square)
+{
+ assert(square);
+ gl_object_render_wireframe(&square->object);
+}
diff --git a/libc3/window/sdl2/gl_vertex.c b/libc3/window/sdl2/gl_vertex.c
new file mode 100644
index 0000000..3cec9ed
--- /dev/null
+++ b/libc3/window/sdl2/gl_vertex.c
@@ -0,0 +1,25 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <libc3/c3.h>
+#include "gl_point_3d.h"
+#include "gl_vertex.h"
+
+void gl_vertex_transform (s_gl_vertex *vertex,
+ const s_gl_matrix_4d *matrix)
+{
+ assert(vertex);
+ assert(matrix);
+ gl_point_3d_transform(&vertex->position, matrix);
+ gl_point_3d_transform(&vertex->normal, matrix);
+ gl_point_3d_normalize(&vertex->normal);
+}
diff --git a/libc3/window/sdl2/gl_vertex.h b/libc3/window/sdl2/gl_vertex.h
new file mode 100644
index 0000000..8e18083
--- /dev/null
+++ b/libc3/window/sdl2/gl_vertex.h
@@ -0,0 +1,21 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef GL_VERTEX_H
+#define GL_VERTEX_H
+
+#include "types.h"
+
+void gl_vertex_transform (s_gl_vertex *vertex,
+ const s_gl_matrix_4d *matrix);
+
+#endif /* GL_VERTEX_H */
diff --git a/libc3/window/sdl2/sources.mk b/libc3/window/sdl2/sources.mk
index 281244d..6589755 100644
--- a/libc3/window/sdl2/sources.mk
+++ b/libc3/window/sdl2/sources.mk
@@ -4,6 +4,7 @@ HEADERS = \
"gl_cylinder.h" \
"gl_font.h" \
"gl_ft2.h" \
+ "gl_lines.h" \
"gl_matrix_3d.h" \
"gl_matrix_4d.h" \
"gl_object.h" \
@@ -11,8 +12,11 @@ HEADERS = \
"gl_point_2d.h" \
"gl_point_3d.h" \
"gl_sphere.h" \
+ "gl_sprite.h" \
+ "gl_square.h" \
"gl_text.h" \
"gl_triangle.h" \
+ "gl_vertex.h" \
"sdl2_sprite.h" \
"types.h" \
"window_sdl2.h" \
@@ -21,14 +25,18 @@ SOURCES = \
"gl_camera.c" \
"gl_cylinder.c" \
"gl_font.c" \
+ "gl_lines.c" \
"gl_matrix_4d.c" \
"gl_object.c" \
"gl_ortho.c" \
"gl_point_2d.c" \
"gl_point_3d.c" \
"gl_sphere.c" \
+ "gl_sprite.c" \
+ "gl_square.c" \
"gl_text.c" \
"gl_triangle.c" \
+ "gl_vertex.c" \
"sdl2_sprite.c" \
"window_sdl2.c" \
diff --git a/libc3/window/sdl2/sources.sh b/libc3/window/sdl2/sources.sh
index f41cb08..490c35b 100644
--- a/libc3/window/sdl2/sources.sh
+++ b/libc3/window/sdl2/sources.sh
@@ -1,3 +1,3 @@
# sources.sh generated by update_sources
-HEADERS='gl_camera.h gl_cylinder.h gl_font.h gl_ft2.h gl_matrix_3d.h gl_matrix_4d.h gl_object.h gl_ortho.h gl_point_2d.h gl_point_3d.h gl_sphere.h gl_text.h gl_triangle.h sdl2_sprite.h types.h window_sdl2.h '
-SOURCES='gl_camera.c gl_cylinder.c gl_font.c gl_matrix_4d.c gl_object.c gl_ortho.c gl_point_2d.c gl_point_3d.c gl_sphere.c gl_text.c gl_triangle.c sdl2_sprite.c window_sdl2.c '
+HEADERS='gl_camera.h gl_cylinder.h gl_font.h gl_ft2.h gl_lines.h gl_matrix_3d.h gl_matrix_4d.h gl_object.h gl_ortho.h gl_point_2d.h gl_point_3d.h gl_sphere.h gl_sprite.h gl_square.h gl_text.h gl_triangle.h gl_vertex.h sdl2_sprite.h types.h window_sdl2.h '
+SOURCES='gl_camera.c gl_cylinder.c gl_font.c gl_lines.c gl_matrix_4d.c gl_object.c gl_ortho.c gl_point_2d.c gl_point_3d.c gl_sphere.c gl_sprite.c gl_square.c gl_text.c gl_triangle.c gl_vertex.c sdl2_sprite.c window_sdl2.c '
diff --git a/libc3/window/sdl2/types.h b/libc3/window/sdl2/types.h
index 0b655f0..a4e3630 100644
--- a/libc3/window/sdl2/types.h
+++ b/libc3/window/sdl2/types.h
@@ -29,6 +29,7 @@
typedef struct gl_camera s_gl_camera;
typedef struct gl_cylinder s_gl_cylinder;
typedef struct gl_font s_gl_font;
+typedef struct gl_lines s_gl_lines;
typedef struct gl_matrix_3d s_gl_matrix_3d;
typedef struct gl_matrix_4d s_gl_matrix_4d;
typedef struct gl_object s_gl_object;
@@ -36,6 +37,7 @@ typedef struct gl_ortho s_gl_ortho;
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_sprite s_gl_sprite;
typedef struct gl_square s_gl_square;
typedef struct gl_text s_gl_text;
typedef struct gl_triangle s_gl_triangle;
@@ -86,6 +88,12 @@ struct gl_font {
s_str real_path;
};
+struct gl_lines {
+ s_array vertex;
+ u32 gl_vao;
+ u32 gl_vbo;
+};
+
struct gl_matrix_3d {
f64 xx;
f64 xy;
@@ -235,6 +243,22 @@ struct gl_sphere {
uw segments_v;
};
+struct gl_sprite {
+ s_gl_object object;
+ s_str path;
+ s_str real_path;
+ uw total_w;
+ uw total_h;
+ uw dim_x;
+ uw dim_y;
+ uw frame_count;
+ uw w;
+ uw h;
+ uw tex_w;
+ uw tex_h;
+ GLuint *texture;
+};
+
struct gl_square {
s_gl_object object;
uw segments_u;