refactor: move DOOM out to the mtkports ports tree
Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_018Ae69wJS7sueQMUwNxV3nX
This commit is contained in:
+26
@@ -181,6 +181,20 @@ kernel: kernel-deps
|
|||||||
programs:
|
programs:
|
||||||
$(MAKE) -C programs
|
$(MAKE) -C programs
|
||||||
|
|
||||||
|
# Build out-of-tree ports (~/dev/mtkports) and stage their app bundles into
|
||||||
|
# programs/bin/apps/. Opt-in: the base ISO ships only what lives in
|
||||||
|
# programs/src/, so this is never a dependency of the default build. Run it
|
||||||
|
# before 'make ramdisk' to include ports in the image.
|
||||||
|
MTKPORTS ?= $(HOME)/dev/mtkports
|
||||||
|
|
||||||
|
.PHONY: ports
|
||||||
|
ports: programs
|
||||||
|
@if [ -d "$(MTKPORTS)" ]; then \
|
||||||
|
$(MAKE) -C "$(MTKPORTS)" install MONTAUKOS="$(CURDIR)"; \
|
||||||
|
else \
|
||||||
|
echo "ports: $(MTKPORTS) not found - skipping (set MTKPORTS=/path/to/mtkports)"; \
|
||||||
|
fi
|
||||||
|
|
||||||
.PHONY: ramdisk
|
.PHONY: ramdisk
|
||||||
ramdisk: limine/limine kernel programs
|
ramdisk: limine/limine kernel programs
|
||||||
mkdir -p programs/bin/boot/limine
|
mkdir -p programs/bin/boot/limine
|
||||||
@@ -245,6 +259,18 @@ release: limine/limine kernel ramdisk
|
|||||||
cp kernel/bin-$(ARCH)/kernel iso_root/boot/
|
cp kernel/bin-$(ARCH)/kernel iso_root/boot/
|
||||||
strip iso_root/boot/kernel
|
strip iso_root/boot/kernel
|
||||||
cp -r programs/bin .release-tmp
|
cp -r programs/bin .release-tmp
|
||||||
|
# A release ISO ships only in-tree apps, so drop any out-of-tree port bundles
|
||||||
|
# that happen to be staged in programs/bin/apps (each carries a .port marker).
|
||||||
|
# Pass RELEASE_WITH_PORTS=1 to deliberately cut a ports-included image.
|
||||||
|
ifneq ($(RELEASE_WITH_PORTS),1)
|
||||||
|
@for m in $$(find .release-tmp/apps -name .port 2>/dev/null); do \
|
||||||
|
d=$$(dirname $$m); \
|
||||||
|
echo "release: excluding port bundle $$(basename $$d)"; \
|
||||||
|
rm -rf "$$d"; \
|
||||||
|
done
|
||||||
|
else
|
||||||
|
@echo "release: RELEASE_WITH_PORTS=1 - including out-of-tree port bundles"
|
||||||
|
endif
|
||||||
find .release-tmp -name '*.elf' -exec strip {} +
|
find .release-tmp -name '*.elf' -exec strip {} +
|
||||||
./scripts/mkramdisk.sh .release-tmp iso_root/boot/ramdisk.tar
|
./scripts/mkramdisk.sh .release-tmp iso_root/boot/ramdisk.tar
|
||||||
rm -rf .release-tmp
|
rm -rf .release-tmp
|
||||||
|
|||||||
-1
Submodule doomgeneric deleted from fc60163949
+4
-10
@@ -49,7 +49,7 @@ BINDIR := bin
|
|||||||
PROGRAMS := $(notdir $(wildcard src/*))
|
PROGRAMS := $(notdir $(wildcard src/*))
|
||||||
|
|
||||||
# Programs with custom Makefiles (built separately).
|
# Programs with custom Makefiles (built separately).
|
||||||
CUSTOM_BUILDS := 2048 doom fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display terminal klog procmgr powermgr calculator charmap desktop login shell paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs libloader crashpad
|
CUSTOM_BUILDS := 2048 fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display terminal klog procmgr powermgr calculator charmap desktop login shell paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs libloader crashpad
|
||||||
SYSTEM_PROGRAMS := $(filter-out $(CUSTOM_BUILDS),$(PROGRAMS))
|
SYSTEM_PROGRAMS := $(filter-out $(CUSTOM_BUILDS),$(PROGRAMS))
|
||||||
|
|
||||||
# Build targets: system programs go to bin/os/, apps go to bin/apps/<name>/.
|
# Build targets: system programs go to bin/os/, apps go to bin/apps/<name>/.
|
||||||
@@ -89,9 +89,9 @@ WPDIR := data/wallpapers
|
|||||||
WPSRC := $(wildcard $(WPDIR)/*.jpg)
|
WPSRC := $(wildcard $(WPDIR)/*.jpg)
|
||||||
WPDST := $(patsubst $(WPDIR)/%,$(BINDIR)/os/wallpapers/%,$(WPSRC))
|
WPDST := $(patsubst $(WPDIR)/%,$(BINDIR)/os/wallpapers/%,$(WPSRC))
|
||||||
|
|
||||||
.PHONY: all clean 2048 doom fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display terminal klog procmgr powermgr calculator charmap login desktop shell paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs icons fonts configs bearssl libc tls libjpeg libjpegwrite install-apps libloader crashpad check-syscalls gen-syscalls
|
.PHONY: all clean 2048 fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display terminal klog procmgr powermgr calculator charmap login desktop shell paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs icons fonts configs bearssl libc tls libjpeg libjpegwrite install-apps libloader crashpad check-syscalls gen-syscalls
|
||||||
|
|
||||||
all: bearssl libc libjpeg libjpegwrite tls libloader devkit $(TARGETS) fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display terminal klog procmgr powermgr calculator charmap 2048 doom paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs login desktop shell icons fonts install-apps crashpad $(MANDST) $(WWWDST) $(CA_CERTS) $(CONFIGDST) $(FWDST) $(LICDST) $(WPDST)
|
all: bearssl libc libjpeg libjpegwrite tls libloader devkit $(TARGETS) fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display terminal klog procmgr powermgr calculator charmap 2048 paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs login desktop shell icons fonts install-apps crashpad $(MANDST) $(WWWDST) $(CA_CERTS) $(CONFIGDST) $(FWDST) $(LICDST) $(WPDST)
|
||||||
|
|
||||||
# Build BearSSL static library (cross-compiled for freestanding x86_64).
|
# Build BearSSL static library (cross-compiled for freestanding x86_64).
|
||||||
BEARSSL_INCLUDES := -isystem $(shell cd .. && pwd)/kernel/freestnd-c-hdrs/x86_64/include -isystem $(abspath include/libc)
|
BEARSSL_INCLUDES := -isystem $(shell cd .. && pwd)/kernel/freestnd-c-hdrs/x86_64/include -isystem $(abspath include/libc)
|
||||||
@@ -284,11 +284,6 @@ mandelbrot: libc
|
|||||||
$(MAKE) -C src/2048
|
$(MAKE) -C src/2048
|
||||||
|
|
||||||
# Build RPG demo game via its own Makefile (depends on libc).
|
# Build RPG demo game via its own Makefile (depends on libc).
|
||||||
# Build doom via its own Makefile (depends on libc and the shared-lib loader,
|
|
||||||
# both of which it links).
|
|
||||||
doom: libc libloader
|
|
||||||
$(MAKE) -C src/doom
|
|
||||||
|
|
||||||
# Build screenshot tool (depends on libc, libjpegwrite, libloader, and libdialogs).
|
# Build screenshot tool (depends on libc, libjpegwrite, libloader, and libdialogs).
|
||||||
screenshot: libc libjpegwrite libloader dialogs
|
screenshot: libc libjpegwrite libloader dialogs
|
||||||
$(MAKE) -C src/screenshot
|
$(MAKE) -C src/screenshot
|
||||||
@@ -334,7 +329,7 @@ crashpad: libc
|
|||||||
$(MAKE) -C src/crashpad
|
$(MAKE) -C src/crashpad
|
||||||
|
|
||||||
# Install app bundles (manifests, icons, data files) into bin/apps/<name>/.
|
# Install app bundles (manifests, icons, data files) into bin/apps/<name>/.
|
||||||
install-apps: 2048 doom paint spreadsheet wordprocessor weather wikipedia imageviewer fontpreview pdfviewer disks devexplorer installer audio music video bluetooth network display terminal klog procmgr powermgr calculator charmap screenshot texteditor mandelbrot printers timezone crashpad
|
install-apps: 2048 paint spreadsheet wordprocessor weather wikipedia imageviewer fontpreview pdfviewer disks devexplorer installer audio music video bluetooth network display terminal klog procmgr powermgr calculator charmap screenshot texteditor mandelbrot printers timezone crashpad
|
||||||
../scripts/install_apps.sh
|
../scripts/install_apps.sh
|
||||||
|
|
||||||
# Copy man pages into bin/man/ so mkramdisk.sh picks them up.
|
# Copy man pages into bin/man/ so mkramdisk.sh picks them up.
|
||||||
@@ -464,7 +459,6 @@ clean:
|
|||||||
$(MAKE) -C lib/libjpegwrite clean
|
$(MAKE) -C lib/libjpegwrite clean
|
||||||
$(MAKE) -C lib/tls clean
|
$(MAKE) -C lib/tls clean
|
||||||
$(MAKE) -C src/fetch clean
|
$(MAKE) -C src/fetch clean
|
||||||
$(MAKE) -C src/doom clean
|
|
||||||
$(MAKE) -C src/login clean
|
$(MAKE) -C src/login clean
|
||||||
$(MAKE) -C src/shell clean
|
$(MAKE) -C src/shell clean
|
||||||
$(MAKE) -C src/desktop clean
|
$(MAKE) -C src/desktop clean
|
||||||
|
|||||||
@@ -1,211 +0,0 @@
|
|||||||
# Makefile for DOOM (doomgeneric) on MontaukOS
|
|
||||||
# Copyright (c) 2025 Daniel Hammer
|
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
|
||||||
.SUFFIXES:
|
|
||||||
|
|
||||||
# ---- Toolchain ----
|
|
||||||
|
|
||||||
TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk-
|
|
||||||
ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),)
|
|
||||||
CC = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first)
|
|
||||||
CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first)
|
|
||||||
LD = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first)
|
|
||||||
else
|
|
||||||
CC := $(TOOLCHAIN_PREFIX)gcc
|
|
||||||
CXX := $(TOOLCHAIN_PREFIX)g++
|
|
||||||
LD := $(TOOLCHAIN_PREFIX)gcc
|
|
||||||
endif
|
|
||||||
|
|
||||||
# ---- Paths ----
|
|
||||||
|
|
||||||
DOOM_SRC := ../../../doomgeneric/doomgeneric
|
|
||||||
LIBC_INC := ../../include/libc
|
|
||||||
PROG_INC := ../../include
|
|
||||||
LIBDIR := ../../lib
|
|
||||||
LOADER_LIB := ../../lib/libloader
|
|
||||||
LINK_LD := ../../link.ld
|
|
||||||
BINDIR := ../../bin
|
|
||||||
OBJDIR := obj
|
|
||||||
|
|
||||||
# ---- Compiler flags ----
|
|
||||||
|
|
||||||
CFLAGS := \
|
|
||||||
-std=gnu11 \
|
|
||||||
-g -O2 -pipe \
|
|
||||||
-Wall \
|
|
||||||
-Wno-unused-parameter \
|
|
||||||
-Wno-unused-variable \
|
|
||||||
-Wno-missing-field-initializers \
|
|
||||||
-Wno-sign-compare \
|
|
||||||
-Wno-pointer-sign \
|
|
||||||
-ffreestanding \
|
|
||||||
-fno-stack-protector \
|
|
||||||
-fno-stack-check \
|
|
||||||
-ffunction-sections \
|
|
||||||
-fdata-sections \
|
|
||||||
-msse \
|
|
||||||
-msse2 \
|
|
||||||
-DNORMALUNIX \
|
|
||||||
-DLINUX \
|
|
||||||
-DFEATURE_SOUND \
|
|
||||||
-isystem $(LIBC_INC) \
|
|
||||||
-I . \
|
|
||||||
-I $(PROG_INC) \
|
|
||||||
-I $(DOOM_SRC) \
|
|
||||||
-isystem $(shell $(CC) -print-file-name=include)
|
|
||||||
|
|
||||||
CXXFLAGS := \
|
|
||||||
-std=gnu++20 \
|
|
||||||
-g -O2 -pipe \
|
|
||||||
-Wall \
|
|
||||||
-Wno-unused-parameter \
|
|
||||||
-ffreestanding \
|
|
||||||
-fno-stack-protector \
|
|
||||||
-fno-stack-check \
|
|
||||||
-fno-rtti \
|
|
||||||
-fno-exceptions \
|
|
||||||
-ffunction-sections \
|
|
||||||
-fdata-sections \
|
|
||||||
-msse \
|
|
||||||
-msse2 \
|
|
||||||
-isystem $(LIBC_INC) \
|
|
||||||
-I . \
|
|
||||||
-I $(PROG_INC)
|
|
||||||
|
|
||||||
# ---- Linker flags ----
|
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-nostdlib \
|
|
||||||
-Wl,--gc-sections \
|
|
||||||
-T $(LINK_LD)
|
|
||||||
|
|
||||||
# ---- DOOM source files (excluding platform-specific ports and sound backends) ----
|
|
||||||
|
|
||||||
DOOM_SRCS := \
|
|
||||||
am_map.c \
|
|
||||||
d_event.c \
|
|
||||||
d_items.c \
|
|
||||||
d_iwad.c \
|
|
||||||
d_loop.c \
|
|
||||||
d_main.c \
|
|
||||||
d_mode.c \
|
|
||||||
d_net.c \
|
|
||||||
doomdef.c \
|
|
||||||
doomgeneric.c \
|
|
||||||
doomstat.c \
|
|
||||||
dstrings.c \
|
|
||||||
dummy.c \
|
|
||||||
f_finale.c \
|
|
||||||
f_wipe.c \
|
|
||||||
g_game.c \
|
|
||||||
gusconf.c \
|
|
||||||
hu_lib.c \
|
|
||||||
hu_stuff.c \
|
|
||||||
i_cdmus.c \
|
|
||||||
i_endoom.c \
|
|
||||||
i_input.c \
|
|
||||||
i_joystick.c \
|
|
||||||
i_scale.c \
|
|
||||||
i_sound.c \
|
|
||||||
i_system.c \
|
|
||||||
i_timer.c \
|
|
||||||
i_video.c \
|
|
||||||
info.c \
|
|
||||||
m_argv.c \
|
|
||||||
m_bbox.c \
|
|
||||||
m_cheat.c \
|
|
||||||
m_config.c \
|
|
||||||
m_controls.c \
|
|
||||||
m_fixed.c \
|
|
||||||
m_menu.c \
|
|
||||||
m_misc.c \
|
|
||||||
m_random.c \
|
|
||||||
memio.c \
|
|
||||||
mus2mid.c \
|
|
||||||
p_ceilng.c \
|
|
||||||
p_doors.c \
|
|
||||||
p_enemy.c \
|
|
||||||
p_floor.c \
|
|
||||||
p_inter.c \
|
|
||||||
p_lights.c \
|
|
||||||
p_map.c \
|
|
||||||
p_maputl.c \
|
|
||||||
p_mobj.c \
|
|
||||||
p_plats.c \
|
|
||||||
p_pspr.c \
|
|
||||||
p_saveg.c \
|
|
||||||
p_setup.c \
|
|
||||||
p_sight.c \
|
|
||||||
p_spec.c \
|
|
||||||
p_switch.c \
|
|
||||||
p_telept.c \
|
|
||||||
p_tick.c \
|
|
||||||
p_user.c \
|
|
||||||
r_bsp.c \
|
|
||||||
r_data.c \
|
|
||||||
r_draw.c \
|
|
||||||
r_main.c \
|
|
||||||
r_plane.c \
|
|
||||||
r_segs.c \
|
|
||||||
r_sky.c \
|
|
||||||
r_things.c \
|
|
||||||
s_sound.c \
|
|
||||||
sha1.c \
|
|
||||||
sounds.c \
|
|
||||||
st_lib.c \
|
|
||||||
st_stuff.c \
|
|
||||||
statdump.c \
|
|
||||||
tables.c \
|
|
||||||
v_video.c \
|
|
||||||
w_checksum.c \
|
|
||||||
w_file.c \
|
|
||||||
w_file_stdc.c \
|
|
||||||
w_main.c \
|
|
||||||
w_wad.c \
|
|
||||||
wi_stuff.c \
|
|
||||||
z_zone.c
|
|
||||||
|
|
||||||
# Local source files
|
|
||||||
LOCAL_SRCS := doomgeneric_montauk.c i_sound_montauk.c
|
|
||||||
LOCAL_CXX_SRCS := doom_wad_check.cpp
|
|
||||||
|
|
||||||
# ---- Object files ----
|
|
||||||
|
|
||||||
DOOM_OBJS := $(addprefix $(OBJDIR)/,$(DOOM_SRCS:.c=.o))
|
|
||||||
LOCAL_OBJS := $(addprefix $(OBJDIR)/,$(LOCAL_SRCS:.c=.o))
|
|
||||||
LOCAL_CXX_OBJS := $(addprefix $(OBJDIR)/,$(LOCAL_CXX_SRCS:.cpp=.o))
|
|
||||||
ALL_OBJS := $(DOOM_OBJS) $(LOCAL_OBJS) $(LOCAL_CXX_OBJS)
|
|
||||||
|
|
||||||
# ---- Target ----
|
|
||||||
|
|
||||||
TARGET := $(BINDIR)/apps/doom/doom.elf
|
|
||||||
|
|
||||||
.PHONY: all clean
|
|
||||||
|
|
||||||
all: $(TARGET)
|
|
||||||
|
|
||||||
$(TARGET): $(ALL_OBJS) $(LINK_LD) Makefile $(LOADER_LIB)/liblibloader.a $(LIBDIR)/libc/liblibc.a
|
|
||||||
mkdir -p $(BINDIR)/apps/doom
|
|
||||||
$(LD) $(CFLAGS) $(LDFLAGS) $(ALL_OBJS) $(LOADER_LIB)/liblibloader.a $(LIBDIR)/libc/liblibc.a -o $@
|
|
||||||
|
|
||||||
# DOOM source files (from doomgeneric directory)
|
|
||||||
$(OBJDIR)/%.o: $(DOOM_SRC)/%.c Makefile
|
|
||||||
mkdir -p $(OBJDIR)
|
|
||||||
$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
|
|
||||||
|
|
||||||
# Local source files
|
|
||||||
$(OBJDIR)/%.o: %.c Makefile
|
|
||||||
mkdir -p $(OBJDIR)
|
|
||||||
$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
|
|
||||||
|
|
||||||
# Local C++ source files
|
|
||||||
$(OBJDIR)/%.o: %.cpp Makefile
|
|
||||||
mkdir -p $(OBJDIR)
|
|
||||||
$(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OBJDIR) $(TARGET)
|
|
||||||
|
|
||||||
# Auto-generated header dependency tracking (-MMD -MP).
|
|
||||||
-include $(ALL_OBJS:.o=.d)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/* Dummy SDL_mixer.h - not needed for MontaukOS sound backend */
|
|
||||||
#ifndef SDL_MIXER_H
|
|
||||||
#define SDL_MIXER_H
|
|
||||||
#endif
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* doom_wad_check.cpp
|
|
||||||
* Warns the user and exits cleanly if no DOOM WAD is present
|
|
||||||
* Copyright (c) 2026 Daniel Hammer
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gui/dialogs.hpp>
|
|
||||||
#include <montauk/syscall.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
extern "C" [[noreturn]] void doom_warn_missing_wad(const char* path) {
|
|
||||||
char message[400];
|
|
||||||
snprintf(message, sizeof(message),
|
|
||||||
"No DOOM WAD file was found at %s.\n\n"
|
|
||||||
"MontaukOS cannot ship proprietary DOOM WADs (doom1.wad, doom.wad, "
|
|
||||||
"freedoom1.wad, etc.) on its ISO images due to copyright restrictions.\n\n"
|
|
||||||
"Copy a legally obtained WAD file to that path and relaunch DOOM.",
|
|
||||||
path);
|
|
||||||
|
|
||||||
gui::dialogs::message_box("DOOM", message, gui::dialogs::MESSAGE_BOX_OK);
|
|
||||||
montauk::exit(1);
|
|
||||||
}
|
|
||||||
@@ -1,269 +0,0 @@
|
|||||||
/*
|
|
||||||
* doomgeneric_montauk.c
|
|
||||||
* DOOM platform implementation for MontaukOS (standalone window server client)
|
|
||||||
* Copyright (c) 2025 Daniel Hammer
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "doomgeneric.h"
|
|
||||||
#include "doomkeys.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* ---- Raw syscall interface (C versions) ---- */
|
|
||||||
|
|
||||||
static inline long _zos_syscall0(long nr) {
|
|
||||||
long ret;
|
|
||||||
__asm__ volatile("syscall" : "=a"(ret) : "a"(nr)
|
|
||||||
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline long _zos_syscall1(long nr, long a1) {
|
|
||||||
long ret;
|
|
||||||
__asm__ volatile(
|
|
||||||
"mov %[a1], %%rdi\n\t"
|
|
||||||
"syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(nr), [a1] "r"(a1)
|
|
||||||
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline long _zos_syscall2(long nr, long a1, long a2) {
|
|
||||||
long ret;
|
|
||||||
__asm__ volatile(
|
|
||||||
"mov %[a1], %%rdi\n\t"
|
|
||||||
"mov %[a2], %%rsi\n\t"
|
|
||||||
"syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(nr), [a1] "r"(a1), [a2] "r"(a2)
|
|
||||||
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline long _zos_syscall4(long nr, long a1, long a2, long a3, long a4) {
|
|
||||||
long ret;
|
|
||||||
__asm__ volatile(
|
|
||||||
"mov %[a1], %%rdi\n\t"
|
|
||||||
"mov %[a2], %%rsi\n\t"
|
|
||||||
"mov %[a3], %%rdx\n\t"
|
|
||||||
"mov %[a4], %%r10\n\t"
|
|
||||||
"syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(nr), [a1] "r"(a1), [a2] "r"(a2), [a3] "r"(a3), [a4] "r"(a4)
|
|
||||||
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Syscall numbers (must match kernel/src/Api/Syscall.hpp) */
|
|
||||||
#define SYS_EXIT 0
|
|
||||||
#define SYS_SLEEP_MS 2
|
|
||||||
#define SYS_PRINT 4
|
|
||||||
#define SYS_GETMILLISECONDS 14
|
|
||||||
#define SYS_WINCREATE 54
|
|
||||||
#define SYS_WINDESTROY 55
|
|
||||||
#define SYS_WINPRESENT 56
|
|
||||||
#define SYS_WINPOLL 57
|
|
||||||
|
|
||||||
/* Window server structs (must match montauk::abi::WinCreateResult and montauk::abi::WinEvent) */
|
|
||||||
struct WinCreateResult {
|
|
||||||
int id; /* -1 on failure */
|
|
||||||
unsigned _pad;
|
|
||||||
unsigned long pixelVa; /* VA of pixel buffer in caller's address space */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WinEvent {
|
|
||||||
unsigned char type; /* 0=key, 1=mouse, 2=resize, 3=close */
|
|
||||||
unsigned char _pad[3];
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned char scancode;
|
|
||||||
char ascii;
|
|
||||||
unsigned char pressed;
|
|
||||||
unsigned char shift;
|
|
||||||
unsigned char ctrl;
|
|
||||||
unsigned char alt;
|
|
||||||
} key;
|
|
||||||
struct { int x, y, scroll; unsigned char buttons, prev_buttons; } mouse;
|
|
||||||
struct { int w, h; } resize;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---- Window state ---- */
|
|
||||||
|
|
||||||
static int g_winId = -1;
|
|
||||||
static uint32_t* g_pixBuf = 0;
|
|
||||||
|
|
||||||
/* ---- Circular key queue ---- */
|
|
||||||
|
|
||||||
#define KEY_QUEUE_SIZE 64
|
|
||||||
|
|
||||||
struct KeyQueueEntry {
|
|
||||||
int pressed;
|
|
||||||
unsigned char doomkey;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct KeyQueueEntry g_keyQueue[KEY_QUEUE_SIZE];
|
|
||||||
static int g_keyQueueRead = 0;
|
|
||||||
static int g_keyQueueWrite = 0;
|
|
||||||
|
|
||||||
static void key_queue_push(int pressed, unsigned char doomkey) {
|
|
||||||
int next = (g_keyQueueWrite + 1) % KEY_QUEUE_SIZE;
|
|
||||||
if (next == g_keyQueueRead) return; /* full, drop */
|
|
||||||
g_keyQueue[g_keyQueueWrite].pressed = pressed;
|
|
||||||
g_keyQueue[g_keyQueueWrite].doomkey = doomkey;
|
|
||||||
g_keyQueueWrite = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int key_queue_pop(int* pressed, unsigned char* doomkey) {
|
|
||||||
if (g_keyQueueRead == g_keyQueueWrite) return 0;
|
|
||||||
*pressed = g_keyQueue[g_keyQueueRead].pressed;
|
|
||||||
*doomkey = g_keyQueue[g_keyQueueRead].doomkey;
|
|
||||||
g_keyQueueRead = (g_keyQueueRead + 1) % KEY_QUEUE_SIZE;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- PS/2 scancode to ASCII table (set 1, unshifted) ---- */
|
|
||||||
|
|
||||||
static const char scancode_to_ascii[128] = {
|
|
||||||
0, 27, '1','2','3','4','5','6','7','8','9','0','-','=','\b',
|
|
||||||
'\t','q','w','e','r','t','y','u','i','o','p','[',']','\n',
|
|
||||||
0, 'a','s','d','f','g','h','j','k','l',';','\'','`',
|
|
||||||
0, '\\','z','x','c','v','b','n','m',',','.','/', 0,
|
|
||||||
'*', 0, ' '
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---- PS/2 scancode to DOOM key mapping ---- */
|
|
||||||
|
|
||||||
static unsigned char scancode_to_doomkey(unsigned char scancode, char ascii) {
|
|
||||||
switch (scancode) {
|
|
||||||
case 0x48: return KEY_UPARROW;
|
|
||||||
case 0x50: return KEY_DOWNARROW;
|
|
||||||
case 0x4B: return KEY_LEFTARROW;
|
|
||||||
case 0x4D: return KEY_RIGHTARROW;
|
|
||||||
case 0x1C: return KEY_ENTER;
|
|
||||||
case 0x01: return KEY_ESCAPE;
|
|
||||||
case 0x39: return KEY_USE; /* Space = use */
|
|
||||||
case 0x1D: return KEY_FIRE; /* LCtrl = fire */
|
|
||||||
case 0x2A: return KEY_RSHIFT; /* LShift = run */
|
|
||||||
case 0x36: return KEY_RSHIFT; /* RShift = run */
|
|
||||||
case 0x38: return KEY_RALT; /* Alt = strafe */
|
|
||||||
case 0x0E: return KEY_BACKSPACE;
|
|
||||||
case 0x0F: return KEY_TAB;
|
|
||||||
/* F1-F10 */
|
|
||||||
case 0x3B: return KEY_F1;
|
|
||||||
case 0x3C: return KEY_F2;
|
|
||||||
case 0x3D: return KEY_F3;
|
|
||||||
case 0x3E: return KEY_F4;
|
|
||||||
case 0x3F: return KEY_F5;
|
|
||||||
case 0x40: return KEY_F6;
|
|
||||||
case 0x41: return KEY_F7;
|
|
||||||
case 0x42: return KEY_F8;
|
|
||||||
case 0x43: return KEY_F9;
|
|
||||||
case 0x44: return KEY_F10;
|
|
||||||
case 0x57: return KEY_F11;
|
|
||||||
case 0x58: return KEY_F12;
|
|
||||||
/* Equals and minus for screen size */
|
|
||||||
case 0x0D: return KEY_EQUALS;
|
|
||||||
case 0x0C: return KEY_MINUS;
|
|
||||||
default:
|
|
||||||
/* Pass through printable ASCII as lowercase */
|
|
||||||
if (ascii >= 'a' && ascii <= 'z') return (unsigned char)ascii;
|
|
||||||
if (ascii >= '0' && ascii <= '9') return (unsigned char)ascii;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- Poll window events and enqueue key events ---- */
|
|
||||||
|
|
||||||
static void poll_keyboard(void) {
|
|
||||||
struct WinEvent evt;
|
|
||||||
while (_zos_syscall2(SYS_WINPOLL, (long)g_winId, (long)&evt) > 0) {
|
|
||||||
if (evt.type == 0) {
|
|
||||||
/* Key event */
|
|
||||||
unsigned char baseSc = evt.key.scancode & 0x7F;
|
|
||||||
|
|
||||||
char ascii = 0;
|
|
||||||
if (baseSc < 128)
|
|
||||||
ascii = scancode_to_ascii[baseSc];
|
|
||||||
|
|
||||||
unsigned char dk = scancode_to_doomkey(baseSc, ascii);
|
|
||||||
if (dk != 0) {
|
|
||||||
key_queue_push(evt.key.pressed ? 1 : 0, dk);
|
|
||||||
}
|
|
||||||
} else if (evt.type == 3) {
|
|
||||||
/* Close event — exit the process */
|
|
||||||
_zos_syscall1(SYS_EXIT, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- DG platform functions ---- */
|
|
||||||
|
|
||||||
void DG_Init(void) {
|
|
||||||
struct WinCreateResult result;
|
|
||||||
_zos_syscall4(SYS_WINCREATE, (long)"DOOM", (long)DOOMGENERIC_RESX,
|
|
||||||
(long)DOOMGENERIC_RESY, (long)&result);
|
|
||||||
|
|
||||||
if (result.id < 0) {
|
|
||||||
_zos_syscall1(SYS_EXIT, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_winId = result.id;
|
|
||||||
g_pixBuf = (uint32_t*)result.pixelVa;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DG_DrawFrame(void) {
|
|
||||||
/* Poll keyboard first */
|
|
||||||
poll_keyboard();
|
|
||||||
|
|
||||||
/* Copy DG_ScreenBuffer into the shared pixel buffer */
|
|
||||||
if (g_pixBuf == 0 || DG_ScreenBuffer == 0) return;
|
|
||||||
|
|
||||||
memcpy(g_pixBuf, DG_ScreenBuffer,
|
|
||||||
DOOMGENERIC_RESX * DOOMGENERIC_RESY * sizeof(uint32_t));
|
|
||||||
|
|
||||||
/* Mark window as dirty so the compositor picks it up */
|
|
||||||
_zos_syscall1(SYS_WINPRESENT, (long)g_winId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DG_SleepMs(uint32_t ms) {
|
|
||||||
_zos_syscall1(SYS_SLEEP_MS, (long)ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t DG_GetTicksMs(void) {
|
|
||||||
return (uint32_t)_zos_syscall0(SYS_GETMILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DG_GetKey(int* pressed, unsigned char* doomKey) {
|
|
||||||
return key_queue_pop(pressed, doomKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DG_SetWindowTitle(const char* title) {
|
|
||||||
(void)title;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- Entry point ---- */
|
|
||||||
|
|
||||||
/* Shows a warning dialog explaining that MontaukOS cannot ship proprietary
|
|
||||||
* DOOM WADs and does not return (implemented in doom_wad_check.cpp, which
|
|
||||||
* links against the shared dialog library). */
|
|
||||||
extern void doom_warn_missing_wad(const char* path);
|
|
||||||
|
|
||||||
void _start(void) {
|
|
||||||
static const char* wadPath = "0:/apps/doom/doom1.wad";
|
|
||||||
|
|
||||||
FILE* wad = fopen(wadPath, "rb");
|
|
||||||
if (!wad) {
|
|
||||||
doom_warn_missing_wad(wadPath);
|
|
||||||
/* unreachable: doom_warn_missing_wad() exits the process */
|
|
||||||
}
|
|
||||||
fclose(wad);
|
|
||||||
|
|
||||||
char *argv[] = { "doom", "-iwad", (char*)wadPath, 0 };
|
|
||||||
doomgeneric_Create(3, argv);
|
|
||||||
for (;;) {
|
|
||||||
doomgeneric_Tick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,362 +0,0 @@
|
|||||||
/*
|
|
||||||
* i_sound_montauk.c
|
|
||||||
* DOOM sound effects and music modules for MontaukOS
|
|
||||||
* Implements software mixing of 16 SFX channels into the HDA audio device.
|
|
||||||
* Copyright (c) 2026 Daniel Hammer
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "deh_str.h"
|
|
||||||
#include "i_sound.h"
|
|
||||||
#include "i_system.h"
|
|
||||||
#include "i_swap.h"
|
|
||||||
#include "m_argv.h"
|
|
||||||
#include "m_misc.h"
|
|
||||||
#include "w_wad.h"
|
|
||||||
#include "z_zone.h"
|
|
||||||
#include "doomtype.h"
|
|
||||||
|
|
||||||
/* ========================================================================
|
|
||||||
Raw syscall interface for audio
|
|
||||||
======================================================================== */
|
|
||||||
|
|
||||||
static inline long _snd_syscall1(long nr, long a1) {
|
|
||||||
long ret;
|
|
||||||
__asm__ volatile(
|
|
||||||
"mov %[a1], %%rdi\n\t"
|
|
||||||
"syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(nr), [a1] "r"(a1)
|
|
||||||
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline long _snd_syscall3(long nr, long a1, long a2, long a3) {
|
|
||||||
long ret;
|
|
||||||
__asm__ volatile(
|
|
||||||
"mov %[a1], %%rdi\n\t"
|
|
||||||
"mov %[a2], %%rsi\n\t"
|
|
||||||
"mov %[a3], %%rdx\n\t"
|
|
||||||
"syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(nr), [a1] "r"(a1), [a2] "r"(a2), [a3] "r"(a3)
|
|
||||||
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SYS_AUDIOOPEN 80
|
|
||||||
#define SYS_AUDIOCLOSE 81
|
|
||||||
#define SYS_AUDIOWRITE 82
|
|
||||||
|
|
||||||
/* ========================================================================
|
|
||||||
Audio mixing engine
|
|
||||||
======================================================================== */
|
|
||||||
|
|
||||||
/* Required by i_sound.c config binding */
|
|
||||||
int use_libsamplerate = 0;
|
|
||||||
float libsamplerate_scale = 0.65f;
|
|
||||||
|
|
||||||
#define NUM_CHANNELS 16
|
|
||||||
#define MIX_RATE 44100
|
|
||||||
#define MIX_CHANNELS 2
|
|
||||||
#define MIX_BITS 16
|
|
||||||
|
|
||||||
/* Samples per mix frame (~35 fps, slightly oversized for timing jitter) */
|
|
||||||
#define MIX_SAMPLES 1260
|
|
||||||
#define MIX_BUF_BYTES (MIX_SAMPLES * MIX_CHANNELS * (MIX_BITS / 8))
|
|
||||||
|
|
||||||
/* Channel state */
|
|
||||||
struct snd_channel {
|
|
||||||
const uint8_t *data; /* 8-bit unsigned PCM samples */
|
|
||||||
uint32_t length; /* number of samples */
|
|
||||||
uint32_t pos; /* playback position (16.16 fixed-point) */
|
|
||||||
uint32_t step; /* step per output sample (16.16 fixed-point) */
|
|
||||||
int vol_left; /* left volume (0-127) */
|
|
||||||
int vol_right; /* right volume (0-127) */
|
|
||||||
sfxinfo_t *sfxinfo; /* NULL = inactive */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct snd_channel channels[NUM_CHANNELS];
|
|
||||||
static int audio_handle = -1;
|
|
||||||
static boolean sound_initialized = false;
|
|
||||||
static boolean use_sfx_prefix;
|
|
||||||
|
|
||||||
/* Static mix buffer (stereo interleaved int16_t) */
|
|
||||||
static int16_t mix_buf[MIX_SAMPLES * MIX_CHANNELS];
|
|
||||||
|
|
||||||
/* ========================================================================
|
|
||||||
Sound effect loading (DMX format from WAD lumps)
|
|
||||||
======================================================================== */
|
|
||||||
|
|
||||||
static void GetSfxLumpName(sfxinfo_t *sfx, char *buf, size_t buf_len) {
|
|
||||||
if (sfx->link != NULL)
|
|
||||||
sfx = sfx->link;
|
|
||||||
|
|
||||||
if (use_sfx_prefix)
|
|
||||||
M_snprintf(buf, buf_len, "ds%s", DEH_String(sfx->name));
|
|
||||||
else
|
|
||||||
M_StringCopy(buf, DEH_String(sfx->name), buf_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse a DMX sound lump. Returns the raw 8-bit PCM data and fills in
|
|
||||||
samplerate and length. Returns NULL on failure. */
|
|
||||||
static const uint8_t *ParseDmxSound(int lumpnum, int *out_rate, uint32_t *out_len) {
|
|
||||||
unsigned int lumplen = W_LumpLength(lumpnum);
|
|
||||||
const uint8_t *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
if (lumplen < 8 || data[0] != 0x03 || data[1] != 0x00)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
int samplerate = (data[3] << 8) | data[2];
|
|
||||||
uint32_t length = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4];
|
|
||||||
|
|
||||||
if (length > lumplen - 8 || length <= 48)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* DMX skips first 16 and last 16 bytes of sample data */
|
|
||||||
*out_rate = samplerate;
|
|
||||||
*out_len = length - 32;
|
|
||||||
return data + 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================
|
|
||||||
Volume/separation helpers
|
|
||||||
======================================================================== */
|
|
||||||
|
|
||||||
static void SetChannelVolSep(int ch, int vol, int sep) {
|
|
||||||
/* vol: 0-127, sep: 0-254 (0=full left, 127=center, 254=full right) */
|
|
||||||
channels[ch].vol_left = ((254 - sep) * vol) / 127;
|
|
||||||
channels[ch].vol_right = (sep * vol) / 127;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================
|
|
||||||
Software mixer - mix all active channels into mix_buf
|
|
||||||
======================================================================== */
|
|
||||||
|
|
||||||
static void MixChannels(int num_samples) {
|
|
||||||
/* Clear mix buffer */
|
|
||||||
memset(mix_buf, 0, (size_t)(num_samples * MIX_CHANNELS) * sizeof(int16_t));
|
|
||||||
|
|
||||||
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
|
|
||||||
struct snd_channel *c = &channels[ch];
|
|
||||||
if (c->sfxinfo == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int16_t *out = mix_buf;
|
|
||||||
|
|
||||||
for (int i = 0; i < num_samples; i++) {
|
|
||||||
uint32_t ipos = c->pos >> 16;
|
|
||||||
|
|
||||||
if (ipos >= c->length) {
|
|
||||||
/* Sound finished */
|
|
||||||
c->sfxinfo = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert 8-bit unsigned (0-255, 128=silence) to signed (-128..127)
|
|
||||||
then scale to 16-bit range */
|
|
||||||
int sample = ((int)c->data[ipos] - 128) << 8;
|
|
||||||
|
|
||||||
/* Apply volume and accumulate (additive mixing) */
|
|
||||||
int left = out[i * 2 + 0] + ((sample * c->vol_left) >> 7);
|
|
||||||
int right = out[i * 2 + 1] + ((sample * c->vol_right) >> 7);
|
|
||||||
|
|
||||||
/* Clamp to int16_t range */
|
|
||||||
if (left > 32767) left = 32767;
|
|
||||||
else if (left < -32768) left = -32768;
|
|
||||||
if (right > 32767) right = 32767;
|
|
||||||
else if (right < -32768) right = -32768;
|
|
||||||
|
|
||||||
out[i * 2 + 0] = (int16_t)left;
|
|
||||||
out[i * 2 + 1] = (int16_t)right;
|
|
||||||
|
|
||||||
c->pos += c->step;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================
|
|
||||||
sound_module_t implementation
|
|
||||||
======================================================================== */
|
|
||||||
|
|
||||||
static boolean I_Montauk_InitSound(boolean _use_sfx_prefix) {
|
|
||||||
use_sfx_prefix = _use_sfx_prefix;
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
|
||||||
memset(&channels[i], 0, sizeof(channels[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
audio_handle = (int)_snd_syscall3(SYS_AUDIOOPEN,
|
|
||||||
(long)MIX_RATE, (long)MIX_CHANNELS, (long)MIX_BITS);
|
|
||||||
|
|
||||||
if (audio_handle < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sound_initialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void I_Montauk_ShutdownSound(void) {
|
|
||||||
if (!sound_initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++)
|
|
||||||
channels[i].sfxinfo = NULL;
|
|
||||||
|
|
||||||
if (audio_handle >= 0) {
|
|
||||||
_snd_syscall1(SYS_AUDIOCLOSE, (long)audio_handle);
|
|
||||||
audio_handle = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sound_initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int I_Montauk_GetSfxLumpNum(sfxinfo_t *sfx) {
|
|
||||||
char namebuf[9];
|
|
||||||
GetSfxLumpName(sfx, namebuf, sizeof(namebuf));
|
|
||||||
return W_GetNumForName(namebuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void I_Montauk_UpdateSound(void) {
|
|
||||||
if (!sound_initialized || audio_handle < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Mix one frame of audio and submit to the device */
|
|
||||||
MixChannels(MIX_SAMPLES);
|
|
||||||
|
|
||||||
const uint8_t *ptr = (const uint8_t *)mix_buf;
|
|
||||||
int remaining = MIX_BUF_BYTES;
|
|
||||||
|
|
||||||
/* Write as much as the device accepts (non-blocking) */
|
|
||||||
while (remaining > 0) {
|
|
||||||
int written = (int)_snd_syscall3(SYS_AUDIOWRITE,
|
|
||||||
(long)audio_handle, (long)ptr, (long)remaining);
|
|
||||||
if (written <= 0)
|
|
||||||
break;
|
|
||||||
ptr += written;
|
|
||||||
remaining -= written;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void I_Montauk_UpdateSoundParams(int channel, int vol, int sep) {
|
|
||||||
if (!sound_initialized || channel < 0 || channel >= NUM_CHANNELS)
|
|
||||||
return;
|
|
||||||
if (channels[channel].sfxinfo == NULL)
|
|
||||||
return;
|
|
||||||
SetChannelVolSep(channel, vol, sep);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int I_Montauk_StartSound(sfxinfo_t *sfxinfo, int channel, int vol, int sep) {
|
|
||||||
if (!sound_initialized || channel < 0 || channel >= NUM_CHANNELS)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Stop any sound already on this channel */
|
|
||||||
channels[channel].sfxinfo = NULL;
|
|
||||||
|
|
||||||
/* Load and parse the sound lump */
|
|
||||||
if (sfxinfo->lumpnum == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int samplerate;
|
|
||||||
uint32_t length;
|
|
||||||
const uint8_t *data = ParseDmxSound(sfxinfo->lumpnum, &samplerate, &length);
|
|
||||||
if (data == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Set up the channel */
|
|
||||||
channels[channel].data = data;
|
|
||||||
channels[channel].length = length;
|
|
||||||
channels[channel].pos = 0;
|
|
||||||
/* Resampling step: source_rate / MIX_RATE in 16.16 fixed-point */
|
|
||||||
channels[channel].step = ((uint32_t)samplerate << 16) / MIX_RATE;
|
|
||||||
|
|
||||||
SetChannelVolSep(channel, vol, sep);
|
|
||||||
channels[channel].sfxinfo = sfxinfo;
|
|
||||||
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void I_Montauk_StopSound(int channel) {
|
|
||||||
if (!sound_initialized || channel < 0 || channel >= NUM_CHANNELS)
|
|
||||||
return;
|
|
||||||
channels[channel].sfxinfo = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean I_Montauk_SoundIsPlaying(int channel) {
|
|
||||||
if (!sound_initialized || channel < 0 || channel >= NUM_CHANNELS)
|
|
||||||
return false;
|
|
||||||
return channels[channel].sfxinfo != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void I_Montauk_PrecacheSounds(sfxinfo_t *sounds, int num_sounds) {
|
|
||||||
/* No-op: we load on demand */
|
|
||||||
(void)sounds;
|
|
||||||
(void)num_sounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
static snddevice_t sound_montauk_devices[] = {
|
|
||||||
SNDDEVICE_SB,
|
|
||||||
SNDDEVICE_PAS,
|
|
||||||
SNDDEVICE_GUS,
|
|
||||||
SNDDEVICE_WAVEBLASTER,
|
|
||||||
SNDDEVICE_SOUNDCANVAS,
|
|
||||||
SNDDEVICE_AWE32,
|
|
||||||
};
|
|
||||||
|
|
||||||
sound_module_t DG_sound_module = {
|
|
||||||
sound_montauk_devices,
|
|
||||||
arrlen(sound_montauk_devices),
|
|
||||||
I_Montauk_InitSound,
|
|
||||||
I_Montauk_ShutdownSound,
|
|
||||||
I_Montauk_GetSfxLumpNum,
|
|
||||||
I_Montauk_UpdateSound,
|
|
||||||
I_Montauk_UpdateSoundParams,
|
|
||||||
I_Montauk_StartSound,
|
|
||||||
I_Montauk_StopSound,
|
|
||||||
I_Montauk_SoundIsPlaying,
|
|
||||||
I_Montauk_PrecacheSounds,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ========================================================================
|
|
||||||
music_module_t implementation (stub - no MIDI synthesis)
|
|
||||||
======================================================================== */
|
|
||||||
|
|
||||||
static boolean I_Montauk_InitMusic(void) { return true; }
|
|
||||||
static void I_Montauk_ShutdownMusic(void) {}
|
|
||||||
static void I_Montauk_SetMusicVolume(int vol) { (void)vol; }
|
|
||||||
static void I_Montauk_PauseMusic(void) {}
|
|
||||||
static void I_Montauk_ResumeMusic(void) {}
|
|
||||||
static void *I_Montauk_RegisterSong(void *data, int len) { (void)data; (void)len; return (void *)1; }
|
|
||||||
static void I_Montauk_UnRegisterSong(void *h) { (void)h; }
|
|
||||||
static void I_Montauk_PlaySong(void *h, boolean loop) { (void)h; (void)loop; }
|
|
||||||
static void I_Montauk_StopSong(void) {}
|
|
||||||
static boolean I_Montauk_MusicIsPlaying(void) { return false; }
|
|
||||||
static void I_Montauk_PollMusic(void) {}
|
|
||||||
|
|
||||||
static snddevice_t music_montauk_devices[] = {
|
|
||||||
SNDDEVICE_SB,
|
|
||||||
SNDDEVICE_ADLIB,
|
|
||||||
SNDDEVICE_GUS,
|
|
||||||
};
|
|
||||||
|
|
||||||
music_module_t DG_music_module = {
|
|
||||||
music_montauk_devices,
|
|
||||||
arrlen(music_montauk_devices),
|
|
||||||
I_Montauk_InitMusic,
|
|
||||||
I_Montauk_ShutdownMusic,
|
|
||||||
I_Montauk_SetMusicVolume,
|
|
||||||
I_Montauk_PauseMusic,
|
|
||||||
I_Montauk_ResumeMusic,
|
|
||||||
I_Montauk_RegisterSong,
|
|
||||||
I_Montauk_UnRegisterSong,
|
|
||||||
I_Montauk_PlaySong,
|
|
||||||
I_Montauk_StopSong,
|
|
||||||
I_Montauk_MusicIsPlaying,
|
|
||||||
I_Montauk_PollMusic,
|
|
||||||
};
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
[app]
|
|
||||||
name = "DOOM"
|
|
||||||
binary = "doom.elf"
|
|
||||||
icon = "doom.svg"
|
|
||||||
|
|
||||||
[menu]
|
|
||||||
category = "Games"
|
|
||||||
visible = true
|
|
||||||
@@ -16,7 +16,6 @@ ICON_SRC="$PROJECT_ROOT/programs/gui/icons/Flat-Remix-Blue-Light-darkPanel"
|
|||||||
# The binary is already built by each app's Makefile into bin/apps/<name>/
|
# The binary is already built by each app's Makefile into bin/apps/<name>/
|
||||||
APPS=(
|
APPS=(
|
||||||
"2048|categories/scalable/2048.svg"
|
"2048|categories/scalable/2048.svg"
|
||||||
"doom|apps/scalable/doom.svg"
|
|
||||||
"spreadsheet|mimetypes/scalable/spreadsheet.svg"
|
"spreadsheet|mimetypes/scalable/spreadsheet.svg"
|
||||||
"wordprocessor|apps/scalable/libreoffice6.0-writer.svg"
|
"wordprocessor|apps/scalable/libreoffice6.0-writer.svg"
|
||||||
"weather|apps/scalable/weather-widget.svg"
|
"weather|apps/scalable/weather-widget.svg"
|
||||||
@@ -54,6 +53,11 @@ for entry in "${APPS[@]}"; do
|
|||||||
app_dir="$BIN/apps/$name"
|
app_dir="$BIN/apps/$name"
|
||||||
mkdir -p "$app_dir"
|
mkdir -p "$app_dir"
|
||||||
|
|
||||||
|
# This bundle is in-tree. If an out-of-tree port previously claimed the
|
||||||
|
# same name, drop its marker so the release step does not mistake this
|
||||||
|
# for a port and prune it from the ISO.
|
||||||
|
rm -f "$app_dir/.port"
|
||||||
|
|
||||||
# Copy manifest
|
# Copy manifest
|
||||||
manifest="$SRC/$name/manifest.toml"
|
manifest="$SRC/$name/manifest.toml"
|
||||||
if [ -f "$manifest" ]; then
|
if [ -f "$manifest" ]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user