mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Record "seed" when generating images as well
For reproducibility
This commit is contained in:
@@ -22,25 +22,25 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
FILE *rngRecorder; // File to which the random bytes will be read
|
||||||
uint32_t randBits = 0; // Storage for bits read from the input stream but not yet used
|
uint32_t randBits = 0; // Storage for bits read from the input stream but not yet used
|
||||||
uint8_t randCount = 0; // How many bits are currently stored in the above
|
uint8_t randCount = 0; // How many bits are currently stored in the above
|
||||||
size_t nbRandBytes = 0;
|
|
||||||
|
|
||||||
static uint32_t getRandomBits(uint8_t count) {
|
static uint32_t getRandomBits(uint8_t count) {
|
||||||
// Trying to read one more byte with `randCount` at least this high will drop some bits
|
// Trying to read one more byte with `randCount` at least this high will drop some bits!
|
||||||
// If the count is no higher than that limit, then the loop will exit without reading more bytes
|
// If the count is no higher than that limit, then the loop is guaranteed to exit without
|
||||||
|
// reading more bytes.
|
||||||
assert(count <= sizeof(randBits) * 8 + 1);
|
assert(count <= sizeof(randBits) * 8 + 1);
|
||||||
|
|
||||||
// Read bytes until we have enough bits to serve the request
|
// Read bytes until we have enough bits to serve the request
|
||||||
while (count > randCount) {
|
while (count > randCount) {
|
||||||
int data = getchar();
|
int data = getchar();
|
||||||
if (data == EOF) {
|
if (data == EOF) {
|
||||||
fprintf(stderr, "Exit after reading %zu bytes\n", nbRandBytes);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
randBits |= (uint32_t)data << randCount;
|
randBits |= (uint32_t)data << randCount;
|
||||||
randCount += 8;
|
randCount += 8;
|
||||||
++nbRandBytes;
|
fputc(data, rngRecorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t result = randBits & (((uint32_t)1 << count) - 1);
|
uint32_t result = randBits & (((uint32_t)1 << count) - 1);
|
||||||
@@ -49,6 +49,14 @@ static uint32_t getRandomBits(uint8_t count) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush any remaining bits in the RNG storage
|
||||||
|
*/
|
||||||
|
static void flushRng(void) {
|
||||||
|
randCount = 0;
|
||||||
|
randBits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand a 5-bit color component to 8 bits with minimal bias
|
* Expand a 5-bit color component to 8 bits with minimal bias
|
||||||
*/
|
*/
|
||||||
@@ -203,10 +211,17 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char filename[maxBasenameLen + 25];
|
char filename[maxBasenameLen + sizeof("65535.png")];
|
||||||
for (uint16_t i = 0;; i++) { // 65k images ought to be enough
|
for (uint16_t i = 0;; i++) { // 65k images ought to be enough
|
||||||
for (int index = 1; index < argc; index++) {
|
for (int index = 1; index < argc; index++) {
|
||||||
sprintf(filename, "%s%" PRIu16 ".png", argv[index], i);
|
int len = sprintf(filename, "%s%" PRIu16 ".rng", argv[index], i);
|
||||||
|
rngRecorder = fopen(filename, "wb");
|
||||||
|
if (!rngRecorder) {
|
||||||
|
perror("RNG fopen");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
filename[len - 3] = 'p'; // `.rng` -> `.png`
|
||||||
FILE *img = fopen(filename, "wb");
|
FILE *img = fopen(filename, "wb");
|
||||||
if (!img) {
|
if (!img) {
|
||||||
perror("PNG fopen");
|
perror("PNG fopen");
|
||||||
@@ -227,10 +242,15 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure that image generation starts on byte boundaries
|
||||||
|
// (This is necessary so that all involved random bits are recorded in the `.rng` file)
|
||||||
|
flushRng();
|
||||||
|
|
||||||
png_init_io(png, img);
|
png_init_io(png, img);
|
||||||
generate_random_image(png, pngInfo);
|
generate_random_image(png, pngInfo);
|
||||||
png_destroy_write_struct(&png, &pngInfo);
|
png_destroy_write_struct(&png, &pngInfo);
|
||||||
fclose(img);
|
fclose(img);
|
||||||
|
fclose(rngRecorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == UINT16_MAX) {
|
if (i == UINT16_MAX) {
|
||||||
|
|||||||
Reference in New Issue
Block a user