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.
51 lines
2.1 KiB
C
51 lines
2.1 KiB
C
#include "map_header_bridge.h"
|
|
#include "factorio_map_header.h"
|
|
#include <string.h>
|
|
|
|
struct w2c_map__host {
|
|
w2c_factorio__map__header *module;
|
|
unsigned reads;
|
|
};
|
|
|
|
u32 w2c_map__host_read_or_throw(struct w2c_map__host *env, u64 source, u64 destination, u64 size) {
|
|
wasm_rt_memory_t *memory = w2c_factorio__map__header_memory(env->module);
|
|
if (memory->size < 24 || source > memory->size - 24 ||
|
|
size > memory->size || destination > memory->size - size) return 2;
|
|
uint64_t reader[3];
|
|
memcpy(reader, memory->data + source, sizeof(reader));
|
|
uint64_t data = reader[0], length = reader[1], cursor = reader[2];
|
|
if (data > memory->size || length > memory->size - data) return 2;
|
|
if (cursor > length || size > length - cursor) return 1;
|
|
memmove(memory->data + destination, memory->data + data + cursor, (size_t)size);
|
|
cursor += size;
|
|
memcpy(memory->data + source + 16, &cursor, sizeof(cursor));
|
|
++env->reads;
|
|
return 0;
|
|
}
|
|
|
|
int factorio_map_header_parse(const uint8_t *payload, size_t length,
|
|
FactorioMapVersion version, FactorioMapHeader *out) {
|
|
if (!payload || !out) return 2;
|
|
if (!wasm_rt_is_initialized()) wasm_rt_init();
|
|
w2c_factorio__map__header module;
|
|
struct w2c_map__host env = {.module = &module};
|
|
wasm2c_factorio__map__header_instantiate(&module, &env);
|
|
uint8_t *memory = w2c_factorio__map__header_memory(&module)->data;
|
|
uint64_t registers[32] = {0};
|
|
registers[0] = 2048; registers[1] = 512; registers[31] = 65280;
|
|
uint64_t reader[5] = {4096, length < 24 ? length : 24, 0,
|
|
(uint64_t)version.major << 48 | (uint64_t)version.minor << 32 |
|
|
(uint64_t)version.patch << 16 | version.build, version.flag};
|
|
memcpy(memory, registers, sizeof(registers));
|
|
memcpy(memory + 512, reader, sizeof(reader));
|
|
memcpy(memory + 4096, payload, (size_t)reader[1]);
|
|
int result = (int)w2c_factorio__map__header_run(&module, 0, 1000);
|
|
if (!result) {
|
|
FactorioMapHeader parsed = {.version = version};
|
|
memcpy(parsed.tick_fields, memory + 2064, sizeof(parsed.tick_fields));
|
|
*out = parsed;
|
|
}
|
|
wasm2c_factorio__map__header_free(&module);
|
|
return result;
|
|
}
|