Compare commits

...

4 Commits

27 changed files with 1171 additions and 866 deletions

View File

@ -14,6 +14,7 @@
#include "margaret/png_pixel_masses.h"
#include "lucy.h"
#include "alice.h"
#include "precise_integers.h"
int main() {
mkdir_nofail("l1");
@ -31,6 +32,7 @@ int main() {
generate_margaret_png_pixel_masses_header();
generate_l1_lucy_headers();
generate_code_for_alice_on_l1();
generate_l1_header_for_precise_integers();
finish_layer(cstr("l1"));
return 0;
}

View File

@ -12,147 +12,137 @@ NODISCARD VecU8 codegen_name_xvecn(SpanU8 xvec, int n) {
return VecU8_fmt("%s%c", xvec, '0' + n);
}
NODISCARD VecU8 generate_xvecn_struct_and_base_methods(SpanU8 xvec, SpanU8 memb, int n) {
VecU8 g_xvecn = codegen_name_xvecn(xvec, n);
SpanU8 xvecn = VecU8_to_span(&g_xvecn);
VecU8 res = VecU8_new();
void codegen_append_xvecn_struct_and_base_methods(VecU8* res, SpanU8 xvec, SpanU8 memb, int n) {
VecU8 xvecn = codegen_name_xvecn(xvec, n);
/* Structure definition */
VecU8_append_span(&res, cstr("typedef struct {\n"));
VecU8_append_cstr(res, "typedef struct {\n");
for (int ci = 0; ci < n; ci++) {
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s %s;\n", memb, vec_field_name(ci)));
VecU8_append_fmt(res, SPACE "%s %s;\n", memb, vec_field_name(ci));
}
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", xvecn));
VecU8_append_fmt(res, "} %r;\n\n", xvecn);
/* xvecn_add_xvecn method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_add_%s(%s A, %s B) {\n"
SPACE "return(%s){ ",
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
VecU8_append_fmt(res,
"%r %r_add_%r(%r A, %r B) {\n"
SPACE "return(%r){ ",
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn);
for (int ci = 0; ci < n; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("A.%s + B.%s", vec_field_name(ci), vec_field_name(ci)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "A.%s + B.%s", vec_field_name(ci), vec_field_name(ci));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
/* xvecn_minus_xvecn method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_minus_%s(%s A, %s B) {\n"
SPACE "return (%s){ ",
VecU8_append_vec(res, VecU8_fmt(
"%r %r_minus_%r(%r A, %r B) {\n"
SPACE "return (%r){ ",
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
for (int ci = 0; ci < n; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("A.%s - B.%s", vec_field_name(ci), vec_field_name(ci)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "A.%s - B.%s", vec_field_name(ci), vec_field_name(ci));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
/* xvecn_minus method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_minus(%s A) {\n"
SPACE "return (%s){ ",
xvecn, xvecn, xvecn, xvecn));
VecU8_append_fmt(res,
"%r %r_minus(%r A) {\n"
SPACE "return (%r){ ",
xvecn, xvecn, xvecn, xvecn);
for (int ci = 0; ci < n; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("-A.%s", vec_field_name(ci)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "-A.%s", vec_field_name(ci));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_drop(g_xvecn);
return res;
}
NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb, int n, SpanU8 sqrt_func) {
VecU8 g_xvecn = codegen_name_xvecn(xvec, n);
SpanU8 xvecn = VecU8_to_span(&g_xvecn);
VecU8 res = generate_xvecn_struct_and_base_methods(xvec, memb, n);
/* xvecn_length method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_length(%s A) {\n"
SPACE "return %s(",
memb, xvecn, xvecn, sqrt_func));
for (int i = 0; i < n; i++) {
if (i)
VecU8_append_span(&res, cstr(" + "));
VecU8_append_vec(&res, VecU8_fmt("A.%s * A.%s", vec_field_name(i), vec_field_name(i)));
}
VecU8_append_span(&res, cstr(");\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
/* xvecn_mul_scal method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_mul_scal(%s A, %s B) {\n"
SPACE "return (%s) { ",
xvecn, xvecn, xvecn, memb, xvecn));
VecU8_append_fmt(res,
"%r %r_mul_scal(%r A, %s B) {\n"
SPACE "return (%r) { ",
xvecn, xvecn, xvecn, memb, xvecn);
for (int ci = 0; ci < n; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("A.%s * B", vec_field_name(ci)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "A.%s * B", vec_field_name(ci));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
/* xvecn_div_by_scal method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_div_by_scal(%s A, %s B) {\n"
SPACE "return %s_mul_scal(A, 1/B);\n"
"}\n\n", xvecn, xvecn, xvecn, memb, xvecn));
/* xvecn_mul_xvecn method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_mul_%s(%s A, %s B) {\n"
SPACE "return (%s){ ",
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
for (int ci = 0; ci < n; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("A.%s * B.%s", vec_field_name(ci), vec_field_name(ci)));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
/* xvecn_dot method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_dot(%s A, %s B) {\n"
SPACE "return ",
memb, xvecn, xvecn, xvecn));
for (int i = 0; i < n; i++) {
if (i)
VecU8_append_span(&res, cstr(" + "));
VecU8_append_vec(&res, VecU8_fmt("A.%s * B.%s", vec_field_name(i), vec_field_name(i)));
}
VecU8_append_span(&res, cstr(";\n}\n\n"));
/* xvecn_normalize method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_normalize(%s A) {\n"
SPACE "return %s_div_by_scal(A, %s_length(A));\n"
"}\n\n", xvecn, xvecn, xvecn, xvecn, xvecn));
VecU8_append_cstr(res, " };\n}\n\n");
VecU8_drop(g_xvecn);
return res;
VecU8_drop(xvecn);
}
NODISCARD VecU8 generate_xvecn_method_and_one(SpanU8 xvec, int n) {
assert(2 <= n && n < 4);
VecU8 g_xvecn = codegen_name_xvecn(xvec, n);
VecU8 g_xvecn_pp = codegen_name_xvecn(xvec, n + 1);
SpanU8 xvecn = VecU8_to_span(&g_xvecn);
SpanU8 xvecn_pp = VecU8_to_span(&g_xvecn_pp);
void codegen_append_xvecn_struct_and_cool_methods(VecU8* res, SpanU8 xvec, SpanU8 memb, int n, SpanU8 sqrt_func) {
VecU8 xvecn = codegen_name_xvecn(xvec, n);
codegen_append_xvecn_struct_and_base_methods(res, xvec, memb, n);
/* xvecn_length method */
VecU8_append_fmt(res,
"%s %r_length(%r A) {\n"
SPACE "return %s(",
memb, xvecn, xvecn, sqrt_func);
for (int i = 0; i < n; i++) {
if (i)
VecU8_append_cstr(res, " + ");
VecU8_append_fmt(res, "A.%s * A.%s", vec_field_name(i), vec_field_name(i));
}
VecU8_append_cstr(res, ");\n}\n\n");
/* xvecn_div_by_scal method */
VecU8_append_fmt(res,
"%r %r_div_by_scal(%r A, %s B) {\n"
SPACE "return %r_mul_scal(A, 1/B);\n"
"}\n\n", xvecn, xvecn, xvecn, memb, xvecn);
/* xvecn_mul_xvecn method */
VecU8_append_fmt(res,
"%r %r_mul_%r(%r A, %r B) {\n"
SPACE "return (%r){ ",
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn);
for (int ci = 0; ci < n; ci++) {
if (ci)
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "A.%s * B.%s", vec_field_name(ci), vec_field_name(ci));
}
VecU8_append_cstr(res, " };\n}\n\n");
/* xvecn_dot method */
VecU8_append_fmt(res,
"%s %r_dot(%r A, %r B) {\n"
SPACE "return ",
memb, xvecn, xvecn, xvecn);
for (int i = 0; i < n; i++) {
if (i)
VecU8_append_cstr(res, " + ");
VecU8_append_fmt(res, "A.%s * B.%s", vec_field_name(i), vec_field_name(i));
}
VecU8_append_cstr(res, ";\n}\n\n");
/* xvecn_normalize method */
VecU8_append_fmt(res,
"%r %r_normalize(%r A) {\n"
SPACE "return %r_div_by_scal(A, %r_length(A));\n"
"}\n\n", xvecn, xvecn, xvecn, xvecn, xvecn);
VecU8 res = VecU8_fmt(
"%s %s_and_one(%s A) {\n"
SPACE "return (%s){ ",
VecU8_drop(xvecn);
}
void codegen_append_xvecn_method_and_one(VecU8* res, SpanU8 xvec, int n) {
assert(2 <= n && n < 4);
VecU8 xvecn = codegen_name_xvecn(xvec, n);
VecU8 xvecn_pp = codegen_name_xvecn(xvec, n + 1);
VecU8_append_fmt(res,
"%r %r_and_one(%r A) {\n"
SPACE "return (%r){ ",
xvecn_pp, xvecn, xvecn, xvecn_pp);
for (int i = 0; i < n; i++) {
VecU8_append_vec(&res, VecU8_fmt("A.%s, ", vec_field_name(i)));
VecU8_append_fmt(res, "A.%s, ", vec_field_name(i));
}
VecU8_append_span(&res, cstr("1 };\n}\n\n"));
VecU8_append_cstr(res, "1 };\n}\n\n");
VecU8_drop(g_xvecn_pp);
VecU8_drop(g_xvecn);
return res;
VecU8_drop(xvecn_pp);
VecU8_drop(xvecn);
}
NODISCARD VecU8 generate_xvec3_method_cross(SpanU8 xvec) {
VecU8 g_xvec3 = codegen_name_xvecn(xvec, 3);
SpanU8 xvec3 = VecU8_to_span(&g_xvec3);
VecU8 res = VecU8_fmt(
"%s %s_cross(%s A, %s B) {\n"
SPACE "return (%s){A.y * B.z - A.z * B.y, -A.x * B.z + A.z * B.x, A.x * B.y - A.y * B.x};\n"
void codegen_append_xvec3_method_cross(VecU8* res, SpanU8 xvec) {
VecU8 xvec3 = codegen_name_xvecn(xvec, 3);
VecU8_append_fmt(res,
"%r %r_cross(%r A, %r B) {\n"
SPACE "return (%r){A.y * B.z - A.z * B.y, -A.x * B.z + A.z * B.x, A.x * B.y - A.y * B.x};\n"
"}\n\n", xvec3, xvec3, xvec3, xvec3, xvec3);
VecU8_drop(g_xvec3);
return res;
VecU8_drop(xvec3);
}
NODISCARD VecU8 codegen_name_xmatnm(SpanU8 xmat, int cols, int rows) {
@ -162,201 +152,256 @@ NODISCARD VecU8 codegen_name_xmatnm(SpanU8 xmat, int cols, int rows) {
return VecU8_fmt("%s%cx%c", xmat, '0' + cols, '0' + rows);
}
NODISCARD VecU8 generate_xmatnm_struct_and_methods(
void codegen_append_xmatnm_struct_and_methods(VecU8* res,
SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int cols, int rows, int sizeof_member
) {
VecU8 g_xmatnm = codegen_name_xmatnm(xmat, cols, rows);
SpanU8 xmatnm = VecU8_to_span(&g_xmatnm);
VecU8 g_xvecm = codegen_name_xvecn(xvec, rows);
SpanU8 xvecm = VecU8_to_span(&g_xvecm);
VecU8 res = VecU8_new();
VecU8 xmatnm = codegen_name_xmatnm(xmat, cols, rows);
VecU8 xvecm = codegen_name_xvecn(xvec, rows);
/* Structure xmatnm
/* Structure xmatnm. todo: NO, std140 is NOT OUR EVERYTHING. TODO: get rid of padding
* With columns padded to 16 bytes (for std140, std140 is our everything) */
int sv = (rows * sizeof_member) % 16;
VecU8_append_span(&res, cstr("typedef struct {\n"));
VecU8_append_cstr(res, "typedef struct {\n");
for (int x = 0; x < cols; x++) {
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s %s;\n", xvecm, vec_field_name(x)));
VecU8_append_fmt(res, SPACE "%r %s;\n", xvecm, vec_field_name(x));
if (sv) {
VecU8_append_vec(&res, VecU8_fmt(SPACE "char _padding_%u[%u];\n", (U64)x, (U64)(16 - sv)));
VecU8_append_fmt(res, SPACE "char _padding_%u[%u];\n", (U64)x, (U64)(16 - sv));
}
}
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", xmatnm));
VecU8_append_fmt(res, "} %r;\n\n", xmatnm);
/* xmatnm_new method */
VecU8_append_vec(&res, VecU8_fmt("%s %s_new(", xmatnm, xmatnm));
VecU8_append_fmt(res, "%r %r_new(", xmatnm, xmatnm);
for (int y = 0; y < rows; y++) {
for (int x = 0; x < cols; x++) {
if (x > 0 || y > 0)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("%s %s%s", memb, vec_field_name(x), vec_field_name(y)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "%s %s%s", memb, vec_field_name(x), vec_field_name(y));
}
}
VecU8_append_vec(&res, VecU8_fmt(") {\n" SPACE "return (%s){ ", xmatnm));
VecU8_append_fmt(res, ") {\n" SPACE "return (%r){ ", xmatnm);
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt(".%s = { ", vec_field_name(x)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, ".%s = { ", vec_field_name(x));
for (int y = 0; y < rows; y++) {
if (y)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("%s%s", vec_field_name(x), vec_field_name(y)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "%s%s", vec_field_name(x), vec_field_name(y));
}
VecU8_append_span(&res, cstr(" }"));
VecU8_append_cstr(res, " }");
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
/* xmatnm_add_xmatnm method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_add_%s(%s A, %s B) {\n"
SPACE "return (%s){ ",
xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm));
VecU8_append_fmt(res,
"%r %r_add_%r(%r A, %r B) {\n"
SPACE "return (%r){ ",
xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm);
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt(".%s = %s_add_%s(A.%s, B.%s)",
vec_field_name(x), xvecm, xvecm, vec_field_name(x), vec_field_name(x)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, ".%s = %r_add_%r(A.%s, B.%s)",
vec_field_name(x), xvecm, xvecm, vec_field_name(x), vec_field_name(x));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
/* xmatnm_minus_xmatnm method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_minus_%s(%s A, %s B) {\n"
SPACE "return (%s){ ",
xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm));
VecU8_append_fmt(res,
"%r %r_minus_%r(%r A, %r B) {\n"
SPACE "return (%r){ ",
xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm);
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt(".%s = %s_minus_%s(A.%s, B.%s)",
vec_field_name(x), xvecm, xvecm, vec_field_name(x), vec_field_name(x)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, ".%s = %r_minus_%r(A.%s, B.%s)",
vec_field_name(x), xvecm, xvecm, vec_field_name(x), vec_field_name(x));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
/* xmatnm_minus method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_minus(%s A) {\n"
SPACE "return (%s){ ",
xmatnm, xmatnm, xmatnm, xmatnm));
VecU8_append_fmt(res,
"%r %r_minus(%r A) {\n"
SPACE "return (%r){ ",
xmatnm, xmatnm, xmatnm, xmatnm);
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt(".%s = %s_minus(A.%s)",
vec_field_name(x), xvecm, vec_field_name(x)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, ".%s = %r_minus(A.%s)",
vec_field_name(x), xvecm, vec_field_name(x));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
/* xmatnm_mul_scal method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_mul_scal(%s A, %s B) {\n"
SPACE "return (%s){ ",
xmatnm, xmatnm, xmatnm, memb, xmatnm));
VecU8_append_fmt(res,
"%r %r_mul_scal(%r A, %s B) {\n"
SPACE "return (%r){ ",
xmatnm, xmatnm, xmatnm, memb, xmatnm);
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt(".%s = %s_mul_scal(A.%s, B)",
vec_field_name(x), xvecm, vec_field_name(x)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, ".%s = %r_mul_scal(A.%s, B)",
vec_field_name(x), xvecm, vec_field_name(x));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
/* xmatnm_div_by_scal method */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_div_by_scal(%s A, %s B) {\n"
SPACE "return %s_mul_scal(A, 1/B);\n"
"}\n\n", xmatnm, xmatnm, xmatnm, memb, xmatnm));
VecU8_append_fmt(res,
"%r %r_div_by_scal(%r A, %s B) {\n"
SPACE "return %r_mul_scal(A, 1/B);\n"
"}\n\n", xmatnm, xmatnm, xmatnm, memb, xmatnm);
VecU8 g_xvecn = codegen_name_xvecn(xvec, cols);
SpanU8 xvecn = VecU8_to_span(&g_xvecn);
VecU8 xvecn = codegen_name_xvecn(xvec, cols);
/* xmatnm_mul_xvecn */
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_mul_%s(%s A, %s B) {\n"
SPACE "return (%s){ ",
xvecm, xmatnm, xvecn, xmatnm, xvecn, xvecm));
VecU8_append_fmt(res,
"%r %r_mul_%r(%r A, %r B) {\n"
SPACE "return (%r){ ",
xvecm, xmatnm, xvecn, xmatnm, xvecn, xvecm);
for (int y = 0; y < rows; y++) {
if (y)
VecU8_append(&res, ',');
VecU8_append_span(&res, cstr("\n" SPACE8));
VecU8_append(res, ',');
VecU8_append_cstr(res, "\n" SPACE8);
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(" + "));
VecU8_append_vec(&res, VecU8_fmt("A.%s.%s * B.%s", vec_field_name(x), vec_field_name(y), vec_field_name(x)));
VecU8_append_cstr(res, " + ");
VecU8_append_fmt(res, "A.%s.%s * B.%s", vec_field_name(x), vec_field_name(y), vec_field_name(x));
}
}
VecU8_append_span(&res, cstr("\n" SPACE "};\n}\n\n"));
VecU8_append_cstr(res, "\n" SPACE "};\n}\n\n");
VecU8_drop(g_xvecn);
VecU8_drop(g_xvecm);
VecU8_drop(g_xmatnm);
return res;
VecU8_drop(xvecn);
VecU8_drop(xvecm);
VecU8_drop(xmatnm);
}
/* xmatnm_transpose method */
NODISCARD VecU8 generate_xmatnm_transpose_method(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int cols, int rows) {
VecU8 g_xmatnm = codegen_name_xmatnm(xmat, cols, rows);
VecU8 g_xmatmn = codegen_name_xmatnm(xmat, rows, cols);
SpanU8 xmatnm = VecU8_to_span(&g_xmatnm);
SpanU8 xmatmn = VecU8_to_span(&g_xmatmn);
VecU8 res = VecU8_fmt(
"%s %s_transpose(%s A) {\n"
SPACE "return (%s){ ",
void codegen_append_xmatnm_transpose_method(VecU8* res, SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int cols, int rows) {
VecU8 xmatnm = codegen_name_xmatnm(xmat, cols, rows);
VecU8 xmatmn = codegen_name_xmatnm(xmat, rows, cols);
VecU8_append_fmt(res,
"%r %r_transpose(%r A) {\n"
SPACE "return (%r){ ",
xmatmn, xmatnm, xmatnm, xmatmn);
for (int bx = 0; bx < rows; bx++) {
if (bx)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt(".%s = { ", vec_field_name(bx)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, ".%s = { ", vec_field_name(bx));
for (int by = 0; by < cols; by++) {
if (by)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("A.%s.%s", vec_field_name(by), vec_field_name(bx)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "A.%s.%s", vec_field_name(by), vec_field_name(bx));
}
VecU8_append_span(&res, cstr(" }"));
VecU8_append_cstr(res, " }");
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
VecU8_drop(g_xmatmn);
VecU8_drop(g_xmatnm);
return res;
VecU8_drop(xmatmn);
VecU8_drop(xmatnm);
}
NODISCARD VecU8 generate_square_xmatn_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int n) {
VecU8 g_xmatn = codegen_name_xmatnm(xmat, n, n);
SpanU8 xmatn = VecU8_to_span(&g_xmatn);
VecU8 res = VecU8_new();
void codegen_append_xmat234_det_method(VecU8* res, SpanU8 xmat, SpanU8 xvec, SpanU8 memb){
VecU8_append_fmt(res,
"%s %s2_det(%s2 a){\n"
SPACE "return a.x.x * a.y.y - a.x.y * a.y.x;\n"
"}\n\n", memb, xmat, xmat);
VecU8_append_fmt(res,
"%s %s3_det(%s3 a){\n"
SPACE "return", memb, xmat, xmat);
for (int i = 0; i < 3; i++) {
if (i)
VecU8_append_cstr(res, "\n" SPACE SPACE);
for (int j = 0; j < 3; j++) {
if (j == i)
continue;
int k = 3 - i - j;
assert(k != i && k != j);
bool minused = ((i > j) + (j > k) + (i > k)) % 2;
VecU8_append_fmt(res, " %c a.x.%s * a.y.%s * a.z.%s",
minused ? '-' : '+', vec_field_name(i), vec_field_name(j), vec_field_name(k));
}
}
VecU8_append_cstr(res, ";\n}\n\n");
VecU8_append_vec(&res, VecU8_fmt(
"const %s %s_E = { ", xmatn, xmatn));
VecU8_append_fmt(res,
"%s %s4_det(%s4 a){\n"
SPACE "return", memb, xmat, xmat);
for (int i = 0; i < 4; i++) {
if (i)
VecU8_append_cstr(res, "\n" SPACE SPACE);
for (int j = 0; j < 4; j++) {
if (j == i)
continue;
for (int k = 0; k < 4; k++) {
if (i == k || j == k)
continue;
int u = 6 - i - j - k;
assert(u != i && u != j && u != k);
bool minused = ((i > j) + (j > k) + (i > k) + (i > u) + (j > u) + (k > u)) % 2;
VecU8_append_fmt(res, " %c a.x.%s * a.y.%s * a.z.%s * a.w.%s",
minused ? '-' : '+', vec_field_name(i), vec_field_name(j), vec_field_name(k), vec_field_name(u));
}
}
}
VecU8_append_cstr(res, ";\n}\n\n");
}
void codegen_append_square_xmatn_methods(VecU8* res, SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int n) {
VecU8 xmatn = codegen_name_xmatnm(xmat, n, n);
VecU8 xvecn = codegen_name_xvecn(xvec, n);
VecU8_append_fmt(res,
"const %r %r_E = { ", xmatn, xmatn);
for (int x = 0; x < n; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt(".%s = {", vec_field_name(x)));
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, ".%s = {", vec_field_name(x));
for (int y = 0; y < n; y++) {
if (y)
VecU8_append_span(&res, cstr(", "));
VecU8_append(&res, '0' + (x == y));
VecU8_append_cstr(res, ", ");
VecU8_append(res, '0' + (x == y));
}
VecU8_append_span(&res, cstr(" }"));
VecU8_append_cstr(res, " }");
}
VecU8_append_span(&res, cstr(" };\n\n"));
VecU8_append_cstr(res, " };\n\n");
VecU8_drop(g_xmatn);
return res;
VecU8_append_fmt(res,
"%r %r_new_for_proj(%r v){\n" /* xmatn, xmatn, xvecn */
SPACE "return (%r){ ", /* xmatn */
xmatn, xmatn, xvecn, xmatn);
for (int x = 0; x < n; x++) {
VecU8_append_cstr(res, "\n" SPACE SPACE);
VecU8_append_fmt(res, ".%s={", vec_field_name(x));
for (int y = 0; y < n; y++) {
if (y)
VecU8_append_cstr(res, ", ");
VecU8_append_fmt(res, "v.%s * v.%s", vec_field_name(x), vec_field_name(y));
}
VecU8_append_cstr(res, "},");
}
VecU8_append_cstr(res, "};\n}\n\n");
VecU8_drop(xmatn);
VecU8_drop(xvecn);
}
NODISCARD VecU8 generate_xmat_inverse_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb){
VecU8 res = VecU8_fmt("%s4 %s4_inverse(%s4 A) {\n", xmat, xmat, xmat);
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s m2[6][6] = {\n", memb));
void codegen_append_xmat_inverse_methods(VecU8* res, SpanU8 xmat, SpanU8 xvec, SpanU8 memb){
VecU8_append_fmt(res, "%s4 %s4_inverse(%s4 A) {\n", xmat, xmat, xmat);
VecU8_append_fmt(res, SPACE "%s m2[6][6] = {\n", memb);
SpanU8 first_of_pair[6] = {cstr("x"), cstr("x"), cstr("x"), cstr("y"), cstr("y"), cstr("z")};
SpanU8 second_of_pair[6] = {cstr("y"), cstr("z"), cstr("w"), cstr("z"), cstr("w"), cstr("w")};
for (int w_col = 0; w_col < 6; w_col++) {
VecU8_append_span(&res, cstr(SPACE SPACE "{ "));
VecU8_append_cstr(res, SPACE SPACE "{ ");
for (int w_row = 0; w_row < 6; w_row++) {
if (w_row)
VecU8_append_span(&res, cstr(", "));
VecU8_append_cstr(res, ", ");
/* first first = A second first = B
* first second = C second second = D
* A * D - B * C */
VecU8_append_vec(&res, VecU8_fmt("A.%s.%s * A.%s.%s - A.%s.%s * A.%s.%s",
VecU8_append_fmt(res, "A.%s.%s * A.%s.%s - A.%s.%s * A.%s.%s",
first_of_pair[w_col], first_of_pair[w_row], second_of_pair[w_col], second_of_pair[w_row],
second_of_pair[w_col], first_of_pair[w_row], first_of_pair[w_col], second_of_pair[w_row]
));
);
}
VecU8_append_span(&res, cstr(" },\n"));
VecU8_append_cstr(res, " },\n");
}
VecU8_append_span(&res, cstr(SPACE "};\n"));
VecU8_append_cstr(res, SPACE "};\n");
U64 a0_contr[4] = {5, 5, 4, 3};
U64 a1_contr[4] = {4, 2, 2, 1};
@ -364,150 +409,152 @@ NODISCARD VecU8 generate_xmat_inverse_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 m
SpanU8 a0[4] = {cstr("y"), cstr("x"), cstr("x"), cstr("x")};
SpanU8 a1[4] = {cstr("z"), cstr("z"), cstr("y"), cstr("y")};
SpanU8 a2[4] = {cstr("w"), cstr("w"), cstr("w"), cstr("z")};
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s m3[4][4] = {\n", memb));
VecU8_append_fmt(res, SPACE "%s m3[4][4] = {\n", memb);
for (int no_col = 0; no_col < 4; no_col++) {
SpanU8 walking_column = a0[no_col];
U64 minor_col_pair = a0_contr[no_col];
VecU8_append_span(&res, cstr(SPACE SPACE "{ "));
VecU8_append_cstr(res, SPACE SPACE "{ ");
for (int no_row = 0; no_row < 4; no_row++) {
if (no_row)
VecU8_append_span(&res, cstr(", \n" SPACE SPACE));
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_cstr(res, ", \n" SPACE SPACE);
VecU8_append_fmt(res,
"A.%s.%s * m2[%u][%u] - A.%s.%s * m2[%u][%u] + A.%s.%s * m2[%u][%u]",
walking_column, a0[no_row], minor_col_pair, a0_contr[no_row],
walking_column, a1[no_row], minor_col_pair, a1_contr[no_row],
walking_column, a2[no_row], minor_col_pair, a2_contr[no_row]));
walking_column, a2[no_row], minor_col_pair, a2_contr[no_row]);
}
VecU8_append_span(&res, cstr(" },\n"));
VecU8_append_cstr(res, " },\n");
}
VecU8_append_span(&res, cstr(SPACE "};\n"));
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_cstr(res, SPACE "};\n");
VecU8_append_fmt(res,
SPACE "%s d = 1 / (A.x.x * m3[0][0] - A.x.y * m3[0][1] + A.x.z * m3[0][2] - A.x.w * m3[0][3]);\n"
SPACE "return (mat4){ "
, memb));
SPACE "return (mat4){ ",
memb);
for (U64 i = 0; i < 4; i++) {
if (i)
VecU8_append_span(&res, cstr(",\n" SPACE SPACE ));
VecU8_append_vec(&res, VecU8_fmt(".%s={ ", vec_field_name((int)i)));
VecU8_append_cstr(res, ",\n" SPACE SPACE );
VecU8_append_fmt(res, ".%s={ ", vec_field_name((int)i));
for (U64 j = 0; j < 4; j++) {
if (j)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("%sm3[%u][%u] * d",
(i + j) % 2 ? cstr("-") : cstr(""), j, i));
VecU8_append_cstr(res,", ");
VecU8_append_fmt(res, "%sm3[%u][%u] * d",
(i + j) % 2 ? cstr("-") : cstr(""), j, i);
}
VecU8_append_span(&res, cstr(" }"));
VecU8_append_cstr(res, " }");
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"%s2 %s2_inverse(%s2 A) {\n" /* xmat, xmat, xmat */
SPACE "%s d = 1 / (A.x.x * A.y.y - A.y.x * A.x.y);\n" /* memb */
SPACE "return (%s2){ .x = { A.y.y * d, -A.x.y * d}, .y = {-A.y.x * d, A.x.x * d}};\n" /* xmat */
"}\n\n", xmat, xmat, xmat, memb, xmat));
"}\n\n", xmat, xmat, xmat, memb, xmat);
/* No inverse for mat3 yet :( */
// VecU8_append_vec(&res, VecU8_fmt( "%s3 %s3_inverse(%s3 A) {\n", xmat, xmat, xmat));
// VecU8_append_vec(&res, VecU8_fmt(SPACE "%s d = 1 / ("));
// VecU8_append_span(&res, cstr("}\n"));
return res;
}
NODISCARD VecU8 generate_xmatnm_method_mul_xmatkn(SpanU8 xmat, int n, int m, int k) {
VecU8 g_xmatkm = codegen_name_xmatnm(xmat, k, m);
VecU8 g_xmatnm = codegen_name_xmatnm(xmat, n, m);
VecU8 g_xmatkn = codegen_name_xmatnm(xmat, k, n);
SpanU8 xmatkm = VecU8_to_span(&g_xmatkm);
SpanU8 xmatnm = VecU8_to_span(&g_xmatnm);
SpanU8 xmatkn = VecU8_to_span(&g_xmatkn);
void codegen_append_xmatnm_method_mul_xmatkn(VecU8* res, SpanU8 xmat, int n, int m, int k) {
VecU8 xmatkm = codegen_name_xmatnm(xmat, k, m);
VecU8 xmatnm = codegen_name_xmatnm(xmat, n, m);
VecU8 xmatkn = codegen_name_xmatnm(xmat, k, n);
VecU8 res = VecU8_fmt(
"%s %s_mul_%s(%s A, %s B) {\n"
SPACE "return (%s){ ",
VecU8_append_fmt(res,
"%r %r_mul_%r(%r A, %r B) {\n"
SPACE "return (%r){ ",
xmatkm, xmatnm, xmatkn, xmatnm, xmatkn, xmatkm);
for (int x = 0; x < k; x++) {
if (x)
VecU8_append_span(&res, cstr(","));
VecU8_append_span(&res, cstr("\n" SPACE8));
VecU8_append_cstr(res, ",");
VecU8_append_cstr(res, "\n" SPACE8);
VecU8_append_vec(&res, VecU8_fmt(".%s = { ", vec_field_name(x)));
VecU8_append_fmt(res, ".%s = { ", vec_field_name(x));
for (int y = 0; y < m; y++) {
if (y)
VecU8_append_span(&res, cstr(", "));
VecU8_append_cstr(res, ", ");
for (int z = 0; z < n; z++) {
if (z)
VecU8_append_span(&res, cstr(" + "));
VecU8_append_vec(&res, VecU8_fmt("A.%s.%s * B.%s.%s",
vec_field_name(z), vec_field_name(y), vec_field_name(x), vec_field_name(z)));
VecU8_append_cstr(res, " + ");
VecU8_append_fmt(res, "A.%s.%s * B.%s.%s",
vec_field_name(z), vec_field_name(y), vec_field_name(x), vec_field_name(z));
}
}
VecU8_append_span(&res, cstr(" }"));
VecU8_append_cstr(res, " }");
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_append_cstr(res, " };\n}\n\n");
VecU8_drop(g_xmatkm);
VecU8_drop(g_xmatnm);
VecU8_drop(g_xmatkn);
return res;
VecU8_drop(xmatkm);
VecU8_drop(xmatnm);
VecU8_drop(xmatkn);
}
NODISCARD VecU8 generate_xvec234_structs_and_base_methods(SpanU8 xvec, SpanU8 memb) {
VecU8 res = VecU8_new();
void codegen_append_xvec234_structs_and_base_methods(VecU8* res, SpanU8 xvec, SpanU8 memb) {
for (int n = 2; n <= 4; n++)
VecU8_append_vec(&res, generate_xvecn_struct_and_base_methods(xvec, memb, n));
return res;
codegen_append_xvecn_struct_and_base_methods(res, xvec, memb, n);
}
NODISCARD VecU8 generate_xvec234_structs_and_cool_methods(SpanU8 xvec, SpanU8 memb, SpanU8 sqrt_func) {
VecU8 res = VecU8_new();
void codegen_append_xvec234_structs_and_cool_methods(VecU8* res, SpanU8 xvec, SpanU8 memb, SpanU8 sqrt_func) {
for (int n = 2; n <= 4; n++)
VecU8_append_vec(&res, generate_xvecn_struct_and_cool_methods(xvec, memb, n, sqrt_func));
codegen_append_xvecn_struct_and_cool_methods(res, xvec, memb, n, sqrt_func);
for (int n = 2; n <= 3; n++)
VecU8_append_vec(&res, generate_xvecn_method_and_one(xvec, n));
VecU8_append_vec(&res, generate_xvec3_method_cross(xvec));
return res;
codegen_append_xvecn_method_and_one(res, xvec, n);
codegen_append_xvec3_method_cross(res, xvec);
}
NODISCARD VecU8 generate_xmat234x234_structs_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member) {
VecU8 res = VecU8_new();
void codegen_append_xmat234x234_structs_and_base_methods(VecU8* res,
SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member
){
for (int cols = 2; cols <= 4; cols++) {
for (int rows = 2; rows <= 4; rows++) {
VecU8_append_vec(&res, generate_xmatnm_struct_and_methods(xmat, xvec, memb, cols, rows, sizeof_member));
codegen_append_xmatnm_struct_and_methods(res, xmat, xvec, memb, cols, rows, sizeof_member);
}
}
for (int cols = 2; cols <= 4; cols++) {
for (int rows = 2; rows <= 4; rows++) {
VecU8_append_vec(&res, generate_xmatnm_transpose_method(xmat, xvec, memb, cols, rows));
codegen_append_xmatnm_transpose_method(res, xmat, xvec, memb, cols, rows);
}
}
for (int n = 2; n <= 4; n++) {
VecU8_append_vec(&res, generate_square_xmatn_methods(xmat, xvec, memb, n));
codegen_append_square_xmatn_methods(res, xmat, xvec, memb, n);
}
for (int n = 2; n <= 4; n++) {
for (int m = 2; m <= 4; m++) {
for (int k = 2; k <= 4; k++) {
VecU8_append_vec(&res, generate_xmatnm_method_mul_xmatkn(xmat, n, m, k));
codegen_append_xmatnm_method_mul_xmatkn(res, xmat, n, m, k);
}
}
}
VecU8_append_vec(&res, generate_xmat_inverse_methods(xmat, xvec, memb));
return res;
codegen_append_xmat234_det_method(res, xmat, xvec, memb);
}
void codegen_append_xmat234x234_structs_and_cool_methods(VecU8* res,
SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member
){
codegen_append_xmat234x234_structs_and_base_methods(res, xmat, xvec, memb, sizeof_member);
codegen_append_xmat_inverse_methods(res, xmat, xvec, memb);
}
void generate_geom_header() {
GeneratedHeader res = begin_header(cstr("l1/geom.h"));
VecU8_append_span(&res.result, cstr("#include \"../../src/l1/core/int_primitives.h\"\n"));
VecU8_append_span(&res.result, cstr("#include <math.h>\n\n"));
VecU8_append_vec(&res.result, generate_xvec234_structs_and_base_methods(cstr("cvec"), cstr("U8")));
VecU8_append_vec(&res.result, generate_xvec234_structs_and_base_methods(cstr("uvec"), cstr("U32")));
VecU8_append_vec(&res.result, generate_xvec234_structs_and_base_methods(cstr("s64vec"), cstr("S64")));
VecU8_append_vec(&res.result, generate_xvec234_structs_and_base_methods(cstr("ivec"), cstr("S32")));
codegen_append_xvec234_structs_and_base_methods(&res.result, cstr("cvec"), cstr("U8"));
codegen_append_xvec234_structs_and_base_methods(&res.result, cstr("uvec"), cstr("U32"));
codegen_append_xvec234_structs_and_base_methods(&res.result, cstr("s64vec"), cstr("S64"));
codegen_append_xvec234_structs_and_base_methods(&res.result, cstr("ivec"), cstr("S32"));
for (U64 i = 2; i <= 4; i++) {
VecU8_append_vec(&res.result, VecU8_fmt("typedef ivec%u s32vec%u;\n", i, i));
}
VecU8_append_span(&res.result, cstr("\n"));
VecU8_append_vec(&res.result, generate_xvec234_structs_and_cool_methods(cstr("vec"), cstr("float"), cstr("sqrtf")));
VecU8_append_vec(&res.result, generate_xvec234_structs_and_cool_methods(cstr("dvec"), cstr("double"), cstr("sqrt")));
VecU8_append_vec(&res.result, generate_xmat234x234_structs_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float)));
/* VecU8_append_vec(&res.result, generate_xmat234x234_structs_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double))); */
codegen_append_xvec234_structs_and_cool_methods(&res.result, cstr("vec"), cstr("float"), cstr("sqrtf"));
codegen_append_xvec234_structs_and_cool_methods(&res.result, cstr("dvec"), cstr("double"), cstr("sqrt"));
// todo: remove padding from matrix structure. VERY IMPORTANT!!! Add padding on the fly when transferring to vulkan
codegen_append_xmat234x234_structs_and_cool_methods(&res.result, cstr("mat"), cstr("vec"), cstr("float"), sizeof(float));
codegen_append_xmat234x234_structs_and_base_methods(&res.result, cstr("s64mat"), cstr("s64vec"), cstr("S64"), sizeof(S64));
finish_header(res);
}

View File

@ -1,5 +1,5 @@
#pragma once
// todo: refactor (with VecU8_append_fmt)
#include "../../codegen/util_template_inst.h"
typedef struct {

View File

@ -4,57 +4,57 @@
#include "../codegen/util_template_inst.h"
/* Used to generate both _at() and _cat() methods */
NODISCARD VecU8 generate_texture_data_method_at(SpanU8 tex, SpanU8 pixvec, SpanU8 memb, bool const_access) {
return VecU8_fmt(
void codegen_append_texture_data_method_at(VecU8* res, SpanU8 tex, SpanU8 memb, bool const_access) {
VecU8_append_fmt(res,
"%s%s* %s_%sat(%s%s* self, size_t x, size_t y) {\n"
SPACE "assert(x < self->width);\n"
SPACE "return %s_%sat(&self->pixels, x + y * self->width);\n"
SPACE "return Vec%s_%sat(&self->pixels, x + y * self->width);\n"
"}\n\n",
const_access ? cstr("const ") : cstr(""), memb, tex, const_access ? cstr("") : cstr("m"),
const_access ? cstr("const ") : cstr(""), tex, pixvec, const_access ? cstr("") : cstr("m"));
const_access ? cstr("const ") : cstr(""), tex, memb, const_access ? cstr("") : cstr("m"));
}
/* `tex` is the type name of texture data type
* `memb` is the type name of pixel data type */
NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8 memb, SpanU8 luminosity_formula) {
VecU8 g_pixvec = VecU8_fmt("Vec%s", memb);
SpanU8 pixvec = VecU8_to_span(&g_pixvec);
VecU8 res = VecU8_fmt(
void codegen_append_texture_data_struct_and_necc_methods(VecU8* res,
SpanU8 tex, SpanU8 memb, SpanU8 luminosity_formula
) {
VecU8_append_fmt(res,
"typedef struct {\n"
SPACE "%s pixels;\n"
SPACE "Vec%s pixels;\n"
SPACE "size_t width;\n"
SPACE "size_t height;\n"
"} %s;\n\n", pixvec, tex);
"} %s;\n\n", memb, tex);
/* Method _new() */
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"%s %s_new(U32 width, U32 height) {\n"
SPACE "assert(width == 0 || height == 0 ||\n"
SPACE SPACE "!(SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10));\n"
SPACE "return (%s){.pixels = %s_new_zeroinit((size_t)width * height), .width = width, .height = height};\n"
"}\n\n", tex, tex, tex, pixvec));
SPACE "return (%s){.pixels = Vec%s_new_zeroinit((size_t)width * height), .width = width, .height = height};\n"
"}\n\n", tex, tex, tex, memb);
/* Method _drop() */
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"void %s_drop(%s self) {\n"
SPACE "%s_drop(self.pixels);\n"
"}\n\n", tex, tex, pixvec));
SPACE "Vec%s_drop(self.pixels);\n"
"}\n\n", tex, tex, memb);
/* Methods _at and _cat */
VecU8_append_vec(&res, generate_texture_data_method_at(tex, pixvec, memb, false));
VecU8_append_vec(&res, generate_texture_data_method_at(tex, pixvec, memb, true));
codegen_append_texture_data_method_at(res, tex, memb, false);
codegen_append_texture_data_method_at(res, tex, memb, true);
/* Method _get_size_in_bytes */
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"size_t %s_get_size_in_bytes(const %s* self) {\n"
SPACE "return self->pixels.len * sizeof(%s);\n"
"}\n\n", tex, tex, memb));
"}\n\n", tex, tex, memb);
/* Result<tex, VecU8> structure */
VecU8_append_vec(&res, generate_result_template_inst(tex, cstr("VecU8"), false, false));
VecU8_append_vec(res, generate_result_template_inst(tex, cstr("VecU8"), false, false));
/* Method _from_bitmap_text()
/* Method _is_inside() */
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"bool %s_is_inside(const %s* self, S32 x, S32 y) {\n"
SPACE "return x >= 0 && y >= 0 && x < (S32)self->width && self->width * y + x < self->pixels.len;\n"
"}\n\n", tex, tex));
"}\n\n", tex, tex);
/* Method _print() */
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"void %s_print(const %s* self) {\n" /* tex, tex */
SPACE "U64 width = self->width;\n"
SPACE "U64 height = self->height;\n"
@ -80,10 +80,7 @@ NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8
SPACE SPACE "}\n"
SPACE SPACE "putc('\\n', stdout);\n"
SPACE "}\n"
"}\n\n", tex, tex, memb, tex, luminosity_formula));
VecU8_drop(g_pixvec);
return res;
"}\n\n", tex, tex, memb, tex, luminosity_formula);
}
void generate_pixel_masses_header() {
@ -92,11 +89,13 @@ void generate_pixel_masses_header() {
VecU8_append_span(&res.result, cstr("#include \"../../src/l1/system/fileio.h\"\n"));
VecU8_append_span(&res.result, cstr("#include \"VecAndSpan_cvec3.h\"\n"));
VecU8_append_span(&res.result, cstr("#include \"VecAndSpan_cvec4.h\"\n\n"));
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8"), cstr("U8"),
cstr("(float)pix / 255")));
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8"), cstr("cvec3"),
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f")));
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8A8"), cstr("cvec4"),
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f")));
codegen_append_texture_data_struct_and_necc_methods(&res.result,
cstr("TextureDataR8"), cstr("U8"), cstr("(float)pix / 255"));
codegen_append_texture_data_struct_and_necc_methods(&res.result,
cstr("TextureDataR8G8B8"), cstr("cvec3"),
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f"));
codegen_append_texture_data_struct_and_necc_methods(&res.result,
cstr("TextureDataR8G8B8A8"), cstr("cvec4"),
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f"));
finish_header(res);
}

View File

@ -0,0 +1,20 @@
#pragma once
// todo: write something here after I close КТ-1
#include "../codegen/codegen.h"
void generate_precise_addition_func(VecU8* res, U64 liA, U64 liB){
assert(liA < 1000 && liB < 1000);
assert(liA >= liB);
VecU8_append_vec(res, VecU8_fmt(
"void S%u_add_S%u(S%u* a, S%u b){\n", liA * 64, liB * 64, liA * 64, liB * 64));
// for (size_t i = 10; )
VecU8_append_span(res, cstr("}\n\n"));
}
void generate_l1_header_for_precise_integers(){
GeneratedHeader h = begin_header(cstr("l1/precise_integers.h"));
VecU8_append_span(&h.result, cstr("#include \"../../src/l1/core/int_primitives.h\"\n"));
finish_header(h);
}

View File

@ -18,6 +18,11 @@ void generate_headers_for_r0_r1_r2_r3() {
.T = cstr("PlayingSound"), .vec_extended = true
}, false);
}
mkdir_nofail("l1/eve/r4");
{ /* r4 */
SpanU8 ns = cstr("r4");
generate_eve_span_company_for_primitive(l, ns, cstr("LightSourceState"), true, false);
}
mkdir_nofail("l1/eve/ds_test");
{ /* This structure is needed for testing purposes only */
generate_eve_span_company_for_primitive(l, cstr("ds_test"), cstr("RefRBTreeNode_S64"), true, false);

View File

@ -15,21 +15,21 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
VecU8 res = VecU8_new();
if (gen_node_declaration) {
VecU8_append_vec(&res, VecU8_fmt("typedef struct ListNode%s ListNode%s;\n", op.T, op.T));
VecU8_append_fmt(&res, "typedef struct ListNode%s ListNode%s;\n", op.T, op.T);
}
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(&res,
"struct ListNode%s {\n" /* op.T */
SPACE "ListNode%s* prev;\n" /* op.T */
SPACE "ListNode%s* next;\n" /* op.T */
SPACE "%s el;\n" /* op.T */
"};\n\n", op.T, op.T, op.T, op.T));
"};\n\n", op.T, op.T, op.T, op.T);
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(&res,
"typedef struct {\n"
SPACE "ListNode%s* first;\n" /* op.T */
"} List%s;\n\n", /* op.T */
op.T, op.T));
VecU8_append_vec(&res, VecU8_fmt(
op.T, op.T);
VecU8_append_fmt(&res,
"#define List%s_new() {0}\n\n" /* op.T */
"void List%s_drop(List%s self) {\n" /* op.T, op.T */
SPACE "ListNode%s* cur = self.first;\n" /* op.T */
@ -41,8 +41,8 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
SPACE "}\n"
"}\n\n",
op.T, op.T, op.T, op.T, op.T,
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE "%s_drop(cur->el);\n", op.T)));
VecU8_append_vec(&res, VecU8_fmt(
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE "%s_drop(cur->el);\n", op.T));
VecU8_append_fmt(&res,
"ListNode%s* List%s_insert(List%s* self, %s el) {\n" /* op.T, op.T, op.T, op.T */
SPACE "ListNode%s* new_node = safe_malloc(sizeof(ListNode%s));\n" /* op.T, op.T */
SPACE "new_node->prev = NULL;\n"
@ -52,16 +52,16 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
SPACE SPACE "self->first->prev = new_node;\n"
SPACE "self->first = new_node;\n"
SPACE "return new_node;\n"
"}\n\n", op.T, op.T, op.T, op.T, op.T, op.T));
VecU8_append_vec(&res, VecU8_fmt(
"}\n\n", op.T, op.T, op.T, op.T, op.T, op.T);
VecU8_append_fmt(&res,
"void List%s_insert_node(List%s* self, ListNode%s* new_node) {\n" /* op.T, op.T, op.T */
SPACE "new_node->prev = NULL;\n"
SPACE "new_node->next = self->first;\n"
SPACE "if (self->first)\n"
SPACE SPACE "self->first->prev = new_node;\n"
SPACE "self->first = new_node;\n"
"}\n\n", op.T, op.T, op.T));
VecU8_append_vec(&res, VecU8_fmt(
"}\n\n", op.T, op.T, op.T);
VecU8_append_fmt(&res,
"void List%s_erase_by_it(List%s* self, ListNode%s* it) {\n" /* op.T, op.T, op.T */
SPACE "if (it->prev)\n"
SPACE SPACE "it->prev->next = it->next;\n"
@ -73,8 +73,8 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
SPACE "free(it);\n"
"}\n\n",
op.T, op.T, op.T,
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(it->el);\n", op.T)));
VecU8_append_vec(&res, VecU8_fmt(
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(it->el);\n", op.T));
VecU8_append_fmt(&res,
"void List%s_sink(List%s* self) {\n" /* op.T, op.T */
SPACE "ListNode%s* cur = self->first;\n" /* op.T */
SPACE "while (cur){\n"
@ -86,7 +86,7 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
SPACE "self->first = NULL;\n"
"}\n\n",
op.T, op.T, op.T, op.T,
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE "%s_drop(cur->el);\n", op.T)));
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE "%s_drop(cur->el);\n", op.T));
return res;
}

