You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.7 KiB
98 lines
2.7 KiB
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <glib.h>
|
|
|
|
int s03_A0F3 = 0x5D0B1C11;
|
|
int s03_A0F7 = 0x35E79125;
|
|
int s03_A0FB = 0x56596b10;
|
|
int s03_A0FF = 0x7FFFFB0A;
|
|
int s03_A103 = 0x1B080733;
|
|
|
|
int s03_A107;
|
|
int s03_A10B;
|
|
int s03_A10D;
|
|
int s03_A10E;
|
|
|
|
char buffer[0x200];
|
|
|
|
int main()
|
|
{
|
|
FILE *f = fopen("fools.sav", "r");
|
|
if (!f) {
|
|
perror("fopen");
|
|
exit(1);
|
|
}
|
|
fseek(f, 0x6567, SEEK_SET);
|
|
fread(buffer, 1, 0x200, f);
|
|
fclose(f);
|
|
|
|
GHashTable *hashtable = g_hash_table_new(g_direct_hash, g_direct_equal);
|
|
|
|
double start = clock();
|
|
do {
|
|
gint lcg = s03_A0F3 & 0xFFFFFE00;
|
|
gint cur_lcg = GPOINTER_TO_INT(g_hash_table_lookup(hashtable, GINT_TO_POINTER(lcg)));
|
|
cur_lcg += 1;
|
|
g_hash_table_replace(hashtable, GINT_TO_POINTER(lcg), GINT_TO_POINTER(cur_lcg));
|
|
|
|
s03_A0F3 = (s03_A0F3 * s03_A0F7 + s03_A0FB) & 0xFFFFFFFF;
|
|
|
|
if (s03_A0FF % 0x100000 == 0) {
|
|
double framespers = 0x100000 / ((double)(clock() - start) / CLOCKS_PER_SEC);
|
|
unsigned eta = (double)(s03_A0FF) / framespers;
|
|
fprintf(stderr, "Progress: %d (speed: %.2f iter/s, ETA: %02u:%02u:%02u)\n",
|
|
s03_A0FF, framespers,
|
|
eta / 60 / 60, (eta / 60) % 60, eta % 60);
|
|
start = clock();
|
|
}
|
|
} while (--s03_A0FF);
|
|
|
|
int count = 0;
|
|
|
|
GHashTableIter iter;
|
|
gpointer key, value;
|
|
g_hash_table_iter_init(&iter, hashtable);
|
|
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
|
count += GPOINTER_TO_INT(value) % 2;
|
|
}
|
|
|
|
int i = 0;
|
|
start = clock();
|
|
g_hash_table_iter_init(&iter, hashtable);
|
|
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
|
if (GPOINTER_TO_INT(value) % 2 == 0) {
|
|
continue;
|
|
}
|
|
|
|
double framespers = 1 / ((double)(clock() - start) / CLOCKS_PER_SEC);
|
|
unsigned eta = (double)(count - i) / framespers;
|
|
fprintf(stderr, "Progress: %d/%d %.2f%% (speed: %.2f iter/s, ETA: %02u:%02u:%02u)\n",
|
|
i, count, (double)i / count * 100, framespers,
|
|
eta / 60 / 60, (eta / 60) % 60, eta % 60);
|
|
start = clock();
|
|
i += 1;
|
|
|
|
s03_A107 = s03_A103;
|
|
|
|
s03_A10B = (GPOINTER_TO_INT(key) & 0xFF00) >> 8;
|
|
s03_A10D = (GPOINTER_TO_INT(key) & 0xFF0000) >> 16;
|
|
s03_A10E = (GPOINTER_TO_INT(key) & 0xFF000000) >> 24;
|
|
|
|
int bufi = 0;
|
|
do {
|
|
s03_A10B = ((s03_A10B / 2) * s03_A10D + s03_A10E) & 0xFFFF;
|
|
buffer[bufi] ^= s03_A10B & 0xFF;
|
|
|
|
if (++bufi >= 0x200) bufi = 0;
|
|
} while (--s03_A107);
|
|
}
|
|
|
|
g_hash_table_destroy(hashtable);
|
|
|
|
f = fopen("output.buf", "w");
|
|
fwrite(buffer, 1, 0x200, f);
|
|
fclose(f);
|
|
|
|
return 0;
|
|
}
|
|
|