Skip to content

Commit 84a850d

Browse files
author
diekmann
committed
wrapping doom via rust
1 parent 6597c39 commit 84a850d

File tree

10 files changed

+99
-5
lines changed

10 files changed

+99
-5
lines changed

doom/.cargo/config

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[target.i686-unknown-linux-gnu]
2+
runner = "./run_in_256colors.sh"
3+
4+
5+
[build]
6+
# doom is a 32bit application.
7+
target = "i686-unknown-linux-gnu"
8+
9+
[net]
10+
offline = true

doom/Cargo.lock

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doom/Cargo.toml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "doom"
3+
version = "0.1.0"
4+
authors = ["diekmann <none@localhost>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]

doom/README.md

+38-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ But we want to build everything from scratch in this series, without Emscripten.
77

88
---
99

10-
We start with the original vanilla DOOM sources from https://github.com/id-Software/DOOM at [6ed1e40](https://github.com/diekmann/wasm-fizzbuzz/commit/6ed1e4067082bfe61a7b767b91dc981aa1517f94).
10+
We start with the original vanilla DOOM sources from <https://github.com/id-Software/DOOM> at [6ed1e40](https://github.com/diekmann/wasm-fizzbuzz/commit/6ed1e4067082bfe61a7b767b91dc981aa1517f94).
1111

1212
Some minor tweaks are necessary to compile the 1997 sources on my 64bit Ubuntu 20.04.
1313

@@ -28,3 +28,40 @@ With those tweaks, DOOM is starting with X11 rendering:
2828
![DOOM is compiling and starting with X11 rendering (no WebAssembly used so far)](imgs/doom_booting_x11.png)
2929

3030
Time to port this to WebAssembly next.
31+
32+
---
33+
34+
Following <https://surma.dev/things/c-to-webassembly/>, we want to compile DOOM as `wasm32`.
35+
But this will be a long journey.
36+
And we cannot play doom once we switch to `wasm32` untill the graphics driver for X11 is removed and replaced by a graphics driver for the web.
37+
Therefore, to test as much as possible and be able to play doom during development, I will develop on X86 for as long as possible and change architecture to `wasm32` reather late.
38+
39+
First, let's replace the compiler from `gcc` to `clang`, turn on optimization, and disable debugging.
40+
This reduces binary size from `1,9M` to `383K`
41+
42+
To get doom ready for the web, we need to do the following
43+
44+
* Replace the X11 graphics driver with something that works in the browser.
45+
* Replace the sound driver with, .... my PC does not have speakers, let's just remove sound.
46+
* Replace all calls DOOM makes into the C stand library (such as `malloc` or `fopen`) with implementations that work in the browser. Either by implementing them in WebAssembly or JavaScript.
47+
48+
Since the year is 2021, there is no reason to write new C code, ...
49+
50+
```
51+
~/git/wasm-fizzbuzz/doom$ cargo init
52+
```
53+
54+
To make the doom C code callable interoperable with rust, we no longer compile it into a binry, but build a static library (`liblinuxxdoom.a`) instead.
55+
Inspired by <https://docs.rust-embedded.org/book/interoperability/c-with-rust.html>, we should be able to call DOOM's `D_DoomMain` from rust then.
56+
57+
We are essentially still working on a 32bit application, remeber?
58+
59+
```
60+
cargo run --target=i686-unknown-linux-gnu
61+
```
62+
63+
Adding a `.cargo/config` to select the default target and a runner...
64+
65+
And we got DOOM starting from rust \m/
66+
67+
![DOOM starting via cargo](imgs/doom_booting_x11_rust.png)

doom/build.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
fn main() {
2+
// TODO: go to linuxdoom-1.10 and `make linux/linuxxdoom.a` first
3+
println!("cargo:rustc-link-search=linuxdoom-1.10/linux");
4+
println!("cargo:rustc-link-lib=linuxxdoom");
5+
6+
7+
// libraries which should be removed before going to wasm
8+
println!("cargo:rustc-link-lib=Xext");
9+
println!("cargo:rustc-link-lib=X11");
10+
println!("cargo:rustc-link-lib=nsl");
11+
println!("cargo:rustc-link-lib=m");
12+
}

doom/doom1.wad

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
linuxdoom-1.10/doom1.wad

doom/imgs/doom_booting_x11_rust.png

265 KB
Loading

doom/linuxdoom-1.10/Makefile

+8-4
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
#
55
# $Log:$
66
#
7-
CC= clang
7+
CC=clang
8+
AR=llvm-ar-10
89

910
# doom was written with the implicit assumption that ints and pointers are 32bit.
1011
# Adding -m32 to make it compile on 64bit archs.
1112
# on Ubuntu 20.04:
1213
# apt install gcc-multilib libx11-dev:i386 libxext-dev:i386
13-
14-
CFLAGS=-m32 -O2 -Wall -flto -Wno-unused-const-variable -DNORMALUNIX -DLINUX
14+
CFLAGS=-m32 -O2 -Wall -Wno-unused-const-variable -DNORMALUNIX -DLINUX
1515
LDFLAGS=-L/usr/X11R6/lib
1616
LIBS=-lXext -lX11 -lnsl -lm
1717

@@ -88,8 +88,9 @@ clean:
8888
rm -f *.o *~ *.flc
8989
rm -f $(O)/*
9090

91+
# link-time optimization only when building the binary, but not when building the *.o files, since we want to link them with rust.
9192
$(O)/linuxxdoom: $(OBJS) $(O)/i_main.o
92-
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(O)/i_main.o \
93+
$(CC) -flto $(CFLAGS) $(LDFLAGS) $(OBJS) $(O)/i_main.o \
9394
-o $(O)/linuxxdoom $(LIBS)
9495

9596
$(O)/%.o: %.c
@@ -101,6 +102,9 @@ run: all
101102
sleep 1 # ugly!! waiting for Xephyr to start.
102103
DISPLAY=:1 ./$(O)/linuxxdoom -2
103104

105+
$(O)/liblinuxxdoom.a: $(OBJS)
106+
$(AR) rcs $@ $^
107+
104108
#############################################################
105109
#
106110
#############################################################

doom/run_in_256colors.sh

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
Xephyr :1 -screen 640x400x8 -title DooM &
3+
sleep 1 # ugly!! waiting for Xephyr to start.
4+
DISPLAY=:1 "${1}" -2

doom/src/main.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
extern "C" {
2+
fn D_DoomMain() -> !;
3+
}
4+
5+
fn main() {
6+
println!("Hello, world from rust!");
7+
8+
// TODO: set global variables
9+
// myargc=2 and myargv={"-2"}
10+
11+
unsafe { D_DoomMain() };
12+
}

0 commit comments

Comments
 (0)