View File

@ -6,42 +6,39 @@
// todo: add _less_ method
// todo: rewrite this crap
NODISCARD VecU8 generate_VecT_struct(SpanU8 T, bool skip_declaration_gen){
VecU8 res = VecU8_new();
void codegen_append_VecT_struct(VecU8* res, SpanU8 T, bool skip_declaration_gen){
if (!skip_declaration_gen) {
VecU8_append_vec(&res, VecU8_fmt("typedef struct Vec%s Vec%s;\n\n", T, T));
VecU8_append_fmt(res, "typedef struct Vec%s Vec%s;\n\n", T, T);
}
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"struct Vec%s {\n"
SPACE "%s* buf;\n"
SPACE "size_t len;\n"
SPACE "size_t capacity;\n"
"};\n\n", T, T));
return res;
"};\n\n", T, T);
}
// todo: add resize method
/* if !primitive, requires methods T_drop, and, if also clonable, requires method T_clone */
NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonable) {
VecU8 res = VecU8_new();
void codegen_append_VecT_base_methods(VecU8* res, SpanU8 T, bool primitive, bool clonable) {
VecU8_append_fmt(res, "#define Vec%s_new() ((Vec%s){ 0 })\n\n", T, T);
VecU8_append_vec(&res, VecU8_fmt("#define Vec%s_new() ((Vec%s){ 0 })\n\n", T, T));
VecU8_append_vec(&res, VecU8_fmt("void Vec%s_drop(Vec%s self) {\n", T, T));
VecU8_append_fmt(res, "void Vec%s_drop(Vec%s self) {\n", T, T);
if (!primitive) {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
SPACE "for (size_t i = 0; i < self.len; i++) \n"
SPACE SPACE "%s_drop(self.buf[i]);\n", T));
SPACE SPACE "%s_drop(self.buf[i]);\n", T);
}
VecU8_append_vec(&res, VecU8_fmt(
SPACE "free(self.buf);\n"
"}\n\n"));
VecU8_append_cstr(res,
SPACE "free(self.buf);\n"
"}\n\n");
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"NODISCARD Vec%s Vec%s_new_reserved(size_t n) {\n"
SPACE "return (Vec%s){ .buf = (%s*)safe_calloc(n, sizeof(%s)), .len = 0, .capacity = n };\n"
"}\n\n", T, T, T, T, T));
"}\n\n", T, T, T, T, T);
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"void Vec%s_append(Vec%s* self, %s el) {\n" /* T, T, T */
SPACE "size_t new_length = self->len + 1;\n"
SPACE "if (new_length > self->capacity) {\n"
@ -51,21 +48,21 @@ NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonab
SPACE "}\n"
SPACE "self->buf[self->len] = el;\n"
SPACE "self->len = new_length;\n"
"}\n\n", T, T, T, T, T));
"}\n\n", T, T, T, T, T);
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"%s* Vec%s_mat(Vec%s* self, size_t i) {\n"
SPACE "assert(i < self->len);\n"
SPACE "return &self->buf[i];\n"
"}\n\n", T, T, T));
"}\n\n", T, T, T);
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"const %s* Vec%s_at(const Vec%s* self, size_t i) {\n"
SPACE "assert(i < self->len);\n"
SPACE "return &self->buf[i];\n"
"}\n\n", T, T, T));
"}\n\n", T, T, T);
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"void Vec%s_sink(Vec%s* self, size_t new_len) {\n" /* T, T */
SPACE "assert(new_len <= self->len);\n"
"%v" /* dropping */
@ -74,25 +71,25 @@ NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonab
primitive ? vcstr("") : VecU8_fmt(
SPACE "for (size_t i = new_len; i < self->len; i++)\n"
SPACE SPACE "%s_drop(self->buf[i]);\n", /* T */
T)));
T));
if (clonable) {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"NODISCARD Vec%s Vec%s_clone(const Vec%s* self) {\n" /* T, T, T */
SPACE "Vec%s res = (Vec%s){.buf = (%s*)safe_calloc(self->len, sizeof(%s)),\n" /* T, T, T, T */
SPACE SPACE ".len = self->len, .capacity = self->len};\n",
T, T, T, T, T, T, T));
T, T, T, T, T, T, T);
if (primitive) {
VecU8_append_vec(&res, VecU8_fmt(SPACE "memcpy(res.buf, self->buf, self->len * sizeof(%s));\n", T));
VecU8_append_fmt(res, SPACE "memcpy(res.buf, self->buf, self->len * sizeof(%s));\n", T);
} else {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
SPACE "for (size_t i = 0; i < self->len; i++)\n"
SPACE SPACE "res.buf[i] = %s_clone(&self->buf[i]);\n", T));
SPACE SPACE "res.buf[i] = %s_clone(&self->buf[i]);\n", T);
}
VecU8_append_span(&res, cstr(SPACE "return res;\n}\n\n"));
VecU8_append_cstr(res, SPACE "return res;\n}\n\n");
}
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"void Vec%s_append_vec(Vec%s* self, Vec%s b) {\n" /* T, T, T */
SPACE "size_t new_length = self->len + b.len;\n"
SPACE "if (new_length > self->capacity) {\n"
@ -105,128 +102,114 @@ NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonab
SPACE "}\n"
SPACE "self->len = new_length;\n"
SPACE "free(b.buf);\n"
"}\n\n", T, T, T, T, T));
"}\n\n", T, T, T, T, T);
if (primitive) {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"NODISCARD Vec%s Vec%s_new_zeroinit(size_t len) {\n" /* T, T */
SPACE "return (Vec%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* T, T, T */
"}\n\n",
T, T, T, T, T));
T, T, T, T, T);
}
return res;
}
/* if !primitive, requires methods T_clone, T_drop */
NODISCARD VecU8 generate_VecT_trivmove_extended_methods(SpanU8 T, bool primitive, bool clonable) {
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
SpanU8 VecT = VecU8_to_span(&g_VecT);
VecU8 res = VecU8_new();
void codegen_append_VecT_trivmove_extended_methods(VecU8* res, SpanU8 T, bool primitive, bool clonable) {
VecU8 VecT = VecU8_fmt("Vec%s", T);
VecU8_append_vec(&res, VecU8_fmt(
"%s%s %s_pop(%s* self) {\n"
VecU8_append_fmt(res,
"%s%s %r_pop(%r* self) {\n"
SPACE "assert(self->len > 0);\n"
SPACE "self->len--;\n"
SPACE "return self->buf[self->len];\n"
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT));
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT);
if (!primitive) {
VecU8_append_vec(&res, VecU8_fmt(
"void %s_pop_and_drop(%s* self) {\n"
VecU8_append_fmt(res,
"void %r_pop_and_drop(%r* self) {\n"
SPACE "assert(self->len > 0);\n"
SPACE "%s_drop(self->buf[self->len - 1]);\n"
SPACE "self->len--;\n"
"}\n\n", VecT, VecT, T));
"}\n\n", VecT, VecT, T);
}
VecU8_append_vec(&res, VecU8_fmt(
"%s%s %s_unordered_pop(%s* self, size_t ind) {\n"
VecU8_append_fmt(res,
"%s%s %r_unordered_pop(%r* self, size_t ind) {\n"
SPACE "assert(ind < self->len);\n"
SPACE "%s res = self->buf[ind];\n"
SPACE "self->buf[ind] = self->buf[self->len - 1];\n"
SPACE "self->len--;\n"
SPACE "return res;\n"
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT, T));
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT, T);
if (!primitive) {
VecU8_append_vec(&res, VecU8_fmt(
"void %s_unordered_pop_and_drop(%s* self, size_t ind) {\n"
VecU8_append_fmt(res,
"void %r_unordered_pop_and_drop(%r* self, size_t ind) {\n"
SPACE "assert(ind < self->len);\n"
SPACE "%s_drop(self->buf[ind]);\n"
SPACE "self->buf[ind] = self->buf[self->len - 1];\n"
SPACE "self->len--;\n"
"}\n\n", VecT, VecT, T));
"}\n\n", VecT, VecT, T);
}
VecU8_append_vec(&res, VecU8_fmt(
"NODISCARD %s %s_swap_with_empty(%s* cell) {\n"
SPACE "%s val = *cell;\n"
SPACE "*cell = (%s){NULL, 0, 0};\n"
SPACE "return val;\n"
"}\n\n", VecT, VecT, VecT, VecT, VecT));
if (primitive) {
VecU8_append_vec(&res, VecU8_fmt(
"NODISCARD %s %s_new_filled(size_t len, %s el) {\n" /* VecT, VecT, T */
SPACE "%s res = (%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
VecU8_append_fmt(res,
"NODISCARD %r %r_new_filled(size_t len, %s el) {\n" /* VecT, VecT, T */
SPACE "%r res = (%r){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
SPACE "for (size_t i = 0; i < len; i++)\n"
SPACE SPACE "res.buf[i] = el;\n"
SPACE "return res;\n"
"}\n\n", VecT, VecT, T, VecT, VecT, T, T));
"}\n\n", VecT, VecT, T, VecT, VecT, T, T);
} else if (clonable) {
VecU8_append_vec(&res, VecU8_fmt(
"NODISCARD %s %s_new_filled(size_t len, const %s* el) {\n" /* VecT, VecT, T */
SPACE "%s res = (%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
VecU8_append_fmt(res,
"NODISCARD %r %r_new_filled(size_t len, const %s* el) {\n" /* VecT, VecT, T */
SPACE "%r res = (%r){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
SPACE "for (size_t i = 0; i < len; i++)\n"
SPACE SPACE "res.buf[i] = %s_clone(el);\n" /* T */
SPACE "return res;\n"
"}\n\n", VecT, VecT, T, VecT, VecT, T, T, T));
"}\n\n", VecT, VecT, T, VecT, VecT, T, T, T);
}
VecU8_drop(g_VecT); // VecT invalidated
return res;
VecU8_drop(VecT);
}
// todo: add _less_ method
/* if !integer requires method T_equal_T */
NODISCARD VecU8 generate_VecT_equal_method(SpanU8 T, bool integer) {
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
SpanU8 VecT = VecU8_to_span(&g_VecT);
VecU8 res = VecU8_fmt(
"bool %s_equal_%s(const %s* A, const %s* B) {\n"
SPACE "if (A->len != B->len)\n"
SPACE SPACE "return false;\n"
SPACE "for (size_t i = 0; i < A->len; i++) {\n", VecT, VecT, VecT, VecT);
void codegen_append_VecT_equal_method(VecU8* res, SpanU8 T, bool integer) {
VecU8 VecT = VecU8_fmt("Vec%s", T);
VecU8_append_fmt(res,
"bool %r_equal_%r(const %r* A, const %r* B) {\n"
SPACE "if (A->len != B->len)\n"
SPACE SPACE "return false;\n"
SPACE "for (size_t i = 0; i < A->len; i++) {\n", VecT, VecT, VecT, VecT);
if (integer) {
VecU8_append_span(&res, cstr(SPACE8 "if (A->buf[i] != B->buf[i])\n"));
VecU8_append_cstr(res, SPACE8 "if (A->buf[i] != B->buf[i])\n");
} else {
VecU8_append_vec(&res, VecU8_fmt(SPACE8 "if (!%s_equal_%s(A->buf + i, B->buf + i))\n", T, T));
VecU8_append_fmt(res, SPACE8 "if (!%s_equal_%s(A->buf + i, B->buf + i))\n", T, T);
}
VecU8_append_span(&res, cstr(
VecU8_append_cstr(res,
SPACE SPACE SPACE "return false;\n"
SPACE "}\n"
SPACE "return true;\n"
"}\n\n"
));
);
VecU8_drop(g_VecT);
return res;
VecU8_drop(VecT);
}
/* requires method T_new */
NODISCARD VecU8 generate_VecT_new_of_size_method(SpanU8 T) {
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
SpanU8 VecT = VecU8_to_span(&g_VecT);
VecU8 res = VecU8_fmt(
"NODISCARD %s %s_new_of_size(size_t len) {\n" /* VecT, VecT */
SPACE "%s res = (%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
SPACE "for (size_t i = 0; i < len; i++)\n"
SPACE SPACE "res.buf[i] = %s_new();\n" /* T */
SPACE "return res;\n"
"}\n", VecT, VecT, VecT, VecT, T, T, T);
VecU8_drop(g_VecT);
return res;
void codegen_append_VecT_new_of_size_method(VecU8* res, SpanU8 T) {
VecU8 VecT = VecU8_fmt("Vec%s", T);
VecU8_append_fmt(res,
"NODISCARD %r %r_new_of_size(size_t len) {\n" /* VecT, VecT */
SPACE "%r res = (%r){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
SPACE "for (size_t i = 0; i < len; i++)\n"
SPACE SPACE "res.buf[i] = %s_new();\n" /* T */
SPACE "return res;\n"
"}\n", VecT, VecT, VecT, VecT, T, T, T);
VecU8_drop(VecT);
}
/* helper function. SpanT is either SpanT or MutSpanT */
@ -268,158 +251,143 @@ void codegen_append_some_span_span_method(VecU8* res, SpanU8 SpanT) {
"}\n\n", SpanT, SpanT, SpanT, SpanT));
}
NODISCARD VecU8 generate_SpanT_structures(SpanU8 T, bool add_mutable, bool skip_declaration_gen){
VecU8 res = VecU8_new();
codegen_append_some_span_struct(&res, T, cstr(""), cstr("const "), skip_declaration_gen);
void codegen_append_SpanT_structures(VecU8* res, SpanU8 T, bool add_mutable, bool skip_declaration_gen){
codegen_append_some_span_struct(res, T, cstr(""), cstr("const "), skip_declaration_gen);
if (add_mutable)
codegen_append_some_span_struct(&res, T, cstr("Mut"), cstr(""), skip_declaration_gen);
return res;
codegen_append_some_span_struct(res, T, cstr("Mut"), cstr(""), skip_declaration_gen);
}
/* T must be sized. Option `add_sort` requires option `add_mutable` and method T_less
* add_mutable option generates MutSpanT.
* add_equal option generates equal method. add_extended option generated extended methods
*/
NODISCARD VecU8 generate_SpanT_base_methods(
void codegen_append_SpanT_base_methods(VecU8* res,
SpanU8 T, bool integer, bool add_mutable, bool add_equal, bool add_extended
) {
VecU8 g_SpanT = VecU8_fmt("Span%s", T);
VecU8 g_MutSpanT = VecU8_fmt("MutSpan%s", T);
SpanU8 SpanT = VecU8_to_span(&g_SpanT);
SpanU8 MutSpanT = VecU8_to_span(&g_MutSpanT);
VecU8 res = VecU8_new();
VecU8 SpanT = VecU8_fmt("Span%s", T);
VecU8 MutSpanT = VecU8_fmt("MutSpan%s", T);
if (add_equal) {
codegen_append_some_span_equal_method(&res, SpanT);
codegen_append_some_span_equal_method(res, VecU8_to_span(&SpanT));
if (add_mutable)
codegen_append_some_span_equal_method(&res, MutSpanT);
codegen_append_some_span_equal_method(res, VecU8_to_span(&MutSpanT));
}
if (add_mutable) {
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_to_%s(%s self) {\n"
SPACE "return (%s){.data = self.data, .len = self.len};\n"
"}\n\n", SpanT, MutSpanT, SpanT, MutSpanT, SpanT));
VecU8_append_fmt(res,
"%r %r_to_%r(%r self) {\n"
SPACE "return (%r){.data = self.data, .len = self.len};\n"
"}\n\n", SpanT, MutSpanT, SpanT, MutSpanT, SpanT);
}
codegen_append_some_span_at_method(&res, T, SpanT, cstr("const "));
codegen_append_some_span_at_method(res, T, VecU8_to_span(&SpanT), cstr("const "));
if (add_mutable)
codegen_append_some_span_at_method(&res, T, MutSpanT, cstr(""));
codegen_append_some_span_at_method(res, T, VecU8_to_span(&MutSpanT), cstr(""));
if (add_extended) {
codegen_append_some_span_span_method(&res, SpanT);
codegen_append_some_span_span_method(res, VecU8_to_span(&SpanT));
if (add_mutable)
codegen_append_some_span_span_method(&res, MutSpanT);
codegen_append_some_span_span_method(res, VecU8_to_span(&MutSpanT));
}
VecU8_drop(g_MutSpanT);
VecU8_drop(g_SpanT);
return res;
VecU8_drop(MutSpanT);
VecU8_drop(SpanT);
}
NODISCARD VecU8 generate_span_company_sort_methods(SpanU8 T, bool t_integer, bool mut_span, bool vec){
VecU8 res = VecU8_new();
VecU8_append_vec(&res, VecU8_fmt(
void codegen_append_span_company_sort_methods(VecU8* res, SpanU8 T, bool t_integer, bool mut_span, bool vec){
VecU8_append_fmt(res,
"int %s_qcompare(const void* a, const void* b) {\n" /* T */
SPACE "const %s* A = a;\n" /* T */
SPACE "const %s* B = b;\n" /* T */
SPACE "return %v;\n" /* we return stuff */
"}\n\n",
T, T, T, t_integer ? vcstr("(int)(*B < *A) - (int)(*A < *B)") :
VecU8_fmt("(int)%s_less_%s(B, A) - (int)%s_less_%s(A, B)", T, T, T, T)));
VecU8_fmt("(int)%s_less_%s(B, A) - (int)%s_less_%s(A, B)", T, T, T, T));
if (mut_span) {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"void MutSpan%s_sort(MutSpan%s self) {\n"
SPACE "qsort(self.data, self.len, sizeof(%s), %s_qcompare);\n"
"}\n\n", T, T, T, T));
"}\n\n", T, T, T, T);
}
if (vec) {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
"void Vec%s_sort(Vec%s* self) {\n"
SPACE "qsort(self->buf, self->len, sizeof(%s), %s_qcompare);\n"
"}\n\n", T, T, T, T));
"}\n\n", T, T, T, T);
}
return res;
}
/* T must be trivially movable. If !primitive, requires methods T_drop (implicitly) and, if clonable, requires T_clone */
NODISCARD VecU8 generate_SpanT_VecT_trivmove_collab(SpanU8 T, bool primitive, bool clonable, bool add_mutable, bool add_extended) {
VecU8 g_SpanT = VecU8_fmt("Span%s", T);
VecU8 g_MutSpanT = VecU8_fmt("MutSpan%s", T);
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
SpanU8 SpanT = VecU8_to_span(&g_SpanT);
SpanU8 MutSpanT = VecU8_to_span(&g_MutSpanT);
SpanU8 VecT = VecU8_to_span(&g_VecT);
VecU8 res = VecU8_new();
void codegen_append_SpanT_VecT_trivmove_collab(VecU8* res,
SpanU8 T, bool primitive, bool clonable, bool add_mutable, bool add_extended) {
VecU8 SpanT = VecU8_fmt("Span%s", T);
VecU8 MutSpanT = VecU8_fmt("MutSpan%s", T);
VecU8 VecT = VecU8_fmt("Vec%s", T);
if (clonable) {
VecU8_append_vec(&res, VecU8_fmt(
"NODISCARD %s %s_from_span(%s src){\n" /* VecT, VecT, SpanT */
SPACE "%s res = (%s){ .buf = (%s*)safe_calloc(src.len, sizeof(%s)), .len = src.len, .capacity = src.len };\n", /* VecT, VecT, T, T */
VecT, VecT, SpanT, VecT, VecT, T, T));
VecU8_append_fmt(res,
"NODISCARD %r %r_from_span(%r src){\n" /* VecT, VecT, SpanT */
SPACE "%r res = (%r){ .buf = (%s*)safe_calloc(src.len, sizeof(%s)), .len = src.len, .capacity = src.len };\n", /* VecT, VecT, T, T */
VecT, VecT, SpanT, VecT, VecT, T, T);
if (primitive) {
VecU8_append_vec(&res, VecU8_fmt(
SPACE "memcpy(res.buf, src.data, src.len * sizeof(%s));\n", T));
VecU8_append_fmt(res, SPACE "memcpy(res.buf, src.data, src.len * sizeof(%s));\n", T);
} else {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(res,
SPACE "for (size_t i = 0; i < src.len; i++)\n"
SPACE8 "res.buf[i] = %s_clone(&src.data[i]);\n", T));
SPACE8 "res.buf[i] = %s_clone(&src.data[i]);\n", T);
}
VecU8_append_span(&res, cstr(SPACE "return res;\n}\n\n"));
VecU8_append_cstr(res, SPACE "return res;\n}\n\n");
}
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_to_span(const %s* vec){\n"
SPACE "return (%s){vec->buf, vec->len};\n"
"}\n\n", SpanT, VecT, VecT, SpanT));
VecU8_append_fmt(res,
"%r %r_to_span(const %r* vec){\n"
SPACE "return (%r){vec->buf, vec->len};\n"
"}\n\n", SpanT, VecT, VecT, SpanT);
if (add_mutable) {
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_to_mspan(%s* vec){\n"
SPACE "return (%s){vec->buf, vec->len};\n"
"}\n\n", MutSpanT, VecT, VecT, MutSpanT));
VecU8_append_fmt(res,
"%r %r_to_mspan(%r* vec){\n"
SPACE "return (%r){vec->buf, vec->len};\n"
"}\n\n", MutSpanT, VecT, VecT, MutSpanT);
}
if (clonable) {
VecU8_append_vec(&res, VecU8_fmt(
"void %s_append_span(%s* self, %s b) {\n" /* VecT, VecT, SpanT */
VecU8_append_fmt(res,
"void %r_append_span(%r* self, %r b) {\n" /* VecT, VecT, SpanT */
SPACE "size_t new_length = self->len + b.len;\n"
SPACE "if (new_length > self->capacity) {\n"
SPACE SPACE "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
SPACE SPACE "self->buf = (%s*)safe_realloc(self->buf, new_capacity * sizeof(%s));\n" /* T, T */
SPACE SPACE "self->capacity = new_capacity;\n"
SPACE "}\n", VecT, VecT, SpanT, T, T));
SPACE "}\n", VecT, VecT, SpanT, T, T);
if (primitive) {
VecU8_append_vec(&res, VecU8_fmt(
SPACE "memcpy(self->buf + self->len, b.data, b.len * sizeof(%s));\n", T));
VecU8_append_fmt(res,
SPACE "memcpy(self->buf + self->len, b.data, b.len * sizeof(%s));\n", T);
} else {
VecU8_append_vec(&res, VecU8_fmt(
SPACE "for (size_t i = 0; i < b.len; i++)\n"
SPACE SPACE "self->buf[self->len + i] = %s_clone(&b.data[i]);\n", T));
VecU8_append_fmt(res,
SPACE "for (size_t i = 0; i < b.len; i++)\n"
SPACE SPACE "self->buf[self->len + i] = %s_clone(&b.data[i]);\n", T);
}
VecU8_append_span(&res, cstr(
VecU8_append_cstr(res,
SPACE "self->len = new_length;\n"
"}\n\n"));
"}\n\n");
}
if (add_extended) {
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_span(const %s* vec, size_t start, size_t len) {\n"
VecU8_append_fmt(res,
"%r %r_span(const %r* vec, size_t start, size_t len) {\n"
SPACE "assert(start < SIZE_MAX - len && start + len <= vec->len);\n"
SPACE "return (%s){.data = vec->buf + start, .len = len};\n"
"}\n\n", SpanT, VecT, VecT, SpanT));
SPACE "return (%r){.data = vec->buf + start, .len = len};\n"
"}\n\n", SpanT, VecT, VecT, SpanT);
if (add_mutable) {
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_mspan(%s* vec, size_t start, size_t len) {\n"
VecU8_append_fmt(res,
"%r %r_mspan(%r* vec, size_t start, size_t len) {\n"
SPACE "assert(start < SIZE_MAX - len && start + len <= vec->len);\n"
SPACE "return (%s){.data = vec->buf + start, .len = len};\n"
"}\n\n", MutSpanT, VecT, VecT, MutSpanT));
SPACE "return (%r){.data = vec->buf + start, .len = len};\n"
"}\n\n", MutSpanT, VecT, VecT, MutSpanT);
}
}
VecU8_drop(g_VecT);
VecU8_drop(g_MutSpanT);
VecU8_drop(g_SpanT);
return res;
VecU8_drop(VecT);
VecU8_drop(MutSpanT);
VecU8_drop(SpanT);
}
/* The only reason this function exists is because in C it is easier to supply a lot of brace list arguments,
@ -478,37 +446,38 @@ NODISCARD VecU8 generate_util_templates_instantiation(util_templates_instantiati
if (generate_structures) {
if (op.vec) {
VecU8_append_vec(&res, generate_VecT_struct(op.T, op.skip_declaration_gen));
codegen_append_VecT_struct(&res, op.T, op.skip_declaration_gen);
}
if (op.span) {
VecU8_append_vec(&res, generate_SpanT_structures(op.T, op.mut_span, op.skip_declaration_gen));
codegen_append_SpanT_structures(&res, op.T, op.mut_span, op.skip_declaration_gen);
}
}
if (generate_methods) {
if (op.vec) {
VecU8_append_vec(&res, generate_VecT_base_methods(op.T, op.t_primitive, op.t_clonable));
codegen_append_VecT_base_methods(&res, op.T, op.t_primitive, op.t_clonable);
}
if (op.vec_extended) {
assert(op.vec);
VecU8_append_vec(&res, generate_VecT_trivmove_extended_methods(op.T, op.t_primitive, op.t_clonable));
codegen_append_VecT_trivmove_extended_methods(&res, op.T, op.t_primitive, op.t_clonable);
}
if (op.vec_equal) {
assert(op.vec);
VecU8_append_vec(&res, generate_VecT_equal_method(op.T, op.t_integer));
codegen_append_VecT_equal_method(&res, op.T, op.t_integer);
}
if (op.vec_new_of_size) {
assert(op.vec);
VecU8_append_vec(&res, generate_VecT_new_of_size_method(op.T));
codegen_append_VecT_new_of_size_method(&res, op.T);
}
if (op.span) {
VecU8_append_vec(&res, generate_SpanT_base_methods(op.T, op.t_integer, op.mut_span, false, op.span_extended));
codegen_append_SpanT_base_methods(&res, op.T, op.t_integer, op.mut_span, false, op.span_extended);
}
if (op.sort) {
VecU8_append_vec(&res, generate_span_company_sort_methods(op.T, op.t_integer, op.mut_span, op.vec));
codegen_append_span_company_sort_methods(&res, op.T, op.t_integer, op.mut_span, op.vec);
}
if (op.collab_vec_span) {
assert(op.vec && op.span);
VecU8_append_vec(&res, generate_SpanT_VecT_trivmove_collab(op.T, op.t_primitive, op.t_clonable, op.mut_span, op.collab_vec_span_extended));
codegen_append_SpanT_VecT_trivmove_collab(&res,
op.T, op.t_primitive, op.t_clonable, op.mut_span, op.collab_vec_span_extended);
}
}
return res;
@ -611,48 +580,48 @@ NODISCARD VecU8 generate_result_template_inst(SpanU8 OkT, SpanU8 ErrT, bool ok_t
assert(!ok_t_void || ok_t_primitive);
assert(!err_t_void || err_t_primitive);
VecU8 g_ResultT = get_ResultType_inst_name(OkT, ErrT);
SpanU8 ResultT = VecU8_to_span(&g_ResultT);
VecU8 ResultT = get_ResultType_inst_name(OkT, ErrT);
VecU8 res = VecU8_new();
VecU8_append_span(&res, cstr(
VecU8_append_cstr(&res,
"typedef struct {\n"
SPACE "Result_variant variant;\n"));
SPACE "Result_variant variant;\n");
if (ok_t_void && !err_t_void) {
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s err;\n", ErrT));
VecU8_append_fmt(&res, SPACE "%s err;\n", ErrT);
} else if (!ok_t_void && err_t_void) {
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s ok;\n", OkT));
VecU8_append_fmt(&res, SPACE "%s ok;\n", OkT);
} else {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(&res,
SPACE "union {\n"
SPACE SPACE "%s ok;\n"
SPACE SPACE "%s err;\n"
SPACE "};\n", OkT, ErrT));
SPACE "};\n", OkT, ErrT);
}
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", ResultT));
VecU8_append_fmt(&res, "} %r;\n\n", ResultT);
/* This method is 100% useless */
if (!ok_t_primitive || !err_t_primitive) {
VecU8_append_vec(&res, VecU8_fmt(
"void %s_drop(%s self) {\n", ResultT, ResultT));
VecU8_append_fmt(&res,
"void %r_drop(%r self) {\n", ResultT, ResultT);
if (ok_t_primitive && !err_t_primitive) {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(&res,
SPACE "if (self.variant == Result_Err)\n"
SPACE SPACE "%s_drop(self.err);\n", ErrT));
SPACE SPACE "%s_drop(self.err);\n", ErrT);
} else if (!ok_t_primitive && err_t_primitive) {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(&res,
SPACE "if (self.variant == Result_Ok)\n"
SPACE SPACE "%s_drop(self.ok);\n", OkT));
SPACE SPACE "%s_drop(self.ok);\n", OkT);
} else {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(&res,
SPACE "if (self.variant == Result_Ok)\n"
SPACE SPACE "%s_drop(self.ok);\n"
SPACE "else\n"
SPACE SPACE "%s_drop(self.err);\n", OkT, ErrT));
SPACE SPACE "%s_drop(self.err);\n", OkT, ErrT);
}
VecU8_append_span(&res, cstr("}\n\n"));
VecU8_append_cstr(&res, "}\n\n");
}
VecU8_drop(g_ResultT); /* ResultT variable invalidated */
VecU8_drop(ResultT); /* ResultT variable invalidated */
return res;
}
@ -691,52 +660,53 @@ void option_template_instantiation_op_fix(option_template_instantiation_op* self
NODISCARD VecU8 generate_OptionT_struct_and_methods(option_template_instantiation_op op) {
option_template_instantiation_op_fix(&op);
VecU8 g_OptionT = VecU8_fmt("Option%s", op.T);
SpanU8 OptionT = VecU8_to_span(&g_OptionT);
VecU8 OptionT = VecU8_fmt("Option%s", op.T);
VecU8 res = VecU8_new();
if (op.t_ptr) {
VecU8_append_vec(&res, VecU8_fmt("typedef %s %s;\n", op.T, OptionT));
VecU8_append_vec(&res, VecU8_fmt("#define None_%s() NULL\n", op.T));
VecU8_append_vec(&res, VecU8_fmt("%s Some_%s(%s ref) {\n" SPACE "return ref;\n}\n\n", OptionT, op.T, op.T));
VecU8_append_vec(&res, VecU8_fmt(
"%s %s_expect(%s self) {\n"
VecU8_append_fmt(&res, "typedef %s %r;\n", op.T, OptionT);
VecU8_append_fmt(&res, "#define None_%s() NULL\n", op.T);
VecU8_append_fmt(&res, "%r Some_%s(%s ref) {\n" SPACE "return ref;\n}\n\n", OptionT, op.T, op.T);
VecU8_append_fmt(&res,
"%s %r_expect(%r self) {\n"
SPACE "if (self == NULL){\n"
SPACE SPACE "abortf(\"Expected something in %r got NULL\\n\");\n"
SPACE "return self;\n"
"}\n\n", op.T, OptionT, OptionT));
"}\n\n", op.T, OptionT, OptionT, OptionT);
} else {
VecU8_append_vec(&res, VecU8_fmt(
VecU8_append_fmt(&res,
"typedef struct {\n"
SPACE "Option_variant variant;\n"
SPACE "%s some;\n"
"} %s;\n\n", op.T, OptionT));
VecU8_append_vec(&res, VecU8_fmt("#define None_%s() (%s){ .variant = Option_None }\n\n", op.T, OptionT));
VecU8_append_vec(&res, VecU8_fmt(
"NODISCARD %s Some_%s(%s obj) {\n"
SPACE "return (%s){ .variant = Option_Some, .some = obj };\n"
"}\n\n", OptionT, op.T, op.T, OptionT));
VecU8_append_vec(&res, VecU8_fmt(
"NODISCARD %s %s_expect(%s self){\n"
"} %r;\n\n", op.T, OptionT);
VecU8_append_fmt(&res, "#define None_%s() (%r){ .variant = Option_None }\n\n", op.T, OptionT);
VecU8_append_fmt(&res,
"NODISCARD %r Some_%s(%s obj) {\n"
SPACE "return (%r){ .variant = Option_Some, .some = obj };\n"
"}\n\n", OptionT, op.T, op.T, OptionT);
VecU8_append_fmt(&res,
"NODISCARD %s %r_expect(%r self){\n"
SPACE "if (self.variant == Option_None)\n"
SPACE SPACE "abortf(\"Expected something in %s got None\\n\");\n"
SPACE SPACE "abortf(\"Expected something in %r got None\\n\");\n"
SPACE "return self.some;\n"
"}\n\n", op.T, OptionT, OptionT, OptionT));
"}\n\n", op.T, OptionT, OptionT, OptionT);
if (!op.t_primitive) {
VecU8_append_vec(&res, VecU8_fmt(
"void %s_drop(%s self) {\n"
VecU8_append_fmt(&res,
"void %r_drop(%r self) {\n"
SPACE "if (self.variant == Option_None)\n"
SPACE SPACE "%s_drop(self.some);\n"
"}\n\n", OptionT, OptionT, op.T));
"}\n\n", OptionT, OptionT, op.T);
if (op.t_clonable) {
VecU8_append_vec(&res, VecU8_fmt(
"NODISCARD %s %s_clone(const %s* self) {\n"
VecU8_append_fmt(&res,
"NODISCARD %r %r_clone(const %r* self) {\n"
SPACE "if (self->variant == Option_None)\n"
SPACE SPACE "return (%s) { .variant = Option_None };\n"
SPACE "return (%s){ .variant = Option_Some, .some = %s_clone(&self->some) };\n"
"}\n\n", OptionT, OptionT, OptionT, OptionT, OptionT, op.T));
SPACE SPACE "return (%r) { .variant = Option_None };\n"
SPACE "return (%r){ .variant = Option_Some, .some = %s_clone(&self->some) };\n"
"}\n\n", OptionT, OptionT, OptionT, OptionT, OptionT, op.T);
}
}
}
VecU8_drop(g_OptionT);
VecU8_drop(OptionT);
return res;
}

View File

@ -40,6 +40,7 @@ void VecU8_print(VecU8 self){
VecU8_drop(self);
}
/* Wrapper around vsnprintf */
NODISCARD VecU8 VecU8_format(const char *fmt, ...) {
assert(fmt);
@ -152,17 +153,10 @@ VecU8 U64_stringification(U64 x){
return res;
}
/* %s - SpanU8
* %v - VecU8
* %u - U64
* %c - int (one byte character)
* %i - S64
*/
NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
assert(fmt);
NODISCARD VecU8 VecU8_fmt_va_list(const char* fmt, va_list args){
size_t k = 0;
va_list args;
va_start(args, fmt);
va_list repeat;
va_copy(repeat, args);
for (const char *ch = fmt; *ch; ) {
if (*ch == '%') {
ch++;
@ -175,7 +169,7 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
va_arg(args, int);
k++;
} else if (*ch == 'v') {
/* We had not taken ownership of YET (will take it the next iteration) */
/* We had not taken ownership of it YET (will take it the next iteration) */
VecU8 vs = va_arg(args, VecU8);
k += vs.len;
} else if (*ch == 'i') {
@ -184,6 +178,9 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
} else if (*ch == 'u') {
U64 x = va_arg(args, U64);
k += U64_stringification_get_length(x);
} else if (*ch == 'r') {
VecU8 vs = va_arg(args, VecU8);
k += vs.len;
} else
abortf("Format syntax error at pos %lu! Watch out, be careful", (size_t)(ch - fmt));
} else {
@ -191,29 +188,31 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
}
ch++;
}
va_end(args);
VecU8 res = VecU8_new_reserved(k);
va_start(args, fmt);
for (const char *ch = fmt; *ch;) {
if (*ch == '%') {
ch++;
if (*ch == '%') {
VecU8_append(&res, '%');
} else if (*ch == 's') {
SpanU8 s = va_arg(args, SpanU8);
SpanU8 s = va_arg(repeat, SpanU8);
VecU8_append_span(&res, s);
} else if (*ch == 'c') {
int byte = va_arg(args, int);
int byte = va_arg(repeat, int);
VecU8_append(&res, (U8)byte);
} else if (*ch == 'v') {
VecU8 vs = va_arg(args, VecU8);
VecU8 vs = va_arg(repeat, VecU8);
VecU8_append_vec(&res, vs); /* Moved ownership of vs argument */
} else if (*ch == 'i') {
S64 x = va_arg(args, S64);
S64 x = va_arg(repeat, S64);
S64_stringification_into_buf(x, &res);
} else if (*ch == 'u') {
U64 x = va_arg(args, U64);
U64 x = va_arg(repeat, U64);
U64_stringification_into_buf(x, &res);
} else if (*ch == 'r') {
VecU8 vs = va_arg(repeat, VecU8);
VecU8_append_span(&res, VecU8_to_span(&vs));
/* But we won't deallocate `vs` because never took ownership of it */
} else
assert(false);
} else {
@ -221,10 +220,40 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
}
ch++;
}
va_end(repeat);
return res;
}
/* %s - SpanU8
* %v - VecU8
* %u - U64
* %c - int (one byte character)
* %i - S64
* %r - VecU8 (but taken by reference, it won't be deallocated)
* Yes, I am breaking the dumb ownership-syntax-crutch convention I set up myself
*/
NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
assert(fmt);
va_list args;
va_start(args, fmt);
VecU8 res = VecU8_fmt_va_list(fmt, args);
va_end(args);
return res;
}
void VecU8_append_cstr(VecU8* res, const char* lit){
VecU8_append_span(res, SpanU8_from_cstr(lit));
}
// todo: add VecX_resize method. I really REALLY need to refactor this awful code
void VecU8_append_fmt(VecU8* res, const char* fmt, ...){
va_list args;
va_start(args, fmt);
VecU8 t = VecU8_fmt_va_list(fmt, args);
VecU8_append_vec(res, t);
va_end(args);
}
// todo: generate a special span method to check equality of contents
bool SpanU8_cont_equal(SpanU8 a, SpanU8 b) {
if (a.len != b.len)

View File

@ -36,60 +36,6 @@ bool marie_same_dir3(float A0, float A1, float A2, float B) {
return A0 == 0 || A1 == 0 || A2 == 0 || (diff & 0x80000000u) == 0;
}
// This function uses floating point arithmetic, which is very bad
/* cross product (vi - u) x (vj - u). If {vi, vj, vu} are points of CCW triangle, this will be it's positive surface */
float marie_surface(vec2 vi, vec2 vj, vec2 u) {
return u.x * (vi.y - vj.y) + u.y * (vj.x - vi.x) + (vi.x * vj.y - vj.x * vi.y);
}
typedef vec4 MarieVertAttr;
typedef struct {
vec2 pos;
MarieVertAttr attr;
} MariePlaneVertAttr;
typedef struct {
vec2 v0;
vec2 v1;
vec2 v2;
} MarieTriangle;
MarieTriangle MarieTriangle_mat3x2_mul_pos(MarieTriangle self, mat3x2 trop) {
return (MarieTriangle){
.v0 = mat3x2_mul_vec3(trop, vec2_and_one(self.v0)),
.v1 = mat3x2_mul_vec3(trop, vec2_and_one(self.v1)),
.v2 = mat3x2_mul_vec3(trop, vec2_and_one(self.v2))};
}
#include "../../../gen/l1/eve/marie/VecMarieTriangle.h"
typedef struct {
MariePlaneVertAttr v0;
MariePlaneVertAttr v1;
MariePlaneVertAttr v2;
} MarieTriangleAttr;
MarieTriangleAttr MarieTriangle_goto_nat_cords_pres_par(MarieTriangle self, mat3x2 trop) {
return (MarieTriangleAttr){
{mat3x2_mul_vec3(trop, vec2_and_one(self.v0)), {self.v0.x, self.v0.y, 0, 0}},
{mat3x2_mul_vec3(trop, vec2_and_one(self.v1)), {self.v1.x, self.v1.y, 0, 0}},
{mat3x2_mul_vec3(trop, vec2_and_one(self.v2)), {self.v2.x, self.v2.y, 0, 0}},
};
}
#include "../../../gen/l1/eve/marie/VecMarieTriangleAttr.h"
vec2 marie_intersect_lines(vec2 A1, vec2 B1, vec2 A2, vec2 B2) {
vec2 alpha = vec2_minus_vec2(B1, A1);
vec2 beta = vec2_minus_vec2(A2, B2);
vec2 gamma = vec2_minus_vec2(A2, A1);
float det_alpha_beta = alpha.x * beta.y - alpha.y * beta.x;
float det_gamma_beta = gamma.x * beta.y - gamma.y * beta.x;
float t1 = det_gamma_beta / det_alpha_beta;
return vec2_add_vec2(A1, vec2_mul_scal(alpha, t1));
}
float marie_clamp_float(float a, float l, float r) {
return (a < l) ? l : ((a <= r) ? a : r);
}

View File

@ -1,5 +1,5 @@
#pragma once
// todo: refactor (with VecU8_append_fmt)
#include "all_set_map_templ_util_inst.h"
/* Assuming A nd B are passed as intended */

View File

@ -1,5 +1,5 @@
#pragma once
// todo: refactor (with VecU8_append_fmt)
#include "all_set_map_templ_util_inst.h"
NODISCARD VecU8 codegen_rbtree__node_struct_name(map_instantiation_op op){

View File

@ -1,5 +1,5 @@
#pragma once
// todo: refactor (with VecU8_append_fmt)
#include "../../l1/codegen/codegen.h"
typedef struct {

36
src/l1_5/core/color.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
#include "../../../gen/l1/geom.h"
#include "randomness.h"
// Convert HSV (hue is in degrees; s, v in [0,1]) to RGB (in [0,1]^3)
static vec3 hsv_to_rgb(float h, float s, float v) {
h = fmodf(h, 360.0f);
if (h < 0.0f) h += 360.0f;
float hf = h / 60.0f;
int i = (int)floorf(hf);
float f = hf - (float)i;
float p = v * (1.0f - s);
float q = v * (1.0f - s * f);
float t = v * (1.0f - s * (1.0f - f));
vec3 rgb;
switch (i) {
case 0: rgb.x = v; rgb.y = t; rgb.z = p; break;
case 1: rgb.x = q; rgb.y = v; rgb.z = p; break;
case 2: rgb.x = p; rgb.y = v; rgb.z = t; break;
case 3: rgb.x = p; rgb.y = q; rgb.z = v; break;
case 4: rgb.x = t; rgb.y = p; rgb.z = v; break;
default: // i == 5:
rgb.x = v; rgb.y = p; rgb.z = q; break;
}
return rgb;
}
/* Cute little function that has nothing to do with rainbows */
vec3 sample_rainbow_color() {
float hue = frand01() * 360.0f;
float s = 0.95f + 0.05f * frand01(); // in [0.95, 1.0]
float v = 0.85f + 0.15f * frand01(); // in [0.85, 1.0]
return hsv_to_rgb(hue, s, v);
}

View File

@ -0,0 +1,59 @@
#pragma once
#include "../marie/geom_util.h"
#include "math.h"
typedef vec4 quaternion_t;
vec4 quaternion_fl_mul_vec4(vec4 A, vec4 B){
return (vec4){
A.x * B.x - A.y * B.y - A.z * B.z - A.w * B.w,
A.x * B.y + A.y * B.x + A.z * B.w - A.w * B.z,
A.x * B.z - A.y * B.w + A.z * B.x + A.w * B.y,
A.x * B.w + A.y * B.z - A.z * B.y + A.w * B.x,
};
}
/* Assumes abs(a) is 1 */
vec4 unit_quaternion_fl_inverse(vec4 a){
return (vec4){a.x, -a.y, -a.z, -a.w};
}
vec4 quaternion_fl_inverse(vec4 a){
float m = vec4_length(a);
m = 1 / (m * m);
return (vec4){a.x * m, -a.y * m, -a.z * m, -a.w * m};
}
mat3 quaternion_fl_to_rot3d_mat3(vec4 q){
float a = q.x;
float Rx = q.y;
float Ry = q.z;
float Rz = q.w;
return mat3_add_mat3(mat3_add_mat3(
mat3_mul_scal(mat3_E, 2*a*a - 1),
mat3_mul_scal(mat3_for_cross_product((vec3){Rx, Ry, Rz}), 2 * a)), mat3_E);
}
/* This thing requires some MATH */
vec4 unit_quaternion_fl_power(vec4 q, float t){
float qva = vec3_length((vec3){q.y, q.z, q.w});
float fi = atan2f(qva, q.x);
const float rub = 0.001f;
float e_x = cosf(t * fi);
float e_vc;
// float t_to_3 = t*t*t;
// float t_to_5 = t_to_3*t*t;
// float fi_to_2 = fi * fi;
// float fi_to_4 = fi_to_2 * fi_to_2;
// Remember, qva = sin(fi)
if (qva < rub) {
/* I have a feeling this is an overkill... Well, only time __and 100 hours of testing__ will show ;) */
// e_vc = t + (-t_to_3+t) / 6 * fi_to_2 + (3 * t_to_5 - 10 * t_to_3 + 7 * t) / 360 * fi_to_4;
e_vc = t + (-t*t*t+t) / 6 * fi * fi ;
} else {
e_vc = sinf(t *fi) / qva;
}
return (vec4){e_x, e_vc * q.y, e_vc * q.z, e_vc * q.w};
}

View File

@ -0,0 +1,7 @@
#pragma once
#include "stdlib.h"
float frand01(void) {
return (float)rand() / (float)RAND_MAX;
}

View File

@ -0,0 +1,7 @@
#pragma once
#include "../../../gen/l1/geom.h"
mat3 mat3_for_cross_product(vec3 r){
return (mat3){.x = {0, -r.z, r.y}, .y = {r.z, 0, -r.x}, .z = {-r.y, r.x, 0}};
}

View File

@ -0,0 +1,95 @@
#pragma once
#include "../../../gen/l1/geom.h"
/* cross product (vi - u) x (vj - u). If {vi, vj, vu} are points of CCW triangle, this will be it's positive surface */
float marie_surface(vec2 vi, vec2 vj, vec2 u) {
return u.x * (vi.y - vj.y) + u.y * (vj.x - vi.x) + (vi.x * vj.y - vj.x * vi.y);
}
/* 2 lines on a plane (of float type). Assumes lines are intersecting */
vec2 marie_intersect_lines(vec2 A1, vec2 B1, vec2 A2, vec2 B2) {
vec2 alpha = vec2_minus_vec2(B1, A1);
vec2 beta = vec2_minus_vec2(A2, B2);
vec2 gamma = vec2_minus_vec2(A2, A1);
float det_alpha_beta = alpha.x * beta.y - alpha.y * beta.x;
float det_gamma_beta = gamma.x * beta.y - gamma.y * beta.x;
float t1 = det_gamma_beta / det_alpha_beta;
return vec2_add_vec2(A1, vec2_mul_scal(alpha, t1));
}
/* Triangle (ABC) and a ray (from origin P to point Q) in 3d space (of float type). Returns bool: do they intersect */
bool marie_intersect_triangle_and_ray(vec3 A, vec3 B, vec3 C, vec3 P, vec3 Q, vec3* ret){
vec3 alpha = vec3_minus_vec3(A, C);
vec3 beta = vec3_minus_vec3(B, C);
vec3 gamma = vec3_minus_vec3(P, Q);
vec3 delta = vec3_minus_vec3(P, C);
float det_alpha_beta_gamma = mat3_det((mat3){.x = alpha, .y = beta, .z = gamma});
float det_delta_beta_gamma = mat3_det((mat3){.x = delta, .y = beta, .z = gamma});
float det_alpha_delta_gamma = mat3_det((mat3){.x = alpha, .y = delta, .z = gamma});
float det_alpha_beta_delta = mat3_det((mat3){.x = alpha, .y = beta, .z = delta});
if (det_alpha_beta_gamma < 0.0001)
return false;
float b_0 = det_delta_beta_gamma / det_alpha_beta_gamma;
float b_1 = det_alpha_delta_gamma / det_alpha_beta_gamma;
float t = det_alpha_beta_delta / det_alpha_beta_gamma;
if (b_0 < 0 || b_1 < 0 || b_0 + b_1 > 1 || t < 0)
return false;
*ret = vec3_add_vec3(P, vec3_mul_scal(gamma, -t));
return true;
}
/* any inv exp q => any abs bitness a =>
* vec2#(a)#.(q) -> vec2#(a)#.(q) -> vec2#(a)#.(q) -> vec2#(2a+3)#.(2q) */
S64 marie_precise_surface(s64vec2 vi, s64vec2 vj, s64vec2 u){
s64vec2 da = s64vec2_minus_s64vec2(vi, u);
s64vec2 db = s64vec2_minus_s64vec2(vj, u);
/* da, db are vec2#(a+1)#.(q) */
return da.x * db.y - da.y * db.x;
}
bool marie_precise_do_intersect_2d_interv_and_seg(s64vec2 a, s64vec2 b, s64vec2 c, s64vec2 d){
s64vec2 alpha = s64vec2_minus_s64vec2(b, a);
s64vec2 beta = s64vec2_minus_s64vec2(c, d);
s64vec2 gamma = s64vec2_minus_s64vec2(c, a);
S64 det_alpha_beta = alpha.x * beta.y - alpha.y * beta.x;
S64 det_gamma_beta = gamma.x * beta.y - gamma.y * beta.x;
if (det_alpha_beta == 0) {
if (det_gamma_beta != 0)
return false;
if (a.x < b.x) {
return !(c.x <= a.x && d.x <= a.x) && !(b.x <= c.x && b.x <= d.x);
} else if (b.x < a.x) {
return !(c.x <= b.x && d.x <= b.x) && !(a.x <= c.x && a.x <= d.x);
} else if (a.y < b.y) {
return !(c.y <= a.y && d.y <= a.y) && !(b.y <= c.y && b.y <= d.y);
} else if (b.y < a.y) {
return !(c.y <= b.y && d.y <= b.y) && !(a.y <= c.y && a.y <= d.y);
} else
return false; /* This code is unreachable, actually */
}
/* Return det_gamma_beta/det_alpha_beta in (0; 1) */
return 0 < det_gamma_beta && det_gamma_beta < det_alpha_beta;
}
/* Does not work for degenerate case where s(b_prev, b, b_next) = 0.
* Returns false if a is on the edge of angle(b_prev, b, b_next) */
bool marie_precise_is_in_ccw_angle(s64vec2 b_prev, s64vec2 b, s64vec2 b_next, s64vec2 a){
S64 sx = marie_precise_surface(b_prev, b, b_next);
S64 sy = marie_precise_surface(b_prev, b, a);
S64 sz = marie_precise_surface(b, b_next, a);
if (sx < 0) {
return sy > 0 || sz > 0;
} else {
return sy > 0 && sz > 0;
}
}
/* Read source code to understand */
bool marie_order_s64vec2_less(s64vec2 a, s64vec2 b){
return a.x < b.x || (a.x == b.x && a.y < b.y);
}

View File

@ -1,6 +1,6 @@
#pragma once
#include "../marie/graphics_geom.h"
#include "../../l1_5/marie/graphics_geom.h"
#include "../../../gen/l1/VecAndSpan_U32.h"
#include "../../../gen/l1/VecAndSpan_U8.h"
@ -32,19 +32,18 @@ GenericMeshTopology GenericMeshTopology_clone(const GenericMeshTopology* self) {
return (GenericMeshTopology){.vertices = VecGenericMeshVertexInc_clone(&self->vertices), .indexes = VecU32_clone(&self->indexes)};
}
/* non-primitive */
typedef struct {
VecU8 topology_path;
VecU8 diffuse_texture_path;
VecU8 normal_texture_path;
VecU8 specular_texture_path;
} AliceGenericMeshPath;
} AliceGenericMeshTexturePaths;
void AliceGenericMeshPath_drop(AliceGenericMeshPath self) {
VecU8_drop(self.topology_path);
VecU8_drop(self.diffuse_texture_path);
VecU8_drop(self.normal_texture_path);
VecU8_drop(self.specular_texture_path);
}
/* non-primitive */
typedef struct {
VecU8 topology_path;
AliceGenericMeshTexturePaths tex;
} AliceGenericMeshPaths;
typedef struct {
mat4 model_t;

View File

@ -824,35 +824,36 @@ struct Alice {
VkDescriptorSet descriptor_set_for_pipeline_1;
};
ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericMeshPath paths){
GenericMeshTopology topology;
if (SpanU8_is_postfix(cstr(".AliceGenericMesh"), VecU8_to_span(&paths.topology_path) )) {
topology = alice_expect_read_generic_mesh_from_file(paths.topology_path);
} else if (SpanU8_is_postfix(cstr(".obj"), VecU8_to_span(&paths.topology_path) )) {
topology = alice_expect_read_generic_mesh_from_obj_file(paths.topology_path);
} else {
abortf("Иди своей дорогой\n");
}
ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const GenericMeshTopology* topology,
AliceGenericMeshTexturePaths t_paths){
// GenericMeshTopology topology;
// if (SpanU8_is_postfix(cstr(".AliceGenericMesh"), VecU8_to_span(&paths.topology_path) )) {
// topology = alice_expect_read_generic_mesh_from_file(paths.topology_path);
// } else if (SpanU8_is_postfix(cstr(".obj"), VecU8_to_span(&paths.topology_path) )) {
// topology = alice_expect_read_generic_mesh_from_obj_file(paths.topology_path);
// } else {
// abortf("Иди своей дорогой\n");
// }
ListNodeAliceGenericMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceGenericMeshHand));
AliceGenericMeshHand* mm = &mm_node->el;
mm->indexes = topology.indexes.len;
mm->indexes = topology->indexes.len;
mm->instance_attr.count = 0;
mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 200);
mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 200);
mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers,
topology.vertices.len * sizeof(GenericMeshVertex));
topology->vertices.len * sizeof(GenericMeshVertex));
mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers,
topology.indexes.len * sizeof(U32));
topology->indexes.len * sizeof(U32));
// todo: change this, I don't like this at all :(
mm->pixels_diffuse = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&paths.diffuse_texture_path));
mm->pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&paths.normal_texture_path));
mm->pixels_specular = TextureDataR8_read_from_png_nofail(VecU8_to_span(&paths.specular_texture_path));
VecU8_drop(paths.diffuse_texture_path);
VecU8_drop(paths.normal_texture_path);
VecU8_drop(paths.specular_texture_path);
mm->pixels_diffuse = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&t_paths.diffuse_texture_path));
mm->pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&t_paths.normal_texture_path));
mm->pixels_specular = TextureDataR8_read_from_png_nofail(VecU8_to_span(&t_paths.specular_texture_path));
VecU8_drop(t_paths.diffuse_texture_path);
VecU8_drop(t_paths.normal_texture_path);
VecU8_drop(t_paths.specular_texture_path);
mm->staging_diffuse_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers,
mm->pixels_diffuse.pixels.len * sizeof(cvec4));
@ -862,9 +863,9 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericM
mm->pixels_specular.pixels.len * sizeof(U8));
mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
topology.vertices.len * sizeof(GenericMeshVertex));
topology->vertices.len * sizeof(GenericMeshVertex));
mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
topology.indexes.len * sizeof(U32));
topology->indexes.len * sizeof(U32));
mm->diffuse_texture = MargaretImgAllocator_alloc(&alice->dev_local_images,
mm->pixels_diffuse.width, mm->pixels_diffuse.height,
@ -883,20 +884,20 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericM
/* We allocated enough memory, but now it's time to actually fill staging buffers */
/* Filleing staging VBO */
assert(mm->staging_vbo.len >= topology.vertices.len * sizeof(GenericMeshVertex));
assert(mm->vbo.len >= topology.vertices.len * sizeof(GenericMeshVertex));
assert(mm->staging_vbo.len >= topology->vertices.len * sizeof(GenericMeshVertex));
assert(mm->vbo.len >= topology->vertices.len * sizeof(GenericMeshVertex));
GenericMeshVertex* staging_vbo = (GenericMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo);
for (U64 i = 0; i < topology.vertices.len; i++) {
staging_vbo[i].base = topology.vertices.buf[i];
for (U64 i = 0; i < topology->vertices.len; i++) {
staging_vbo[i].base = topology->vertices.buf[i];
}
assert(topology.indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < topology.indexes.len; ti++) {
U32 v0 = topology.indexes.buf[ti * 3 + 0];
U32 v1 = topology.indexes.buf[ti * 3 + 1];
U32 v2 = topology.indexes.buf[ti * 3 + 2];
const GenericMeshVertexInc* A0 = VecGenericMeshVertexInc_at(&topology.vertices, v0);
const GenericMeshVertexInc* A1 = VecGenericMeshVertexInc_at(&topology.vertices, v1);
const GenericMeshVertexInc* A2 = VecGenericMeshVertexInc_at(&topology.vertices, v2);
assert(topology->indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < topology->indexes.len; ti++) {
U32 v0 = topology->indexes.buf[ti * 3 + 0];
U32 v1 = topology->indexes.buf[ti * 3 + 1];
U32 v2 = topology->indexes.buf[ti * 3 + 2];
const GenericMeshVertexInc* A0 = VecGenericMeshVertexInc_at(&topology->vertices, v0);
const GenericMeshVertexInc* A1 = VecGenericMeshVertexInc_at(&topology->vertices, v1);
const GenericMeshVertexInc* A2 = VecGenericMeshVertexInc_at(&topology->vertices, v2);
vec3 dp1 = vec3_minus_vec3(A1->pos, A0->pos);
vec3 dp2 = vec3_minus_vec3(A2->pos, A0->pos);
float du1 = A1->tex.x - A0->tex.x;
@ -913,11 +914,11 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericM
staging_vbo[v0].tang_V = staging_vbo[v1].tang_V = staging_vbo[v2].tang_V = tang_U_V.y;
}
/* Filling EBO is easy */
assert(topology.indexes.len == mm->indexes);
size_t ebo_len = topology.indexes.len * sizeof(U32);
assert(topology->indexes.len == mm->indexes);
size_t ebo_len = topology->indexes.len * sizeof(U32);
assert(mm->ebo.len >= ebo_len);
U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo);
memcpy(staging_ebo, topology.indexes.buf, ebo_len);
memcpy(staging_ebo, topology->indexes.buf, ebo_len);
/* Filling staging textures from memory pixel data */
/* todo: do it immediately ON THE READ */
memcpy(MargaretSubbuf_get_mapped(&mm->staging_diffuse_tex_buf), mm->pixels_diffuse.pixels.buf,
@ -1003,56 +1004,55 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericM
return mm_node;
}
ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, VecU8 path){
ShinyMeshTopology topology = alice_expect_read_shiny_mesh_from_file(path);
ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, const ShinyMeshTopology* topology){
ListNodeAliceShinyMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceShinyMeshHand));
AliceShinyMeshHand* mm = &mm_node->el;
mm->indexes = topology.indexes.len;
mm->indexes = topology->indexes.len;
mm->instance_attr.count = 0;
mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 128);
mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 128);
mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers,
topology.vertices.len * sizeof(ShinyMeshVertex));
topology->vertices.len * sizeof(ShinyMeshVertex));
mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers,
topology.indexes.len * sizeof(U32));
topology->indexes.len * sizeof(U32));
mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
topology.vertices.len * sizeof(ShinyMeshVertex));
topology->vertices.len * sizeof(ShinyMeshVertex));
mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
topology.indexes.len * sizeof(U32));
topology->indexes.len * sizeof(U32));
ListAliceShinyMeshHand_insert_node(&alice->shiny_models.hands, mm_node);
VecRefListNodeAliceShinyMeshHand_append(&alice->shiny_models.to_be_copied_to_device_next_cycle, mm_node);
/* We allocated enough memory, now it's time to actually fill staging buffers */
/* And we start by filling staging VBO */
assert(mm->staging_vbo.len >= topology.vertices.len * sizeof(ShinyMeshVertex));
assert(mm->vbo.len >= topology.vertices.len * sizeof(ShinyMeshVertex));
assert(mm->staging_vbo.len >= topology->vertices.len * sizeof(ShinyMeshVertex));
assert(mm->vbo.len >= topology->vertices.len * sizeof(ShinyMeshVertex));
ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo);
for (U64 i = 0; i < topology.vertices.len; i++) {
staging_vbo[i].base = topology.vertices.buf[i];
for (U64 i = 0; i < topology->vertices.len; i++) {
staging_vbo[i].base = topology->vertices.buf[i];
}
assert(topology.indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < topology.indexes.len; ti++) {
U32 v0 = topology.indexes.buf[ti * 3 + 0];
U32 v1 = topology.indexes.buf[ti * 3 + 1];
U32 v2 = topology.indexes.buf[ti * 3 + 2];
vec3 p0 = VecShinyMeshVertexInc_at(&topology.vertices, v0)->pos;
vec3 p1 = VecShinyMeshVertexInc_at(&topology.vertices, v1)->pos;
vec3 p2 = VecShinyMeshVertexInc_at(&topology.vertices, v2)->pos;
assert(topology->indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < topology->indexes.len; ti++) {
U32 v0 = topology->indexes.buf[ti * 3 + 0];
U32 v1 = topology->indexes.buf[ti * 3 + 1];
U32 v2 = topology->indexes.buf[ti * 3 + 2];
vec3 p0 = VecShinyMeshVertexInc_at(&topology->vertices, v0)->pos;
vec3 p1 = VecShinyMeshVertexInc_at(&topology->vertices, v1)->pos;
vec3 p2 = VecShinyMeshVertexInc_at(&topology->vertices, v2)->pos;
vec3 norm = vec3_normalize(vec3_cross(vec3_minus_vec3(p1, p0), vec3_minus_vec3(p2, p0)));
staging_vbo[v0].normal = staging_vbo[v1].normal = staging_vbo[v2].normal = norm;
}
/* Filling staging EBO is super-duper easy */
assert(topology.indexes.len == mm->indexes);
size_t ebo_len = topology.indexes.len * sizeof(U32);
assert(topology->indexes.len == mm->indexes);
size_t ebo_len = topology->indexes.len * sizeof(U32);
assert(mm->ebo.len >= ebo_len);
U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo);
memcpy(staging_ebo, topology.indexes.buf, ebo_len);
memcpy(staging_ebo, topology->indexes.buf, ebo_len);
return mm_node;
}

