Native iPhone port of Factorio 2.0.77

Run the original macOS ARM64 game code on iOS:
- tools/retarget.py: header-only Mach-O retargeting to an iOS dylib
- platform/native: UIKit host and macOS API shims (AppKit for SDL's
  Cocoa backend, CoreGraphics displays, CoreAudio device, Metal device
  properties, Wuffs PNG decoding, Steam and peripheral stubs)
- touch, overlay, iOS keyboard and hardware keyboard input
- tools/build_native.py: build, sign, install, data copy, launch
- docs: build guide, controls, architecture

Also includes the earlier static-translation research (ARM64 -> WASM ->
native) under docs/research, runtime/, tests/ and tools/.

No game files are included; the build reads them from a local install.
This commit is contained in:
SashaGoncharov19 committed 2026-10-23 15:27:58 +04:00
commit 51d085e865
89 files changed
+7999

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
#include "factorio_rng.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
extern uint32_t factorio_rng_original(uint32_t state[3]);
extern void factorio_rng_seed_original(uint32_t state[3], uint32_t seed);
static uint32_t next_case(uint32_t *seed) {
*seed ^= *seed << 13;
*seed ^= *seed >> 17;
*seed ^= *seed << 5;
return *seed;
}
// Returns zero only after comparing outputs AND mutated state with original
// ARM64 instruction words. No generated code is mapped executable at runtime.
int factorio_rng_verify(void) {
const uint32_t edges[] = {0, 1, 2, 7, 8, 15, 16, 127, 128,
0x7fffffff, 0x80000000, 0xffffffff};
const uint32_t offsets[] = {0, 1, 15, 1024, 65524};
uint32_t random = 0x375adc91;
uint64_t calls = 0;
w2c_factorio__rng instance;
wasm_rt_init();
wasm2c_factorio__rng_instantiate(&instance);
wasm_rt_memory_t *memory = w2c_factorio__rng_memory(&instance);
for (uint32_t example = 0; example < 6848; ++example) {
uint32_t state[3];
if (example < 1728) {
state[0] = edges[example % 12];
state[1] = edges[(example / 12) % 12];
state[2] = edges[example / 144];
} else if (example < 5824) {
for (int i = 0; i < 3; ++i) state[i] = next_case(&random);
}
uint32_t offset = offsets[example % 5];
memset(memory->data, 0xa5, 65536);
if (example >= 5824) {
uint32_t seed = example < 6336 ? example - 5824 : next_case(&random);
factorio_rng_seed_original(state, seed);
w2c_factorio__rng_seed(&instance, offset, seed);
if (memcmp(memory->data + offset, state, 12)) {
fprintf(stderr, "Constructor mismatch at seed %u\n", seed);
wasm2c_factorio__rng_free(&instance);
wasm_rt_free();
return 3;
}
} else {
memcpy(memory->data + offset, state, 12);
}
for (int step = 0; step < 128; ++step) {
uint32_t expected = factorio_rng_original(state);
uint32_t actual = w2c_factorio__rng_get_int(&instance, offset);
++calls;
if (actual != expected || memcmp(memory->data + offset, state, 12)) {
fprintf(stderr, "Mismatch: case %u step %d, expected %08x actual %08x\n",
example, step, expected, actual);
wasm2c_factorio__rng_free(&instance);
wasm_rt_free();
return 1;
}
}
// Catch writes outside the 12-byte state, including unaligned addresses.
for (uint32_t i = 0; i < 65536; ++i) {
if ((i < offset || i >= offset + 12) && memory->data[i] != 0xa5) {
fprintf(stderr, "Out-of-state write: case %u offset %u\n", example, i);
wasm2c_factorio__rng_free(&instance);
wasm_rt_free();
return 2;
}
}
}
wasm2c_factorio__rng_free(&instance);
wasm_rt_free();
printf("PASS: %llu RNG calls and 1024 constructor calls, 6848 starting states, five memory alignments; outputs, state and guards match\n",
(unsigned long long)calls);
return 0;
}
#ifndef FACTORIO_RNG_NO_MAIN
int main(void) { return factorio_rng_verify(); }
#endif