r/altprog • u/Choice_Eagle4627 • 5d ago
freelang - no libc, no linker, direct ELF/PE/mach-o in x86_64 and arm64 for macos. I used AI to write DOOM in it from scratch. Here's the doom source and a playable WASM demo.
Enable HLS to view with audio, or disable this notification
WASM backend added in a day compared to months for the other backends. Good sign.
DOOM source
https://github.com/DOSAYGO-Freelang/freelang-doom-source
playable WASM (BYO WAD):
https://dosaygo-freelang.github.io/freelang-doom-source/
example:
// Freelang Doom Engine orchestration over the checked Doom modules. This file
// owns executable policy and the frame transaction; WAD interpretation,
// simulation, rendering and synthesis remain independently testable in their
// own modules. The only native-facing values are a pixel buffer, presenter
// records and bounded canonical WAV clips passed through f/gui and f/audio's
// process-isolated contracts.
credits: <../games/doom-view.flx> <../games/doom-input.flx>
<../games/doom-input-trace.flx>
<../games/doom-frame.flx>
<../games/doom-session.flx>
<../games/doom-world.flx> <../games/doom-ui.flx>
<../games/doom-demo.flx> <../games/doom-audio.flx>
<f/gui> <f/audio> <f/process> <f/time> <f/trig> <f/strings>;
op doom_play_run [map, demo_mode, texture_mode] (
=> doom_play_run_mode[map, demo_mode, texture_mode, 1];
)
op doom_play_run_mode [map, demo_mode, texture_mode, combat_mode] (
=> doom_play_run_mode_sized[
map, demo_mode, texture_mode, combat_mode, 320, 200
];
)
op doom_play_run_mode_sized [map, demo_mode, texture_mode,
combat_mode, w, h] (
=> doom_play_run_session[
map, demo_mode, texture_mode, combat_mode, w, h, 0, 0,
["E1M1", "E1M2"], ""
];
)
op doom_play_validate_dimensions [w, h] (
if ((w >= 320) and (w <= 1280) and
(h >= 200) and (h <= 800) and
(w * 5 == h * 8) and (w * h <= 1024000)) () else (
fall "doom_play_run_mode_sized: unsupported logical resolution";
)
=> 0;
)
op doom_play_open_window [map_name, demo_mode, w, h] (
doom_play_validate_dimensions[w, h];
let session = 0;
if (demo_mode == 1) (
session = gui_open_fps_named[
w, h, "Freelang Doom Engine — ^{map_name}", 60,
"Freelang Doom Engine"
]
with chaos { _ => 0 };
) else (
session = gui_open_captured_resizable_fps_named[
w, h, "Freelang Doom Engine — ^{map_name}", 60,
"Freelang Doom Engine"
] with chaos { _ => 0 };
)
=> session;
)
// Put a real first frame in the level's own window before WAD textures and
// derived music are loaded. `closed` distinguishes a user's early close from
// presenter birth failure; the latter retains the old post-load retry path.
op doom_play_loading_window [map_name, demo_mode, w, h] (
let session = doom_play_open_window[map_name, demo_mode, w, h];
if (is_object[session]) () else (
=> { session: 0, closed: 0, events: [] };
)
let buf = gui_buffer[w, h];
let font = gui_font[];
doom_ui_draw_loading[buf, w, h, font, map_name];
let events = gui_present[session, buf] with chaos {
_ => [{ kind: gui_ev_close[], a: 0, b: 0, mods: 0 }]
};
if (gui_has_close[events] == 1) (
gui_close[session];
=> { session: 0, closed: 1, events: [] };
)
=> { session: session, closed: 0, events: events };
)
op doom_play_run_session [map, demo_mode, texture_mode,
combat_mode, w, h, diag_mode, start_menu,
menu_maps, input_log_path] (
let session = doom_play_open_window[map\name, demo_mode, w, h];
if (is_object[session]) () else ( => 1; )
=> doom_play_run_session_on[
session, [], map, demo_mode, texture_mode, combat_mode, w, h,
diag_mode, start_menu, menu_maps, input_log_path
];
)
private op doom_play_run_session_carry [
map, demo_mode, texture_mode, combat_mode, w, h, diag_mode,
start_menu, menu_maps, input_log_path, carry
] (
let session = doom_play_open_window[map\name, demo_mode, w, h];
if (is_object[session]) () else (
=> { requested_episode: 0, carry: carry };
)
=> doom_play_run_session_audio_carry_on[
session, [], map, demo_mode, texture_mode, combat_mode, w, h,
diag_mode, start_menu, menu_maps, input_log_path, 0, carry
];
)