View File

@ -164,8 +164,6 @@ void LucyRenderer_another_frame(LucyRenderer* self){
MargaretBufAllocator_expand_or_free_old(self->ve.dev_local_buffers, &self->vbo, needed_vbo_length);
}
if ((self->need_to_transfer) && self->glyphs_count > 0) {
printf("LucyRenderer: we are doing copying\n");
self->need_to_transfer = false;
margaret_rec_cmd_copy_buffer_one_to_one_part(self->ve.transfer_cmd_buffer,
&self->staging_vbo, &self->vbo, 0, needed_vbo_length);

View File

@ -2,6 +2,46 @@
#include "../../../gen/l1/geom.h"
#include "../../l1/marie/geom_alg_utils.h"
#include "../../l1_5/marie/prim_shape_geom.h"
typedef vec4 MarieVertAttr;
typedef struct {
vec2 pos;
MarieVertAttr attr;
} MariePlaneVertAttr;
typedef struct {
vec2 v0;
vec2 v1;
vec2 v2;
} MarieTriangle;
MarieTriangle MarieTriangle_mat3x2_mul_pos(MarieTriangle self, mat3x2 trop) {
return (MarieTriangle){
.v0 = mat3x2_mul_vec3(trop, vec2_and_one(self.v0)),
.v1 = mat3x2_mul_vec3(trop, vec2_and_one(self.v1)),
.v2 = mat3x2_mul_vec3(trop, vec2_and_one(self.v2))};
}
#include "../../../gen/l1/eve/marie/VecMarieTriangle.h"
typedef struct {
MariePlaneVertAttr v0;
MariePlaneVertAttr v1;
MariePlaneVertAttr v2;
} MarieTriangleAttr;
MarieTriangleAttr MarieTriangle_goto_nat_cords_pres_par(MarieTriangle self, mat3x2 trop) {
return (MarieTriangleAttr){
{mat3x2_mul_vec3(trop, vec2_and_one(self.v0)), {self.v0.x, self.v0.y, 0, 0}},
{mat3x2_mul_vec3(trop, vec2_and_one(self.v1)), {self.v1.x, self.v1.y, 0, 0}},
{mat3x2_mul_vec3(trop, vec2_and_one(self.v2)), {self.v2.x, self.v2.y, 0, 0}},
};
}
#include "../../../gen/l1/eve/marie/VecMarieTriangleAttr.h"
typedef struct {
/* guest, x, y, attribute (custom) */

View File

@ -8,57 +8,8 @@
#include "../../../gen/l1/VecAndSpan_VecU64.h"
#include <stdbool.h>
#include <string.h>
#include "../../l1_5/marie/prim_shape_geom.h"
/* any inv exp q => any abs bitness a =>
* vec2#(a)#.(q) -> vec2#(a)#.(q) -> vec2#(a)#.(q) -> vec2#(2a+3)#.(2q) */
S64 marie_precise_surface(s64vec2 vi, s64vec2 vj, s64vec2 u){
s64vec2 da = s64vec2_minus_s64vec2(vi, u);
s64vec2 db = s64vec2_minus_s64vec2(vj, u);
/* da, db are vec2#(a+1)#.(q) */
return da.x * db.y - da.y * db.x;
}
bool marie_precise_do_intersect_2d_interv_and_seg(s64vec2 a, s64vec2 b, s64vec2 c, s64vec2 d){
s64vec2 alpha = s64vec2_minus_s64vec2(b, a);
s64vec2 beta = s64vec2_minus_s64vec2(c, d);
s64vec2 gamma = s64vec2_minus_s64vec2(c, a);
S64 det_alpha_beta = alpha.x * beta.y - alpha.y * beta.x;
S64 det_gamma_beta = gamma.x * beta.y - gamma.y * beta.x;
if (det_alpha_beta == 0) {
if (det_gamma_beta != 0)
return false;
if (a.x < b.x) {
return !(c.x <= a.x && d.x <= a.x) && !(b.x <= c.x && b.x <= d.x);
} else if (b.x < a.x) {
return !(c.x <= b.x && d.x <= b.x) && !(a.x <= c.x && a.x <= d.x);
} else if (a.y < b.y) {
return !(c.y <= a.y && d.y <= a.y) && !(b.y <= c.y && b.y <= d.y);
} else if (b.y < a.y) {
return !(c.y <= b.y && d.y <= b.y) && !(a.y <= c.y && a.y <= d.y);
} else
return false; /* This code is unreachable, actually */
}
/* Return det_gamma_beta/det_alpha_beta in (0; 1) */
return 0 < det_gamma_beta && det_gamma_beta < det_alpha_beta;
}
/* Does not work for degenerate case where s(b_prev, b, b_next) = 0.
* Returns false if a is on the edge of angle(b_prev, b, b_next) */
bool marie_precise_is_in_ccw_angle(s64vec2 b_prev, s64vec2 b, s64vec2 b_next, s64vec2 a){
S64 sx = marie_precise_surface(b_prev, b, b_next);
S64 sy = marie_precise_surface(b_prev, b, a);
S64 sz = marie_precise_surface(b, b_next, a);
if (sx < 0) {
return sy > 0 || sz > 0;
} else {
return sy > 0 && sz > 0;
}
}
/* Read source code to understand */
bool marie_order_s64vec2_less(s64vec2 a, s64vec2 b){
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
typedef struct{
U64 prev, next;

View File

@ -5,7 +5,7 @@
#include <stdio.h>
#include "../../../l1/system/pthread.h"
#include "../../margaret/time_utils.h"
#include "../../marie/graphics_geom.h"
#include "../../../l1_5/marie/graphics_geom.h"
#include "../../marie/rasterization.h"
#include <fcntl.h>

View File

@ -1,13 +1,44 @@
#include "../../l2/core/glb_file.h"
#include "../../l2/alice/engine.h"
#include "../../l1_5/core/quaternion.h"
#include "../../l1_5/marie/prim_shape_geom.h"
#include "../../../gen/l1/VecAndSpan_vec3.h"
#include "../../l1_5/core/color.h"
AliceGenericMeshPath AliceGenericMeshPath_for_log(SpanU8 root_dir, U64 w, U64 r, U64 k) {
return (AliceGenericMeshPath){
.topology_path = VecU8_fmt("%s/gen/l2/models/log_%u_%u_%u.AliceGenericMesh", root_dir, w, r, k),
.diffuse_texture_path = VecU8_fmt("%s/src/l3/textures/log_%u_%u_%u_diffuse.png", root_dir, w, r, k),
.normal_texture_path = VecU8_fmt("%s/gen/l2/textures/log_%u_%u_%u_NORMAL.png", root_dir, w, r, k),
.specular_texture_path = VecU8_fmt("%s/src/l3/textures/log_%u_%u_%u_specular.png", root_dir, w, r, k),
};
typedef struct{
vec3 pos;
vec3 color;
float magnitude;
} LightSourceState;
#include "../../../gen/l1/eve/r4/VecLightSourceState.h"
typedef struct {
float mass;
/* Center of mass relative to "center of mesh" */
vec3 mass_center;
} RigidBodyConfig;
typedef struct {
RigidBodyConfig p;
vec3 pos;
vec3 speed;
quaternion_t rot;
quaternion_t rot_speed;
} RigidBodyState;
/* point `M` is relative to the center of mass */
vec3 RigidBodyState_translate_point(const RigidBodyState* self, vec3 M){
return vec3_add_vec3(self->pos, M);
}
vec3 RigidBodyState_translate_point_of_mesh(const RigidBodyState* self, vec3 M){
return RigidBodyState_translate_point(self, vec3_minus_vec3(M, self->p.mass_center));
}
/* Transforms points relative to center of mass. To get model_t for mesh, multiply transition matrix by this matrix */
mat4 RigidBodyState_get_tran_mat(const RigidBodyState* self){
return marie_translation_mat4(self->pos);
}
vec3 project_dir_onto_plane_xz(vec3 v){
@ -20,13 +51,62 @@ typedef struct{
LucyFace* font_face;
RBTreeNodeLucyFaceFixedSize* font_face_of_size_40;
vec3 hero_pos;
} R4AlphaStuff;
ListNodeAliceGenericMeshHand* ROA_mesh;
GenericMeshTopology ROA_topology;
RigidBodyState ROA_state;
ListNodeAliceShinyMeshHand* LS_mesh;
VecLightSourceState LS_state;
U64 misses_count;
U64 hits_count;
Vecvec3 bullets_stuck_on_ROA;
} R4BetaState;
/* We are surrounded by a giant cubic mesh of light sources */
const int lighting_system_dim = 4;
void main_h_on_wayland_keyboard_key(void* data, U32 keysym, U32 act){
R4BetaState *st = data;
Alice* alice = st->alice;
if (act == WL_KEYBOARD_KEY_STATE_RELEASED && keysym == XKB_KEY_Return) {
printf("Shot a bullet!\n");
vec3 P = alice->cam_info.cam.pos;
vec3 dir = vec3_minus(alice->cam_info.cam.cam_basis.z);
vec3 Q = vec3_add_vec3(P, dir);
bool hit = false;
vec3 impact;
VecU32* Is = &st->ROA_topology.indexes;
VecGenericMeshVertexInc* Vs = &st->ROA_topology.vertices;
assert(Is->len % 3 == 0);
// todo: when I make model-t more complex (add rotation), this code will need to be updated
for (size_t i = 0; i < Is->len; i += 3) {
vec3 A = Vs->buf[Is->buf[i + 0]].pos;
vec3 B = Vs->buf[Is->buf[i + 1]].pos;
vec3 C = Vs->buf[Is->buf[i + 2]].pos;
A = RigidBodyState_translate_point_of_mesh(&st->ROA_state, A);
B = RigidBodyState_translate_point_of_mesh(&st->ROA_state, B);
C = RigidBodyState_translate_point_of_mesh(&st->ROA_state, C);
hit = marie_intersect_triangle_and_ray(A, B, C, P, Q, &impact);
if (hit)
break;
}
if (hit) {
st->hits_count++;
/* See, for some dumb reason I decided that bullets share a mesh with light sources. They are all cubes */
// U64 n = st->bullets_stuck_on_ROA.len + st->LS_state.len;
assert(st->bullets_stuck_on_ROA.len + st->LS_state.len == st->LS_mesh->el.instance_attr.count);
vec3 impact_from_center = vec3_minus_vec3(impact, st->ROA_state.pos);
Vecvec3_append(&st->bullets_stuck_on_ROA, impact_from_center);
} else {
st->misses_count++;
}
}
}
void main_h_on_another_frame(void* data, float fl){
R4AlphaStuff *st = data;
R4BetaState *st = data;
Alice* alice = st->alice;
vec3 proj_back = project_dir_onto_plane_xz(alice->cam_info.cam.cam_basis.z);
vec3 proj_right = project_dir_onto_plane_xz(alice->cam_info.cam.cam_basis.x);
@ -51,16 +131,56 @@ void main_h_on_another_frame(void* data, float fl){
}
alice->cam_info.cam.pos = st->hero_pos;
// margaret_ns_time TIME = margaret_clock_gettime_monotonic_raw();
// printf("Updating text\n");
// LucyRenderer_clear(&alice->lucy_renderer);
// VecU8 text = VecU8_fmt("Time is %u.%u\nHave a good day sir\n", (U64)TIME.tv_sec, (U64)TIME.tv_nsec);
// LucyRenderer_add_text(&alice->lucy_renderer, st->font_face_of_size_40, (vec4){0.1f, 0.2f, 0, 1}, 0,
// VecU8_to_span(&text), (ivec2){100, 100});
AliceGenericMeshHand_set_inst(&st->ROA_mesh->el, 0, (GenericMeshInstanceInc){
.model_t = mat4_mul_mat4(RigidBodyState_get_tran_mat(&st->ROA_state),
marie_translation_mat4(vec3_minus(st->ROA_state.p.mass_center))),
});
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&st->alice->pipeline0_ubo.staging);
assert(pipeline_0_ubo_point_light_max_count >= st->LS_state.len);
for (size_t i = 0; i < st->LS_state.len; i++) {
LightSourceState* ls = &st->LS_state.buf[i];
AliceShinyMeshHand_set_inst(&st->LS_mesh->el, i, (ShinyMeshInstanceInc){
.color_on = ls->color,
.model_t = marie_translation_mat4(ls->pos),
});
ubo->point_light_arr[i] = (Pipeline0PointLight){
.pos = ls->pos, .color = vec3_mul_scal(ls->color, 21)};
}
if (st->LS_state.len + st->bullets_stuck_on_ROA.len > st->LS_mesh->el.instance_attr.count) {
AliceShinyMeshHand_resize_instance_arr(alice, &st->LS_mesh->el, st->LS_state.len + st->bullets_stuck_on_ROA.len);
}
for (size_t i = 0; i < st->bullets_stuck_on_ROA.len; i++) {
vec3 bul_pos = st->bullets_stuck_on_ROA.buf[i];
AliceShinyMeshHand_set_inst(&st->LS_mesh->el, st->LS_state.len + i, (ShinyMeshInstanceInc){
.color_on = (vec3){2, 0, 0},
.model_t = mat4_mul_mat4(mat4_mul_mat4(
RigidBodyState_get_tran_mat(&st->ROA_state),
marie_translation_mat4(bul_pos)),
marie_3d_scal_mat4(0.069f)),
});
}
LucyRenderer_clear(&alice->lucy_renderer);
VecU8 text = VecU8_new();
if (st->misses_count == 0 && st->hits_count == 0) {
VecU8_append_cstr(&text, "Press ENTER to shoot\n");
}
if (st->misses_count > 0) {
VecU8_append_fmt(&text, "You missed %u times\n", st->misses_count);
}
if (st->hits_count > 0) {
VecU8_append_fmt(&text, "You hit ROA %u times\n", st->hits_count);
}
LucyRenderer_add_simple_label(&alice->lucy_renderer, st->font_face_of_size_40, (vec4){0, 0, 0, 1}, 0,
VecU8_to_span(&text), (ivec2){10, 10});
VecU8_drop(text);
}
void run_app(){
R4AlphaStuff st;
R4BetaState st;
st.hero_pos = (vec3){0, 0.81f, 0};
Alice* alice = Alice_new();
st.alice = alice;
@ -87,83 +207,68 @@ void run_app(){
LucyGlyphCache_add_glyphs(lucy_requests);
LucyRenderer_add_simple_label(&st.alice->lucy_renderer, st.font_face_of_size_40, (vec4){0, 0, 0, 1}, 0,
cstr("Bebra budet\nотнюхана\n"), (ivec2){10, 10});
cstr("..."), (ivec2){10, 10});
ListNodeAliceGenericMeshHand* model_gen = Alice_add_generic_mesh(st.alice, AliceGenericMeshPath_for_log(cstr("."), 10, 2, 6));
AliceGenericMeshHand_resize_instance_arr(st.alice, &model_gen->el, 1);
VecU8 ROA_mesh_path = vcstr("./gen/l2/models/log_10_2_6.AliceGenericMesh");
st.ROA_topology = alice_expect_read_generic_mesh_from_file(ROA_mesh_path);
for (int X = 0; X < 1; X++) {
for (int Z = 0; Z < 1; Z++) {
AliceGenericMeshHand_set_inst(&model_gen->el, X * 10 + Z, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){11.f * (float)X, -6, 4.f * (float)Z}),
});
}
}
ListNodeAliceShinyMeshHand *model_sh = Alice_add_shiny_mesh(st.alice, vcstr("./gen/l2/models/cube.AliceShinyMesh"));
AliceShinyMeshHand_resize_instance_arr(st.alice, &model_sh->el, 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
AliceShinyMeshHand_set_inst(&model_sh->el, X * 10 + Z, (ShinyMeshInstanceInc){
.color_on = {0, 1, 0},
.model_t = marie_translation_mat4((vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}),
});
st.ROA_mesh = Alice_add_generic_mesh(st.alice, &st.ROA_topology,
(AliceGenericMeshTexturePaths){
.diffuse_texture_path = vcstr("./src/l3/textures/log_10_2_6_diffuse.png"),
.normal_texture_path = vcstr("./gen/l2/textures/log_10_2_6_NORMAL.png"),
.specular_texture_path = vcstr("./src/l3/textures/log_10_2_6_specular.png")
});
AliceGenericMeshHand_resize_instance_arr(st.alice, &st.ROA_mesh->el, 1);
st.ROA_state = (RigidBodyState){
.p.mass = 100.f, .p.mass_center = (vec3){5, 0.77f, -0.77f},
.pos = (vec3){11.f, 3, 4}, .speed = {0},
.rot = (vec4){1, 0, 0, 0}, .rot_speed = (vec4){1, 0, 0, 0}};
ShinyMeshTopology LS_topology = alice_expect_read_shiny_mesh_from_file(vcstr("./gen/l2/models/cube.AliceShinyMesh"));
st.LS_mesh = Alice_add_shiny_mesh(st.alice, &LS_topology);
ShinyMeshTopology_drop(LS_topology);
const int cubes_in_light_wall = lighting_system_dim * lighting_system_dim;
st.LS_state = VecLightSourceState_new_reserved(cubes_in_light_wall * 6);
const vec3 light_cage_ways[6][2] = {
{{0, 1, 0}, {0, 0, 1}}, {{0, 0, 1}, {0, 1, 0}},
{{1, 0, 0}, {0, 0, 1}}, {{0, 0, 1}, {1, 0, 0}},
{{1, 0, 0}, {0, 1, 0}}, {{0, 1, 0}, {1, 0, 0}},
};
const float light_case_edge_offset = 6.1f;
const float light_case_gap = 12.5f;
const float light_cage_rad = (float)(lighting_system_dim - 1) * light_case_gap / 2 + light_case_edge_offset;
for (U64 s = 0; s < 6; s++) {
vec3 u = light_cage_ways[s][0];
vec3 v = light_cage_ways[s][1];
vec3 dir = vec3_mul_scal(vec3_cross(u, v), light_cage_rad);
for (U64 i = 0; i < lighting_system_dim; i++) {
for (U64 j = 0; j < lighting_system_dim; j++) {
vec3 clr = sample_rainbow_color();
VecLightSourceState_append(&st.LS_state, (LightSourceState){
.pos = vec3_add_vec3(dir, vec3_add_vec3(
vec3_mul_scal(u, -light_cage_rad + light_case_edge_offset + light_case_gap * (float)i),
vec3_mul_scal(v, -light_cage_rad + light_case_edge_offset + light_case_gap * (float)j))),
.color = clr,
.magnitude = 1
});
}
}
}
AliceShinyMeshHand_resize_instance_arr(st.alice, &st.LS_mesh->el, st.LS_state.len);
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&st.alice->pipeline0_ubo.staging);
assert(pipeline_0_ubo_point_light_max_count >= 100);
ubo->point_light_count = 100;
assert(pipeline_0_ubo_point_light_max_count >= st.LS_state.len);
ubo->point_light_count = (int)st.LS_state.len;
ubo->spotlight_count = 0;
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
ubo->point_light_arr[X * 10 + Z] = (Pipeline0PointLight){
.pos = (vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10},
.color = {5, 5, 5}
};
}
}
ubo->point_light_arr[0].color = (vec3){100, 100, 100};
st.misses_count = 0;
st.hits_count = 0;
st.bullets_stuck_on_ROA = Vecvec3_new();
ListNodeAliceGenericMeshHand* skeleton_mesh = Alice_add_generic_mesh(st.alice, (AliceGenericMeshPath){
.topology_path = vcstr("./src/l3/models/skeleton.obj"),
.diffuse_texture_path = vcstr("./src/l3/models/bone.png"),
.normal_texture_path = vcstr("./gen/l2/textures/flat_NORMAL.png"),
.specular_texture_path = vcstr("./gen/l2/textures/flat_NORMAL.png"),
});
AliceGenericMeshHand_resize_instance_arr(alice, &skeleton_mesh->el, 1);
AliceGenericMeshHand_set_inst(&skeleton_mesh->el, 0, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){5.f, -3, 12.f}),
});
ListNodeAliceGenericMeshHand* floor1_mesh = Alice_add_generic_mesh(st.alice, (AliceGenericMeshPath){
.topology_path = vcstr("gen/l2/models/floor1.AliceGenericMesh"),
.diffuse_texture_path = vcstr("src/l3/textures/wood.png"),
.normal_texture_path = vcstr("gen/l2/textures/flat_NORMAL.png"),
.specular_texture_path = vcstr("gen/l2/textures/no_SPECULAR.png"),
});
AliceGenericMeshHand_resize_instance_arr(alice, &floor1_mesh->el, 1);
AliceGenericMeshHand_set_inst(&floor1_mesh->el, 0, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){0, 0, 0}),
});
ListNodeAliceGenericMeshHand* model_puck = Alice_add_generic_mesh(st.alice, (AliceGenericMeshPath){
.topology_path = vcstr("gen/l2/models/puck.AliceGenericMesh"),
.diffuse_texture_path = vcstr("src/l3/textures/puck_diffuse.png"),
.normal_texture_path = vcstr("gen/l2/textures/puck_NORMAL.png"),
.specular_texture_path = vcstr("src/l3/textures/puck_specular.png"),
});
AliceGenericMeshHand_resize_instance_arr(st.alice, &model_puck->el, 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
AliceGenericMeshHand_set_inst(&model_puck->el, X * 10 + Z, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){11.f * (float)X - 20, -1, 4.f * (float)Z - 10}),
});
}
}
Alice_mainloop(st.alice, &(AliceCallbacks){
.on_wl_keyboard_key = main_h_on_wayland_keyboard_key,
.on_another_frame = main_h_on_another_frame,
@ -172,14 +277,4 @@ void run_app(){
int main(){
run_app();
VecU8 file = read_file_by_path(vcstr("./src/l3/models/skeleton.glb"));
GLBFileSegments data;
int c = glb_file_get_segments(VecU8_to_span(&file), &data);
if (c > 0) {
abortf("Incorrect glb ==> %d\n", c);
}
VecU8 json_text = json_encode(&data.gltf);
VecU8_print(json_text);
GLBFileSegments_drop(data);
VecU8_drop(file);
}

View File

@ -1,7 +1,7 @@
#version 450
layout(location = 0) in vec3 norm;
layout(location = 1) in vec3 color_off;
layout(location = 1) in vec3 color_off;
layout(location = 2) in vec3 color_on;
layout(location = 3) in vec3 pos;