summaryrefslogtreecommitdiff
path: root/src/hacks.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/hacks.h')
-rw-r--r--src/hacks.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/hacks.h b/src/hacks.h
new file mode 100644
index 0000000..4846fd1
--- /dev/null
+++ b/src/hacks.h
@@ -0,0 +1,81 @@
+#define NONE(...)
+#define ID(X, ...) X
+#define CALL(F, ...) F(__VA_ARGS__)
+#define EXPAND(...) __VA_ARGS__
+#define BRACE(...) (__VA_ARGS__)
+
+#define IF_0(t, f) f
+#define IF_1(t, f) t
+#define IF_(cond) IF_##cond
+#define IF(cond, t, f) IF_(cond)(t, f)
+
+// add more iterations as needed
+#define FOLD_(F, init, x0, x1, x2, x3, x4, x5, x6, x7, ...) \
+ F(F(F(F(F(F(F(F(init, x0), x1), x2), x3), x4), x5), x6), x7)
+#define FOLD(NIL,...) FOLD_(__VA_ARGS__,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL)
+
+#define GET1(x, ...) x
+#define GET2(x, ...) GET1(__VA_ARGS__)
+#define GET3(x, ...) GET2(__VA_ARGS__)
+
+// add more EQUALS_X_X as needed
+#define EQUALS_0_0 ~, 1
+#define EQUALS_1_1 ~, 1
+#define EQUALS_2_2 ~, 1
+#define EQUALS(X, Y) ID(GET2 BRACE(EQUALS_##X##_##Y, 0))
+
+/*
+#define COMMA(...) ,
+#define HAS_COMMA(...) HAS_COMMA_1(__VA_ARGS__, COMMA(), ~)
+#define HAS_COMMA_1(A, B, ...) HAS_COMMA_2(B, 0, 1, ~)
+#define HAS_COMMA_2(A, B, C, ...) C
+
+#define TRUE(...) 1
+#define FALSE(...) 0
+#define NOT(X) IF(X, 0, 1)
+#define OR(A, B) IF(A, 1, B)
+#define AND(A, B) IF(A, B, 0)
+
+#define IS_CALL(X, ...) HAS_COMMA(ID(COMMA X))
+
+#define AND3(A, B, C) AND(A, AND(B, C))
+
+#define IS_EMPTY(...) AND3( \
+ NOT(HAS_COMMA(__VA_ARGS__)), \
+ NOT(IS_CALL(__VA_ARGS__)), \
+ HAS_COMMA(COMMA __VA_ARGS__ ()))
+*/
+
+#define T_BYTE (1, GLbyte, GL_BYTE)
+#define T_UBYTE (1, GLubyte, GL_UNSIGNED_BYTE)
+#define T_SHORT (1, GLshort, GL_SHORT)
+#define T_USHORT (1, GLushort, GL_UNSIGNED_SHORT)
+#define T_INT (1, GLint, GL_INT)
+#define T_UINT (1, GLuint, GL_UNSIGNED_INT)
+#define T_FIXED (1, GLfixed, GL_FIXED)
+#define T_HALF (1, GLhalf, GL_HALF_FLOAT)
+#define T_FLOAT (1, GLfloat, GL_FLOAT)
+#define T_DOUBLE (1, GLdouble, GL_DOUBLE)
+
+#define T_PRESENT(x) ID(GET1 x)
+#define T_TYPE(x) ID(GET2 x)
+#define T_CONST(x) ID(GET3 x)
+
+#define VERTEX_DEF_FOLD(struct_name, buf_struct, buf_func, index, type, name, count, ...) ( \
+ struct_name, \
+ buf_struct T_TYPE(type) name IF(EQUALS(count, 1),,[count]);, \
+ buf_func \
+ glVertexAttribPointer(index, count, T_CONST(type), \
+ GL_FALSE, sizeof(struct struct_name), (GLvoid *) offsetof(struct struct_name, name)); \
+ glEnableVertexAttribArray(index);, \
+ (1 + index))
+
+#define VERTEX_DEF_FOLD_WRAP(buf, attr) \
+ IF(T_PRESENT(GET1 attr), CALL(VERTEX_DEF_FOLD, EXPAND buf, EXPAND attr, 1), buf)
+
+#define VERTEX_DEF_EMIT(name, buf_struct, buf_func, _) \
+ struct name { buf_struct }; \
+ void name ## _configure_vao() { buf_func };
+
+#define VERTEX_DEF(name, ...) ID(VERTEX_DEF_EMIT FOLD(((0, ~, ~), ~, 0), VERTEX_DEF_FOLD_WRAP, \
+ (name,,, 0), __VA_ARGS__))