commit eb1e7a451ea9305cdcc6878417f4a133a51f52c7 Author: moss Date: Wed Sep 17 21:34:45 2025 -0500 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..64b2cc9 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +lref is a c99 reference implementation of the physics of line rider beta 2 revision 6.2. + +the goal is to byte-for-byte match beta 6.2's results on any given track, such that it can be a drop in replacement for unit tests of more modern physics engines. +it is also the goal to be readable enough to reference for future physics engines. + +it is currently incomplete, but the raylib frontend in this repository can be used to test it against existing .sol track files. +the quality of that code and program is significantly lower than lref.h and only exists for testing purposes. + +### references used to create lref +- [OpenLR](https://github.com/kevansevans/OpenLR) +- line rider beta 2 revision 6.2, decompiled diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..bc55ae3 --- /dev/null +++ b/build.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# this isnt meant to be guarenteed to work on whatever system +# the c compiler invokation just got really big +# works for my system, is a reference for you in the worst case + +cd track_wrapper && zig build --release=fast && cd .. + +clang -Wall -Wextra -pedantic -std=c99 -L/usr/local/lib -I/usr/local/include -I. raylib_frontend.c track_wrapper/zig-out/lib/libtrack_wrapper.a -lraylib -lm diff --git a/lref.h b/lref.h new file mode 100644 index 0000000..bd2f43c --- /dev/null +++ b/lref.h @@ -0,0 +1,644 @@ +// LREF: +// +// c99 reference implementation of line rider, +// with the goal of exactly matching beta 6.2. +// +// ~moss7 + +// code todos +// TODO 6.1 and 6.0 grid registration +// TODO camera implementation +// TODO cleanup / deallocation logic +// TODO consider which functions actually need to be api vs internal + + +// documentation todos +// TODO equivalent flash decomp code in comments for reference +// TODO explain all of the physics functions in comments +// TODO explain parts that may differ in a less contrived engine +// (NaN checks, optimizations not made here for readability, etc) + +// # external includes + +#include +#include +#include + +// these only need to be included by the implementation + +#ifdef LREF_H_IMPLEMENTATION + +#include +#include +#include + +#endif + +// # rider constants + +const double endurance = 0.057; + +const double gravity = 0.175; + +#define POINT_COUNT 10 +#define BONE_COUNT 22 +#define ITERATION_COUNT 6 + +// # rider types + +struct point { + double x; + double y; + double previous_x; + double previous_y; + double momentum_x; + double momentum_y; + double friction; +}; + +struct bone { + bool breakable; + bool repel; + uint8_t a; + uint8_t b; + double restLength; +}; + +struct rider { + struct point points[POINT_COUNT]; + struct bone bones[BONE_COUNT]; + bool dead; + bool sledbroken; +}; + +// # line constants + +const double ZONE = 10; +const double ACC = 0.1; + +// # line types + +struct line_flags { + bool red; + bool invert; + bool left_extended; + bool right_extended; +}; + +struct line_values { + double dx; + double dy; + double invSqrDst; + double nx; + double ny; + double lim1; + double lim2; + double accx; + double accy; +}; + +struct line { + int32_t id; + double x1; + double y1; + double x2; + double y2; + struct line_flags flags; + struct line_values values; +}; + +// # grid constants + +const uint8_t GRID_62 = 0; +const uint8_t GRID_61 = 1; +const uint8_t GRID_60 = 2; + +const double GRIDSIZE = 14; + +#define GRID_ARRAY_BASE_SIZE 65536 + +// # grid types + +struct grid_coordinate { + int64_t x; + int64_t y; +}; + +struct grid_bucket { + struct grid_coordinate key; + struct grid_cell_entry* entry; + struct grid_bucket* next; +}; + +struct grid_cell_entry { + struct line* line; + struct grid_cell_entry* next; +}; + +struct grid { + struct grid_bucket** buckets; + size_t capacity; + size_t cells_total; +}; + +// integer grid coordinate plus the fractional remainder from truncation +struct grid_pos { + struct grid_coordinate coord; + double rx; + double ry; +}; + +// # simulation types + +struct simulation { + double start_x; + double start_y; + struct grid* grid; + struct line* lines; + size_t line_count; + struct rider bosh; +}; + +// # line function declarations + +void line_calculate_values(struct line* line); + +void line_collide(const struct line line, struct point* point); + +// # grid function declarations + +struct grid* grid_new(void); + +void grid_free(struct grid* grid); + +void grid_register_62(struct grid* grid, struct line* line); + +void grid_register_61(struct grid* grid, struct line* line); + +void grid_register_60(struct grid* grid, struct line* line); + +struct grid_coordinate grid_coordinate_at(double x, double y); + +struct grid_pos grid_pos_at(double x, double y); + +// # rider function declarations + +struct rider rider_new(double x, double y); + +// # simulation function declarations + +struct simulation simulation_new(void); + +void simulation_prepare_line_capacity(struct simulation* simulation, size_t capacity); + +void simulation_add_line(struct simulation* simulation, struct line line); + +#ifdef LREF_H_IMPLEMENTATION + +// # line function implementations + +void line_calculate_values(struct line* line) { + line->values.dx = line->x2 - line->x1; + line->values.dy = line->y2 - line->y1; + double sqrDst = (line->values.dx * line->values.dx + line->values.dy * line->values.dy); + line->values.invSqrDst = 1.0 / sqrDst; + double dst = sqrt(sqrDst); + double invDst = 1.0 / dst; + line->values.nx = line->values.dy * invDst * (line->flags.invert ? 1 : -1); + line->values.ny = line->values.dx * invDst * (line->flags.invert ? -1 : 1); + + double lim = fmin(0.25, ZONE / dst); + line->values.lim1 = line->flags.left_extended ? -lim : 0; + line->values.lim2 = line->flags.right_extended ? 1 + lim : 1; + if (!line->flags.red) return; + + line->values.accx = line->values.ny * ACC * (line->flags.invert ? 1 : -1); + line->values.accy = line->values.nx * ACC * (line->flags.invert ? -1 : 1); +} + +void line_collide(const struct line line, struct point* point) { + if (point->momentum_x * line.values.nx + point->momentum_y * line.values.ny <= 0.0) return; + + double distx = point->x - line.x1; + double disty = point->y - line.y1; + double distance_perpendicular = line.values.nx * distx + line.values.ny * disty; + double distance_along = (distx * line.values.dx + disty * line.values.dy) * line.values.invSqrDst; + + if (distance_perpendicular > 0 && distance_perpendicular < ZONE && + distance_along >= line.values.lim1 && distance_along <= line.values.lim2) { + point->x -= distance_perpendicular * line.values.nx; + point->y -= distance_perpendicular * line.values.ny; + + point->previous_x += line.values.ny * point->friction * distance_perpendicular + * (point->previous_x < point->x ? 1 : -1) + (line.flags.red ? line.values.accx : 0); + point->previous_y -= line.values.nx * point->friction * distance_perpendicular + * (point->previous_y < point->y ? -1 : 1) + (line.flags.red ? line.values.accy : 0); + } +} + +// # grid hashtable function implementations + +struct grid* grid_new(void) { + struct grid* grid = calloc(1, sizeof(struct grid)); + grid->buckets = calloc(GRID_ARRAY_BASE_SIZE, sizeof(struct grid_bucket*)); + grid->capacity = GRID_ARRAY_BASE_SIZE; + grid->cells_total = 0; + return grid; +} + +uint64_t grid_hash(const struct grid_coordinate coords) { + uint64_t x = coords.x; + uint64_t y = coords.y; + x ^= y + 0x9e3779b9 + (x << 6) + (x >> 2); + return x; +} + +size_t grid_index(const struct grid grid, const struct grid_coordinate coords) { + return (size_t)grid_hash(coords) & (grid.capacity - 1); +} + +bool grid_keys_eql(const struct grid_coordinate a, const struct grid_coordinate b) { + return a.x == b.x && a.y == b.y; +} + +bool grid_contains_cell(const struct grid grid, const struct grid_coordinate coords) { + size_t index = grid_index(grid, coords); + struct grid_bucket* current = grid.buckets[index]; + while (current != NULL) { + if (grid_keys_eql(current->key, coords)) return true; + current = current->next; + } + return false; +} + +void grid_put_ptr(struct grid* grid, struct grid_bucket* cell) { + size_t index = grid_index(*grid, cell->key); + struct grid_bucket* current = grid->buckets[index]; + if (current == NULL) { + grid->buckets[index] = cell; + cell->next = NULL; + return; + } + while (current->next != NULL) { + // if we are overwriting the old pointer + // (i dont think this ever actually happens + // in lref but for correctness, whatever) + if (grid_keys_eql(current->next->key, cell->key)) { + cell->next = current->next->next; + current->next = cell; + return; + } + current = current->next; + } + current->next = cell; + cell->next = NULL; + grid->cells_total += 1; +} + +bool grid_should_double_capacity(const struct grid grid) { + return (grid.cells_total * 4 > grid.capacity * 3); +} + +void grid_double_capacity(struct grid* grid) { + size_t old_capacity = grid->capacity; + struct grid_bucket** old_buckets = grid->buckets; + grid->capacity *= 2; + grid->buckets = calloc(grid->capacity, sizeof(struct grid_bucket*)); + for (unsigned int i = 0; i < old_capacity; i++) { + struct grid_bucket* next_bucket = old_buckets[i]; + while (next_bucket != NULL) { + struct grid_bucket* current_bucket = next_bucket; + next_bucket = current_bucket->next; + grid_put_ptr(grid, current_bucket); + } + } + free(old_buckets); +} + +struct grid_bucket* grid_cell_new(struct grid_coordinate coords) { + struct grid_bucket* cell = calloc(1, sizeof(struct grid_bucket)); + cell->key = coords; + cell->next = NULL; + cell->entry = NULL; + return cell; +} + +// get the cell at a given coordinate, creating it if it doesnt exist +struct grid_bucket* grid_get_cell(struct grid* grid, const struct grid_coordinate coords) { + size_t index = grid_index(*grid, coords); + struct grid_bucket* current = grid->buckets[index]; + if (current == NULL) { + grid->buckets[index] = grid_cell_new(coords); + return grid->buckets[index]; + } + + if (grid_keys_eql(current->key, coords)) return current; + + while (current->next != NULL) { + if (grid_keys_eql(current->next->key, coords)) return current->next; + current = current->next; + } + + current->next = grid_cell_new(coords); + return current->next; +} + +struct grid_coordinate grid_coordinate_at(double x, double y) { + struct grid_coordinate coord = { .x = (int64_t)floor(x / GRIDSIZE), .y = (int64_t)floor(y / GRIDSIZE) }; + return coord; +} + +struct grid_pos grid_pos_at(double x, double y) { + struct grid_coordinate coord = grid_coordinate_at(x, y); + struct grid_pos pos = { + .coord = coord, + .rx = x - GRIDSIZE * coord.x, + .ry = y - GRIDSIZE * coord.y, + }; + return pos; +} + +// # grid line registry function implementations + +void grid_cell_add_line(struct grid_bucket* cell, struct line* line) { + if (cell->entry == NULL) { + struct grid_cell_entry* entry = calloc(1, sizeof(struct grid_cell_entry)); + entry->line = line; + cell->entry = entry; + return; + } + + struct grid_cell_entry* current = cell->entry; + + if (current->line->id < line->id) { + struct grid_cell_entry* entry = calloc(1, sizeof(struct grid_cell_entry)); + entry->line = line; + entry->next = current; + cell->entry = entry; + return; + } + + while (current->next != NULL) { + if (current->next->line->id < line->id) { + struct grid_cell_entry* entry = calloc(1, sizeof(struct grid_cell_entry)); + entry->line = line; + entry->next = current->next; + current->next = entry; + return; + } + current = current->next; + } + struct grid_cell_entry* entry = calloc(1, sizeof(struct grid_cell_entry)); + entry->line = line; + current->next = entry; +} + +void grid_register_62(struct grid* grid, struct line* line) { + struct grid_pos start = grid_pos_at(line->x1, line->y1); + struct grid_pos end = grid_pos_at(line->x2, line->y2); + + double right = line->values.dx > 0 ? end.coord.x : start.coord.x; + double left = line->values.dx > 0 ? start.coord.x : end.coord.x; + double bottom = line->values.dy > 0 ? end.coord.y : start.coord.y; + double top = line->values.dy > 0 ? start.coord.y : end.coord.y; + + grid_cell_add_line(grid_get_cell(grid, start.coord), line); + + if ((line->values.dx == 0 && line->values.dy == 0) || + (start.coord.x == end.coord.x && start.coord.y == end.coord.y)) return; + + double x = line->x1; + double y = line->y1; + double invDx = 1.0 / line->values.dx; + double invDy = 1.0 / line->values.dy; + + double difX; + double difY; + + while (true) { + if (start.coord.x < 0) { + difX = line->values.dx > 0 ? (GRIDSIZE + start.rx) : (-GRIDSIZE - start.rx); + } else { + difX = line->values.dx > 0 ? (GRIDSIZE - start.rx) : (-(start.rx + 1)); + } + if (start.coord.y < 0) { + difY = line->values.dy > 0 ? (GRIDSIZE + start.ry) : (-GRIDSIZE - start.ry); + } else { + difY = line->values.dy > 0 ? (GRIDSIZE - start.ry) : (-(start.ry + 1)); + } + if (line->values.dx == 0) { + y += difY; + } else if (line->values.dy == 0) { + x += difX; + } else { + double step = y + line->values.dy * difX * invDx; + if (fabs(step - y) < fabs(difY)) { + x += difX; + y = step; + } else if (fabs(step - y) == fabs(difY)) { + x += difX; + y += difY; + } else { + x += line->values.dx * difY * invDy; + y += difY; + } + } + start = grid_pos_at(x, y); + if (start.coord.x >= left && start.coord.x <= right && start.coord.y >= top && start.coord.y <= bottom) { + grid_cell_add_line(grid_get_cell(grid, start.coord), line); + continue; + } + return; + } +} + +// # point function implementations + +void point_apply_momentum(struct point* point) { + point->momentum_x = point->x - point->previous_x; + point->momentum_y = point->y - point->previous_y + gravity; + point->previous_x = point->x; + point->previous_y = point->y; + point->x += point->momentum_x; + point->y += point->momentum_y; +} + +// # rider function implementations + +void rider_init_point(struct rider* bosh, uint8_t index, double x, double y, double friction) { + bosh->points[index].x = x; + bosh->points[index].y = y; + bosh->points[index].previous_x = x - 0.4; + bosh->points[index].previous_y = y; + bosh->points[index].friction = friction; +} + +void rider_init_bone(struct rider* bosh, uint8_t index, uint8_t a, uint8_t b, bool breakable, bool repel) { + bosh->bones[index].a = a; + bosh->bones[index].b = b; + bosh->bones[index].breakable = breakable; + bosh->bones[index].repel = repel; + double x = bosh->points[a].x - bosh->points[b].x; + double y = bosh->points[a].y - bosh->points[b].y; + bosh->bones[index].restLength = sqrt(x * x + y * y) * (repel ? 0.5 : 1.0); +} + +void rider_apply_start_offset(struct rider* bosh, double x, double y) { + for (int i = 0; i < POINT_COUNT; i++) { + struct point* point = &bosh->points[i]; + + point->x += x; + point->y += y; + point->previous_x = point->x - 0.4; + point->previous_y = point->y; + } +} + +struct rider rider_new(double x, double y) { + struct rider bosh; + memset(&bosh, 0, sizeof(bosh)); + + rider_init_point(&bosh, 0, 0.0, 0.0, 0.8); + rider_init_point(&bosh, 1, 0.0, 5.0, 0.0); + rider_init_point(&bosh, 2, 15.0, 5.0, 0.0); + rider_init_point(&bosh, 3, 17.5, 0.0, 0.0); + rider_init_point(&bosh, 4, 5.0, 0.0, 0.8); + rider_init_point(&bosh, 5, 5.0, -5.5, 0.8); + rider_init_point(&bosh, 6, 11.5, -5.0, 0.1); + rider_init_point(&bosh, 7, 11.5, -5.0, 0.1); + rider_init_point(&bosh, 8, 10.0, 5.0, 0.0); + rider_init_point(&bosh, 9, 10.0, 5.0, 0.0); + + rider_init_bone(&bosh, 0, 0, 1, false, false); + rider_init_bone(&bosh, 1, 1, 2, false, false); + rider_init_bone(&bosh, 2, 2, 3, false, false); + rider_init_bone(&bosh, 3, 3, 0, false, false); + rider_init_bone(&bosh, 4, 0, 2, false, false); + rider_init_bone(&bosh, 5, 3, 1, false, false); + rider_init_bone(&bosh, 6, 0, 4, true, false); + rider_init_bone(&bosh, 7, 1, 4, true, false); + rider_init_bone(&bosh, 8, 2, 4, true, false); + rider_init_bone(&bosh, 9, 5, 4, false, false); + rider_init_bone(&bosh, 10, 5, 6, false, false); + rider_init_bone(&bosh, 11, 5, 7, false, false); + rider_init_bone(&bosh, 12, 4, 8, false, false); + rider_init_bone(&bosh, 13, 4, 9, false, false); + rider_init_bone(&bosh, 14, 5, 7, false, false); + rider_init_bone(&bosh, 15, 5, 0, true, false); + rider_init_bone(&bosh, 16, 3, 6, true, false); + rider_init_bone(&bosh, 17, 3, 7, true, false); + rider_init_bone(&bosh, 18, 8, 2, true, false); + rider_init_bone(&bosh, 19, 9, 2, true, false); + rider_init_bone(&bosh, 20, 5, 8, false, true); + rider_init_bone(&bosh, 21, 5, 9, false, true); + + rider_apply_start_offset(&bosh, x, y); + + return bosh; +} + +void rider_bone_satisfy_single(struct rider* bosh, uint8_t bone_idx) { + struct bone bone = bosh->bones[bone_idx]; + struct point* a = &bosh->points[bone.a]; + struct point* b = &bosh->points[bone.b]; + double x = a->x - b->x; + double y = a->y - b->y; + double dist = sqrt(x * x + y * y); + if (bone.repel && dist >= bone.restLength) return; + double effect = (dist - bone.restLength) / dist * 0.5; + if (bone.breakable) { + if (effect > endurance * bone.restLength * 0.5) { + bosh->dead = true; + return; + } + if (bosh->dead) return; + } + double xEffect = x * effect; + double yEffect = y * effect; + a->x -= xEffect; + a->y -= yEffect; + b->x += xEffect; + b->y += yEffect; +} + +void rider_bone_satisfy_all(struct rider* bosh) { + for (uint8_t i = 0; i < BONE_COUNT; i++) { + rider_bone_satisfy_single(bosh, i); + } +} + +void rider_apply_momentum(struct rider* bosh) { + for (uint8_t i = 0; i < POINT_COUNT; i++) { + point_apply_momentum(&bosh->points[i]); + } +} + +void rider_fakie_check(struct rider* bosh) { + double along_sled_x = bosh->points[3].x - bosh->points[0].x; + double along_sled_y = bosh->points[3].y - bosh->points[0].y; + if (along_sled_x * (bosh->points[1].y - bosh->points[0].y) - along_sled_y * (bosh->points[1].x - bosh->points[0].x) < 0) { + bosh->dead = true; + bosh->sledbroken = true; + } + if (along_sled_x * (bosh->points[5].y - bosh->points[4].y) - along_sled_y * (bosh->points[5].x - bosh->points[4].x) > 0) { + bosh->dead = true; + } +} + +// # simulation function implementations + +struct simulation simulation_new(void) { + struct simulation sim = { + .grid = grid_new(), + .bosh = rider_new(0, 0), + }; + + return sim; +} + +void simulation_collide_single_point_and_grid_cell(struct point* point, struct grid_bucket* cell) { + struct grid_cell_entry* current = cell->entry; + while (current != NULL) { + line_collide(*current->line, point); + current = current->next; + } +} + +void simulation_collide_all(struct simulation* simulation) { + for (uint8_t i = 0; i < POINT_COUNT; i++) { + struct point* point = &simulation->bosh.points[i]; + struct grid_coordinate base_coords = grid_pos_at(point->x, point->y).coord; + for (int64_t x = -1; x < 2; x++) { + for (int64_t y = -1; y < 2; y++) { + struct grid_coordinate cell_coords = base_coords; + cell_coords.x += x; + cell_coords.y += y; + struct grid_bucket* cell = grid_get_cell(simulation->grid, cell_coords); + simulation_collide_single_point_and_grid_cell(point, cell); + } + } + } +} + +void simulation_step_frame(struct simulation* simulation) { + rider_apply_momentum(&simulation->bosh); + for (uint8_t i = 0; i < ITERATION_COUNT; i++) { + rider_bone_satisfy_all(&simulation->bosh); + simulation_collide_all(simulation); + } + rider_fakie_check(&simulation->bosh); +} + +void simulation_prepare_line_capacity(struct simulation* simulation, size_t capacity) { + simulation->lines = realloc(simulation->lines, sizeof(struct line) * capacity); +} + +void simulation_add_line(struct simulation* simulation, struct line line) { + line_calculate_values(&line); + simulation->lines[simulation->line_count] = line; + // TODO 61 & 60 + grid_register_62(simulation->grid, &simulation->lines[simulation->line_count]); + simulation->line_count++; +} + +#endif diff --git a/raylib_frontend.c b/raylib_frontend.c new file mode 100644 index 0000000..4f1e6bf --- /dev/null +++ b/raylib_frontend.c @@ -0,0 +1,64 @@ +#define LREF_H_IMPLEMENTATION +#include "lref.h" +#include "track_wrapper/track_wrapper.h" + +#include + +int main(int argc, char** argv) { + if (argc < 3) return EXIT_FAILURE; + uint32_t index = atoi(argv[1]); + struct simulation sim = simulation_new(); + load_sol_track(&sim, argv[2], index); + bool playing = false; + + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "lref test frontend"); + + Camera2D camera = { 0 }; + camera.offset = (Vector2){screenWidth/2.0f, screenHeight/2.0f}; + camera.rotation = 0.0f; + camera.zoom = 4.0f; + + SetTargetFPS(40); + + while (!WindowShouldClose()) { + Vector2 camera_target = {0}; + for (int i = 0; i < POINT_COUNT; i++) { + camera_target.x += sim.bosh.points[i].x; + camera_target.y += sim.bosh.points[i].y; + } + camera_target.x /= POINT_COUNT; + camera_target.y /= POINT_COUNT; + camera.target = camera_target; + if (IsKeyPressed(KEY_SPACE)) { + playing = !playing; + } + BeginDrawing(); + ClearBackground(WHITE); + BeginMode2D(camera); + {// draw bosh + for (int i = 0; i < BONE_COUNT; i++) { + struct bone bone = sim.bosh.bones[i]; + struct point A = sim.bosh.points[bone.a]; + struct point B = sim.bosh.points[bone.b]; + DrawLineV((Vector2){A.x, A.y}, (Vector2){B.x, B.y}, BLACK); + } + } + {// draw lines + for (size_t i = 0; i < sim.line_count; i++) { + struct line line = sim.lines[i]; + DrawLineV((Vector2){line.x1, line.y1}, (Vector2){line.x2, line.y2}, BLACK); + } + } + EndMode2D(); + EndDrawing(); + + if (playing || IsKeyPressed(KEY_RIGHT)) simulation_step_frame(&sim); + } + + CloseWindow(); + + return 0; +} diff --git a/track_wrapper/build.zig b/track_wrapper/build.zig new file mode 100644 index 0000000..39050e1 --- /dev/null +++ b/track_wrapper/build.zig @@ -0,0 +1,59 @@ +const std = @import("std"); + +// Although this function looks imperative, note that its job is to +// declaratively construct a build graph that will be executed by an external +// runner. +pub fn build(b: *std.Build) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + + // Standard optimization options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not + // set a preferred release mode, allowing the user to decide how to optimize. + const optimize = b.standardOptimizeOption(.{}); + + // This creates a "module", which represents a collection of source files alongside + // some compilation options, such as optimization mode and linked system libraries. + // Every executable or library we compile will be based on one or more modules. + const lib_mod = b.createModule(.{ + // `root_source_file` is the Zig "entry point" of the module. If a module + // only contains e.g. external object files, you can make this `null`. + // In this case the main source file is merely a path, however, in more + // complicated build scripts, this could be a generated file. + .root_source_file = b.path("src/root.zig"), + .target = target, + .optimize = optimize, + .pic = true, + }); + + // Now, we will create a static library based on the module we created above. + // This creates a `std.Build.Step.Compile`, which is the build step responsible + // for actually invoking the compiler. + const lib = b.addLibrary(.{ + .linkage = .static, + .name = "track_wrapper", + .root_module = lib_mod, + }); + + // This declares intent for the library to be installed into the standard + // location when the user invokes the "install" step (the default step when + // running `zig build`). + b.installArtifact(lib); + + // Creates a step for unit testing. This only builds the test executable + // but does not run it. + const lib_unit_tests = b.addTest(.{ + .root_module = lib_mod, + }); + + const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); + + // Similar to creating the run step earlier, this exposes a `test` step to + // the `zig build --help` menu, providing a way for the user to request + // running the unit tests. + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&run_lib_unit_tests.step); +} diff --git a/track_wrapper/build.zig.zon b/track_wrapper/build.zig.zon new file mode 100644 index 0000000..92bea58 --- /dev/null +++ b/track_wrapper/build.zig.zon @@ -0,0 +1,47 @@ +.{ + // This is the default name used by packages depending on this one. For + // example, when a user runs `zig fetch --save `, this field is used + // as the key in the `dependencies` table. Although the user can choose a + // different name, most users will stick with this provided value. + // + // It is redundant to include "zig" in this name because it is already + // within the Zig package namespace. + .name = .track_wrapper, + + // This is a [Semantic Version](https://semver.org/). + // In a future version of Zig it will be used for package deduplication. + .version = "0.0.0", + + // Together with name, this represents a globally unique package + // identifier. This field is generated by the Zig toolchain when the + // package is first created, and then *never changes*. This allows + // unambiguous detection of one package being an updated version of + // another. + // + // When forking a Zig project, this id should be regenerated (delete the + // field and run `zig build`) if the upstream project is still maintained. + // Otherwise, the fork is *hostile*, attempting to take control over the + // original project's identity. Thus it is recommended to leave the comment + // on the following line intact, so that it shows up in code reviews that + // modify the field. + .fingerprint = 0x16ca1ccf830cc3bc, // Changing this has security and trust implications. + + // Tracks the earliest Zig version that the package considers to be a + // supported use case. + .minimum_zig_version = "0.14.1", + + // This field is optional. + // Each dependency must either provide a `url` and `hash`, or a `path`. + // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. + // Once all dependencies are fetched, `zig build` no longer requires + // internet connectivity. + .dependencies = .{}, + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + // For example... + //"LICENSE", + //"README.md", + }, +} diff --git a/track_wrapper/src/amf0.zig b/track_wrapper/src/amf0.zig new file mode 100644 index 0000000..353c0e5 --- /dev/null +++ b/track_wrapper/src/amf0.zig @@ -0,0 +1,184 @@ +const std = @import("std"); + +pub const Type = AmfType; +pub const AmfType = enum(u8) { + Number = 0, + Bool = 1, + String = 2, + Object = 3, + // MovieClip = 4, + Null = 5, + Undefined = 6, + // Reference = 7, + Array = 8, + ObjectEnd = 9, + // StrictArray = 10, + // Date = 11, + // LongString = 12, + // Unsupported = 13, + // RecordSet = 14, + // Xml = 15, + // TypedObject = 16, + + pub fn zigTypeOfValue(t: AmfType) type { + return switch (t) { + .Number => f64, + .Bool => bool, + .String => []u8, + .Object => std.StringHashMap(AmfValue), + .Null, .Undefined, .ObjectEnd => void, + .Array => std.ArrayList(AmfValue), + }; + } +}; + +pub const Number = AmfType.zigTypeOfValue(.Number); +pub const Bool = AmfType.zigTypeOfValue(.Bool); +pub const String = AmfType.zigTypeOfValue(.String); +pub const Object = AmfType.zigTypeOfValue(.Object); +pub const Array = AmfType.zigTypeOfValue(.Array); + +pub const Value = AmfValue; +pub const AmfValue = struct { + amf_type: AmfType, + data: *anyopaque, + name: []u8, + alloc: std.mem.Allocator, + + pub fn expectAs(self: AmfValue, comptime t: AmfType) !AmfType.zigTypeOfValue(t) { + if (self.amf_type != t) return error.TypeMismatch; + return @as(*AmfType.zigTypeOfValue(t), @ptrCast(@alignCast(self.data))).*; + } + + pub fn deinit(self: *@This()) void { + switch (self.amf_type) { + .Object => { + var obj: *Object = @ptrCast(@alignCast(self.data)); + var iter = obj.valueIterator(); + while (iter.next()) |field_amf| { + deinit(field_amf); + } + }, + .Array => { + const arr: *Array = @ptrCast(@alignCast(self.data)); + for (arr.items) |*item_amf| { + deinit(item_amf); + } + }, + .String => { + const contents: *[]u8 = @as(*[]u8, @ptrCast(@alignCast(self.data))); + self.alloc.free(contents.*); + }, + .Bool => { + self.alloc.destroy(@as(*bool, @ptrCast(self.data))); + }, + .Number => { + self.alloc.destroy(@as(*f64, @ptrCast(@alignCast(self.data)))); + }, + else => {}, + } + self.alloc.free(self.name); + } + + //pub fn readObjectFields(alloc: std.mem.Allocator, reader: anytype, object: *AmfValue) !void { + // if (object.amf_type != .Object) return error.PassedNonObject; + // const fields: *Object = @ptrCast(@alignCast(object.data)); + // while (true) { + // const val = try read(alloc, reader, false); + // if (val.amf_type == .ObjectEnd) break; + // try fields.put(val.name, val); + // } + //} + + //pub fn readArrayItems(alloc: std.mem.Allocator, reader: anytype, array: *AmfValue) !void { + // if (array.amf_type != .Array) return error.PassedNonArray; + // const items: *Array = @ptrCast(array.data); + // while (true) { + // const val = try read(alloc, reader, false); + // if (val.amf_type == .ObjectEnd) break; + // try items.append(alloc, val); + // } + //} + + pub fn read(alloc: std.mem.Allocator, reader: anytype) !AmfValue { + const name: []u8 = try alloc.alloc(u8, std.math.cast(usize, try reader.readInt(i16, .big)) orelse return error.CastError); + _ = try reader.readAll(name); + const amf_t = std.meta.intToEnum(AmfType, reader.readInt(u8, .big) catch return error.DoneReading) catch return error.UnimplementedAmfType; + + var result = AmfValue{ .name = name, .amf_type = amf_t, .alloc = alloc, .data = undefined }; + switch (amf_t) { + .Number => { + const ptr = try alloc.create(Number); + ptr.* = @bitCast(try reader.readInt(u64, .big)); + result.data = @ptrCast(ptr); + }, + .Bool => { + const ptr = try alloc.create(Bool); + ptr.* = try reader.readByte() != 0; + result.data = @ptrCast(ptr); + }, + .String => { + const len = try reader.readInt(i16, .big); + const ptr = try alloc.create(String); + ptr.* = try alloc.alloc(u8, std.math.cast(usize, len) orelse return error.CastError); + _ = try reader.readAll(ptr.*); + result.data = @ptrCast(ptr); + }, + .Object => { + const ptr = try alloc.create(Object); + ptr.* = Object.init(alloc); + result.data = @ptrCast(ptr); + //try readObjectFields(alloc, reader, &result); + const fields: *Object = ptr; + while (true) { + const val = try read(alloc, reader); + if (val.amf_type == .ObjectEnd) break; + try fields.put(val.name, val); + } + }, + .Null, .Undefined, .ObjectEnd => {}, + .Array => { + const ptr = try alloc.create(Array); + const len = try reader.readInt(i32, .big); + ptr.* = try Array.initCapacity(alloc, std.math.cast(usize, len) orelse return error.CastError); + result.data = @ptrCast(ptr); + //try readArrayItems(alloc, reader, result); + const items: *Array = ptr; + while (true) { + const val = try read(alloc, reader); + if (val.amf_type == .ObjectEnd) break; + try items.append(val); + } + }, + } + return result; + } + + pub fn getProperty(self: AmfValue, name: []const u8) !AmfValue { + if (self.amf_type != .Object) return error.PassedNonObject; + const fields: *Object = @ptrCast(@alignCast(self.data)); + const prop: AmfValue = fields.get(name) orelse return error.NonexistantProperty; + return prop; + } + + pub fn getPropertyExpectType(self: AmfValue, name: []const u8, comptime expected_type: AmfType) !AmfType.zigTypeOfValue(expected_type) { + const prop = try self.getProperty(name); + if (prop.amf_type != expected_type) return error.TypeMismatch; + const ptr: *AmfType.zigTypeOfValue(expected_type) = @ptrCast(@alignCast(prop.data)); + return ptr.*; + } + + pub fn getItem(self: AmfValue, index: usize) !AmfValue { + if (self.amf_type != .Array) return error.PassedNonArray; + const arr: *Array = @ptrCast(@alignCast(self.data)); + if (index >= arr.items.len) return error.OutOfBounds; + return arr.items[index]; + } + + pub fn getItemExpectType(self: AmfValue, index: usize, comptime expected_type: AmfType) !AmfType.zigTypeOfValue(expected_type) { + const item = try self.getItem(index); + if (item.amf_type != expected_type) return error.TypeMismatch; + const ptr: *AmfType.zigTypeOfValue(expected_type) = @ptrCast(@alignCast(item.data)); + return ptr.*; + } +}; diff --git a/track_wrapper/src/include.zig b/track_wrapper/src/include.zig new file mode 100644 index 0000000..e19a702 --- /dev/null +++ b/track_wrapper/src/include.zig @@ -0,0 +1,1128 @@ +pub const __builtin_bswap16 = @import("std").zig.c_builtins.__builtin_bswap16; +pub const __builtin_bswap32 = @import("std").zig.c_builtins.__builtin_bswap32; +pub const __builtin_bswap64 = @import("std").zig.c_builtins.__builtin_bswap64; +pub const __builtin_signbit = @import("std").zig.c_builtins.__builtin_signbit; +pub const __builtin_signbitf = @import("std").zig.c_builtins.__builtin_signbitf; +pub const __builtin_popcount = @import("std").zig.c_builtins.__builtin_popcount; +pub const __builtin_ctz = @import("std").zig.c_builtins.__builtin_ctz; +pub const __builtin_clz = @import("std").zig.c_builtins.__builtin_clz; +pub const __builtin_sqrt = @import("std").zig.c_builtins.__builtin_sqrt; +pub const __builtin_sqrtf = @import("std").zig.c_builtins.__builtin_sqrtf; +pub const __builtin_sin = @import("std").zig.c_builtins.__builtin_sin; +pub const __builtin_sinf = @import("std").zig.c_builtins.__builtin_sinf; +pub const __builtin_cos = @import("std").zig.c_builtins.__builtin_cos; +pub const __builtin_cosf = @import("std").zig.c_builtins.__builtin_cosf; +pub const __builtin_exp = @import("std").zig.c_builtins.__builtin_exp; +pub const __builtin_expf = @import("std").zig.c_builtins.__builtin_expf; +pub const __builtin_exp2 = @import("std").zig.c_builtins.__builtin_exp2; +pub const __builtin_exp2f = @import("std").zig.c_builtins.__builtin_exp2f; +pub const __builtin_log = @import("std").zig.c_builtins.__builtin_log; +pub const __builtin_logf = @import("std").zig.c_builtins.__builtin_logf; +pub const __builtin_log2 = @import("std").zig.c_builtins.__builtin_log2; +pub const __builtin_log2f = @import("std").zig.c_builtins.__builtin_log2f; +pub const __builtin_log10 = @import("std").zig.c_builtins.__builtin_log10; +pub const __builtin_log10f = @import("std").zig.c_builtins.__builtin_log10f; +pub const __builtin_abs = @import("std").zig.c_builtins.__builtin_abs; +pub const __builtin_labs = @import("std").zig.c_builtins.__builtin_labs; +pub const __builtin_llabs = @import("std").zig.c_builtins.__builtin_llabs; +pub const __builtin_fabs = @import("std").zig.c_builtins.__builtin_fabs; +pub const __builtin_fabsf = @import("std").zig.c_builtins.__builtin_fabsf; +pub const __builtin_floor = @import("std").zig.c_builtins.__builtin_floor; +pub const __builtin_floorf = @import("std").zig.c_builtins.__builtin_floorf; +pub const __builtin_ceil = @import("std").zig.c_builtins.__builtin_ceil; +pub const __builtin_ceilf = @import("std").zig.c_builtins.__builtin_ceilf; +pub const __builtin_trunc = @import("std").zig.c_builtins.__builtin_trunc; +pub const __builtin_truncf = @import("std").zig.c_builtins.__builtin_truncf; +pub const __builtin_round = @import("std").zig.c_builtins.__builtin_round; +pub const __builtin_roundf = @import("std").zig.c_builtins.__builtin_roundf; +pub const __builtin_strlen = @import("std").zig.c_builtins.__builtin_strlen; +pub const __builtin_strcmp = @import("std").zig.c_builtins.__builtin_strcmp; +pub const __builtin_object_size = @import("std").zig.c_builtins.__builtin_object_size; +pub const __builtin___memset_chk = @import("std").zig.c_builtins.__builtin___memset_chk; +pub const __builtin_memset = @import("std").zig.c_builtins.__builtin_memset; +pub const __builtin___memcpy_chk = @import("std").zig.c_builtins.__builtin___memcpy_chk; +pub const __builtin_memcpy = @import("std").zig.c_builtins.__builtin_memcpy; +pub const __builtin_expect = @import("std").zig.c_builtins.__builtin_expect; +pub const __builtin_nanf = @import("std").zig.c_builtins.__builtin_nanf; +pub const __builtin_huge_valf = @import("std").zig.c_builtins.__builtin_huge_valf; +pub const __builtin_inff = @import("std").zig.c_builtins.__builtin_inff; +pub const __builtin_isnan = @import("std").zig.c_builtins.__builtin_isnan; +pub const __builtin_isinf = @import("std").zig.c_builtins.__builtin_isinf; +pub const __builtin_isinf_sign = @import("std").zig.c_builtins.__builtin_isinf_sign; +pub const __has_builtin = @import("std").zig.c_builtins.__has_builtin; +pub const __builtin_assume = @import("std").zig.c_builtins.__builtin_assume; +pub const __builtin_unreachable = @import("std").zig.c_builtins.__builtin_unreachable; +pub const __builtin_constant_p = @import("std").zig.c_builtins.__builtin_constant_p; +pub const __builtin_mul_overflow = @import("std").zig.c_builtins.__builtin_mul_overflow; +pub const __u_char = u8; +pub const __u_short = c_ushort; +pub const __u_int = c_uint; +pub const __u_long = c_ulong; +pub const __int8_t = i8; +pub const __uint8_t = u8; +pub const __int16_t = c_short; +pub const __uint16_t = c_ushort; +pub const __int32_t = c_int; +pub const __uint32_t = c_uint; +pub const __int64_t = c_long; +pub const __uint64_t = c_ulong; +pub const __int_least8_t = __int8_t; +pub const __uint_least8_t = __uint8_t; +pub const __int_least16_t = __int16_t; +pub const __uint_least16_t = __uint16_t; +pub const __int_least32_t = __int32_t; +pub const __uint_least32_t = __uint32_t; +pub const __int_least64_t = __int64_t; +pub const __uint_least64_t = __uint64_t; +pub const __quad_t = c_long; +pub const __u_quad_t = c_ulong; +pub const __intmax_t = c_long; +pub const __uintmax_t = c_ulong; +pub const __dev_t = c_ulong; +pub const __uid_t = c_uint; +pub const __gid_t = c_uint; +pub const __ino_t = c_ulong; +pub const __ino64_t = c_ulong; +pub const __mode_t = c_uint; +pub const __nlink_t = c_ulong; +pub const __off_t = c_long; +pub const __off64_t = c_long; +pub const __pid_t = c_int; +pub const __fsid_t = extern struct { + __val: [2]c_int = @import("std").mem.zeroes([2]c_int), +}; +pub const __clock_t = c_long; +pub const __rlim_t = c_ulong; +pub const __rlim64_t = c_ulong; +pub const __id_t = c_uint; +pub const __time_t = c_long; +pub const __useconds_t = c_uint; +pub const __suseconds_t = c_long; +pub const __suseconds64_t = c_long; +pub const __daddr_t = c_int; +pub const __key_t = c_int; +pub const __clockid_t = c_int; +pub const __timer_t = ?*anyopaque; +pub const __blksize_t = c_long; +pub const __blkcnt_t = c_long; +pub const __blkcnt64_t = c_long; +pub const __fsblkcnt_t = c_ulong; +pub const __fsblkcnt64_t = c_ulong; +pub const __fsfilcnt_t = c_ulong; +pub const __fsfilcnt64_t = c_ulong; +pub const __fsword_t = c_long; +pub const __ssize_t = c_long; +pub const __syscall_slong_t = c_long; +pub const __syscall_ulong_t = c_ulong; +pub const __loff_t = __off64_t; +pub const __caddr_t = [*c]u8; +pub const __intptr_t = c_long; +pub const __socklen_t = c_uint; +pub const __sig_atomic_t = c_int; +pub const int_least8_t = __int_least8_t; +pub const int_least16_t = __int_least16_t; +pub const int_least32_t = __int_least32_t; +pub const int_least64_t = __int_least64_t; +pub const uint_least8_t = __uint_least8_t; +pub const uint_least16_t = __uint_least16_t; +pub const uint_least32_t = __uint_least32_t; +pub const uint_least64_t = __uint_least64_t; +pub const int_fast8_t = i8; +pub const int_fast16_t = c_long; +pub const int_fast32_t = c_long; +pub const int_fast64_t = c_long; +pub const uint_fast8_t = u8; +pub const uint_fast16_t = c_ulong; +pub const uint_fast32_t = c_ulong; +pub const uint_fast64_t = c_ulong; +pub const intmax_t = __intmax_t; +pub const uintmax_t = __uintmax_t; +pub const ptrdiff_t = c_long; +pub const wchar_t = c_int; +pub const max_align_t = extern struct { + __clang_max_align_nonce1: c_longlong align(8) = @import("std").mem.zeroes(c_longlong), + __clang_max_align_nonce2: c_longdouble align(16) = @import("std").mem.zeroes(c_longdouble), +}; +//pub export const endurance: f64 = 0.057; +//pub export const gravity: f64 = 0.175; +pub const struct_point = extern struct { + x: f64 = @import("std").mem.zeroes(f64), + y: f64 = @import("std").mem.zeroes(f64), + previous_x: f64 = @import("std").mem.zeroes(f64), + previous_y: f64 = @import("std").mem.zeroes(f64), + momentum_x: f64 = @import("std").mem.zeroes(f64), + momentum_y: f64 = @import("std").mem.zeroes(f64), + friction: f64 = @import("std").mem.zeroes(f64), +}; +pub const struct_bone = extern struct { + breakable: bool = @import("std").mem.zeroes(bool), + repel: bool = @import("std").mem.zeroes(bool), + a: u8 = @import("std").mem.zeroes(u8), + b: u8 = @import("std").mem.zeroes(u8), + restLength: f64 = @import("std").mem.zeroes(f64), +}; +pub const struct_rider = extern struct { + points: [10]struct_point = @import("std").mem.zeroes([10]struct_point), + bones: [22]struct_bone = @import("std").mem.zeroes([22]struct_bone), + dead: bool = @import("std").mem.zeroes(bool), + sledbroken: bool = @import("std").mem.zeroes(bool), +}; +//pub export const ZONE: f64 = 10; +//pub export const ACC: f64 = 0.1; +pub const struct_line_flags = extern struct { + red: bool = @import("std").mem.zeroes(bool), + invert: bool = @import("std").mem.zeroes(bool), + left_extended: bool = @import("std").mem.zeroes(bool), + right_extended: bool = @import("std").mem.zeroes(bool), +}; +pub const struct_line_values = extern struct { + dx: f64 = @import("std").mem.zeroes(f64), + dy: f64 = @import("std").mem.zeroes(f64), + invSqrDst: f64 = @import("std").mem.zeroes(f64), + nx: f64 = @import("std").mem.zeroes(f64), + ny: f64 = @import("std").mem.zeroes(f64), + lim1: f64 = @import("std").mem.zeroes(f64), + lim2: f64 = @import("std").mem.zeroes(f64), + accx: f64 = @import("std").mem.zeroes(f64), + accy: f64 = @import("std").mem.zeroes(f64), +}; +pub const struct_line = extern struct { + id: i32 = @import("std").mem.zeroes(i32), + x1: f64 = @import("std").mem.zeroes(f64), + y1: f64 = @import("std").mem.zeroes(f64), + x2: f64 = @import("std").mem.zeroes(f64), + y2: f64 = @import("std").mem.zeroes(f64), + flags: struct_line_flags = @import("std").mem.zeroes(struct_line_flags), + values: struct_line_values = @import("std").mem.zeroes(struct_line_values), +}; +//pub export const GRID_62: u8 = 0; +//pub export const GRID_61: u8 = 1; +//pub export const GRID_60: u8 = 2; +//pub export const GRIDSIZE: f64 = 14; +pub const struct_grid_coordinate = extern struct { + x: i64 = @import("std").mem.zeroes(i64), + y: i64 = @import("std").mem.zeroes(i64), +}; +pub const struct_grid_cell_entry = extern struct { + line: [*c]struct_line = @import("std").mem.zeroes([*c]struct_line), + next: [*c]struct_grid_cell_entry = @import("std").mem.zeroes([*c]struct_grid_cell_entry), +}; +pub const struct_grid_bucket = extern struct { + key: struct_grid_coordinate = @import("std").mem.zeroes(struct_grid_coordinate), + entry: [*c]struct_grid_cell_entry = @import("std").mem.zeroes([*c]struct_grid_cell_entry), + next: [*c]struct_grid_bucket = @import("std").mem.zeroes([*c]struct_grid_bucket), +}; +pub const struct_grid = extern struct { + buckets: [*c][*c]struct_grid_bucket = @import("std").mem.zeroes([*c][*c]struct_grid_bucket), + capacity: usize = @import("std").mem.zeroes(usize), + cells_total: usize = @import("std").mem.zeroes(usize), +}; +pub const struct_grid_pos = extern struct { + coord: struct_grid_coordinate = @import("std").mem.zeroes(struct_grid_coordinate), + rx: f64 = @import("std").mem.zeroes(f64), + ry: f64 = @import("std").mem.zeroes(f64), +}; +pub const struct_simulation = extern struct { + start_x: f64 = @import("std").mem.zeroes(f64), + start_y: f64 = @import("std").mem.zeroes(f64), + grid: [*c]struct_grid = @import("std").mem.zeroes([*c]struct_grid), + lines: [*c]struct_line = @import("std").mem.zeroes([*c]struct_line), + line_count: usize = @import("std").mem.zeroes(usize), + bosh: struct_rider = @import("std").mem.zeroes(struct_rider), +}; +pub extern fn line_calculate_values(line: [*c]struct_line) void; +pub extern fn line_collide(line: struct_line, point: [*c]struct_point) void; +pub extern fn grid_new() [*c]struct_grid; +pub extern fn grid_free(grid: [*c]struct_grid) void; +pub extern fn grid_register_62(grid: [*c]struct_grid, line: [*c]struct_line) void; +pub extern fn grid_register_61(grid: [*c]struct_grid, line: [*c]struct_line) void; +pub extern fn grid_register_60(grid: [*c]struct_grid, line: [*c]struct_line) void; +pub extern fn grid_coordinate_at(x: f64, y: f64) struct_grid_coordinate; +pub extern fn grid_pos_at(x: f64, y: f64) struct_grid_pos; +pub extern fn rider_new(x: f64, y: f64) struct_rider; +pub extern fn simulation_new() struct_simulation; +pub extern fn simulation_prepare_line_capacity(simulation: [*c]struct_simulation, capacity: usize) void; +pub extern fn simulation_add_line(simulation: [*c]struct_simulation, line: struct_line) void; +//pub extern fn load_sol_track(sim: [*c]struct_simulation, filename: [*c]u8, index: u32) void; +pub const __llvm__ = @as(c_int, 1); +pub const __clang__ = @as(c_int, 1); +pub const __clang_major__ = @as(c_int, 19); +pub const __clang_minor__ = @as(c_int, 1); +pub const __clang_patchlevel__ = @as(c_int, 7); +pub const __clang_version__ = "19.1.7 (https://github.com/ziglang/zig-bootstrap de1b01a8c1dddf75a560123ac1c2ab182b4830da)"; +pub const __GNUC__ = @as(c_int, 4); +pub const __GNUC_MINOR__ = @as(c_int, 2); +pub const __GNUC_PATCHLEVEL__ = @as(c_int, 1); +pub const __GXX_ABI_VERSION = @as(c_int, 1002); +pub const __ATOMIC_RELAXED = @as(c_int, 0); +pub const __ATOMIC_CONSUME = @as(c_int, 1); +pub const __ATOMIC_ACQUIRE = @as(c_int, 2); +pub const __ATOMIC_RELEASE = @as(c_int, 3); +pub const __ATOMIC_ACQ_REL = @as(c_int, 4); +pub const __ATOMIC_SEQ_CST = @as(c_int, 5); +pub const __MEMORY_SCOPE_SYSTEM = @as(c_int, 0); +pub const __MEMORY_SCOPE_DEVICE = @as(c_int, 1); +pub const __MEMORY_SCOPE_WRKGRP = @as(c_int, 2); +pub const __MEMORY_SCOPE_WVFRNT = @as(c_int, 3); +pub const __MEMORY_SCOPE_SINGLE = @as(c_int, 4); +pub const __OPENCL_MEMORY_SCOPE_WORK_ITEM = @as(c_int, 0); +pub const __OPENCL_MEMORY_SCOPE_WORK_GROUP = @as(c_int, 1); +pub const __OPENCL_MEMORY_SCOPE_DEVICE = @as(c_int, 2); +pub const __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES = @as(c_int, 3); +pub const __OPENCL_MEMORY_SCOPE_SUB_GROUP = @as(c_int, 4); +pub const __FPCLASS_SNAN = @as(c_int, 0x0001); +pub const __FPCLASS_QNAN = @as(c_int, 0x0002); +pub const __FPCLASS_NEGINF = @as(c_int, 0x0004); +pub const __FPCLASS_NEGNORMAL = @as(c_int, 0x0008); +pub const __FPCLASS_NEGSUBNORMAL = @as(c_int, 0x0010); +pub const __FPCLASS_NEGZERO = @as(c_int, 0x0020); +pub const __FPCLASS_POSZERO = @as(c_int, 0x0040); +pub const __FPCLASS_POSSUBNORMAL = @as(c_int, 0x0080); +pub const __FPCLASS_POSNORMAL = @as(c_int, 0x0100); +pub const __FPCLASS_POSINF = @as(c_int, 0x0200); +pub const __PRAGMA_REDEFINE_EXTNAME = @as(c_int, 1); +pub const __VERSION__ = "Clang 19.1.7 (https://github.com/ziglang/zig-bootstrap de1b01a8c1dddf75a560123ac1c2ab182b4830da)"; +pub const __OBJC_BOOL_IS_BOOL = @as(c_int, 0); +pub const __CONSTANT_CFSTRINGS__ = @as(c_int, 1); +pub const __clang_literal_encoding__ = "UTF-8"; +pub const __clang_wide_literal_encoding__ = "UTF-32"; +pub const __ORDER_LITTLE_ENDIAN__ = @as(c_int, 1234); +pub const __ORDER_BIG_ENDIAN__ = @as(c_int, 4321); +pub const __ORDER_PDP_ENDIAN__ = @as(c_int, 3412); +pub const __BYTE_ORDER__ = __ORDER_LITTLE_ENDIAN__; +pub const __LITTLE_ENDIAN__ = @as(c_int, 1); +pub const _LP64 = @as(c_int, 1); +pub const __LP64__ = @as(c_int, 1); +pub const __CHAR_BIT__ = @as(c_int, 8); +pub const __BOOL_WIDTH__ = @as(c_int, 8); +pub const __SHRT_WIDTH__ = @as(c_int, 16); +pub const __INT_WIDTH__ = @as(c_int, 32); +pub const __LONG_WIDTH__ = @as(c_int, 64); +pub const __LLONG_WIDTH__ = @as(c_int, 64); +pub const __BITINT_MAXWIDTH__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 8388608, .decimal); +pub const __SCHAR_MAX__ = @as(c_int, 127); +pub const __SHRT_MAX__ = @as(c_int, 32767); +pub const __INT_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const __LONG_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const __LONG_LONG_MAX__ = @as(c_longlong, 9223372036854775807); +pub const __WCHAR_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const __WCHAR_WIDTH__ = @as(c_int, 32); +pub const __WINT_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_uint, 4294967295, .decimal); +pub const __WINT_WIDTH__ = @as(c_int, 32); +pub const __INTMAX_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const __INTMAX_WIDTH__ = @as(c_int, 64); +pub const __SIZE_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const __SIZE_WIDTH__ = @as(c_int, 64); +pub const __UINTMAX_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const __UINTMAX_WIDTH__ = @as(c_int, 64); +pub const __PTRDIFF_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const __PTRDIFF_WIDTH__ = @as(c_int, 64); +pub const __INTPTR_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const __INTPTR_WIDTH__ = @as(c_int, 64); +pub const __UINTPTR_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const __UINTPTR_WIDTH__ = @as(c_int, 64); +pub const __SIZEOF_DOUBLE__ = @as(c_int, 8); +pub const __SIZEOF_FLOAT__ = @as(c_int, 4); +pub const __SIZEOF_INT__ = @as(c_int, 4); +pub const __SIZEOF_LONG__ = @as(c_int, 8); +pub const __SIZEOF_LONG_DOUBLE__ = @as(c_int, 16); +pub const __SIZEOF_LONG_LONG__ = @as(c_int, 8); +pub const __SIZEOF_POINTER__ = @as(c_int, 8); +pub const __SIZEOF_SHORT__ = @as(c_int, 2); +pub const __SIZEOF_PTRDIFF_T__ = @as(c_int, 8); +pub const __SIZEOF_SIZE_T__ = @as(c_int, 8); +pub const __SIZEOF_WCHAR_T__ = @as(c_int, 4); +pub const __SIZEOF_WINT_T__ = @as(c_int, 4); +pub const __SIZEOF_INT128__ = @as(c_int, 16); +pub const __INTMAX_TYPE__ = c_long; +pub const __INTMAX_FMTd__ = "ld"; +pub const __INTMAX_FMTi__ = "li"; +pub const __INTMAX_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `L`"); +// (no file):95:9 +pub const __UINTMAX_TYPE__ = c_ulong; +pub const __UINTMAX_FMTo__ = "lo"; +pub const __UINTMAX_FMTu__ = "lu"; +pub const __UINTMAX_FMTx__ = "lx"; +pub const __UINTMAX_FMTX__ = "lX"; +pub const __UINTMAX_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `UL`"); +// (no file):101:9 +pub const __PTRDIFF_TYPE__ = c_long; +pub const __PTRDIFF_FMTd__ = "ld"; +pub const __PTRDIFF_FMTi__ = "li"; +pub const __INTPTR_TYPE__ = c_long; +pub const __INTPTR_FMTd__ = "ld"; +pub const __INTPTR_FMTi__ = "li"; +pub const __SIZE_TYPE__ = c_ulong; +pub const __SIZE_FMTo__ = "lo"; +pub const __SIZE_FMTu__ = "lu"; +pub const __SIZE_FMTx__ = "lx"; +pub const __SIZE_FMTX__ = "lX"; +pub const __WCHAR_TYPE__ = c_int; +pub const __WINT_TYPE__ = c_uint; +pub const __SIG_ATOMIC_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const __SIG_ATOMIC_WIDTH__ = @as(c_int, 32); +pub const __CHAR16_TYPE__ = c_ushort; +pub const __CHAR32_TYPE__ = c_uint; +pub const __UINTPTR_TYPE__ = c_ulong; +pub const __UINTPTR_FMTo__ = "lo"; +pub const __UINTPTR_FMTu__ = "lu"; +pub const __UINTPTR_FMTx__ = "lx"; +pub const __UINTPTR_FMTX__ = "lX"; +pub const __FLT16_DENORM_MIN__ = @as(f16, 5.9604644775390625e-8); +pub const __FLT16_NORM_MAX__ = @as(f16, 6.5504e+4); +pub const __FLT16_HAS_DENORM__ = @as(c_int, 1); +pub const __FLT16_DIG__ = @as(c_int, 3); +pub const __FLT16_DECIMAL_DIG__ = @as(c_int, 5); +pub const __FLT16_EPSILON__ = @as(f16, 9.765625e-4); +pub const __FLT16_HAS_INFINITY__ = @as(c_int, 1); +pub const __FLT16_HAS_QUIET_NAN__ = @as(c_int, 1); +pub const __FLT16_MANT_DIG__ = @as(c_int, 11); +pub const __FLT16_MAX_10_EXP__ = @as(c_int, 4); +pub const __FLT16_MAX_EXP__ = @as(c_int, 16); +pub const __FLT16_MAX__ = @as(f16, 6.5504e+4); +pub const __FLT16_MIN_10_EXP__ = -@as(c_int, 4); +pub const __FLT16_MIN_EXP__ = -@as(c_int, 13); +pub const __FLT16_MIN__ = @as(f16, 6.103515625e-5); +pub const __FLT_DENORM_MIN__ = @as(f32, 1.40129846e-45); +pub const __FLT_NORM_MAX__ = @as(f32, 3.40282347e+38); +pub const __FLT_HAS_DENORM__ = @as(c_int, 1); +pub const __FLT_DIG__ = @as(c_int, 6); +pub const __FLT_DECIMAL_DIG__ = @as(c_int, 9); +pub const __FLT_EPSILON__ = @as(f32, 1.19209290e-7); +pub const __FLT_HAS_INFINITY__ = @as(c_int, 1); +pub const __FLT_HAS_QUIET_NAN__ = @as(c_int, 1); +pub const __FLT_MANT_DIG__ = @as(c_int, 24); +pub const __FLT_MAX_10_EXP__ = @as(c_int, 38); +pub const __FLT_MAX_EXP__ = @as(c_int, 128); +pub const __FLT_MAX__ = @as(f32, 3.40282347e+38); +pub const __FLT_MIN_10_EXP__ = -@as(c_int, 37); +pub const __FLT_MIN_EXP__ = -@as(c_int, 125); +pub const __FLT_MIN__ = @as(f32, 1.17549435e-38); +pub const __DBL_DENORM_MIN__ = @as(f64, 4.9406564584124654e-324); +pub const __DBL_NORM_MAX__ = @as(f64, 1.7976931348623157e+308); +pub const __DBL_HAS_DENORM__ = @as(c_int, 1); +pub const __DBL_DIG__ = @as(c_int, 15); +pub const __DBL_DECIMAL_DIG__ = @as(c_int, 17); +pub const __DBL_EPSILON__ = @as(f64, 2.2204460492503131e-16); +pub const __DBL_HAS_INFINITY__ = @as(c_int, 1); +pub const __DBL_HAS_QUIET_NAN__ = @as(c_int, 1); +pub const __DBL_MANT_DIG__ = @as(c_int, 53); +pub const __DBL_MAX_10_EXP__ = @as(c_int, 308); +pub const __DBL_MAX_EXP__ = @as(c_int, 1024); +pub const __DBL_MAX__ = @as(f64, 1.7976931348623157e+308); +pub const __DBL_MIN_10_EXP__ = -@as(c_int, 307); +pub const __DBL_MIN_EXP__ = -@as(c_int, 1021); +pub const __DBL_MIN__ = @as(f64, 2.2250738585072014e-308); +pub const __LDBL_DENORM_MIN__ = @as(c_longdouble, 3.64519953188247460253e-4951); +pub const __LDBL_NORM_MAX__ = @as(c_longdouble, 1.18973149535723176502e+4932); +pub const __LDBL_HAS_DENORM__ = @as(c_int, 1); +pub const __LDBL_DIG__ = @as(c_int, 18); +pub const __LDBL_DECIMAL_DIG__ = @as(c_int, 21); +pub const __LDBL_EPSILON__ = @as(c_longdouble, 1.08420217248550443401e-19); +pub const __LDBL_HAS_INFINITY__ = @as(c_int, 1); +pub const __LDBL_HAS_QUIET_NAN__ = @as(c_int, 1); +pub const __LDBL_MANT_DIG__ = @as(c_int, 64); +pub const __LDBL_MAX_10_EXP__ = @as(c_int, 4932); +pub const __LDBL_MAX_EXP__ = @as(c_int, 16384); +pub const __LDBL_MAX__ = @as(c_longdouble, 1.18973149535723176502e+4932); +pub const __LDBL_MIN_10_EXP__ = -@as(c_int, 4931); +pub const __LDBL_MIN_EXP__ = -@as(c_int, 16381); +pub const __LDBL_MIN__ = @as(c_longdouble, 3.36210314311209350626e-4932); +pub const __POINTER_WIDTH__ = @as(c_int, 64); +pub const __BIGGEST_ALIGNMENT__ = @as(c_int, 16); +pub const __WINT_UNSIGNED__ = @as(c_int, 1); +pub const __INT8_TYPE__ = i8; +pub const __INT8_FMTd__ = "hhd"; +pub const __INT8_FMTi__ = "hhi"; +pub const __INT8_C_SUFFIX__ = ""; +pub const __INT16_TYPE__ = c_short; +pub const __INT16_FMTd__ = "hd"; +pub const __INT16_FMTi__ = "hi"; +pub const __INT16_C_SUFFIX__ = ""; +pub const __INT32_TYPE__ = c_int; +pub const __INT32_FMTd__ = "d"; +pub const __INT32_FMTi__ = "i"; +pub const __INT32_C_SUFFIX__ = ""; +pub const __INT64_TYPE__ = c_long; +pub const __INT64_FMTd__ = "ld"; +pub const __INT64_FMTi__ = "li"; +pub const __INT64_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `L`"); +// (no file):202:9 +pub const __UINT8_TYPE__ = u8; +pub const __UINT8_FMTo__ = "hho"; +pub const __UINT8_FMTu__ = "hhu"; +pub const __UINT8_FMTx__ = "hhx"; +pub const __UINT8_FMTX__ = "hhX"; +pub const __UINT8_C_SUFFIX__ = ""; +pub const __UINT8_MAX__ = @as(c_int, 255); +pub const __INT8_MAX__ = @as(c_int, 127); +pub const __UINT16_TYPE__ = c_ushort; +pub const __UINT16_FMTo__ = "ho"; +pub const __UINT16_FMTu__ = "hu"; +pub const __UINT16_FMTx__ = "hx"; +pub const __UINT16_FMTX__ = "hX"; +pub const __UINT16_C_SUFFIX__ = ""; +pub const __UINT16_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 65535, .decimal); +pub const __INT16_MAX__ = @as(c_int, 32767); +pub const __UINT32_TYPE__ = c_uint; +pub const __UINT32_FMTo__ = "o"; +pub const __UINT32_FMTu__ = "u"; +pub const __UINT32_FMTx__ = "x"; +pub const __UINT32_FMTX__ = "X"; +pub const __UINT32_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `U`"); +// (no file):224:9 +pub const __UINT32_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_uint, 4294967295, .decimal); +pub const __INT32_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const __UINT64_TYPE__ = c_ulong; +pub const __UINT64_FMTo__ = "lo"; +pub const __UINT64_FMTu__ = "lu"; +pub const __UINT64_FMTx__ = "lx"; +pub const __UINT64_FMTX__ = "lX"; +pub const __UINT64_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `UL`"); +// (no file):232:9 +pub const __UINT64_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const __INT64_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const __INT_LEAST8_TYPE__ = i8; +pub const __INT_LEAST8_MAX__ = @as(c_int, 127); +pub const __INT_LEAST8_WIDTH__ = @as(c_int, 8); +pub const __INT_LEAST8_FMTd__ = "hhd"; +pub const __INT_LEAST8_FMTi__ = "hhi"; +pub const __UINT_LEAST8_TYPE__ = u8; +pub const __UINT_LEAST8_MAX__ = @as(c_int, 255); +pub const __UINT_LEAST8_FMTo__ = "hho"; +pub const __UINT_LEAST8_FMTu__ = "hhu"; +pub const __UINT_LEAST8_FMTx__ = "hhx"; +pub const __UINT_LEAST8_FMTX__ = "hhX"; +pub const __INT_LEAST16_TYPE__ = c_short; +pub const __INT_LEAST16_MAX__ = @as(c_int, 32767); +pub const __INT_LEAST16_WIDTH__ = @as(c_int, 16); +pub const __INT_LEAST16_FMTd__ = "hd"; +pub const __INT_LEAST16_FMTi__ = "hi"; +pub const __UINT_LEAST16_TYPE__ = c_ushort; +pub const __UINT_LEAST16_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 65535, .decimal); +pub const __UINT_LEAST16_FMTo__ = "ho"; +pub const __UINT_LEAST16_FMTu__ = "hu"; +pub const __UINT_LEAST16_FMTx__ = "hx"; +pub const __UINT_LEAST16_FMTX__ = "hX"; +pub const __INT_LEAST32_TYPE__ = c_int; +pub const __INT_LEAST32_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const __INT_LEAST32_WIDTH__ = @as(c_int, 32); +pub const __INT_LEAST32_FMTd__ = "d"; +pub const __INT_LEAST32_FMTi__ = "i"; +pub const __UINT_LEAST32_TYPE__ = c_uint; +pub const __UINT_LEAST32_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_uint, 4294967295, .decimal); +pub const __UINT_LEAST32_FMTo__ = "o"; +pub const __UINT_LEAST32_FMTu__ = "u"; +pub const __UINT_LEAST32_FMTx__ = "x"; +pub const __UINT_LEAST32_FMTX__ = "X"; +pub const __INT_LEAST64_TYPE__ = c_long; +pub const __INT_LEAST64_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const __INT_LEAST64_WIDTH__ = @as(c_int, 64); +pub const __INT_LEAST64_FMTd__ = "ld"; +pub const __INT_LEAST64_FMTi__ = "li"; +pub const __UINT_LEAST64_TYPE__ = c_ulong; +pub const __UINT_LEAST64_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const __UINT_LEAST64_FMTo__ = "lo"; +pub const __UINT_LEAST64_FMTu__ = "lu"; +pub const __UINT_LEAST64_FMTx__ = "lx"; +pub const __UINT_LEAST64_FMTX__ = "lX"; +pub const __INT_FAST8_TYPE__ = i8; +pub const __INT_FAST8_MAX__ = @as(c_int, 127); +pub const __INT_FAST8_WIDTH__ = @as(c_int, 8); +pub const __INT_FAST8_FMTd__ = "hhd"; +pub const __INT_FAST8_FMTi__ = "hhi"; +pub const __UINT_FAST8_TYPE__ = u8; +pub const __UINT_FAST8_MAX__ = @as(c_int, 255); +pub const __UINT_FAST8_FMTo__ = "hho"; +pub const __UINT_FAST8_FMTu__ = "hhu"; +pub const __UINT_FAST8_FMTx__ = "hhx"; +pub const __UINT_FAST8_FMTX__ = "hhX"; +pub const __INT_FAST16_TYPE__ = c_short; +pub const __INT_FAST16_MAX__ = @as(c_int, 32767); +pub const __INT_FAST16_WIDTH__ = @as(c_int, 16); +pub const __INT_FAST16_FMTd__ = "hd"; +pub const __INT_FAST16_FMTi__ = "hi"; +pub const __UINT_FAST16_TYPE__ = c_ushort; +pub const __UINT_FAST16_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 65535, .decimal); +pub const __UINT_FAST16_FMTo__ = "ho"; +pub const __UINT_FAST16_FMTu__ = "hu"; +pub const __UINT_FAST16_FMTx__ = "hx"; +pub const __UINT_FAST16_FMTX__ = "hX"; +pub const __INT_FAST32_TYPE__ = c_int; +pub const __INT_FAST32_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const __INT_FAST32_WIDTH__ = @as(c_int, 32); +pub const __INT_FAST32_FMTd__ = "d"; +pub const __INT_FAST32_FMTi__ = "i"; +pub const __UINT_FAST32_TYPE__ = c_uint; +pub const __UINT_FAST32_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_uint, 4294967295, .decimal); +pub const __UINT_FAST32_FMTo__ = "o"; +pub const __UINT_FAST32_FMTu__ = "u"; +pub const __UINT_FAST32_FMTx__ = "x"; +pub const __UINT_FAST32_FMTX__ = "X"; +pub const __INT_FAST64_TYPE__ = c_long; +pub const __INT_FAST64_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const __INT_FAST64_WIDTH__ = @as(c_int, 64); +pub const __INT_FAST64_FMTd__ = "ld"; +pub const __INT_FAST64_FMTi__ = "li"; +pub const __UINT_FAST64_TYPE__ = c_ulong; +pub const __UINT_FAST64_MAX__ = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const __UINT_FAST64_FMTo__ = "lo"; +pub const __UINT_FAST64_FMTu__ = "lu"; +pub const __UINT_FAST64_FMTx__ = "lx"; +pub const __UINT_FAST64_FMTX__ = "lX"; +pub const __USER_LABEL_PREFIX__ = ""; +pub const __FINITE_MATH_ONLY__ = @as(c_int, 0); +pub const __GNUC_STDC_INLINE__ = @as(c_int, 1); +pub const __GCC_ATOMIC_TEST_AND_SET_TRUEVAL = @as(c_int, 1); +pub const __GCC_DESTRUCTIVE_SIZE = @as(c_int, 64); +pub const __GCC_CONSTRUCTIVE_SIZE = @as(c_int, 64); +pub const __CLANG_ATOMIC_BOOL_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_CHAR_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_CHAR16_T_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_CHAR32_T_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_WCHAR_T_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_SHORT_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_INT_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_LONG_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_LLONG_LOCK_FREE = @as(c_int, 2); +pub const __CLANG_ATOMIC_POINTER_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_BOOL_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_CHAR_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_CHAR16_T_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_CHAR32_T_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_WCHAR_T_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_SHORT_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_INT_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_LONG_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_LLONG_LOCK_FREE = @as(c_int, 2); +pub const __GCC_ATOMIC_POINTER_LOCK_FREE = @as(c_int, 2); +pub const __NO_INLINE__ = @as(c_int, 1); +pub const __FLT_RADIX__ = @as(c_int, 2); +pub const __DECIMAL_DIG__ = __LDBL_DECIMAL_DIG__; +pub const __ELF__ = @as(c_int, 1); +pub const __GCC_ASM_FLAG_OUTPUTS__ = @as(c_int, 1); +pub const __code_model_small__ = @as(c_int, 1); +pub const __amd64__ = @as(c_int, 1); +pub const __amd64 = @as(c_int, 1); +pub const __x86_64 = @as(c_int, 1); +pub const __x86_64__ = @as(c_int, 1); +pub const __SEG_GS = @as(c_int, 1); +pub const __SEG_FS = @as(c_int, 1); +pub const __seg_gs = @compileError("unable to translate macro: undefined identifier `address_space`"); +// (no file):363:9 +pub const __seg_fs = @compileError("unable to translate macro: undefined identifier `address_space`"); +// (no file):364:9 +pub const __znver2 = @as(c_int, 1); +pub const __znver2__ = @as(c_int, 1); +pub const __tune_znver2__ = @as(c_int, 1); +pub const __REGISTER_PREFIX__ = ""; +pub const __NO_MATH_INLINES = @as(c_int, 1); +pub const __AES__ = @as(c_int, 1); +pub const __PCLMUL__ = @as(c_int, 1); +pub const __LAHF_SAHF__ = @as(c_int, 1); +pub const __LZCNT__ = @as(c_int, 1); +pub const __RDRND__ = @as(c_int, 1); +pub const __FSGSBASE__ = @as(c_int, 1); +pub const __BMI__ = @as(c_int, 1); +pub const __BMI2__ = @as(c_int, 1); +pub const __POPCNT__ = @as(c_int, 1); +pub const __PRFCHW__ = @as(c_int, 1); +pub const __RDSEED__ = @as(c_int, 1); +pub const __ADX__ = @as(c_int, 1); +pub const __MWAITX__ = @as(c_int, 1); +pub const __MOVBE__ = @as(c_int, 1); +pub const __SSE4A__ = @as(c_int, 1); +pub const __FMA__ = @as(c_int, 1); +pub const __F16C__ = @as(c_int, 1); +pub const __SHA__ = @as(c_int, 1); +pub const __FXSR__ = @as(c_int, 1); +pub const __XSAVE__ = @as(c_int, 1); +pub const __XSAVEOPT__ = @as(c_int, 1); +pub const __XSAVEC__ = @as(c_int, 1); +pub const __XSAVES__ = @as(c_int, 1); +pub const __CLFLUSHOPT__ = @as(c_int, 1); +pub const __CLWB__ = @as(c_int, 1); +pub const __WBNOINVD__ = @as(c_int, 1); +pub const __CLZERO__ = @as(c_int, 1); +pub const __RDPID__ = @as(c_int, 1); +pub const __RDPRU__ = @as(c_int, 1); +pub const __CRC32__ = @as(c_int, 1); +pub const __AVX2__ = @as(c_int, 1); +pub const __AVX__ = @as(c_int, 1); +pub const __SSE4_2__ = @as(c_int, 1); +pub const __SSE4_1__ = @as(c_int, 1); +pub const __SSSE3__ = @as(c_int, 1); +pub const __SSE3__ = @as(c_int, 1); +pub const __SSE2__ = @as(c_int, 1); +pub const __SSE2_MATH__ = @as(c_int, 1); +pub const __SSE__ = @as(c_int, 1); +pub const __SSE_MATH__ = @as(c_int, 1); +pub const __MMX__ = @as(c_int, 1); +pub const __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 = @as(c_int, 1); +pub const __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 = @as(c_int, 1); +pub const __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 = @as(c_int, 1); +pub const __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 = @as(c_int, 1); +pub const __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 = @as(c_int, 1); +pub const __SIZEOF_FLOAT128__ = @as(c_int, 16); +pub const unix = @as(c_int, 1); +pub const __unix = @as(c_int, 1); +pub const __unix__ = @as(c_int, 1); +pub const linux = @as(c_int, 1); +pub const __linux = @as(c_int, 1); +pub const __linux__ = @as(c_int, 1); +pub const __gnu_linux__ = @as(c_int, 1); +pub const __FLOAT128__ = @as(c_int, 1); +pub const __STDC__ = @as(c_int, 1); +pub const __STDC_HOSTED__ = @as(c_int, 1); +pub const __STDC_VERSION__ = @as(c_long, 201710); +pub const __STDC_UTF_16__ = @as(c_int, 1); +pub const __STDC_UTF_32__ = @as(c_int, 1); +pub const __STDC_EMBED_NOT_FOUND__ = @as(c_int, 0); +pub const __STDC_EMBED_FOUND__ = @as(c_int, 1); +pub const __STDC_EMBED_EMPTY__ = @as(c_int, 2); +pub const _DEBUG = @as(c_int, 1); +pub const __GCC_HAVE_DWARF2_CFI_ASM = @as(c_int, 1); +pub const _STDINT_H = @as(c_int, 1); +pub const __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION = ""; +pub const _FEATURES_H = @as(c_int, 1); +pub const __KERNEL_STRICT_NAMES = ""; +pub inline fn __GNUC_PREREQ(maj: anytype, min: anytype) @TypeOf(((__GNUC__ << @as(c_int, 16)) + __GNUC_MINOR__) >= ((maj << @as(c_int, 16)) + min)) { + _ = &maj; + _ = &min; + return ((__GNUC__ << @as(c_int, 16)) + __GNUC_MINOR__) >= ((maj << @as(c_int, 16)) + min); +} +pub inline fn __glibc_clang_prereq(maj: anytype, min: anytype) @TypeOf(((__clang_major__ << @as(c_int, 16)) + __clang_minor__) >= ((maj << @as(c_int, 16)) + min)) { + _ = &maj; + _ = &min; + return ((__clang_major__ << @as(c_int, 16)) + __clang_minor__) >= ((maj << @as(c_int, 16)) + min); +} +pub const __GLIBC_USE = @compileError("unable to translate macro: undefined identifier `__GLIBC_USE_`"); +// /usr/include/features.h:191:9 +pub const _DEFAULT_SOURCE = @as(c_int, 1); +pub const __GLIBC_USE_ISOC2Y = @as(c_int, 0); +pub const __GLIBC_USE_ISOC23 = @as(c_int, 0); +pub const __USE_ISOC11 = @as(c_int, 1); +pub const __USE_ISOC99 = @as(c_int, 1); +pub const __USE_ISOC95 = @as(c_int, 1); +pub const __USE_POSIX_IMPLICITLY = @as(c_int, 1); +pub const _POSIX_SOURCE = @as(c_int, 1); +pub const _POSIX_C_SOURCE = @as(c_long, 200809); +pub const __USE_POSIX = @as(c_int, 1); +pub const __USE_POSIX2 = @as(c_int, 1); +pub const __USE_POSIX199309 = @as(c_int, 1); +pub const __USE_POSIX199506 = @as(c_int, 1); +pub const __USE_XOPEN2K = @as(c_int, 1); +pub const __USE_XOPEN2K8 = @as(c_int, 1); +pub const _ATFILE_SOURCE = @as(c_int, 1); +pub const __WORDSIZE = @as(c_int, 64); +pub const __WORDSIZE_TIME64_COMPAT32 = @as(c_int, 1); +pub const __SYSCALL_WORDSIZE = @as(c_int, 64); +pub const __TIMESIZE = __WORDSIZE; +pub const __USE_TIME_BITS64 = @as(c_int, 1); +pub const __USE_MISC = @as(c_int, 1); +pub const __USE_ATFILE = @as(c_int, 1); +pub const __USE_FORTIFY_LEVEL = @as(c_int, 0); +pub const __GLIBC_USE_DEPRECATED_GETS = @as(c_int, 0); +pub const __GLIBC_USE_DEPRECATED_SCANF = @as(c_int, 0); +pub const __GLIBC_USE_C23_STRTOL = @as(c_int, 0); +pub const _STDC_PREDEF_H = @as(c_int, 1); +pub const __STDC_IEC_559__ = @as(c_int, 1); +pub const __STDC_IEC_60559_BFP__ = @as(c_long, 201404); +pub const __STDC_IEC_559_COMPLEX__ = @as(c_int, 1); +pub const __STDC_IEC_60559_COMPLEX__ = @as(c_long, 201404); +pub const __STDC_ISO_10646__ = @as(c_long, 201706); +pub const __GNU_LIBRARY__ = @as(c_int, 6); +pub const __GLIBC__ = @as(c_int, 2); +pub const __GLIBC_MINOR__ = @as(c_int, 41); +pub inline fn __GLIBC_PREREQ(maj: anytype, min: anytype) @TypeOf(((__GLIBC__ << @as(c_int, 16)) + __GLIBC_MINOR__) >= ((maj << @as(c_int, 16)) + min)) { + _ = &maj; + _ = &min; + return ((__GLIBC__ << @as(c_int, 16)) + __GLIBC_MINOR__) >= ((maj << @as(c_int, 16)) + min); +} +pub const _SYS_CDEFS_H = @as(c_int, 1); +pub const __glibc_has_attribute = @compileError("unable to translate macro: undefined identifier `__has_attribute`"); +// /usr/include/sys/cdefs.h:45:10 +pub inline fn __glibc_has_builtin(name: anytype) @TypeOf(__has_builtin(name)) { + _ = &name; + return __has_builtin(name); +} +pub const __glibc_has_extension = @compileError("unable to translate macro: undefined identifier `__has_extension`"); +// /usr/include/sys/cdefs.h:55:10 +pub const __LEAF = ""; +pub const __LEAF_ATTR = ""; +pub const __THROW = @compileError("unable to translate macro: undefined identifier `__nothrow__`"); +// /usr/include/sys/cdefs.h:79:11 +pub const __THROWNL = @compileError("unable to translate macro: undefined identifier `__nothrow__`"); +// /usr/include/sys/cdefs.h:80:11 +pub const __NTH = @compileError("unable to translate macro: undefined identifier `__nothrow__`"); +// /usr/include/sys/cdefs.h:81:11 +pub const __NTHNL = @compileError("unable to translate macro: undefined identifier `__nothrow__`"); +// /usr/include/sys/cdefs.h:82:11 +pub const __COLD = @compileError("unable to translate macro: undefined identifier `__cold__`"); +// /usr/include/sys/cdefs.h:102:11 +pub inline fn __P(args: anytype) @TypeOf(args) { + _ = &args; + return args; +} +pub inline fn __PMT(args: anytype) @TypeOf(args) { + _ = &args; + return args; +} +pub const __CONCAT = @compileError("unable to translate C expr: unexpected token '##'"); +// /usr/include/sys/cdefs.h:131:9 +pub const __STRING = @compileError("unable to translate C expr: unexpected token '#'"); +// /usr/include/sys/cdefs.h:132:9 +pub const __ptr_t = ?*anyopaque; +pub const __BEGIN_DECLS = ""; +pub const __END_DECLS = ""; +pub const __attribute_overloadable__ = @compileError("unable to translate macro: undefined identifier `__overloadable__`"); +// /usr/include/sys/cdefs.h:151:10 +pub inline fn __bos(ptr: anytype) @TypeOf(__builtin_object_size(ptr, __USE_FORTIFY_LEVEL > @as(c_int, 1))) { + _ = &ptr; + return __builtin_object_size(ptr, __USE_FORTIFY_LEVEL > @as(c_int, 1)); +} +pub inline fn __bos0(ptr: anytype) @TypeOf(__builtin_object_size(ptr, @as(c_int, 0))) { + _ = &ptr; + return __builtin_object_size(ptr, @as(c_int, 0)); +} +pub inline fn __glibc_objsize0(__o: anytype) @TypeOf(__bos0(__o)) { + _ = &__o; + return __bos0(__o); +} +pub inline fn __glibc_objsize(__o: anytype) @TypeOf(__bos(__o)) { + _ = &__o; + return __bos(__o); +} +pub const __warnattr = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:370:10 +pub const __errordecl = @compileError("unable to translate C expr: unexpected token 'extern'"); +// /usr/include/sys/cdefs.h:371:10 +pub const __flexarr = @compileError("unable to translate C expr: unexpected token '['"); +// /usr/include/sys/cdefs.h:379:10 +pub const __glibc_c99_flexarr_available = @as(c_int, 1); +pub const __REDIRECT = @compileError("unable to translate C expr: unexpected token '__asm__'"); +// /usr/include/sys/cdefs.h:410:10 +pub const __REDIRECT_NTH = @compileError("unable to translate C expr: unexpected token '__asm__'"); +// /usr/include/sys/cdefs.h:417:11 +pub const __REDIRECT_NTHNL = @compileError("unable to translate C expr: unexpected token '__asm__'"); +// /usr/include/sys/cdefs.h:419:11 +pub const __ASMNAME = @compileError("unable to translate C expr: unexpected token ','"); +// /usr/include/sys/cdefs.h:422:10 +pub inline fn __ASMNAME2(prefix: anytype, cname: anytype) @TypeOf(__STRING(prefix) ++ cname) { + _ = &prefix; + _ = &cname; + return __STRING(prefix) ++ cname; +} +pub const __REDIRECT_FORTIFY = __REDIRECT; +pub const __REDIRECT_FORTIFY_NTH = __REDIRECT_NTH; +pub const __attribute_malloc__ = @compileError("unable to translate macro: undefined identifier `__malloc__`"); +// /usr/include/sys/cdefs.h:452:10 +pub const __attribute_alloc_size__ = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:463:10 +pub const __attribute_alloc_align__ = @compileError("unable to translate macro: undefined identifier `__alloc_align__`"); +// /usr/include/sys/cdefs.h:469:10 +pub const __attribute_pure__ = @compileError("unable to translate macro: undefined identifier `__pure__`"); +// /usr/include/sys/cdefs.h:479:10 +pub const __attribute_const__ = @compileError("unable to translate C expr: unexpected token '__attribute__'"); +// /usr/include/sys/cdefs.h:486:10 +pub const __attribute_maybe_unused__ = @compileError("unable to translate macro: undefined identifier `__unused__`"); +// /usr/include/sys/cdefs.h:492:10 +pub const __attribute_used__ = @compileError("unable to translate macro: undefined identifier `__used__`"); +// /usr/include/sys/cdefs.h:501:10 +pub const __attribute_noinline__ = @compileError("unable to translate macro: undefined identifier `__noinline__`"); +// /usr/include/sys/cdefs.h:502:10 +pub const __attribute_deprecated__ = @compileError("unable to translate macro: undefined identifier `__deprecated__`"); +// /usr/include/sys/cdefs.h:510:10 +pub const __attribute_deprecated_msg__ = @compileError("unable to translate macro: undefined identifier `__deprecated__`"); +// /usr/include/sys/cdefs.h:520:10 +pub const __attribute_format_arg__ = @compileError("unable to translate macro: undefined identifier `__format_arg__`"); +// /usr/include/sys/cdefs.h:533:10 +pub const __attribute_format_strfmon__ = @compileError("unable to translate macro: undefined identifier `__format__`"); +// /usr/include/sys/cdefs.h:543:10 +pub const __attribute_nonnull__ = @compileError("unable to translate macro: undefined identifier `__nonnull__`"); +// /usr/include/sys/cdefs.h:555:11 +pub inline fn __nonnull(params: anytype) @TypeOf(__attribute_nonnull__(params)) { + _ = ¶ms; + return __attribute_nonnull__(params); +} +pub const __returns_nonnull = @compileError("unable to translate macro: undefined identifier `__returns_nonnull__`"); +// /usr/include/sys/cdefs.h:568:10 +pub const __attribute_warn_unused_result__ = @compileError("unable to translate macro: undefined identifier `__warn_unused_result__`"); +// /usr/include/sys/cdefs.h:577:10 +pub const __wur = ""; +pub const __always_inline = @compileError("unable to translate macro: undefined identifier `__always_inline__`"); +// /usr/include/sys/cdefs.h:595:10 +pub const __attribute_artificial__ = @compileError("unable to translate macro: undefined identifier `__artificial__`"); +// /usr/include/sys/cdefs.h:604:10 +pub const __extern_inline = @compileError("unable to translate macro: undefined identifier `__gnu_inline__`"); +// /usr/include/sys/cdefs.h:622:11 +pub const __extern_always_inline = @compileError("unable to translate macro: undefined identifier `__gnu_inline__`"); +// /usr/include/sys/cdefs.h:623:11 +pub const __fortify_function = __extern_always_inline ++ __attribute_artificial__; +pub const __restrict_arr = @compileError("unable to translate C expr: unexpected token '__restrict'"); +// /usr/include/sys/cdefs.h:666:10 +pub inline fn __glibc_unlikely(cond: anytype) @TypeOf(__builtin_expect(cond, @as(c_int, 0))) { + _ = &cond; + return __builtin_expect(cond, @as(c_int, 0)); +} +pub inline fn __glibc_likely(cond: anytype) @TypeOf(__builtin_expect(cond, @as(c_int, 1))) { + _ = &cond; + return __builtin_expect(cond, @as(c_int, 1)); +} +pub const __attribute_nonstring__ = ""; +pub const __attribute_copy__ = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:715:10 +pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI = @as(c_int, 0); +pub inline fn __LDBL_REDIR1(name: anytype, proto: anytype, alias: anytype) @TypeOf(name ++ proto) { + _ = &name; + _ = &proto; + _ = &alias; + return name ++ proto; +} +pub inline fn __LDBL_REDIR(name: anytype, proto: anytype) @TypeOf(name ++ proto) { + _ = &name; + _ = &proto; + return name ++ proto; +} +pub inline fn __LDBL_REDIR1_NTH(name: anytype, proto: anytype, alias: anytype) @TypeOf(name ++ proto ++ __THROW) { + _ = &name; + _ = &proto; + _ = &alias; + return name ++ proto ++ __THROW; +} +pub inline fn __LDBL_REDIR_NTH(name: anytype, proto: anytype) @TypeOf(name ++ proto ++ __THROW) { + _ = &name; + _ = &proto; + return name ++ proto ++ __THROW; +} +pub const __LDBL_REDIR2_DECL = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:792:10 +pub const __LDBL_REDIR_DECL = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:793:10 +pub inline fn __REDIRECT_LDBL(name: anytype, proto: anytype, alias: anytype) @TypeOf(__REDIRECT(name, proto, alias)) { + _ = &name; + _ = &proto; + _ = &alias; + return __REDIRECT(name, proto, alias); +} +pub inline fn __REDIRECT_NTH_LDBL(name: anytype, proto: anytype, alias: anytype) @TypeOf(__REDIRECT_NTH(name, proto, alias)) { + _ = &name; + _ = &proto; + _ = &alias; + return __REDIRECT_NTH(name, proto, alias); +} +pub const __glibc_macro_warning1 = @compileError("unable to translate macro: undefined identifier `_Pragma`"); +// /usr/include/sys/cdefs.h:807:10 +pub const __glibc_macro_warning = @compileError("unable to translate macro: undefined identifier `GCC`"); +// /usr/include/sys/cdefs.h:808:10 +pub const __HAVE_GENERIC_SELECTION = @as(c_int, 1); +pub const __fortified_attr_access = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:853:11 +pub const __attr_access = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:854:11 +pub const __attr_access_none = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:855:11 +pub const __attr_dealloc = @compileError("unable to translate C expr: unexpected token ''"); +// /usr/include/sys/cdefs.h:865:10 +pub const __attr_dealloc_free = ""; +pub const __attribute_returns_twice__ = @compileError("unable to translate macro: undefined identifier `__returns_twice__`"); +// /usr/include/sys/cdefs.h:872:10 +pub const __attribute_struct_may_alias__ = @compileError("unable to translate macro: undefined identifier `__may_alias__`"); +// /usr/include/sys/cdefs.h:881:10 +pub const __stub___compat_bdflush = ""; +pub const __stub_chflags = ""; +pub const __stub_fchflags = ""; +pub const __stub_gtty = ""; +pub const __stub_revoke = ""; +pub const __stub_setlogin = ""; +pub const __stub_sigreturn = ""; +pub const __stub_stty = ""; +pub const __GLIBC_USE_LIB_EXT2 = @as(c_int, 0); +pub const __GLIBC_USE_IEC_60559_BFP_EXT = @as(c_int, 0); +pub const __GLIBC_USE_IEC_60559_BFP_EXT_C23 = @as(c_int, 0); +pub const __GLIBC_USE_IEC_60559_EXT = @as(c_int, 0); +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT = @as(c_int, 0); +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C23 = @as(c_int, 0); +pub const __GLIBC_USE_IEC_60559_TYPES_EXT = @as(c_int, 0); +pub const _BITS_TYPES_H = @as(c_int, 1); +pub const __S16_TYPE = c_short; +pub const __U16_TYPE = c_ushort; +pub const __S32_TYPE = c_int; +pub const __U32_TYPE = c_uint; +pub const __SLONGWORD_TYPE = c_long; +pub const __ULONGWORD_TYPE = c_ulong; +pub const __SQUAD_TYPE = c_long; +pub const __UQUAD_TYPE = c_ulong; +pub const __SWORD_TYPE = c_long; +pub const __UWORD_TYPE = c_ulong; +pub const __SLONG32_TYPE = c_int; +pub const __ULONG32_TYPE = c_uint; +pub const __S64_TYPE = c_long; +pub const __U64_TYPE = c_ulong; +pub const __STD_TYPE = @compileError("unable to translate C expr: unexpected token 'typedef'"); +// /usr/include/bits/types.h:137:10 +pub const _BITS_TYPESIZES_H = @as(c_int, 1); +pub const __SYSCALL_SLONG_TYPE = __SLONGWORD_TYPE; +pub const __SYSCALL_ULONG_TYPE = __ULONGWORD_TYPE; +pub const __DEV_T_TYPE = __UQUAD_TYPE; +pub const __UID_T_TYPE = __U32_TYPE; +pub const __GID_T_TYPE = __U32_TYPE; +pub const __INO_T_TYPE = __SYSCALL_ULONG_TYPE; +pub const __INO64_T_TYPE = __UQUAD_TYPE; +pub const __MODE_T_TYPE = __U32_TYPE; +pub const __NLINK_T_TYPE = __SYSCALL_ULONG_TYPE; +pub const __FSWORD_T_TYPE = __SYSCALL_SLONG_TYPE; +pub const __OFF_T_TYPE = __SYSCALL_SLONG_TYPE; +pub const __OFF64_T_TYPE = __SQUAD_TYPE; +pub const __PID_T_TYPE = __S32_TYPE; +pub const __RLIM_T_TYPE = __SYSCALL_ULONG_TYPE; +pub const __RLIM64_T_TYPE = __UQUAD_TYPE; +pub const __BLKCNT_T_TYPE = __SYSCALL_SLONG_TYPE; +pub const __BLKCNT64_T_TYPE = __SQUAD_TYPE; +pub const __FSBLKCNT_T_TYPE = __SYSCALL_ULONG_TYPE; +pub const __FSBLKCNT64_T_TYPE = __UQUAD_TYPE; +pub const __FSFILCNT_T_TYPE = __SYSCALL_ULONG_TYPE; +pub const __FSFILCNT64_T_TYPE = __UQUAD_TYPE; +pub const __ID_T_TYPE = __U32_TYPE; +pub const __CLOCK_T_TYPE = __SYSCALL_SLONG_TYPE; +pub const __TIME_T_TYPE = __SYSCALL_SLONG_TYPE; +pub const __USECONDS_T_TYPE = __U32_TYPE; +pub const __SUSECONDS_T_TYPE = __SYSCALL_SLONG_TYPE; +pub const __SUSECONDS64_T_TYPE = __SQUAD_TYPE; +pub const __DADDR_T_TYPE = __S32_TYPE; +pub const __KEY_T_TYPE = __S32_TYPE; +pub const __CLOCKID_T_TYPE = __S32_TYPE; +pub const __TIMER_T_TYPE = ?*anyopaque; +pub const __BLKSIZE_T_TYPE = __SYSCALL_SLONG_TYPE; +pub const __FSID_T_TYPE = @compileError("unable to translate macro: undefined identifier `__val`"); +// /usr/include/bits/typesizes.h:73:9 +pub const __SSIZE_T_TYPE = __SWORD_TYPE; +pub const __CPU_MASK_TYPE = __SYSCALL_ULONG_TYPE; +pub const __OFF_T_MATCHES_OFF64_T = @as(c_int, 1); +pub const __INO_T_MATCHES_INO64_T = @as(c_int, 1); +pub const __RLIM_T_MATCHES_RLIM64_T = @as(c_int, 1); +pub const __STATFS_MATCHES_STATFS64 = @as(c_int, 1); +pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 = @as(c_int, 1); +pub const __FD_SETSIZE = @as(c_int, 1024); +pub const _BITS_TIME64_H = @as(c_int, 1); +pub const __TIME64_T_TYPE = __TIME_T_TYPE; +pub const _BITS_WCHAR_H = @as(c_int, 1); +pub const __WCHAR_MAX = __WCHAR_MAX__; +pub const __WCHAR_MIN = -__WCHAR_MAX - @as(c_int, 1); +pub const _BITS_STDINT_INTN_H = @as(c_int, 1); +pub const _BITS_STDINT_UINTN_H = @as(c_int, 1); +pub const _BITS_STDINT_LEAST_H = @as(c_int, 1); +pub const __intptr_t_defined = ""; +pub const __INT64_C = @import("std").zig.c_translation.Macros.L_SUFFIX; +pub const __UINT64_C = @import("std").zig.c_translation.Macros.UL_SUFFIX; +pub const INT8_MIN = -@as(c_int, 128); +pub const INT16_MIN = -@as(c_int, 32767) - @as(c_int, 1); +pub const INT32_MIN = -@import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal) - @as(c_int, 1); +pub const INT64_MIN = -__INT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 9223372036854775807, .decimal)) - @as(c_int, 1); +pub const INT8_MAX = @as(c_int, 127); +pub const INT16_MAX = @as(c_int, 32767); +pub const INT32_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const INT64_MAX = __INT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 9223372036854775807, .decimal)); +pub const UINT8_MAX = @as(c_int, 255); +pub const UINT16_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_int, 65535, .decimal); +pub const UINT32_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_uint, 4294967295, .decimal); +pub const UINT64_MAX = __UINT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 18446744073709551615, .decimal)); +pub const INT_LEAST8_MIN = -@as(c_int, 128); +pub const INT_LEAST16_MIN = -@as(c_int, 32767) - @as(c_int, 1); +pub const INT_LEAST32_MIN = -@import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal) - @as(c_int, 1); +pub const INT_LEAST64_MIN = -__INT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 9223372036854775807, .decimal)) - @as(c_int, 1); +pub const INT_LEAST8_MAX = @as(c_int, 127); +pub const INT_LEAST16_MAX = @as(c_int, 32767); +pub const INT_LEAST32_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const INT_LEAST64_MAX = __INT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 9223372036854775807, .decimal)); +pub const UINT_LEAST8_MAX = @as(c_int, 255); +pub const UINT_LEAST16_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_int, 65535, .decimal); +pub const UINT_LEAST32_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_uint, 4294967295, .decimal); +pub const UINT_LEAST64_MAX = __UINT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 18446744073709551615, .decimal)); +pub const INT_FAST8_MIN = -@as(c_int, 128); +pub const INT_FAST16_MIN = -@import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal) - @as(c_int, 1); +pub const INT_FAST32_MIN = -@import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal) - @as(c_int, 1); +pub const INT_FAST64_MIN = -__INT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 9223372036854775807, .decimal)) - @as(c_int, 1); +pub const INT_FAST8_MAX = @as(c_int, 127); +pub const INT_FAST16_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const INT_FAST32_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const INT_FAST64_MAX = __INT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 9223372036854775807, .decimal)); +pub const UINT_FAST8_MAX = @as(c_int, 255); +pub const UINT_FAST16_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const UINT_FAST32_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const UINT_FAST64_MAX = __UINT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 18446744073709551615, .decimal)); +pub const INTPTR_MIN = -@import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal) - @as(c_int, 1); +pub const INTPTR_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const UINTPTR_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const INTMAX_MIN = -__INT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 9223372036854775807, .decimal)) - @as(c_int, 1); +pub const INTMAX_MAX = __INT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 9223372036854775807, .decimal)); +pub const UINTMAX_MAX = __UINT64_C(@import("std").zig.c_translation.promoteIntLiteral(c_int, 18446744073709551615, .decimal)); +pub const PTRDIFF_MIN = -@import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal) - @as(c_int, 1); +pub const PTRDIFF_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_long, 9223372036854775807, .decimal); +pub const SIG_ATOMIC_MIN = -@import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal) - @as(c_int, 1); +pub const SIG_ATOMIC_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_int, 2147483647, .decimal); +pub const SIZE_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); +pub const WCHAR_MIN = __WCHAR_MIN; +pub const WCHAR_MAX = __WCHAR_MAX; +pub const WINT_MIN = @as(c_uint, 0); +pub const WINT_MAX = @import("std").zig.c_translation.promoteIntLiteral(c_uint, 4294967295, .decimal); +pub inline fn INT8_C(c: anytype) @TypeOf(c) { + _ = &c; + return c; +} +pub inline fn INT16_C(c: anytype) @TypeOf(c) { + _ = &c; + return c; +} +pub inline fn INT32_C(c: anytype) @TypeOf(c) { + _ = &c; + return c; +} +pub const INT64_C = @import("std").zig.c_translation.Macros.L_SUFFIX; +pub inline fn UINT8_C(c: anytype) @TypeOf(c) { + _ = &c; + return c; +} +pub inline fn UINT16_C(c: anytype) @TypeOf(c) { + _ = &c; + return c; +} +pub const UINT32_C = @import("std").zig.c_translation.Macros.U_SUFFIX; +pub const UINT64_C = @import("std").zig.c_translation.Macros.UL_SUFFIX; +pub const INTMAX_C = @import("std").zig.c_translation.Macros.L_SUFFIX; +pub const UINTMAX_C = @import("std").zig.c_translation.Macros.UL_SUFFIX; +pub const __STDBOOL_H = ""; +pub const __bool_true_false_are_defined = @as(c_int, 1); +pub const @"bool" = bool; +pub const @"true" = @as(c_int, 1); +pub const @"false" = @as(c_int, 0); +pub const __need_ptrdiff_t = ""; +pub const __need_size_t = ""; +pub const __need_wchar_t = ""; +pub const __need_NULL = ""; +pub const __need_max_align_t = ""; +pub const __need_offsetof = ""; +pub const __STDDEF_H = ""; +pub const _PTRDIFF_T = ""; +pub const _SIZE_T = ""; +pub const _WCHAR_T = ""; +pub const NULL = @import("std").zig.c_translation.cast(?*anyopaque, @as(c_int, 0)); +pub const __CLANG_MAX_ALIGN_T_DEFINED = ""; +pub const offsetof = @compileError("unable to translate C expr: unexpected token 'an identifier'"); +// /home/moon/.cache/zig/p/N-V-__8AAHqaixIK5xkCeDRdXNzskekn9i1dos0md02qAkgD/lib/include/__stddef_offsetof.h:16:9 +pub const POINT_COUNT = @as(c_int, 10); +pub const BONE_COUNT = @as(c_int, 22); +pub const ITERATION_COUNT = @as(c_int, 6); +pub const GRID_ARRAY_BASE_SIZE = @import("std").zig.c_translation.promoteIntLiteral(c_int, 65536, .decimal); +pub const point = struct_point; +pub const bone = struct_bone; +pub const rider = struct_rider; +pub const line_flags = struct_line_flags; +pub const line_values = struct_line_values; +pub const line = struct_line; +pub const grid_coordinate = struct_grid_coordinate; +pub const grid_cell_entry = struct_grid_cell_entry; +pub const grid_bucket = struct_grid_bucket; +pub const grid = struct_grid; +pub const grid_pos = struct_grid_pos; +pub const simulation = struct_simulation; diff --git a/track_wrapper/src/root.zig b/track_wrapper/src/root.zig new file mode 100644 index 0000000..60de904 --- /dev/null +++ b/track_wrapper/src/root.zig @@ -0,0 +1,62 @@ +const std = @import("std"); +const c = @import("include.zig"); +const sol = @import("sol.zig"); +const amf = @import("amf0.zig"); + +pub export fn load_sol_track(sim: [*c]c.struct_simulation, filename: [*c]u8, index: u32) void { + const file = std.fs.cwd().openFile(std.mem.sliceTo(filename, 0), .{}) catch return; + defer file.close(); + var sol_f = sol.readSol(std.heap.smp_allocator, file.reader()) catch return; + defer sol_f.deinit(); + const tracks = sol.getTracks(sol_f) catch return; + const track = tracks.items[index]; + const startprop = track.getProperty("startLine") catch return; + const lines: amf.Array = track.getPropertyExpectType("data", .Array) catch return; + if (startprop.amf_type == .Number) { + const ID: u32 = std.math.cast(u32, @as(u32, @intFromFloat(@as(*f64, @ptrCast(@alignCast(startprop.data))).*))) orelse return; + + var maybe_line: ?amf.AmfValue = null; + + for (lines.items) |iter_line| { + const iter_ID: u32 = std.math.cast(u32, @as(u32, @intFromFloat(iter_line.getItemExpectType(8, .Number) catch return))) orelse return; + if (iter_ID == ID) { + maybe_line = iter_line; + break; + } + } + + if (maybe_line) |amf_line| { + const line = sol.Line.fromAmf(amf_line) catch return; + sim.*.bosh = c.rider_new(line.x1, line.y1 - 25.0); + } else { + sim.*.bosh = c.rider_new(100.0, 100.0); + } + } else { + if (startprop.amf_type != .Array) return; + const x = startprop.getItemExpectType(0, .Number) catch return; + const y = startprop.getItemExpectType(1, .Number) catch return; + sim.*.bosh = c.rider_new(x, y); + } + + c.simulation_prepare_line_capacity(sim, lines.items.len); + + for (lines.items) |amf_line| { + const line = sol.Line.fromAmf(amf_line) catch continue; + if (line.linetype == .Scenery) continue; + const simline = c.struct_line{ + .id = std.math.cast(i32, line.ID) orelse continue, + .x1 = line.x1, + .y1 = line.y1, + .x2 = line.x2, + .y2 = line.y2, + .flags = .{ + .red = line.linetype == .Acceleration, + .invert = line.invert, + .left_extended = line.left_extended, + .right_extended = line.right_extended, + }, + }; + c.simulation_add_line(sim, simline); + } + // no fucking way !!!!!! its hypothetically done +} diff --git a/track_wrapper/src/sol.zig b/track_wrapper/src/sol.zig new file mode 100644 index 0000000..c02c89b --- /dev/null +++ b/track_wrapper/src/sol.zig @@ -0,0 +1,73 @@ +const std = @import("std"); +const amf = @import("amf0.zig"); + +pub const Track = amf.Value; + +pub fn readSol(alloc: std.mem.Allocator, reader: anytype) !amf.AmfValue { + const sol_version = try reader.readInt(i16, .big); + const length = try reader.readInt(i32, .big); + _ = sol_version; + _ = length; + if (try reader.readInt(i32, .big) != 0x5443534F) return error.InvalidMagicNumber; + try reader.skipBytes(6, .{}); + const name: []u8 = try alloc.alloc(u8, std.math.cast(usize, try reader.readInt(i16, .big)) orelse return error.CastError); + _ = try reader.readAll(name); + if (!std.mem.eql(u8, name, "savedLines")) return error.InvalidSolName; + if (try reader.readInt(i32, .big) != 0) return error.InvalidAmfVersion; + const ptr = try alloc.create(amf.Object); + ptr.* = amf.Object.init(alloc); + const amf_obj = amf.AmfValue{ .name = name, .alloc = alloc, .amf_type = .Object, .data = @ptrCast(ptr) }; + const fields: *amf.Object = ptr; + while (true) { + const val = amf.AmfValue.read(alloc, reader) catch |err| { + if (err == error.EndOfStream) break; + return err; + }; + if (val.amf_type == .ObjectEnd) break; + try fields.put(val.name, val); + } + return amf_obj; +} + +pub fn getTracks(root: amf.AmfValue) !amf.Array { + return root.getPropertyExpectType("trackList", .Array); +} + +pub const LineType = enum(u2) { + Standard = 0, + Acceleration = 1, + Scenery = 2, +}; + +pub const Line = struct { + x1: f64, + y1: f64, + x2: f64, + y2: f64, + invert: bool, + ID: u32, + linetype: LineType, + left_extended: bool, + right_extended: bool, + + pub const Extension = packed struct(u2) { + left: bool, + right: bool, + }; + + pub fn fromAmf(line: amf.Value) !Line { + //std.debug.print("line: {any} 5: {any} 0: {any}", .{ line.amf_type, (try line.getItem(4)).amf_type, (try line.getItem(0)).amf_type }); + const extensions: Extension = @bitCast(@as(u2, @intFromFloat(line.getItemExpectType(4, .Number) catch 0))); + return Line{ + .x1 = try line.getItemExpectType(0, .Number), + .y1 = try line.getItemExpectType(1, .Number), + .x2 = try line.getItemExpectType(2, .Number), + .y2 = try line.getItemExpectType(3, .Number), + .invert = (line.getItemExpectType(5, .Number) catch 0) != 0, + .left_extended = extensions.left, + .right_extended = extensions.right, + .ID = @as(u32, @intFromFloat(try line.getItemExpectType(8, .Number))), + .linetype = @enumFromInt(@as(u2, @intFromFloat(try line.getItemExpectType(9, .Number)))), + }; + } +}; diff --git a/track_wrapper/track_wrapper.h b/track_wrapper/track_wrapper.h new file mode 100644 index 0000000..d391eb5 --- /dev/null +++ b/track_wrapper/track_wrapper.h @@ -0,0 +1,10 @@ +// i already wrote sol parsing in zig so +// this is just some stupid glue code to +// use that instead of dealing with it +// all over again in c + +// this is scuffed but um i uncomment this is i need to generate include.zig +// but leave it commented for when ralib_crontend.c includes it +// #include "lref.h" + +void load_sol_track(struct simulation* sim, char* filename, uint32_t index);