115 lines
2.4 KiB
C
115 lines
2.4 KiB
C
#include "aliases.h"
|
|
#include "ppm.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
typedef struct {
|
|
u64 x;
|
|
u64 y;
|
|
u64 z;
|
|
u64 w;
|
|
} XOR256State;
|
|
|
|
typedef u64(RandGenFunc)(void *s);
|
|
|
|
void test_xorshift_256(Image *img);
|
|
u64 xorshift_256_generate(void *s);
|
|
void test_xoshiro_256ss(Image *img);
|
|
u64 xoshiro_256ss_generate(void *s);
|
|
u64 rol64(u64 x, u64 bits);
|
|
XOR256State init_xor_256_state();
|
|
void write_image_data(Image *img, RandGenFunc *gen_rand, void *s);
|
|
|
|
int main(int argc, char *argv[]) {
|
|
struct timespec ts = {0};
|
|
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
|
|
|
srand48(ts.tv_nsec);
|
|
|
|
u64 w = 1024;
|
|
u64 h = 1024;
|
|
u64 length = w * h;
|
|
Pixel data[length];
|
|
|
|
Image img = {
|
|
.width = w,
|
|
.height = h,
|
|
.data = data,
|
|
};
|
|
|
|
test_xorshift_256(&img);
|
|
write_p6_ppm("./outputs/xorshift256.ppm", &img);
|
|
|
|
test_xoshiro_256ss(&img);
|
|
write_p6_ppm("./outputs/xoshiro256ss.ppm", &img);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
void test_xorshift_256(Image *img) {
|
|
XOR256State state = init_xor_256_state();
|
|
write_image_data(img, xorshift_256_generate, (void *)&state);
|
|
}
|
|
|
|
u64 xorshift_256_generate(void *s) {
|
|
XOR256State *state = (XOR256State *)s;
|
|
|
|
u64 t = state->x ^ (state->x << 11);
|
|
|
|
state->x = state->y;
|
|
state->y = state->z;
|
|
state->z = state->w;
|
|
state->w = (state->w ^ (state->w >> 19)) ^ (t ^ (t >> 8));
|
|
|
|
return state->w;
|
|
}
|
|
|
|
void test_xoshiro_256ss(Image *img) {
|
|
XOR256State state = init_xor_256_state();
|
|
write_image_data(img, xoshiro_256ss_generate, (void *)&state);
|
|
}
|
|
|
|
u64 xoshiro_256ss_generate(void *s) {
|
|
XOR256State *state = (XOR256State *)s;
|
|
|
|
const u64 result = rol64(state->z * 5, 7) * 9;
|
|
const u64 t = state->z << 17;
|
|
|
|
state->y ^= state->w;
|
|
state->x ^= state->z;
|
|
state->z ^= state->y;
|
|
state->w ^= state->x;
|
|
|
|
state->y ^= t;
|
|
state->x = rol64(state->x, 45);
|
|
|
|
return result;
|
|
}
|
|
|
|
u64 rol64(u64 x, u64 bits) { return (x << bits) | (x >> (64 - bits)); }
|
|
|
|
XOR256State init_xor_256_state() {
|
|
return (XOR256State){
|
|
.x = lrand48(),
|
|
.y = lrand48(),
|
|
.z = lrand48(),
|
|
.w = lrand48(),
|
|
};
|
|
}
|
|
|
|
void write_image_data(Image *img, RandGenFunc *gen_rand, void *s) {
|
|
for (u64 y = 0; y < img->height; ++y) {
|
|
for (u64 x = 0; x < img->width; ++x) {
|
|
u64 i = y * img->width + x;
|
|
|
|
u8 pixel = gen_rand(s) % UINT8_MAX;
|
|
img->data[i] = (Pixel){
|
|
.r = pixel,
|
|
.g = pixel,
|
|
.b = pixel,
|
|
};
|
|
}
|
|
}
|
|
}
|