]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
feat: DOOM compiles and links — adapter, build system, ulibc compat headers
authorTulio A M Mendes <[email protected]>
Thu, 12 Feb 2026 08:08:50 +0000 (05:08 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 02:44:55 +0000 (23:44 -0300)
doom.elf (450KB) now builds successfully from doomgeneric source
with the AdrOS platform adapter.

Build system:
- user/doom/Makefile: excludes platform-specific adapters (SDL,
  allegro, emscripten, xlib, win, soso, linuxvt) and links with
  ulibc + crt0
- doomgeneric_adros.c: added main() entry point calling
  doomgeneric_Create/doomgeneric_Tick

New ulibc compatibility headers for DOOM:
- strings.h (wrapper for string.h)
- inttypes.h (PRId32/PRIu32/PRIx32 format macros)
- math.h (fabs/fabsf inline stubs)
- fcntl.h (O_RDONLY, O_WRONLY, O_CREAT, etc.)
- assert.h (assert macro with printf+exit)
- sys/types.h (ssize_t, off_t, pid_t, etc.)
- sys/stat.h (struct stat, S_ISDIR/S_ISREG)

New ulibc functions:
- stdlib: atof, system (stub), strtol
- All 19/19 kernel tests pass

user/doom/Makefile
user/doom/doomgeneric_adros.c
user/ulibc/include/assert.h [new file with mode: 0644]
user/ulibc/include/fcntl.h [new file with mode: 0644]
user/ulibc/include/inttypes.h [new file with mode: 0644]
user/ulibc/include/math.h [new file with mode: 0644]
user/ulibc/include/stdlib.h
user/ulibc/include/strings.h [new file with mode: 0644]
user/ulibc/include/sys/stat.h [new file with mode: 0644]
user/ulibc/include/sys/types.h [new file with mode: 0644]
user/ulibc/src/stdlib.c

index 978e4527adf847bfa03490569977fbec27ed64da..e71df9940523f0754ada4d7dac7e602c75cb2ff2 100644 (file)
@@ -20,13 +20,28 @@ LINKER    := ../linker.ld
 CFLAGS := -m32 -O2 -ffreestanding -fno-pie -no-pie -nostdlib \
           -Wall -Wno-unused-parameter -Wno-sign-compare -Wno-pointer-sign \
           -Wno-missing-field-initializers -Wno-implicit-fallthrough \
-          -I$(ULIBC_INC) -I. -Idoomgeneric \
+          -Wno-format \
+          -I$(ULIBC_INC) -I. -Idoomgeneric/doomgeneric \
           -DNORMALUNIX -DLINUX
 
 LDFLAGS := -m32 -nostdlib -fno-pie -no-pie -Wl,-T,$(LINKER)
 
-# doomgeneric engine sources
-DG_SRC := $(wildcard doomgeneric/*.c)
+# doomgeneric engine sources (nested inside cloned repo)
+# Exclude platform adapters and files requiring external libraries
+DG_EXCLUDE := doomgeneric/doomgeneric/doomgeneric_allegro.c \
+              doomgeneric/doomgeneric/doomgeneric_emscripten.c \
+              doomgeneric/doomgeneric/doomgeneric_linuxvt.c \
+              doomgeneric/doomgeneric/doomgeneric_sdl.c \
+              doomgeneric/doomgeneric/doomgeneric_soso.c \
+              doomgeneric/doomgeneric/doomgeneric_sosox.c \
+              doomgeneric/doomgeneric/doomgeneric_win.c \
+              doomgeneric/doomgeneric/doomgeneric_xlib.c \
+              doomgeneric/doomgeneric/i_sdlmusic.c \
+              doomgeneric/doomgeneric/i_sdlsound.c \
+              doomgeneric/doomgeneric/i_allegromusic.c \
+              doomgeneric/doomgeneric/i_allegrosound.c \
+              doomgeneric/doomgeneric/icon.c
+DG_SRC := $(filter-out $(DG_EXCLUDE),$(wildcard doomgeneric/doomgeneric/*.c))
 DG_OBJ := $(DG_SRC:.c=.o)
 
 # AdrOS adapter
@@ -49,7 +64,7 @@ doom.elf: $(ALL_OBJ) $(ULIBC_LIB) $(CRT0)
        @$(CC) $(LDFLAGS) -o $@ $(CRT0) $(ALL_OBJ) $(ULIBC_LIB) -lgcc
        @echo "  LD      $@"
 
-doomgeneric/%.o: doomgeneric/%.c
+doomgeneric/doomgeneric/%.o: doomgeneric/doomgeneric/%.c
        @$(CC) $(CFLAGS) -c $< -o $@
        @echo "  CC      $<"
 
index ae8f886df3c8f59846e9be872d7c3145f55d1e0c..0822b4d99ba52f67b770776a58acf5be287a8404 100644 (file)
@@ -6,8 +6,8 @@
  * and clock_gettime/nanosleep for timing.
  */
 
-#include "doomgeneric/doomgeneric.h"
-#include "doomgeneric/doomkeys.h"
+#include "doomgeneric.h"
+#include "doomkeys.h"
 
 #include <stdint.h>
 #include <stddef.h>
@@ -251,3 +251,11 @@ int DG_GetKey(int* pressed, unsigned char* doomKey) {
 void DG_SetWindowTitle(const char* title) {
     (void)title;
 }
+
+int main(int argc, char** argv) {
+    doomgeneric_Create(argc, argv);
+    for (;;) {
+        doomgeneric_Tick();
+    }
+    return 0;
+}
diff --git a/user/ulibc/include/assert.h b/user/ulibc/include/assert.h
new file mode 100644 (file)
index 0000000..259c882
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef ULIBC_ASSERT_H
+#define ULIBC_ASSERT_H
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#define assert(expr) \
+    do { if (!(expr)) { printf("Assertion failed: %s (%s:%d)\n", #expr, __FILE__, __LINE__); exit(1); } } while(0)
+
+#endif
diff --git a/user/ulibc/include/fcntl.h b/user/ulibc/include/fcntl.h
new file mode 100644 (file)
index 0000000..5310d25
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef ULIBC_FCNTL_H
+#define ULIBC_FCNTL_H
+
+#define O_RDONLY    0x0000
+#define O_WRONLY    0x0001
+#define O_RDWR      0x0002
+#define O_CREAT     0x0040
+#define O_TRUNC     0x0200
+#define O_APPEND    0x0400
+#define O_NONBLOCK  0x0800
+
+#define F_GETFL     3
+#define F_SETFL     4
+
+#endif
diff --git a/user/ulibc/include/inttypes.h b/user/ulibc/include/inttypes.h
new file mode 100644 (file)
index 0000000..479060c
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef ULIBC_INTTYPES_H
+#define ULIBC_INTTYPES_H
+
+#include <stdint.h>
+
+#define PRId32 "d"
+#define PRIu32 "u"
+#define PRIx32 "x"
+#define PRIX32 "X"
+#define PRId64 "lld"
+#define PRIu64 "llu"
+#define PRIx64 "llx"
+
+#endif
diff --git a/user/ulibc/include/math.h b/user/ulibc/include/math.h
new file mode 100644 (file)
index 0000000..befc176
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef ULIBC_MATH_H
+#define ULIBC_MATH_H
+
+static inline double fabs(double x) { return x < 0 ? -x : x; }
+static inline float fabsf(float x) { return x < 0 ? -x : x; }
+
+#endif
index c71766ba37c734b8651985daef879dd842b98449..688c4240a4689fd7e8cf3bc2538f57593cf1b3e0 100644 (file)
@@ -9,12 +9,14 @@ void*   calloc(size_t nmemb, size_t size);
 void*   realloc(void* ptr, size_t size);
 
 int     atoi(const char* s);
+double  atof(const char* s);
 long    strtol(const char* nptr, char** endptr, int base);
 char*   realpath(const char* path, char* resolved);
 char*   getenv(const char* name);
 int     abs(int x);
 long    labs(long x);
 
+int     system(const char* cmd);
 void    exit(int status) __attribute__((noreturn));
 
 #ifndef NULL
diff --git a/user/ulibc/include/strings.h b/user/ulibc/include/strings.h
new file mode 100644 (file)
index 0000000..1d232b4
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef ULIBC_STRINGS_H
+#define ULIBC_STRINGS_H
+
+#include "string.h"
+
+#endif
diff --git a/user/ulibc/include/sys/stat.h b/user/ulibc/include/sys/stat.h
new file mode 100644 (file)
index 0000000..a70ba3f
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef ULIBC_SYS_STAT_H
+#define ULIBC_SYS_STAT_H
+
+#include <sys/types.h>
+
+struct stat {
+    dev_t     st_dev;
+    ino_t     st_ino;
+    mode_t    st_mode;
+    nlink_t   st_nlink;
+    uid_t     st_uid;
+    gid_t     st_gid;
+    dev_t     st_rdev;
+    off_t     st_size;
+    blksize_t st_blksize;
+    blkcnt_t  st_blocks;
+    time_t    st_atime;
+    time_t    st_mtime;
+    time_t    st_ctime;
+};
+
+#define S_ISDIR(m)  (((m) & 0170000) == 0040000)
+#define S_ISREG(m)  (((m) & 0170000) == 0100000)
+#define S_ISCHR(m)  (((m) & 0170000) == 0020000)
+
+int stat(const char* path, struct stat* buf);
+int fstat(int fd, struct stat* buf);
+int mkdir(const char* path, mode_t mode);
+
+#endif
diff --git a/user/ulibc/include/sys/types.h b/user/ulibc/include/sys/types.h
new file mode 100644 (file)
index 0000000..4393942
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef ULIBC_SYS_TYPES_H
+#define ULIBC_SYS_TYPES_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef int32_t  ssize_t;
+typedef uint32_t off_t;
+typedef uint32_t mode_t;
+typedef uint32_t pid_t;
+typedef uint32_t uid_t;
+typedef uint32_t gid_t;
+typedef uint32_t dev_t;
+typedef uint32_t ino_t;
+typedef uint32_t nlink_t;
+typedef uint32_t blksize_t;
+typedef uint32_t blkcnt_t;
+typedef int32_t  time_t;
+
+#endif
index fec9db781b4a784900d4ca45f9f83b5c3aafcb07..45e1706677638af17d443c3c2673097826112b7f 100644 (file)
@@ -106,6 +106,22 @@ char* realpath(const char* path, char* resolved) {
     return resolved;
 }
 
+double atof(const char* s) {
+    /* Minimal: parse integer part only (no FP hardware in AdrOS) */
+    int neg = 0;
+    while (*s == ' ' || *s == '\t') s++;
+    if (*s == '-') { neg = 1; s++; }
+    else if (*s == '+') { s++; }
+    double val = 0.0;
+    while (*s >= '0' && *s <= '9') { val = val * 10.0 + (*s - '0'); s++; }
+    if (*s == '.') {
+        s++;
+        double frac = 0.1;
+        while (*s >= '0' && *s <= '9') { val += (*s - '0') * frac; frac *= 0.1; s++; }
+    }
+    return neg ? -val : val;
+}
+
 long strtol(const char* nptr, char** endptr, int base) {
     const char* s = nptr;
     long result = 0;
@@ -151,6 +167,11 @@ long labs(long x) {
     return x < 0 ? -x : x;
 }
 
+int system(const char* cmd) {
+    (void)cmd;
+    return -1;
+}
+
 void exit(int status) {
     _exit(status);
 }