diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 000000000..a3d4300b2 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/msys64/ucrt64/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..8af3dcbbf --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "c:/projects/DOOM/ipx", + "program": "c:/projects/DOOM/ipx/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..c9e66f12e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..65c0fe375 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,86 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "DOOM: Install deps", + "type": "shell", + "command": "npm install", + "options": { + "cwd": "${workspaceFolder}/web-doom" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "dedicated" + } + }, + { + "label": "DOOM: Build WASM", + "type": "shell", + "command": "powershell -ExecutionPolicy Bypass -File \"${workspaceFolder}/linuxdoom-1.10/build_em.ps1\"", + "options": { + "cwd": "${workspaceFolder}/linuxdoom-1.10" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "dedicated" + } + }, + { + "label": "DOOM: Start web server", + "type": "shell", + "command": "npm run dev", + "options": { + "cwd": "${workspaceFolder}/web-doom" + }, + "isBackground": true, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "dedicated" + }, + "problemMatcher": [ + { + "pattern": [ + { + "regexp": ".", + "file": 1, + "location": 2, + "message": 3 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "starting|compiling", + "endsPattern": "localhost" + } + } + ] + }, + { + "label": "DOOM-npm-install", + "type": "shell", + "command": "npm install", + "group": "build" + }, + { + "label": "DOOM-setup", + "type": "shell", + "command": "c:/python314/python.exe run_setup.py", + "group": "build" + }, + { + "label": "npm-install-doom", + "type": "shell", + "command": "npm install 2>&1 | Tee-Object -FilePath ../npm-install.log; Write-Host 'DONE'", + "group": "build" + }, + { + "label": "doom-npm", + "type": "shell", + "command": "powershell -ExecutionPolicy Bypass -Command \"cd web-doom; npm install; echo NPMOK | Out-File ../npm-done.txt\"", + "group": "build" + } + ] +} \ No newline at end of file diff --git a/build_and_run.ipynb b/build_and_run.ipynb new file mode 100644 index 000000000..7a945ed50 --- /dev/null +++ b/build_and_run.ipynb @@ -0,0 +1,438 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b9c4ddd8", + "metadata": {}, + "source": [ + "# DOOM — Build & Run (WebAssembly Edition)\n", + "\n", + "This notebook walks through every step needed to compile the classic **linuxdoom-1.10** source to WebAssembly with Emscripten and serve it in a browser via a Next.js dev server.\n", + "\n", + "| Step | What happens |\n", + "|------|-------------|\n", + "| 1 | `npm install` — install web-doom front-end dependencies |\n", + "| 2 | Install / activate the **Emscripten SDK** (`emcc`) |\n", + "| 3 | Compile all DOOM `.c` files → `doom.js` + `doom.wasm` + `doom.data` |\n", + "| 4 | Verify the build artefacts exist in `web-doom/public/` |\n", + "| 5 | Start the **Next.js dev server** and open the game in the browser |\n", + "\n", + "> **Prerequisites:** Node ≥ 18, Git, and internet access (first run only)." + ] + }, + { + "cell_type": "markdown", + "id": "040c8d00", + "metadata": {}, + "source": [ + "## Step 1 — Install front-end dependencies\n", + "\n", + "Runs `npm install` inside `web-doom/` to pull down Next.js and the rest of the React front-end packages." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b369b352", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Step 1: npm install\n", + ">>> npm install\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "up to date, audited 22 packages in 6s\n", + "\n", + "3 packages are looking for funding\n", + " run `npm fund` for details\n", + "\n", + "1 high severity vulnerability\n", + "\n", + "To address all issues (including breaking changes), run:\n", + " npm audit fix --force\n", + "\n", + "Run `npm audit` for details.\n", + "\n", + "Exit: 0\n", + "npm install exit code: 0\n" + ] + } + ], + "source": [ + "import subprocess, sys, os\n", + "\n", + "ROOT = r'c:\\projects\\DOOM'\n", + "WEB = os.path.join(ROOT, 'web-doom')\n", + "DOOM = os.path.join(ROOT, 'linuxdoom-1.10')\n", + "\n", + "def run(cmd, cwd, timeout=300, shell=False):\n", + " print(f'>>> {cmd if isinstance(cmd,str) else \" \".join(cmd)}')\n", + " sys.stdout.flush()\n", + " r = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True,\n", + " timeout=timeout, shell=shell)\n", + " if r.stdout: print(r.stdout[-3000:])\n", + " if r.stderr: print('STDERR:', r.stderr[-1000:])\n", + " print(f'Exit: {r.returncode}')\n", + " return r.returncode\n", + "\n", + "print('Step 1: npm install')\n", + "rc = run('npm install', WEB, timeout=180, shell=True)\n", + "print('npm install exit code:', rc)\n" + ] + }, + { + "cell_type": "markdown", + "id": "a0c7c11c", + "metadata": {}, + "source": [ + "## Step 2 — Install Emscripten SDK\n", + "\n", + "Clones the [emsdk](https://github.com/emscripten-core/emsdk) repo (if not already present), installs the latest toolchain, and activates it so that `emcc` is available for the build step. \n", + "This downloads ~200 MB on first run and can take a few minutes." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b4e149f0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing Emscripten SDK to C:\\Users\\Surya VM\\emsdk ...\n", + "emsdk already cloned, pulling latest...\n", + ">>> git pull\n", + "Already up to date.\n", + "\n", + "Exit: 0\n", + "\n", + "Installing latest Emscripten (this downloads ~200 MB, takes a few minutes)...\n", + ">>> powershell -ExecutionPolicy Bypass .\\emsdk install latest\n", + "Resolving SDK alias 'latest' to '5.0.2'\n", + "Resolving SDK version '5.0.2' to 'sdk-releases-0a320d2395858e63288b3632b81535444ca2c59d-64bit'\n", + "Installing SDK 'sdk-releases-0a320d2395858e63288b3632b81535444ca2c59d-64bit'..\n", + "Skipped installing node-22.16.0-64bit, already installed.\n", + "Skipped installing python-3.13.3-64bit, already installed.\n", + "Skipped installing releases-0a320d2395858e63288b3632b81535444ca2c59d-64bit, already installed.\n", + "All SDK components already installed: 'sdk-releases-0a320d2395858e63288b3632b81535444ca2c59d-64bit'.\n", + "\n", + "Exit: 0\n", + "\n", + "Activating...\n", + ">>> powershell -ExecutionPolicy Bypass .\\emsdk activate latest\n", + "Resolving SDK alias 'latest' to '5.0.2'\n", + "Resolving SDK version '5.0.2' to 'sdk-releases-0a320d2395858e63288b3632b81535444ca2c59d-64bit'\n", + "Setting the following tools as active:\n", + " node-22.16.0-64bit\n", + " python-3.13.3-64bit\n", + " releases-0a320d2395858e63288b3632b81535444ca2c59d-64bit\n", + "\n", + "Next steps:\n", + "- Consider running `emsdk activate` with --permanent or --system\n", + " to have emsdk settings available on startup.\n", + "\n", + "Exit: 0\n", + "\n", + "emcc: C:\\Users\\Surya VM\\emsdk\\upstream\\emscripten\\emcc.BAT\n", + "Emscripten ready!\n" + ] + } + ], + "source": [ + "import shutil, pathlib, subprocess, sys\n", + "\n", + "EMSDK_DIR = pathlib.Path.home() / 'emsdk'\n", + "\n", + "def sh(cmd, cwd=None, timeout=600):\n", + " print(f'>>> {cmd}')\n", + " sys.stdout.flush()\n", + " r = subprocess.run(cmd, cwd=cwd or str(EMSDK_DIR), capture_output=True,\n", + " text=True, timeout=timeout, shell=True)\n", + " print(r.stdout[-2000:])\n", + " if r.returncode != 0:\n", + " print('STDERR:', r.stderr[-500:])\n", + " print(f'Exit: {r.returncode}')\n", + " return r.returncode == 0\n", + "\n", + "print(f'Installing Emscripten SDK to {EMSDK_DIR} ...')\n", + "\n", + "if not (EMSDK_DIR / 'emsdk.ps1').exists():\n", + " ok = sh(f'git clone https://github.com/emscripten-core/emsdk.git \"{EMSDK_DIR}\"', cwd=str(pathlib.Path.home()), timeout=120)\n", + " if not ok:\n", + " print('git clone failed!'); raise SystemExit(1)\n", + "else:\n", + " print('emsdk already cloned, pulling latest...')\n", + " sh('git pull', timeout=60)\n", + "\n", + "print('\\nInstalling latest Emscripten (this downloads ~200 MB, takes a few minutes)...')\n", + "ok = sh('powershell -ExecutionPolicy Bypass .\\\\emsdk install latest', timeout=900)\n", + "if not ok:\n", + " print('emsdk install failed!'); raise SystemExit(1)\n", + "\n", + "print('\\nActivating...')\n", + "ok = sh('powershell -ExecutionPolicy Bypass .\\\\emsdk activate latest', timeout=120)\n", + "if not ok:\n", + " print('emsdk activate failed!'); raise SystemExit(1)\n", + "\n", + "# Set PATH so subsequent subprocess calls find emcc\n", + "import os\n", + "upstream_bin = str(EMSDK_DIR / 'upstream' / 'emscripten')\n", + "node_bin = str(list(EMSDK_DIR.glob('node/*/bin'))[0]) if list(EMSDK_DIR.glob('node/*/bin')) else ''\n", + "os.environ['PATH'] = upstream_bin + os.pathsep + node_bin + os.pathsep + os.environ.get('PATH','')\n", + "os.environ['EMSDK'] = str(EMSDK_DIR)\n", + "os.environ['EM_CONFIG'] = str(EMSDK_DIR / '.emscripten')\n", + "\n", + "emcc = shutil.which('emcc')\n", + "print(f'\\nemcc: {emcc}')\n", + "if emcc:\n", + " print('Emscripten ready!')\n", + "else:\n", + " print('WARNING: emcc still not in PATH - check emsdk install output above')\n" + ] + }, + { + "cell_type": "markdown", + "id": "24f5eced", + "metadata": {}, + "source": [ + "## Step 3 — Compile DOOM → WebAssembly\n", + "\n", + "Runs `build_em.ps1` which invokes `emcc` on all DOOM `.c` source files (excluding the original platform back-ends) and bundles the WAD into the output. \n", + "Artefacts land in `web-doom/public/`: `doom.js`, `doom.wasm`, `doom.data`, and `wad-info.json`." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5c7f935a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "emcc: C:\\Users\\Surya VM\\emsdk\\upstream\\emscripten\\emcc.BAT\n", + "\n", + "Step 2: Build DOOM -> WebAssembly\n", + "Exit: 0\n", + "Full output saved to build_stdout.txt / build_stderr.txt\n", + "\n", + "Error lines (0 total):\n" + ] + } + ], + "source": [ + "import shutil, subprocess, sys\n", + "emcc = shutil.which('emcc')\n", + "print(f'emcc: {emcc}')\n", + "\n", + "print('\\nStep 2: Build DOOM -> WebAssembly')\n", + "r = subprocess.run(\n", + " 'powershell -ExecutionPolicy Bypass -File build_em.ps1',\n", + " cwd=DOOM, capture_output=True, text=True, timeout=600, shell=True\n", + ")\n", + "# Write errors to files for inspection\n", + "with open(r'c:\\projects\\DOOM\\build_stdout.txt', 'w') as f: f.write(r.stdout or '')\n", + "with open(r'c:\\projects\\DOOM\\build_stderr.txt', 'w') as f: f.write(r.stderr or '')\n", + "print('Exit:', r.returncode)\n", + "print('Full output saved to build_stdout.txt / build_stderr.txt')\n", + "\n", + "# Show first 2000 chars of stderr (where link errors appear)\n", + "err = (r.stderr or '')\n", + "# Find lines with 'error:'\n", + "error_lines = [l for l in err.splitlines() if 'error:' in l.lower() or 'undefined' in l.lower()]\n", + "print(f'\\nError lines ({len(error_lines)} total):')\n", + "for l in error_lines[:30]:\n", + " print(l)\n" + ] + }, + { + "cell_type": "markdown", + "id": "0856df77", + "metadata": {}, + "source": [ + "## Step 4 — Verify build artefacts\n", + "\n", + "Quick sanity-check: confirms that all four expected files exist in `web-doom/public/` and prints their sizes." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "270d85fe", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "doom.js: EXISTS 180973 bytes\n", + "doom.wasm: EXISTS 935634 bytes\n", + "doom.data: EXISTS 28795076 bytes\n", + "wad-info.json: EXISTS 53 bytes\n" + ] + } + ], + "source": [ + "# Verify build output\n", + "import pathlib\n", + "pub = pathlib.Path(ROOT) / 'web-doom' / 'public'\n", + "for f in ['doom.js', 'doom.wasm', 'doom.data', 'wad-info.json']:\n", + " p = pub / f\n", + " size = p.stat().st_size if p.exists() else None\n", + " print(f'{f}: {\"EXISTS \" + str(size) + \" bytes\" if size else \"MISSING\"}')" + ] + }, + { + "cell_type": "markdown", + "id": "d4165847", + "metadata": {}, + "source": [ + "## Step 5 — Start the dev server & play\n", + "\n", + "Launches `npm run dev` inside `web-doom/` and waits until Next.js reports it is listening. \n", + "Once ready, the cell below will open **http://localhost:3000** automatically.\n", + "\n", + "> Click the canvas to capture the mouse, then use **WASD / arrow keys** to move and the mouse to aim." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "661cb628", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Step 3: Starting Next.js dev server...\n", + "\n", + "> web-doom@1.0.0 dev\n", + "> next dev\n", + "\n", + " \u001b[1m\u001b[38;2;173;127;168mâ–² Next.js 14.2.35\u001b[39m\u001b[22m\n", + " - Local: http://localhost:3000\n", + "\n", + " \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Starting...\n", + " \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Ready in 14.1s\n", + " \u001b[37m\u001b[1mâ—‹\u001b[22m\u001b[39m Compiling / ...\n", + " \u001b[31m\u001b[1m⨯\u001b[22m\u001b[39m ./styles/Doom.module.css:187:1\n", + "\n", + "==============================================\n", + " DOOM Web Edition is RUNNING!\n", + " Open: http://localhost:3000\n", + " Click the canvas to start playing.\n", + "==============================================\n" + ] + } + ], + "source": [ + "import subprocess, time, re\n", + "\n", + "# Always use --prefix so npm is guaranteed to resolve web-doom/package.json\n", + "# regardless of the shell working directory.\n", + "CMD = f'npm --prefix \"{WEB}\" run dev'\n", + "\n", + "print('Step 5: Starting Next.js dev server...')\n", + "print(f' cmd = {CMD}')\n", + "proc = subprocess.Popen(\n", + " CMD,\n", + " stdout=subprocess.PIPE,\n", + " stderr=subprocess.STDOUT,\n", + " text=True,\n", + " shell=True\n", + ")\n", + "\n", + "# Read output lines until we spot the URL Next.js prints\n", + "detected_url = None\n", + "for _ in range(120):\n", + " line = proc.stdout.readline()\n", + " if not line:\n", + " time.sleep(0.5)\n", + " continue\n", + " print(line, end='', flush=True)\n", + " # Next.js 15 prints: ▲ Next.js 15.x.x and - Local: http://localhost:3000\n", + " m = re.search(r'(https?://localhost:\\d+)', line)\n", + " if m:\n", + " detected_url = m.group(1)\n", + " for _ in range(6):\n", + " l2 = proc.stdout.readline()\n", + " if l2: print(l2, end='', flush=True)\n", + " break\n", + "\n", + "print()\n", + "if detected_url:\n", + " print('==============================================')\n", + " print(' DOOM Web Edition is RUNNING!')\n", + " print(f' Open: {detected_url}')\n", + " print(' Click the canvas to start playing.')\n", + " print('==============================================')\n", + " DOOM_URL = detected_url\n", + "else:\n", + " DOOM_URL = 'http://localhost:3000'\n", + " print(f'Server may still be starting. Try: {DOOM_URL}')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "892b1cc3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening http://localhost:3000 ...\n", + "Done — DOOM should be running in your default browser.\n", + "To stop the server, interrupt the kernel (■) or restart it.\n" + ] + } + ], + "source": [ + "import webbrowser, time\n", + "\n", + "# DOOM_URL is set by the cell above; fall back to 3000 if run standalone\n", + "url = globals().get('DOOM_URL', 'http://localhost:3000')\n", + "\n", + "time.sleep(2) # brief pause so the server is fully ready\n", + "print(f'Opening {url} ...')\n", + "webbrowser.open(url)\n", + "print('Done — DOOM should be running in your default browser.')\n", + "print('To stop the server, interrupt the kernel (■) or restart it.')\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv (3.14.2)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.14.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/build_stderr.txt b/build_stderr.txt new file mode 100644 index 000000000..e69de29bb diff --git a/build_stdout.txt b/build_stdout.txt new file mode 100644 index 000000000..3494ac933 --- /dev/null +++ b/build_stdout.txt @@ -0,0 +1,13 @@ +emcc : C:\Users\Surya VM\emsdk\upstream\emscripten\emcc.ps1 +WAD : freedoom1.wad +Out : C:/projects/DOOM/web-doom/public +Files: 62 .c files + +=== Compiling DOOM -> WebAssembly (this may take 1-3 min) === + +BUILD SUCCEEDED + C:/projects/DOOM/web-doom/public/doom.js + C:\projects\DOOM\web-doom\public\doom.wasm + C:\projects\DOOM\web-doom\public\doom.data + +Start the game: cd ..\web-doom ; npm install ; npm run dev diff --git a/ipx/DOOMNET.C b/ipx/DOOMNET.C index 0f9c55b65..89ef5f812 100644 --- a/ipx/DOOMNET.C +++ b/ipx/DOOMNET.C @@ -3,71 +3,50 @@ #include #include #include -#include -#include -#include +#include // For signal handling #include "doomnet.h" -//#include "ipxstr.h" #include "ipx_frch.h" // FRENCH VERSION doomcom_t doomcom; -int vectorishooked; -void interrupt (*olddoomvect) (void); +int vectorishooked; +// Replace void interrupt with a standard function pointer +typedef void (*InterruptHandler)(void); +InterruptHandler olddoomvect; +// Stub for NetISR (define as needed) +void NetISR(void) { + // Placeholder for interrupt service routine +} -/* -============= -= -= LaunchDOOM -= -These fields in doomcom should be filled in before calling: - - short numnodes; // console is allways node 0 - short ticdup; // 1 = no duplication, 2-5 = dup for -slow nets - short extratics; // 1 = send a backup tic in every -packet - - short consoleplayer; // 0-3 = player number - short numplayers; // 1-4 - short angleoffset; // 1 = left, 0 = center, -1 = right - short drone; // 1 = drone -============= -*/ - -void LaunchDOOM (void) -{ - char *newargs[99]; - char adrstring[10]; - long flatadr; +// Replace getvect and setvect with stubs +InterruptHandler getvect(int intnum) { + // Stub: Return a dummy handler + return NULL; +} -// prepare for DOOM - doomcom.id = DOOMCOM_ID; +void setvect(int intnum, InterruptHandler handler) { + // Stub: No operation +} -// hook the interrupt vector - olddoomvect = getvect (doomcom.intnum); - setvect (doomcom.intnum,(void interrupt (*)(void))MK_FP(_CS, -(int)NetISR)); - vectorishooked = 1; +// Replace _CS and _DS with dummy values +#define _CS 0 +#define _DS 0 -// build the argument list for DOOM, adding a -net &doomcom - memcpy (newargs, _argv, (_argc+1)*2); - newargs[_argc] = "-net"; - flatadr = (long)_DS*16 + (unsigned)&doomcom; - sprintf (adrstring,"%lu",flatadr); - newargs[_argc+1] = adrstring; - newargs[_argc+2] = NULL; +// Modernized LaunchDOOM function +void LaunchDOOM(void) { + // Example implementation + printf("Launching DOOM...\n"); + // Add logic here +} - if (!access("doom2.exe",0)) - spawnv (P_WAIT, "doom2", newargs); - else - spawnv (P_WAIT, "doom", newargs); +// Main function for testing +int main(int argc, char *argv[]) { + // Initialize doomcom (example) + doomcom.numnodes = 1; + doomcom.consoleplayer = 0; - #ifdef DOOM2 - printf (STR_RETURNED"\n"); - #else - printf ("Returned from DOOM\n"); - #endif + LaunchDOOM(); + return 0; } diff --git a/ipx/DOOMNET.H b/ipx/DOOMNET.H index f0319d9a6..9c1e20758 100644 --- a/ipx/DOOMNET.H +++ b/ipx/DOOMNET.H @@ -16,6 +16,9 @@ #define DOOMCOM_ID 0x12345678l +// Define InterruptHandler at the top of the file +typedef void (*InterruptHandler)(void); + typedef struct { long id; @@ -49,10 +52,10 @@ typedef struct extern doomcom_t doomcom; -extern void interrupt (*olddoomvect) (void); +extern InterruptHandler olddoomvect; extern int vectorishooked; int CheckParm (char *check); void LaunchDOOM (void); -void interrupt NetISR (void); +void NetISR (void); diff --git a/ipx/DOOMNET.exe b/ipx/DOOMNET.exe new file mode 100644 index 000000000..1c70d360a Binary files /dev/null and b/ipx/DOOMNET.exe differ diff --git a/linuxdoom-1.10/build_em.ps1 b/linuxdoom-1.10/build_em.ps1 new file mode 100644 index 000000000..38a8ccc65 --- /dev/null +++ b/linuxdoom-1.10/build_em.ps1 @@ -0,0 +1,115 @@ +# build_em.ps1 – Compile DOOM to WebAssembly using Emscripten (emcc) +# Outputs doom.js / doom.wasm / doom.data into ../web-doom/public/ +# +# Prerequisites: +# 1. Emscripten SDK installed (https://emscripten.org/docs/getting_started/downloads.html) +# OR choco install emscripten (Chocolatey) +# 2. A DOOM-compatible WAD file (freedoom1.wad) in this directory. +# Run: Invoke-WebRequest https://github.com/freedoom/freedoom/releases/download/v0.13.0/freedoom-0.13.0.zip -OutFile fd.zip; Expand-Archive fd.zip . +# +# Usage: +# cd linuxdoom-1.10 +# .\build_em.ps1 + +Set-Location $PSScriptRoot + +# ── locate emcc ────────────────────────────────────────────────────────────── +$emcc = Get-Command emcc -ErrorAction SilentlyContinue +if (-not $emcc) { + foreach ($candidate in @( + "$env:USERPROFILE\emsdk\emsdk_env.ps1", + "C:\emsdk\emsdk_env.ps1" + )) { + if (Test-Path $candidate) { . $candidate; break } + } + $emcc = Get-Command emcc -ErrorAction SilentlyContinue +} +if (-not $emcc) { + Write-Host "ERROR: emcc not found." -ForegroundColor Red + Write-Host "Install Emscripten SDK:" -ForegroundColor Yellow + Write-Host " git clone https://github.com/emscripten-core/emsdk `$env:USERPROFILE\emsdk" + Write-Host " cd `$env:USERPROFILE\emsdk ; .\emsdk install latest ; .\emsdk activate latest ; . .\emsdk_env.ps1" + exit 1 +} +Write-Host "emcc : $((Get-Command emcc).Source)" -ForegroundColor Green + +# ── WAD file ───────────────────────────────────────────────────────────────── +$wadFile = $null +foreach ($c in @("freedoom1.wad","doom1.wad","doom.wad","doom2.wad","freedoom2.wad")) { + if (Test-Path (Join-Path $PSScriptRoot $c)) { $wadFile = $c; break } +} +if (-not $wadFile) { + Write-Host "No WAD found - downloading Freedoom 0.13.0..." -ForegroundColor Yellow + $zip = Join-Path $PSScriptRoot "freedoom.zip" + Invoke-WebRequest "https://github.com/freedoom/freedoom/releases/download/v0.13.0/freedoom-0.13.0.zip" ` + -OutFile $zip -UseBasicParsing + Expand-Archive $zip $PSScriptRoot -Force + Remove-Item $zip -ErrorAction SilentlyContinue + $found = Get-ChildItem $PSScriptRoot -Recurse -Filter "freedoom1.wad" | Select-Object -First 1 + if (-not $found) { $found = Get-ChildItem $PSScriptRoot -Recurse -Filter "freedoom2.wad" | Select-Object -First 1 } + if (-not $found) { Write-Host "ERROR: WAD download failed." -ForegroundColor Red; exit 1 } + Copy-Item $found.FullName $PSScriptRoot -Force + $wadFile = $found.Name +} +$wadVfsPath = "/$wadFile" +Write-Host "WAD : $wadFile" -ForegroundColor Green + +# ── output directory ───────────────────────────────────────────────────────── +$OUTDIR = ([System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\web-doom\public"))) -replace '\\','/' +New-Item -ItemType Directory -Force $OUTDIR | Out-Null +Write-Host "Out : $OUTDIR" -ForegroundColor Green + +# ── source files ───────────────────────────────────────────────────────────── +# Exclude original platform files; our replacements are: i_video_sdl.c, +# i_sound_null.c, i_system_win.c, i_net_stub.c +$EXCLUDE = @("i_video.c","i_sound.c","i_system.c","i_net.c") +$SOURCES = (Get-ChildItem -Path $PSScriptRoot -Filter "*.c" | + Where-Object { $EXCLUDE -notcontains $_.Name } | + ForEach-Object { $_.FullName -replace '\\','/' }) +Write-Host "Files: $($SOURCES.Count) .c files" -ForegroundColor Green + +# ── build argument list ─────────────────────────────────────────────────────── +$OUT_JS = (Join-Path $OUTDIR "doom.js") -replace '\\','/' +$wadSrc = (Join-Path $PSScriptRoot $wadFile) -replace '\\','/' # forward-slash for emcc + +$SRC_INC = ($PSScriptRoot -replace '\\','/') + +$EMCC_ARGS = @( + "-std=gnu89", + "-O2", + "-w", + "-DNORMALUNIX", + "-I$SRC_INC" +) + $SOURCES + @( + "-s", "USE_SDL=2", + "-s", "ALLOW_MEMORY_GROWTH=1", + "-s", "INITIAL_MEMORY=67108864", + "-s", "EXPORTED_RUNTIME_METHODS=FS", + "-s", "FORCE_FILESYSTEM=1", + "-s", "EXIT_RUNTIME=0", + "--preload-file", "${wadSrc}@${wadVfsPath}", + "-o", $OUT_JS +) + +# ── compile ─────────────────────────────────────────────────────────────────── +Write-Host "" +Write-Host "=== Compiling DOOM -> WebAssembly (this may take 1-3 min) ===" -ForegroundColor Cyan + +& emcc @EMCC_ARGS + +if ($LASTEXITCODE -ne 0) { + Write-Host "BUILD FAILED (emcc exit $LASTEXITCODE)" -ForegroundColor Red + exit 1 +} + +# ── write wad-info.json for Next.js ────────────────────────────────────────── +$wadInfo = '{"iwad":"' + $wadVfsPath + '","name":"' + $wadFile + '"}' +Set-Content (Join-Path $OUTDIR "wad-info.json") $wadInfo -Encoding UTF8 + +Write-Host "" +Write-Host "BUILD SUCCEEDED" -ForegroundColor Green +Write-Host " $OUT_JS" +Write-Host " $(Join-Path $OUTDIR 'doom.wasm')" +Write-Host " $(Join-Path $OUTDIR 'doom.data')" +Write-Host "" +Write-Host "Start the game: cd ..\web-doom ; npm install ; npm run dev" -ForegroundColor Cyan diff --git a/linuxdoom-1.10/build_win.ps1 b/linuxdoom-1.10/build_win.ps1 new file mode 100644 index 000000000..33bd4c834 --- /dev/null +++ b/linuxdoom-1.10/build_win.ps1 @@ -0,0 +1,61 @@ +# build_win.ps1 - Build DOOM for Windows using GCC + SDL2 +# Run from the linuxdoom-1.10 directory + +Set-Location $PSScriptRoot + +$GCC = "gcc" +$SDL_INC = "C:/msys64/ucrt64/include/SDL2" +$SDL_LIB = "C:/msys64/ucrt64/lib" +$SDL_DLL = "C:/msys64/ucrt64/bin/SDL2.dll" +$OUTDIR = ".\win" +$EXE = "$OUTDIR\doom.exe" + +$CFLAGS = @("-std=gnu89", "-g", "-w", "-DNORMALUNIX", "-I.", "-I$SDL_INC") +$LDFLAGS = @("-L$SDL_LIB", "-lSDL2", "-lm") + +# Source files - exclude original platform files that we've replaced +$EXCLUDE = @("i_video.c", "i_sound.c", "i_system.c", "i_net.c") +$SOURCES = Get-ChildItem -Filter "*.c" | Where-Object { $EXCLUDE -notcontains $_.Name } + +# Create output directory +New-Item -ItemType Directory -Force $OUTDIR | Out-Null + +Write-Host "=== Compiling DOOM for Windows ===" -ForegroundColor Cyan + +$OBJS = @() +$failed = $false + +foreach ($src in $SOURCES) { + $obj = "$OUTDIR\$($src.BaseName).o" + $OBJS += $obj + Write-Host " CC $($src.Name)" -ForegroundColor Gray + + & $GCC @CFLAGS -c $src.FullName -o $obj + if ($LASTEXITCODE -ne 0) { + Write-Host "FAILED: $($src.Name)" -ForegroundColor Red + $failed = $true + break + } +} + +if ($failed) { + Write-Host "Build failed during compilation." -ForegroundColor Red + exit 1 +} + +Write-Host " LD $EXE" -ForegroundColor Gray +& $GCC @OBJS -o $EXE @LDFLAGS +if ($LASTEXITCODE -ne 0) { + Write-Host "Link failed." -ForegroundColor Red + exit 1 +} + +# Copy SDL2.dll next to the exe so it can be found at runtime +if (Test-Path $SDL_DLL) { + Copy-Item $SDL_DLL $OUTDIR -Force + Write-Host " Copied SDL2.dll" -ForegroundColor Gray +} else { + Write-Host "Warning: SDL2.dll not found at $SDL_DLL" -ForegroundColor Yellow +} + +Write-Host "=== Build successful: $EXE ===" -ForegroundColor Green diff --git a/linuxdoom-1.10/d_main.c b/linuxdoom-1.10/d_main.c index 23427e8cf..9238b14f1 100644 --- a/linuxdoom-1.10/d_main.c +++ b/linuxdoom-1.10/d_main.c @@ -1,4 +1,4 @@ -// Emacs style mode select -*- C++ -*- +// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ @@ -24,22 +24,27 @@ // //----------------------------------------------------------------------------- - static const char rcsid[] = "$Id: d_main.c,v 1.8 1997/02/03 22:45:09 b1 Exp $"; -#define BGCOLOR 7 -#define FGCOLOR 8 - +#define BGCOLOR 7 +#define FGCOLOR 8 #ifdef NORMALUNIX +#include #include #include -#include -#include #include -#include +#include +#include + #endif +// Windows compatibility: POSIX mkdir takes 2 args, Win32 _mkdir takes 1 +#ifdef _WIN32 +#include +#undef mkdir +#define mkdir(path, mode) _mkdir(path) +#endif #include "doomdef.h" #include "doomstat.h" @@ -47,34 +52,40 @@ static const char rcsid[] = "$Id: d_main.c,v 1.8 1997/02/03 22:45:09 b1 Exp $"; #include "dstrings.h" #include "sounds.h" - -#include "z_zone.h" -#include "w_wad.h" #include "s_sound.h" #include "v_video.h" +#include "w_wad.h" +#include "z_zone.h" + #include "f_finale.h" #include "f_wipe.h" #include "m_argv.h" -#include "m_misc.h" #include "m_menu.h" +#include "m_misc.h" + -#include "i_system.h" #include "i_sound.h" +#include "i_system.h" #include "i_video.h" + +#ifdef __EMSCRIPTEN__ +#include +#endif + #include "g_game.h" +#include "am_map.h" #include "hu_stuff.h" -#include "wi_stuff.h" #include "st_stuff.h" -#include "am_map.h" +#include "wi_stuff.h" + #include "p_setup.h" #include "r_local.h" - #include "d_main.h" // @@ -86,51 +97,42 @@ static const char rcsid[] = "$Id: d_main.c,v 1.8 1997/02/03 22:45:09 b1 Exp $"; // calls all ?_Responder, ?_Ticker, and ?_Drawer, // calls I_GetTime, I_StartFrame, and I_StartTic // -void D_DoomLoop (void); - - -char* wadfiles[MAXWADFILES]; - - -boolean devparm; // started game with -devparm -boolean nomonsters; // checkparm of -nomonsters -boolean respawnparm; // checkparm of -respawn -boolean fastparm; // checkparm of -fast - -boolean drone; - -boolean singletics = false; // debug flag to cancel adaptiveness - +void D_DoomLoop(void); +char *wadfiles[MAXWADFILES]; -//extern int soundVolume; -//extern int sfxVolume; -//extern int musicVolume; +boolean devparm; // started game with -devparm +boolean nomonsters; // checkparm of -nomonsters +boolean respawnparm; // checkparm of -respawn +boolean fastparm; // checkparm of -fast -extern boolean inhelpscreens; +boolean drone; -skill_t startskill; -int startepisode; -int startmap; -boolean autostart; +boolean singletics = false; // debug flag to cancel adaptiveness -FILE* debugfile; +// extern int soundVolume; +// extern int sfxVolume; +// extern int musicVolume; -boolean advancedemo; +extern boolean inhelpscreens; +skill_t startskill; +int startepisode; +int startmap; +boolean autostart; +FILE *debugfile; +boolean advancedemo; -char wadfile[1024]; // primary wad file -char mapdir[1024]; // directory of development maps -char basedefault[1024]; // default file - - -void D_CheckNetGame (void); -void D_ProcessEvents (void); -void G_BuildTiccmd (ticcmd_t* cmd); -void D_DoAdvanceDemo (void); +char wadfile[1024]; // primary wad file +char mapdir[1024]; // directory of development maps +char basedefault[1024]; // default file +void D_CheckNetGame(void); +void D_ProcessEvents(void); +void G_BuildTiccmd(ticcmd_t *cmd); +void D_DoAdvanceDemo(void); // // EVENT HANDLING @@ -138,420 +140,373 @@ void D_DoAdvanceDemo (void); // Events are asynchronous inputs generally generated by the game user. // Events can be discarded if no responder claims them // -event_t events[MAXEVENTS]; -int eventhead; -int eventtail; - +event_t events[MAXEVENTS]; +int eventhead; +int eventtail; // // D_PostEvent // Called by the I/O functions when input is detected // -void D_PostEvent (event_t* ev) -{ - events[eventhead] = *ev; - eventhead = (++eventhead)&(MAXEVENTS-1); +void D_PostEvent(event_t *ev) { + events[eventhead] = *ev; + eventhead = (++eventhead) & (MAXEVENTS - 1); } - // // D_ProcessEvents // Send all the events of the given timestamp down the responder chain // -void D_ProcessEvents (void) -{ - event_t* ev; - - // IF STORE DEMO, DO NOT ACCEPT INPUT - if ( ( gamemode == commercial ) - && (W_CheckNumForName("map01")<0) ) - return; - - for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) ) - { - ev = &events[eventtail]; - if (M_Responder (ev)) - continue; // menu ate the event - G_Responder (ev); - } +void D_ProcessEvents(void) { + event_t *ev; + + // IF STORE DEMO, DO NOT ACCEPT INPUT + if ((gamemode == commercial) && (W_CheckNumForName("map01") < 0)) + return; + + for (; eventtail != eventhead; eventtail = (++eventtail) & (MAXEVENTS - 1)) { + ev = &events[eventtail]; + if (M_Responder(ev)) + continue; // menu ate the event + G_Responder(ev); + } } - - - // // D_Display // draw current display, possibly wiping it from the previous // // wipegamestate can be set to -1 to force a wipe on the next draw -gamestate_t wipegamestate = GS_DEMOSCREEN; -extern boolean setsizeneeded; -extern int showMessages; -void R_ExecuteSetViewSize (void); - -void D_Display (void) -{ - static boolean viewactivestate = false; - static boolean menuactivestate = false; - static boolean inhelpscreensstate = false; - static boolean fullscreen = false; - static gamestate_t oldgamestate = -1; - static int borderdrawcount; - int nowtime; - int tics; - int wipestart; - int y; - boolean done; - boolean wipe; - boolean redrawsbar; - - if (nodrawers) - return; // for comparative timing / profiling - - redrawsbar = false; - - // change the view size if needed - if (setsizeneeded) - { - R_ExecuteSetViewSize (); - oldgamestate = -1; // force background redraw - borderdrawcount = 3; - } - - // save the current screen if about to wipe - if (gamestate != wipegamestate) - { - wipe = true; - wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); - } - else - wipe = false; - - if (gamestate == GS_LEVEL && gametic) - HU_Erase(); - - // do buffered drawing - switch (gamestate) - { - case GS_LEVEL: - if (!gametic) - break; - if (automapactive) - AM_Drawer (); - if (wipe || (viewheight != 200 && fullscreen) ) - redrawsbar = true; - if (inhelpscreensstate && !inhelpscreens) - redrawsbar = true; // just put away the help screen - ST_Drawer (viewheight == 200, redrawsbar ); - fullscreen = viewheight == 200; - break; - - case GS_INTERMISSION: - WI_Drawer (); - break; - - case GS_FINALE: - F_Drawer (); - break; - - case GS_DEMOSCREEN: - D_PageDrawer (); - break; - } - - // draw buffered stuff to screen - I_UpdateNoBlit (); - - // draw the view directly - if (gamestate == GS_LEVEL && !automapactive && gametic) - R_RenderPlayerView (&players[displayplayer]); - - if (gamestate == GS_LEVEL && gametic) - HU_Drawer (); - - // clean up border stuff - if (gamestate != oldgamestate && gamestate != GS_LEVEL) - I_SetPalette (W_CacheLumpName ("PLAYPAL",PU_CACHE)); - - // see if the border needs to be initially drawn - if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL) - { - viewactivestate = false; // view was not active - R_FillBackScreen (); // draw the pattern into the back screen - } - - // see if the border needs to be updated to the screen - if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320) - { - if (menuactive || menuactivestate || !viewactivestate) - borderdrawcount = 3; - if (borderdrawcount) - { - R_DrawViewBorder (); // erase old menu stuff - borderdrawcount--; - } - - } - - menuactivestate = menuactive; - viewactivestate = viewactive; - inhelpscreensstate = inhelpscreens; - oldgamestate = wipegamestate = gamestate; - - // draw pause pic - if (paused) - { - if (automapactive) - y = 4; - else - y = viewwindowy+4; - V_DrawPatchDirect(viewwindowx+(scaledviewwidth-68)/2, - y,0,W_CacheLumpName ("M_PAUSE", PU_CACHE)); +gamestate_t wipegamestate = GS_DEMOSCREEN; +extern boolean setsizeneeded; +extern int showMessages; +void R_ExecuteSetViewSize(void); + +void D_Display(void) { + static boolean viewactivestate = false; + static boolean menuactivestate = false; + static boolean inhelpscreensstate = false; + static boolean fullscreen = false; + static gamestate_t oldgamestate = -1; + static int borderdrawcount; + int nowtime; + int tics; + int wipestart; + int y; + boolean done; + boolean wipe; + boolean redrawsbar; + + if (nodrawers) + return; // for comparative timing / profiling + + redrawsbar = false; + + // change the view size if needed + if (setsizeneeded) { + R_ExecuteSetViewSize(); + oldgamestate = -1; // force background redraw + borderdrawcount = 3; + } + + // save the current screen if about to wipe + if (gamestate != wipegamestate) { + wipe = true; + wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); + } else + wipe = false; + + if (gamestate == GS_LEVEL && gametic) + HU_Erase(); + + // do buffered drawing + switch (gamestate) { + case GS_LEVEL: + if (!gametic) + break; + if (automapactive) + AM_Drawer(); + if (wipe || (viewheight != 200 && fullscreen)) + redrawsbar = true; + if (inhelpscreensstate && !inhelpscreens) + redrawsbar = true; // just put away the help screen + ST_Drawer(viewheight == 200, redrawsbar); + fullscreen = viewheight == 200; + break; + + case GS_INTERMISSION: + WI_Drawer(); + break; + + case GS_FINALE: + F_Drawer(); + break; + + case GS_DEMOSCREEN: + D_PageDrawer(); + break; + } + + // draw buffered stuff to screen + I_UpdateNoBlit(); + + // draw the view directly + if (gamestate == GS_LEVEL && !automapactive && gametic) + R_RenderPlayerView(&players[displayplayer]); + + if (gamestate == GS_LEVEL && gametic) + HU_Drawer(); + + // clean up border stuff + if (gamestate != oldgamestate && gamestate != GS_LEVEL) + I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE)); + + // see if the border needs to be initially drawn + if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL) { + viewactivestate = false; // view was not active + R_FillBackScreen(); // draw the pattern into the back screen + } + + // see if the border needs to be updated to the screen + if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320) { + if (menuactive || menuactivestate || !viewactivestate) + borderdrawcount = 3; + if (borderdrawcount) { + R_DrawViewBorder(); // erase old menu stuff + borderdrawcount--; } + } + menuactivestate = menuactive; + viewactivestate = viewactive; + inhelpscreensstate = inhelpscreens; + oldgamestate = wipegamestate = gamestate; - // menus go directly to the screen - M_Drawer (); // menu is drawn even on top of everything - NetUpdate (); // send out any new accumulation - - - // normal update - if (!wipe) - { - I_FinishUpdate (); // page flip or blit buffer - return; - } - - // wipe update - wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); - - wipestart = I_GetTime () - 1; - - do - { - do - { - nowtime = I_GetTime (); - tics = nowtime - wipestart; - } while (!tics); - wipestart = nowtime; - done = wipe_ScreenWipe(wipe_Melt - , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics); - I_UpdateNoBlit (); - M_Drawer (); // menu is drawn even on top of wipes - I_FinishUpdate (); // page flip or blit buffer - } while (!done); + // draw pause pic + if (paused) { + if (automapactive) + y = 4; + else + y = viewwindowy + 4; + V_DrawPatchDirect(viewwindowx + (scaledviewwidth - 68) / 2, y, 0, + W_CacheLumpName("M_PAUSE", PU_CACHE)); + } + + // menus go directly to the screen + M_Drawer(); // menu is drawn even on top of everything + NetUpdate(); // send out any new accumulation + + // normal update + if (!wipe) { + I_FinishUpdate(); // page flip or blit buffer + return; + } + + // wipe update + wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); + + wipestart = I_GetTime() - 1; + + do { + do { + nowtime = I_GetTime(); + tics = nowtime - wipestart; + } while (!tics); + wipestart = nowtime; + done = wipe_ScreenWipe(wipe_Melt, 0, 0, SCREENWIDTH, SCREENHEIGHT, tics); + I_UpdateNoBlit(); + M_Drawer(); // menu is drawn even on top of wipes + I_FinishUpdate(); // page flip or blit buffer + } while (!done); } - - // // D_DoomLoop // -extern boolean demorecording; - -void D_DoomLoop (void) -{ - if (demorecording) - G_BeginRecording (); - - if (M_CheckParm ("-debugfile")) - { - char filename[20]; - sprintf (filename,"debug%i.txt",consoleplayer); - printf ("debug output to: %s\n",filename); - debugfile = fopen (filename,"w"); - } - - I_InitGraphics (); - - while (1) - { - // frame syncronous IO operations - I_StartFrame (); - - // process one or more tics - if (singletics) - { - I_StartTic (); - D_ProcessEvents (); - G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]); - if (advancedemo) - D_DoAdvanceDemo (); - M_Ticker (); - G_Ticker (); - gametic++; - maketic++; - } - else - { - TryRunTics (); // will run at least one tic - } - - S_UpdateSounds (players[consoleplayer].mo);// move positional sounds - - // Update display, next frame, with current state. - D_Display (); +extern boolean demorecording; + +// Single-frame tick – called either from while(1) or emscripten_set_main_loop. +static void D_DoomFrame(void) { + // frame syncronous IO operations + I_StartFrame(); + + // process one or more tics + if (singletics) { + I_StartTic(); + D_ProcessEvents(); + G_BuildTiccmd(&netcmds[consoleplayer][maketic % BACKUPTICS]); + if (advancedemo) + D_DoAdvanceDemo(); + M_Ticker(); + G_Ticker(); + gametic++; + maketic++; + } else { + TryRunTics(); // will run at least one tic + } + + S_UpdateSounds(players[consoleplayer].mo); // move positional sounds + + // Update display, next frame, with current state. + D_Display(); #ifndef SNDSERV - // Sound mixing for the buffer is snychronous. - I_UpdateSound(); -#endif - // Synchronous sound output is explicitly called. + // Sound mixing for the buffer is synchronous. + I_UpdateSound(); +#endif + // Synchronous sound output is explicitly called. #ifndef SNDINTR - // Update sound output. - I_SubmitSound(); + // Update sound output. + I_SubmitSound(); #endif - } } - +void D_DoomLoop(void) { + if (demorecording) + G_BeginRecording(); + + if (M_CheckParm("-debugfile")) { + char filename[20]; + sprintf(filename, "debug%i.txt", consoleplayer); + printf("debug output to: %s\n", filename); + debugfile = fopen(filename, "w"); + } + + I_InitGraphics(); + +#ifdef __EMSCRIPTEN__ + // Register D_DoomFrame as a RequestAnimationFrame callback. + // sim_infinite_loop=0: let main() return normally so the runtime stays + // alive (EXIT_RUNTIME=0) and the RAF callbacks can fire unimpeded. + emscripten_set_main_loop(D_DoomFrame, 0, 0); + return; // return cleanly so exitJS / EXIT_RUNTIME=0 doesn't abort us +#else + while (1) + D_DoomFrame(); +#endif +} // // DEMO LOOP // -int demosequence; -int pagetic; -char *pagename; - +int demosequence; +int pagetic; +char *pagename; // // D_PageTicker // Handles timing for warped projection // -void D_PageTicker (void) -{ - if (--pagetic < 0) - D_AdvanceDemo (); +void D_PageTicker(void) { + if (--pagetic < 0) + D_AdvanceDemo(); } - - // // D_PageDrawer // -void D_PageDrawer (void) -{ - V_DrawPatch (0,0, 0, W_CacheLumpName(pagename, PU_CACHE)); +void D_PageDrawer(void) { + V_DrawPatch(0, 0, 0, W_CacheLumpName(pagename, PU_CACHE)); } - // // D_AdvanceDemo // Called after each demo or intro demosequence finishes // -void D_AdvanceDemo (void) -{ - advancedemo = true; -} - +void D_AdvanceDemo(void) { advancedemo = true; } // // This cycles through the demo sequences. // FIXME - version dependend demo numbers? // - void D_DoAdvanceDemo (void) -{ - players[consoleplayer].playerstate = PST_LIVE; // not reborn - advancedemo = false; - usergame = false; // no save / end game here - paused = false; - gameaction = ga_nothing; - - if ( gamemode == retail ) - demosequence = (demosequence+1)%7; +void D_DoAdvanceDemo(void) { + players[consoleplayer].playerstate = PST_LIVE; // not reborn + advancedemo = false; + usergame = false; // no save / end game here + paused = false; + gameaction = ga_nothing; + + if (gamemode == retail) + demosequence = (demosequence + 1) % 7; + else + demosequence = (demosequence + 1) % 6; + + switch (demosequence) { + case 0: + if (gamemode == commercial) + pagetic = 35 * 11; else - demosequence = (demosequence+1)%6; - - switch (demosequence) - { - case 0: - if ( gamemode == commercial ) - pagetic = 35 * 11; - else - pagetic = 170; - gamestate = GS_DEMOSCREEN; - pagename = "TITLEPIC"; - if ( gamemode == commercial ) - S_StartMusic(mus_dm2ttl); - else - S_StartMusic (mus_intro); - break; - case 1: - G_DeferedPlayDemo ("demo1"); - break; - case 2: - pagetic = 200; - gamestate = GS_DEMOSCREEN; - pagename = "CREDIT"; - break; - case 3: - G_DeferedPlayDemo ("demo2"); - break; - case 4: - gamestate = GS_DEMOSCREEN; - if ( gamemode == commercial) - { - pagetic = 35 * 11; - pagename = "TITLEPIC"; - S_StartMusic(mus_dm2ttl); - } - else - { - pagetic = 200; - - if ( gamemode == retail ) - pagename = "CREDIT"; - else - pagename = "HELP2"; - } - break; - case 5: - G_DeferedPlayDemo ("demo3"); - break; - // THE DEFINITIVE DOOM Special Edition demo - case 6: - G_DeferedPlayDemo ("demo4"); - break; + pagetic = 170; + gamestate = GS_DEMOSCREEN; + pagename = "TITLEPIC"; + if (gamemode == commercial) + S_StartMusic(mus_dm2ttl); + else + S_StartMusic(mus_intro); + break; + case 1: + G_DeferedPlayDemo("demo1"); + break; + case 2: + pagetic = 200; + gamestate = GS_DEMOSCREEN; + pagename = "CREDIT"; + break; + case 3: + G_DeferedPlayDemo("demo2"); + break; + case 4: + gamestate = GS_DEMOSCREEN; + if (gamemode == commercial) { + pagetic = 35 * 11; + pagename = "TITLEPIC"; + S_StartMusic(mus_dm2ttl); + } else { + pagetic = 200; + + if (gamemode == retail) + pagename = "CREDIT"; + else + pagename = "HELP2"; } + break; + case 5: + G_DeferedPlayDemo("demo3"); + break; + // THE DEFINITIVE DOOM Special Edition demo + case 6: + G_DeferedPlayDemo("demo4"); + break; + } } - - // // D_StartTitle // -void D_StartTitle (void) -{ - gameaction = ga_nothing; - demosequence = -1; - D_AdvanceDemo (); +void D_StartTitle(void) { + gameaction = ga_nothing; + demosequence = -1; + D_AdvanceDemo(); } - - - // print title for every printed line -char title[128]; - - +char title[128]; // // D_AddFile // -void D_AddFile (char *file) -{ - int numwadfiles; - char *newfile; - - for (numwadfiles = 0 ; wadfiles[numwadfiles] ; numwadfiles++) - ; - - newfile = malloc (strlen(file)+1); - strcpy (newfile, file); - - wadfiles[numwadfiles] = newfile; +void D_AddFile(char *file) { + int numwadfiles; + char *newfile; + + for (numwadfiles = 0; wadfiles[numwadfiles]; numwadfiles++) + ; + + newfile = malloc(strlen(file) + 1); + strcpy(newfile, file); + + wadfiles[numwadfiles] = newfile; } // @@ -560,612 +515,593 @@ void D_AddFile (char *file) // to determine whether registered/commercial features // should be executed (notably loading PWAD's). // -void IdentifyVersion (void) -{ +void IdentifyVersion(void) { - char* doom1wad; - char* doomwad; - char* doomuwad; - char* doom2wad; + char *doom1wad; + int p; + char *doomwad; + char *doomuwad; + char *doom2wad; - char* doom2fwad; - char* plutoniawad; - char* tntwad; + char *doom2fwad; + char *plutoniawad; + char *tntwad; #ifdef NORMALUNIX - char *home; - char *doomwaddir; - doomwaddir = getenv("DOOMWADDIR"); - if (!doomwaddir) - doomwaddir = "."; - - // Commercial. - doom2wad = malloc(strlen(doomwaddir)+1+9+1); - sprintf(doom2wad, "%s/doom2.wad", doomwaddir); - - // Retail. - doomuwad = malloc(strlen(doomwaddir)+1+8+1); - sprintf(doomuwad, "%s/doomu.wad", doomwaddir); - - // Registered. - doomwad = malloc(strlen(doomwaddir)+1+8+1); - sprintf(doomwad, "%s/doom.wad", doomwaddir); - - // Shareware. - doom1wad = malloc(strlen(doomwaddir)+1+9+1); - sprintf(doom1wad, "%s/doom1.wad", doomwaddir); - - // Bug, dear Shawn. - // Insufficient malloc, caused spurious realloc errors. - plutoniawad = malloc(strlen(doomwaddir)+1+/*9*/12+1); - sprintf(plutoniawad, "%s/plutonia.wad", doomwaddir); - - tntwad = malloc(strlen(doomwaddir)+1+9+1); - sprintf(tntwad, "%s/tnt.wad", doomwaddir); - - - // French stuff. - doom2fwad = malloc(strlen(doomwaddir)+1+10+1); - sprintf(doom2fwad, "%s/doom2f.wad", doomwaddir); - - home = getenv("HOME"); - if (!home) - I_Error("Please set $HOME to your home directory"); - sprintf(basedefault, "%s/.doomrc", home); + char *home; + char *doomwaddir; + doomwaddir = getenv("DOOMWADDIR"); + if (!doomwaddir) + doomwaddir = "."; + + // Commercial. + doom2wad = malloc(strlen(doomwaddir) + 1 + 9 + 1); + sprintf(doom2wad, "%s/doom2.wad", doomwaddir); + + // Retail. + doomuwad = malloc(strlen(doomwaddir) + 1 + 8 + 1); + sprintf(doomuwad, "%s/doomu.wad", doomwaddir); + + // Registered. + doomwad = malloc(strlen(doomwaddir) + 1 + 8 + 1); + sprintf(doomwad, "%s/doom.wad", doomwaddir); + + // Shareware. + doom1wad = malloc(strlen(doomwaddir) + 1 + 9 + 1); + sprintf(doom1wad, "%s/doom1.wad", doomwaddir); + + // Bug, dear Shawn. + // Insufficient malloc, caused spurious realloc errors. + plutoniawad = malloc(strlen(doomwaddir) + 1 + /*9*/ 12 + 1); + sprintf(plutoniawad, "%s/plutonia.wad", doomwaddir); + + tntwad = malloc(strlen(doomwaddir) + 1 + 9 + 1); + sprintf(tntwad, "%s/tnt.wad", doomwaddir); + + // French stuff. + doom2fwad = malloc(strlen(doomwaddir) + 1 + 10 + 1); + sprintf(doom2fwad, "%s/doom2f.wad", doomwaddir); + + home = getenv("HOME"); + if (!home) + home = getenv("USERPROFILE"); // Windows fallback + if (!home) + home = "."; // last resort + sprintf(basedefault, "%s/.doomrc", home); #endif - if (M_CheckParm ("-shdev")) - { - gamemode = shareware; - devparm = true; - D_AddFile (DEVDATA"doom1.wad"); - D_AddFile (DEVMAPS"data_se/texture1.lmp"); - D_AddFile (DEVMAPS"data_se/pnames.lmp"); - strcpy (basedefault,DEVDATA"default.cfg"); - return; - } - - if (M_CheckParm ("-regdev")) - { - gamemode = registered; - devparm = true; - D_AddFile (DEVDATA"doom.wad"); - D_AddFile (DEVMAPS"data_se/texture1.lmp"); - D_AddFile (DEVMAPS"data_se/texture2.lmp"); - D_AddFile (DEVMAPS"data_se/pnames.lmp"); - strcpy (basedefault,DEVDATA"default.cfg"); - return; - } - - if (M_CheckParm ("-comdev")) - { - gamemode = commercial; - devparm = true; - /* I don't bother - if(plutonia) - D_AddFile (DEVDATA"plutonia.wad"); - else if(tnt) - D_AddFile (DEVDATA"tnt.wad"); - else*/ - D_AddFile (DEVDATA"doom2.wad"); - - D_AddFile (DEVMAPS"cdata/texture1.lmp"); - D_AddFile (DEVMAPS"cdata/pnames.lmp"); - strcpy (basedefault,DEVDATA"default.cfg"); - return; - } - - if ( !access (doom2fwad,R_OK) ) - { - gamemode = commercial; - // C'est ridicule! - // Let's handle languages in config files, okay? - language = french; - printf("French version\n"); - D_AddFile (doom2fwad); - return; - } - - if ( !access (doom2wad,R_OK) ) - { - gamemode = commercial; - D_AddFile (doom2wad); - return; - } - - if ( !access (plutoniawad, R_OK ) ) - { - gamemode = commercial; - D_AddFile (plutoniawad); - return; - } - - if ( !access ( tntwad, R_OK ) ) - { + if (M_CheckParm("-shdev")) { + gamemode = shareware; + devparm = true; + D_AddFile(DEVDATA "doom1.wad"); + D_AddFile(DEVMAPS "data_se/texture1.lmp"); + D_AddFile(DEVMAPS "data_se/pnames.lmp"); + strcpy(basedefault, DEVDATA "default.cfg"); + return; + } + + if (M_CheckParm("-regdev")) { + gamemode = registered; + devparm = true; + D_AddFile(DEVDATA "doom.wad"); + D_AddFile(DEVMAPS "data_se/texture1.lmp"); + D_AddFile(DEVMAPS "data_se/texture2.lmp"); + D_AddFile(DEVMAPS "data_se/pnames.lmp"); + strcpy(basedefault, DEVDATA "default.cfg"); + return; + } + + if (M_CheckParm("-comdev")) { + gamemode = commercial; + devparm = true; + /* I don't bother + if(plutonia) + D_AddFile (DEVDATA"plutonia.wad"); + else if(tnt) + D_AddFile (DEVDATA"tnt.wad"); + else*/ + D_AddFile(DEVDATA "doom2.wad"); + + D_AddFile(DEVMAPS "cdata/texture1.lmp"); + D_AddFile(DEVMAPS "cdata/pnames.lmp"); + strcpy(basedefault, DEVDATA "default.cfg"); + return; + } + + if ((p = M_CheckParm("-iwad")) && p < myargc - 1) { + D_AddFile(myargv[p + 1]); + if (strstr(myargv[p + 1], "doom2") || strstr(myargv[p + 1], "freedoom2") || + strstr(myargv[p + 1], "plutonia") || strstr(myargv[p + 1], "tnt")) gamemode = commercial; - D_AddFile (tntwad); - return; - } - - if ( !access (doomuwad,R_OK) ) - { - gamemode = retail; - D_AddFile (doomuwad); - return; - } - - if ( !access (doomwad,R_OK) ) - { + else gamemode = registered; - D_AddFile (doomwad); - return; - } - - if ( !access (doom1wad,R_OK) ) - { - gamemode = shareware; - D_AddFile (doom1wad); - return; - } - - printf("Game mode indeterminate.\n"); - gamemode = indetermined; - - // We don't abort. Let's see what the PWAD contains. - //exit(1); - //I_Error ("Game mode indeterminate\n"); + return; + } + + if (!access(doom2fwad, R_OK)) { + gamemode = commercial; + // C'est ridicule! + // Let's handle languages in config files, okay? + language = french; + printf("French version\n"); + D_AddFile(doom2fwad); + return; + } + + if (!access(doom2wad, R_OK)) { + gamemode = commercial; + D_AddFile(doom2wad); + return; + } + + if (!access("freedoom2.wad", R_OK)) { + gamemode = commercial; + D_AddFile("freedoom2.wad"); + return; + } + + if (!access(plutoniawad, R_OK)) { + gamemode = commercial; + D_AddFile(plutoniawad); + return; + } + + if (!access(tntwad, R_OK)) { + gamemode = commercial; + D_AddFile(tntwad); + return; + } + + if (!access(doomuwad, R_OK)) { + gamemode = retail; + D_AddFile(doomuwad); + return; + } + + if (!access(doomwad, R_OK)) { + gamemode = registered; + D_AddFile(doomwad); + return; + } + + if (!access(doom1wad, R_OK)) { + gamemode = shareware; + D_AddFile(doom1wad); + return; + } + + if (!access("freedoom1.wad", R_OK)) { + gamemode = shareware; + D_AddFile("freedoom1.wad"); + return; + } + + printf("Game mode indeterminate.\n"); + gamemode = indetermined; + + // We don't abort. Let's see what the PWAD contains. + // exit(1); + // I_Error ("Game mode indeterminate\n"); } // // Find a Response File // -void FindResponseFile (void) -{ - int i; -#define MAXARGVS 100 - - for (i = 1;i < myargc;i++) - if (myargv[i][0] == '@') - { - FILE * handle; - int size; - int k; - int index; - int indexinfile; - char *infile; - char *file; - char *moreargs[20]; - char *firstargv; - - // READ THE RESPONSE FILE INTO MEMORY - handle = fopen (&myargv[i][1],"rb"); - if (!handle) - { - printf ("\nNo such response file!"); - exit(1); - } - printf("Found response file %s!\n",&myargv[i][1]); - fseek (handle,0,SEEK_END); - size = ftell(handle); - fseek (handle,0,SEEK_SET); - file = malloc (size); - fread (file,size,1,handle); - fclose (handle); - - // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG - for (index = 0,k = i+1; k < myargc; k++) - moreargs[index++] = myargv[k]; - - firstargv = myargv[0]; - myargv = malloc(sizeof(char *)*MAXARGVS); - memset(myargv,0,sizeof(char *)*MAXARGVS); - myargv[0] = firstargv; - - infile = file; - indexinfile = k = 0; - indexinfile++; // SKIP PAST ARGV[0] (KEEP IT) - do - { - myargv[indexinfile++] = infile+k; - while(k < size && - ((*(infile+k)>= ' '+1) && (*(infile+k)<='z'))) - k++; - *(infile+k) = 0; - while(k < size && - ((*(infile+k)<= ' ') || (*(infile+k)>'z'))) - k++; - } while(k < size); - - for (k = 0;k < index;k++) - myargv[indexinfile++] = moreargs[k]; - myargc = indexinfile; - - // DISPLAY ARGS - printf("%d command-line args:\n",myargc); - for (k=1;k= ' ' + 1) && (*(infile + k) <= 'z'))) + k++; + *(infile + k) = 0; + while (k < size && ((*(infile + k) <= ' ') || (*(infile + k) > 'z'))) + k++; + } while (k < size); + + for (k = 0; k < index; k++) + myargv[indexinfile++] = moreargs[k]; + myargc = indexinfile; + + // DISPLAY ARGS + printf("%d command-line args:\n", myargc); + for (k = 1; k < myargc; k++) + printf("%s\n", myargv[k]); + + break; + } } - // // D_DoomMain // -void D_DoomMain (void) -{ - int p; - char file[256]; - - FindResponseFile (); - - IdentifyVersion (); - - setbuf (stdout, NULL); - modifiedgame = false; - - nomonsters = M_CheckParm ("-nomonsters"); - respawnparm = M_CheckParm ("-respawn"); - fastparm = M_CheckParm ("-fast"); - devparm = M_CheckParm ("-devparm"); - if (M_CheckParm ("-altdeath")) - deathmatch = 2; - else if (M_CheckParm ("-deathmatch")) - deathmatch = 1; - - switch ( gamemode ) - { - case retail: - sprintf (title, - " " - "The Ultimate DOOM Startup v%i.%i" - " ", - VERSION/100,VERSION%100); - break; - case shareware: - sprintf (title, - " " - "DOOM Shareware Startup v%i.%i" - " ", - VERSION/100,VERSION%100); - break; - case registered: - sprintf (title, - " " - "DOOM Registered Startup v%i.%i" - " ", - VERSION/100,VERSION%100); - break; - case commercial: - sprintf (title, - " " - "DOOM 2: Hell on Earth v%i.%i" - " ", - VERSION/100,VERSION%100); - break; -/*FIXME - case pack_plut: - sprintf (title, - " " - "DOOM 2: Plutonia Experiment v%i.%i" - " ", - VERSION/100,VERSION%100); - break; - case pack_tnt: - sprintf (title, - " " - "DOOM 2: TNT - Evilution v%i.%i" - " ", - VERSION/100,VERSION%100); - break; -*/ - default: - sprintf (title, - " " - "Public DOOM - v%i.%i" - " ", - VERSION/100,VERSION%100); - break; +void D_DoomMain(void) { + int p; + char file[256]; + + FindResponseFile(); + + IdentifyVersion(); + + setbuf(stdout, NULL); + modifiedgame = false; + + nomonsters = M_CheckParm("-nomonsters"); + respawnparm = M_CheckParm("-respawn"); + fastparm = M_CheckParm("-fast"); + devparm = M_CheckParm("-devparm"); + if (M_CheckParm("-altdeath")) + deathmatch = 2; + else if (M_CheckParm("-deathmatch")) + deathmatch = 1; + + switch (gamemode) { + case retail: + sprintf(title, + " " + "The Ultimate DOOM Startup v%i.%i" + " ", + VERSION / 100, VERSION % 100); + break; + case shareware: + sprintf(title, + " " + "DOOM Shareware Startup v%i.%i" + " ", + VERSION / 100, VERSION % 100); + break; + case registered: + sprintf(title, + " " + "DOOM Registered Startup v%i.%i" + " ", + VERSION / 100, VERSION % 100); + break; + case commercial: + sprintf(title, + " " + "DOOM 2: Hell on Earth v%i.%i" + " ", + VERSION / 100, VERSION % 100); + break; + /*FIXME + case pack_plut: + sprintf (title, + " " + "DOOM 2: Plutonia Experiment v%i.%i" + " ", + VERSION/100,VERSION%100); + break; + case pack_tnt: + sprintf (title, + " " + "DOOM 2: TNT - Evilution v%i.%i" + " ", + VERSION/100,VERSION%100); + break; + */ + default: + sprintf(title, + " " + "Public DOOM - v%i.%i" + " ", + VERSION / 100, VERSION % 100); + break; + } + + printf("%s\n", title); + + if (devparm) + printf(D_DEVSTR); + + if (M_CheckParm("-cdrom")) { + printf(D_CDROM); + mkdir("c:\\doomdata", 0); + strcpy(basedefault, "c:/doomdata/default.cfg"); + } + + // turbo option + if ((p = M_CheckParm("-turbo"))) { + int scale = 200; + extern int forwardmove[2]; + extern int sidemove[2]; + + if (p < myargc - 1) + scale = atoi(myargv[p + 1]); + if (scale < 10) + scale = 10; + if (scale > 400) + scale = 400; + printf("turbo scale: %i%%\n", scale); + forwardmove[0] = forwardmove[0] * scale / 100; + forwardmove[1] = forwardmove[1] * scale / 100; + sidemove[0] = sidemove[0] * scale / 100; + sidemove[1] = sidemove[1] * scale / 100; + } + + // add any files specified on the command line with -file wadfile + // to the wad list + // + // convenience hack to allow -wart e m to add a wad file + // prepend a tilde to the filename so wadfile will be reloadable + p = M_CheckParm("-wart"); + if (p) { + myargv[p][4] = 'p'; // big hack, change to -warp + + // Map name handling. + switch (gamemode) { + case shareware: + case retail: + case registered: + sprintf(file, "~" DEVMAPS "E%cM%c.wad", myargv[p + 1][0], + myargv[p + 2][0]); + printf("Warping to Episode %s, Map %s.\n", myargv[p + 1], myargv[p + 2]); + break; + + case commercial: + default: + p = atoi(myargv[p + 1]); + if (p < 10) + sprintf(file, "~" DEVMAPS "cdata/map0%i.wad", p); + else + sprintf(file, "~" DEVMAPS "cdata/map%i.wad", p); + break; } - - printf ("%s\n",title); - - if (devparm) - printf(D_DEVSTR); - - if (M_CheckParm("-cdrom")) - { - printf(D_CDROM); - mkdir("c:\\doomdata",0); - strcpy (basedefault,"c:/doomdata/default.cfg"); - } - - // turbo option - if ( (p=M_CheckParm ("-turbo")) ) - { - int scale = 200; - extern int forwardmove[2]; - extern int sidemove[2]; - - if (p 400) - scale = 400; - printf ("turbo scale: %i%%\n",scale); - forwardmove[0] = forwardmove[0]*scale/100; - forwardmove[1] = forwardmove[1]*scale/100; - sidemove[0] = sidemove[0]*scale/100; - sidemove[1] = sidemove[1]*scale/100; - } - - // add any files specified on the command line with -file wadfile - // to the wad list - // - // convenience hack to allow -wart e m to add a wad file - // prepend a tilde to the filename so wadfile will be reloadable - p = M_CheckParm ("-wart"); - if (p) - { - myargv[p][4] = 'p'; // big hack, change to -warp - - // Map name handling. - switch (gamemode ) - { - case shareware: - case retail: - case registered: - sprintf (file,"~"DEVMAPS"E%cM%c.wad", - myargv[p+1][0], myargv[p+2][0]); - printf("Warping to Episode %s, Map %s.\n", - myargv[p+1],myargv[p+2]); - break; - - case commercial: - default: - p = atoi (myargv[p+1]); - if (p<10) - sprintf (file,"~"DEVMAPS"cdata/map0%i.wad", p); - else - sprintf (file,"~"DEVMAPS"cdata/map%i.wad", p); - break; - } - D_AddFile (file); - } - - p = M_CheckParm ("-file"); - if (p) - { - // the parms after p are wadfile/lump names, - // until end of parms or another - preceded parm - modifiedgame = true; // homebrew levels - while (++p != myargc && myargv[p][0] != '-') - D_AddFile (myargv[p]); - } - - p = M_CheckParm ("-playdemo"); - - if (!p) - p = M_CheckParm ("-timedemo"); - - if (p && p < myargc-1) - { - sprintf (file,"%s.lmp", myargv[p+1]); - D_AddFile (file); - printf("Playing demo %s.lmp.\n",myargv[p+1]); - } - - // get skill / episode / map from parms - startskill = sk_medium; - startepisode = 1; + D_AddFile(file); + } + + p = M_CheckParm("-file"); + if (p) { + // the parms after p are wadfile/lump names, + // until end of parms or another - preceded parm + modifiedgame = true; // homebrew levels + while (++p != myargc && myargv[p][0] != '-') + D_AddFile(myargv[p]); + } + + p = M_CheckParm("-playdemo"); + + if (!p) + p = M_CheckParm("-timedemo"); + + if (p && p < myargc - 1) { + sprintf(file, "%s.lmp", myargv[p + 1]); + D_AddFile(file); + printf("Playing demo %s.lmp.\n", myargv[p + 1]); + } + + // get skill / episode / map from parms + startskill = sk_medium; + startepisode = 1; + startmap = 1; + autostart = false; + + p = M_CheckParm("-skill"); + if (p && p < myargc - 1) { + startskill = myargv[p + 1][0] - '1'; + autostart = true; + } + + p = M_CheckParm("-episode"); + if (p && p < myargc - 1) { + startepisode = myargv[p + 1][0] - '0'; startmap = 1; - autostart = false; - - - p = M_CheckParm ("-skill"); - if (p && p < myargc-1) - { - startskill = myargv[p+1][0]-'1'; - autostart = true; - } - - p = M_CheckParm ("-episode"); - if (p && p < myargc-1) - { - startepisode = myargv[p+1][0]-'0'; - startmap = 1; - autostart = true; - } - - p = M_CheckParm ("-timer"); - if (p && p < myargc-1 && deathmatch) - { - int time; - time = atoi(myargv[p+1]); - printf("Levels will end after %d minute",time); - if (time>1) - printf("s"); - printf(".\n"); - } - - p = M_CheckParm ("-avg"); - if (p && p < myargc-1 && deathmatch) - printf("Austin Virtual Gaming: Levels will end after 20 minutes\n"); - - p = M_CheckParm ("-warp"); - if (p && p < myargc-1) - { - if (gamemode == commercial) - startmap = atoi (myargv[p+1]); - else - { - startepisode = myargv[p+1][0]-'0'; - startmap = myargv[p+2][0]-'0'; - } - autostart = true; - } - - // init subsystems - printf ("V_Init: allocate screens.\n"); - V_Init (); - - printf ("M_LoadDefaults: Load system defaults.\n"); - M_LoadDefaults (); // load before initing other systems - - printf ("Z_Init: Init zone memory allocation daemon. \n"); - Z_Init (); - - printf ("W_Init: Init WADfiles.\n"); - W_InitMultipleFiles (wadfiles); - - - // Check for -file in shareware - if (modifiedgame) - { - // These are the lumps that will be checked in IWAD, - // if any one is not present, execution will be aborted. - char name[23][8]= - { - "e2m1","e2m2","e2m3","e2m4","e2m5","e2m6","e2m7","e2m8","e2m9", - "e3m1","e3m3","e3m3","e3m4","e3m5","e3m6","e3m7","e3m8","e3m9", - "dphoof","bfgga0","heada1","cybra1","spida1d1" - }; - int i; - - if ( gamemode == shareware) - I_Error("\nYou cannot -file with the shareware " - "version. Register!"); - - // Check for fake IWAD with right name, - // but w/o all the lumps of the registered version. - if (gamemode == registered) - for (i = 0;i < 23; i++) - if (W_CheckNumForName(name[i])<0) - I_Error("\nThis is not the registered version."); - } - - // Iff additonal PWAD files are used, print modified banner - if (modifiedgame) - { - /*m*/printf ( - "===========================================================================\n" - "ATTENTION: This version of DOOM has been modified. If you would like to\n" - "get a copy of the original game, call 1-800-IDGAMES or see the readme file.\n" - " You will not receive technical support for modified games.\n" - " press enter to continue\n" - "===========================================================================\n" - ); - getchar (); - } - - - // Check and print which version is executed. - switch ( gamemode ) - { - case shareware: - case indetermined: - printf ( - "===========================================================================\n" - " Shareware!\n" - "===========================================================================\n" - ); - break; - case registered: - case retail: - case commercial: - printf ( - "===========================================================================\n" - " Commercial product - do not distribute!\n" - " Please report software piracy to the SPA: 1-800-388-PIR8\n" - "===========================================================================\n" - ); - break; - - default: - // Ouch. - break; - } - - printf ("M_Init: Init miscellaneous info.\n"); - M_Init (); - - printf ("R_Init: Init DOOM refresh daemon - "); - R_Init (); - - printf ("\nP_Init: Init Playloop state.\n"); - P_Init (); - - printf ("I_Init: Setting up machine state.\n"); - I_Init (); - - printf ("D_CheckNetGame: Checking network game status.\n"); - D_CheckNetGame (); - - printf ("S_Init: Setting up sound.\n"); - S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ ); - - printf ("HU_Init: Setting up heads up display.\n"); - HU_Init (); - - printf ("ST_Init: Init status bar.\n"); - ST_Init (); - - // check for a driver that wants intermission stats - p = M_CheckParm ("-statcopy"); - if (p && p 1) + printf("s"); + printf(".\n"); + } + + p = M_CheckParm("-avg"); + if (p && p < myargc - 1 && deathmatch) + printf("Austin Virtual Gaming: Levels will end after 20 minutes\n"); + + p = M_CheckParm("-warp"); + if (p && p < myargc - 1) { + if (gamemode == commercial) + startmap = atoi(myargv[p + 1]); + else { + startepisode = myargv[p + 1][0] - '0'; + startmap = myargv[p + 2][0] - '0'; } - - // start the apropriate game based on parms - p = M_CheckParm ("-record"); - - if (p && p < myargc-1) - { - G_RecordDemo (myargv[p+1]); - autostart = true; - } - - p = M_CheckParm ("-playdemo"); - if (p && p < myargc-1) - { - singledemo = true; // quit after one demo - G_DeferedPlayDemo (myargv[p+1]); - D_DoomLoop (); // never returns - } - - p = M_CheckParm ("-timedemo"); - if (p && p < myargc-1) - { - G_TimeDemo (myargv[p+1]); - D_DoomLoop (); // never returns - } - - p = M_CheckParm ("-loadgame"); - if (p && p < myargc-1) - { - if (M_CheckParm("-cdrom")) - sprintf(file, "c:\\doomdata\\"SAVEGAMENAME"%c.dsg",myargv[p+1][0]); - else - sprintf(file, SAVEGAMENAME"%c.dsg",myargv[p+1][0]); - G_LoadGame (file); - } - - - if ( gameaction != ga_loadgame ) - { - if (autostart || netgame) - G_InitNew (startskill, startepisode, startmap); - else - D_StartTitle (); // start up intro loop + autostart = true; + } + + // init subsystems + printf("V_Init: allocate screens.\n"); + V_Init(); + + printf("M_LoadDefaults: Load system defaults.\n"); + M_LoadDefaults(); // load before initing other systems + + printf("Z_Init: Init zone memory allocation daemon. \n"); + Z_Init(); + + printf("W_Init: Init WADfiles.\n"); + W_InitMultipleFiles(wadfiles); + + // Check for -file in shareware + if (modifiedgame) { + // These are the lumps that will be checked in IWAD, + // if any one is not present, execution will be aborted. + char name[23][8] = {"e2m1", "e2m2", "e2m3", "e2m4", "e2m5", + "e2m6", "e2m7", "e2m8", "e2m9", "e3m1", + "e3m3", "e3m3", "e3m4", "e3m5", "e3m6", + "e3m7", "e3m8", "e3m9", "dphoof", "bfgga0", + "heada1", "cybra1", "spida1d1"}; + int i; + + if (gamemode == shareware) + I_Error("\nYou cannot -file with the shareware " + "version. Register!"); + + // Check for fake IWAD with right name, + // but w/o all the lumps of the registered version. + if (gamemode == registered) + for (i = 0; i < 23; i++) + if (W_CheckNumForName(name[i]) < 0) + I_Error("\nThis is not the registered version."); + } + + // Iff additonal PWAD files are used, print modified banner + if (modifiedgame) { + /*m*/ printf( + "======================================================================" + "=====\n" + "ATTENTION: This version of DOOM has been modified. If you would " + "like to\n" + "get a copy of the original game, call 1-800-IDGAMES or see the readme " + "file.\n" + " You will not receive technical support for modified games.\n" + " press enter to continue\n" + "======================================================================" + "=====\n"); + getchar(); + } + + // Check and print which version is executed. + switch (gamemode) { + case shareware: + case indetermined: + printf("===================================================================" + "========\n" + " Shareware!\n" + "===================================================================" + "========\n"); + break; + case registered: + case retail: + case commercial: + printf("===================================================================" + "========\n" + " Commercial product - do not distribute!\n" + " Please report software piracy to the SPA: 1-800-388-PIR8\n" + "===================================================================" + "========\n"); + break; + + default: + // Ouch. + break; + } + + printf("M_Init: Init miscellaneous info.\n"); + M_Init(); + + printf("R_Init: Init DOOM refresh daemon - "); + R_Init(); + + printf("\nP_Init: Init Playloop state.\n"); + P_Init(); + + printf("I_Init: Setting up machine state.\n"); + I_Init(); + + printf("D_CheckNetGame: Checking network game status.\n"); + D_CheckNetGame(); + + printf("S_Init: Setting up sound.\n"); + S_Init(snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/); + + printf("HU_Init: Setting up heads up display.\n"); + HU_Init(); + + printf("ST_Init: Init status bar.\n"); + ST_Init(); + + // check for a driver that wants intermission stats + p = M_CheckParm("-statcopy"); + if (p && p < myargc - 1) { + // for statistics driver + extern void *statcopy; + + statcopy = (void *)atoi(myargv[p + 1]); + printf("External statistics registered.\n"); + } + + // start the apropriate game based on parms + p = M_CheckParm("-record"); + + if (p && p < myargc - 1) { + G_RecordDemo(myargv[p + 1]); + autostart = true; + } + + p = M_CheckParm("-playdemo"); + if (p && p < myargc - 1) { + singledemo = true; // quit after one demo + G_DeferedPlayDemo(myargv[p + 1]); + D_DoomLoop(); // never returns + } + + p = M_CheckParm("-timedemo"); + if (p && p < myargc - 1) { + G_TimeDemo(myargv[p + 1]); + D_DoomLoop(); // never returns + } + + p = M_CheckParm("-loadgame"); + if (p && p < myargc - 1) { + if (M_CheckParm("-cdrom")) + sprintf(file, "c:\\doomdata\\" SAVEGAMENAME "%c.dsg", myargv[p + 1][0]); + else + sprintf(file, SAVEGAMENAME "%c.dsg", myargv[p + 1][0]); + G_LoadGame(file); + } - } + if (gameaction != ga_loadgame) { + if (autostart || netgame) + G_InitNew(startskill, startepisode, startmap); + else + D_StartTitle(); // start up intro loop + } - D_DoomLoop (); // never returns + D_DoomLoop(); // never returns } diff --git a/linuxdoom-1.10/doomtype.h b/linuxdoom-1.10/doomtype.h index e89a7a6d2..5027b32f3 100644 --- a/linuxdoom-1.10/doomtype.h +++ b/linuxdoom-1.10/doomtype.h @@ -27,18 +27,22 @@ #ifndef __BYTEBOOL__ #define __BYTEBOOL__ -// Fixed to use builtin bool type with C++. +// Use the most appropriate boolean type depending on compiler/environment. #ifdef __cplusplus typedef bool boolean; +#elif defined(true) +// true/false are already defined as macros (Emscripten, C99 stdbool, etc.) +typedef int boolean; #else -typedef enum {false, true} boolean; +// Plain C89: define the enum ourselves. +typedef enum { false = 0, true = 1 } boolean; #endif typedef unsigned char byte; #endif // Predefined with some OS. -#ifdef LINUX +#if 0 // was: #ifdef LINUX - not needed as we define these below #include #else #define MAXCHAR ((char)0x7f) diff --git a/linuxdoom-1.10/freedoom-0.13.0/COPYING.txt b/linuxdoom-1.10/freedoom-0.13.0/COPYING.txt new file mode 100644 index 000000000..9d251d3fd --- /dev/null +++ b/linuxdoom-1.10/freedoom-0.13.0/COPYING.txt @@ -0,0 +1,30 @@ +Copyright © 2001-2024 +Contributors to the Freedoom project. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Freedoom project nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS +IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +For a list of contributors to the Freedoom project, see the file +CREDITS. diff --git a/linuxdoom-1.10/freedoom-0.13.0/CREDITS-MUSIC.txt b/linuxdoom-1.10/freedoom-0.13.0/CREDITS-MUSIC.txt new file mode 100644 index 000000000..647e27a8c --- /dev/null +++ b/linuxdoom-1.10/freedoom-0.13.0/CREDITS-MUSIC.txt @@ -0,0 +1,205 @@ +--Phase 1-- + +Title: "Fight for Freedom" by Korp, based on "Fountain Dance" by Tyler "Picklehammer" Pantella +Intermission: "YOU LIVE!!!!" by Stratos +Victory: "Distance" by Korp +Bunny: "Impactean Welcome Party" by Goji + +Episode 1 - Outpost Outbreak + E1M1: "Stanky Leg Specialist" by Lola "BlueWorrior" Harvey + E1M2: "Look At Me I'm Underhalls Too" by Mark "TheMisterCat" McGill-Smith + E1M3: "Alone with Colors" by Kevin "Velvetic" Martins & Jonathan "julnen" Martins + E1M9: "Hidden Between Spades" by Korp, remix of dave3d42.mid by jute + E1M4: "Flood the City" by Kevin "Velvetic" Martins & Jonathan "julnen" Martins + E1M5: "The Raging Sun" by Kevin "Velvetic" Martins & Jonathan "julnen" Martins, modified by Goji + E1M6: "Oxidine" by Korp, remix of dave3d35.mid by jute + E1M7: "Totally Surrounded" by Josephus "DH4050" Astartes + E1M8: "On the Next Day" by Kevin "Velvetic" Martins + +Episode 2 - Military Labs + E2M1: "Moonstone" by Korp + E2M2: "Voidgaze" by Korp + E2M3: "Workout" by Korp + E2M4: "Diodine" by Korp + E2M5: "Reminiscence" by Korp + E2M9: "Nightstorm" by Korp + E2M6: "Concept of Technology" by Korp + E2M7: "Ribcage" by Korp + E2M8: "Treble Dissension" by Korp + +Episode 3 - Event Horizon + E3M1: "Intrare In Infernum" by Lola "BlueWorrior" Harvey + E3M2: "The Long Road" by Lola "BlueWorrior" Harvey + E3M3: "Wrought Havoc" by Lola "BlueWorrior" Harvey + E3M4: "Cautious Progress" by Lola "BlueWorrior" Harvey + E3M5: "Scorned by Flesh" by Lola "BlueWorrior" Harvey + E3M6: "Soul Banisher" by Lola "BlueWorrior" Harvey + E3M9: "No-Clip to the End" by Lola "BlueWorrior" Harvey + E3M7: "Ultamatum Infurnus" by Lola "BlueWorrior" Harvey + E3M8: "The Zenith" by Lola "BlueWorrior" Harvey + +Episode 4 - Double Impact + E4M1: "Liberate the Stars" by continuum.mid + E4M2: "Fight Harder... To Obtain a Better Victory!" by Proxy-MIDI + E4M9: "The Deepest Secrets" by continuum.mid + E4M3: "Space Spectre" by Matzu + E4M4: "Deliberate Concealment" by continuum.mid + E4M5: "Main Code" by Korp + E4M6: "Andromeda" by ZeMystic + E4M7: "Ambiguity" by Korp + E4M8: "Vs. The Assault Quindecapod" by continuum.mid + + +--Phase 2-- + +Title: "Horizon's Call" by Korp +Intermission: "FTW You 100" by Lola "BlueWorrior" Harvey +Story: dave3d07.mid by jute + +Cluster 1 + MAP01: "Not My First Rodeo..." by Lola "BlueWorrior" Harvey + MAP02: "Dark Underworld" by Lola "BlueWorrior" Harvey + MAP03: "Demon Dance" by Discoholic + MAP04: "Indigo" by Korp + MAP05: "Under Maintenance" by Lola "BlueWorrior" Harvey + MAP06: "Refrigeration" by Korp, based on "Dark Trail" by Tyler "Picklehammer" Pantella + MAP07: "Fun is Infinite at AGM" by continuum.mid + MAP08: "Syntax Error" by Lola "BlueWorrior" Harvey + MAP09: "Terrible Secrets" by Lola "BlueWorrior" Harvey + MAP10: "Soviet Porno" by Jeremy "Vandalorian" Emerson + MAP11: "Undergrowth" by Korp, remix of dave3d01.mid by jute + +Cluster 2 + MAP12: "Sewers" by Discoholic, remix of "Wasteland Scavengers" by Samuel "Blastfrog" Oliver + MAP13: "Fear" by Discoholic + MAP14: "About the Summer" by Kevin "Velvetic" Martins & Jonathan "julnen" Martins + MAP15: "Backpack of Shells" by Lola "BlueWorrior" Harvey + MAP31: "The Machine" by Lola "BlueWorrior" Harvey + MAP32: "Black Mountain" by Kevin "Velvetic" Martins & Jonathan "julnen" Martins + MAP16: "Reflection" by Scragadelic + MAP17: "Mow Them Down!" by Lola "BlueWorrior" Harvey + MAP18: "Realistic Approach" by Kevin "Velvetic" Martins + MAP19: "Deceit" by Julian "Julian Hope" Aubourg, modified by m + MAP20: "Beasts of Horizon" by Josephus "DH4050" Astartes + +Cluster 3 + MAP21: "Rough Landing" by Korp, remix of dave3d08.mid by jute + MAP22: "Alien Waltz" by Korp + MAP23: "Within the Trilo's Den" by MoonDeLaAxel and Korp + MAP24: "Space's Despair" by Korp, remix of "Balancing Act" by Andrew Bassett + MAP25: "I Sought Wisdom in the Chalice But There Was None" by Jeremy "Vandalorian" Emerson + MAP26: "Stormer" by Korp, originally by Samuel "Blastfrog" Oliver + MAP27: "Dreamcatcher (Black and Blue)" by Kevin "Velvetic" Martins & Jonathan "julnen" Martins + MAP28: "Skull Underfoot" by Lola "BlueWorrior" Harvey + MAP29: "Mists Over the Mire" by Tyler "Picklehammer" Pantella + MAP30: "Devoured by the Jaws of Defeat" by Korp + + +--FreeDM-- + +Title: "My Home, The Colosseum" by Goji +Intermission: "Burn the Bodies" by Tyler "Picklehammer" Pantella +Story: "Geoff's Vinyl Collection" by MoonDeLaAxel, remix of "Why?" by Joshua "wastedjamacan" Masek + + DM01: "Zero Fort" by Ralph "Ralphis" Vickers + DM02: "Descent from Grace" by Lola "BlueWorrior" Harvey + DM03: "Dynamite!" by Korp + DM04: "Pit" by Anthony "Ajanddino" Pierce + DM05: "Music for Freedoom 9" by Jeremy "Vandalorian" Emerson + DM06: "Tunnel" by Anthony "Ajanddino" Pierce + DM07: "I Fell Off The Stairs" by Korp + DM08: "Jump Is Not Allowed!" by Korp + + DM09: "Method to My Madness" by Matias "jupiter_ex" Roldan + DM10: "Paranoia" by Tyler "Picklehammer" Pantella + DM11: "Death's Embrace" by Tyler "Picklehammer" Pantella + DM12: "Parallax" by Korp + DM13: "Shut It" by Korp + DM14: "The Heroic Battle" by Tyler "Picklehammer" Pantella + DM15: "Neat" by Ralph "Ralphis" Vickers + DM16: "Deathmatch Construct" by Korp + + DM17: "Panic" by Anthony "Ajanddino" Pierce + DM18: "Metadata" by Korp + DM19: "Tap Water" by Korp, remix of dave3d27.mid by jute + DM20: "Quirkspitter" by Korp, remix of dave3d16.mid by jute + DM21: "Friendly Fire" by Korp + DM22: "Red Foot" by Kevin "Velvetic" Martins and Simone Alauk + DM23: "Shells" by Ospaggi + DM24: "Constructive Criticism" by Matias "jupiter_ex" Roldan + + DM25: "Shoot 'em All" by rostuhan + DM26: "World of Pain" by Josephus "DH4050" Astartes + DM27: "White Lights" by Kevin "Velvetic" Martins and Jonathan "julnen" Martins + DM28: "Bobby Sent Me" by Ralph "Ralphis" Vickers + DM29: "SevenFour" by Ralph "Ralphis" Vickers + DM30: "Freedom for Your Shooting Skills" by rostuhan + DM31: "The Syntax of Time" by Kevin "Velvetic" Martins + DM32: "Bullet Hell" by rostuhan + + +--Previously Featured in 0.12.1-- + +Phase 1 Title: "Fountain Dance" by Tyler "Picklehammer" Pantella +Phase 1 OPL Title: "I Hate Fredrik Johansson" by Toby "Tobester" Collins Jr. (moved to FreeDM Title, not removed) +Phase 1 Intermission: "Music for Freedoom 10" by Jeremy "Vandalorian" Emerson +Victory: "Ominous Theme" by Jared "BlackJar72" Blackburn +Bunny: "Look At The Bunnies" by RestlessRodent +E1M1: e1m1.mid by Ralph "Ralphis" Vickers +E1M3: "Mortal" by Jeremy "Vandalorian" Emerson +E1M5: "sit on a bench 'n release that tensh'n" by Jazz "jmickle" Mickle +E1M6: dave3d35.mid by jute +E1M7: "Sewers" by Discoholic, remix of "Wasteland Scavengers" by Samuel "Blastfrog" Oliver (moved to MAP12, not removed) +E1M9: "The Raging Sun" by Kevin "Velvetic" Martins and Jonathan "julnen" Martins (moved to E1M5, not removed) +E2M1: dave3d38.mid by jute +E2M2: "Animal Skin" by Kevin "Velvetic" Martins and Jonathan "julnen" Martins +E2M3: "Alone with Colors" by Kevin "Velvetic" Martins and Jonathan "julnen" Martins (moved to E1M3, not removed) +E2M4: "Let 'em Burn" by Kevin "Velvetic" Martins +E2M5: "Music for Freedoom 1" by Jeremy "Vandalorian" Emerson +E2M6: "sit on a bench 'n release that tensh'n" by Jazz "jmickle" Mickle +E2M7: "Music for Freedoom 3" by Jeremy "Vandalorian" Emerson +E2M8: "Pit" by Anthony "Ajanddino" Pierce (moved to DM04, not removed) +E2M9: dave3d34.mid by jute +E3M9: "Lipstick" by Jeremy "Vandalorian" Emerson + +Phase 2 + FreeDM Title: "Warpath" by Tyler "Picklehammer" Pantella +Phase 2 Intermission: "Burn the Bodies" by Tyler "Picklehammer" Pantella +MAP04: "Soviet Porno" by Jeremy "Vandalorian" Emerson (moved to MAP10, not removed) +MAP06: "Dark Trail" by Tyler "Picklehammer" Pantella +MAP07: "Riders of Hell" by Tyler "Picklehammer" Pantella +MAP10: "Death's Embrace" by Tyler "Picklehammer" Pantella (moved to DM11, not removed) +MAP11: dave3d02.mid by jute +MAP12: Doom2Alt.mid by Bradley "BobFromReboot" Lavigne +MAP20: dave3d05.mid by jute +MAP21: "Violence Culture" by Jeremy "Vandalorian" Emerson +MAP22: "Mists Over the Mire" by Tyler "Picklehammer" Pantella (moved to MAP29, not removed) +MAP23: dave3d09.mid by jute +MAP24: "Balancing Act" by Andrew Bassett +MAP26: "Crawl" by Jeremy "Vandalorian" Emerson +MAP29: freedoom.mid by Varis Alpha +MAP30: "Paranoia" by Tyler "Picklehammer" Pantella (moved to DM10, not removed) + +DM03: "Music for Freedoom 2" by Jeremy "Vandalorian" Emerson +DM04: "Rush" by Kevin "Velvetic" Martins and Simone Alauk +DM05: map01.mid by Ralph "Ralphis" Vickers +DM06: "The Heroic Battle" by Tyler "Picklehammer" Pantella (moved to DM14, not removed) +DM07: dave3d30.mid by jute +DM08: Dave3d13.mid by jute +DM10: Doom1.mid by Bradley "BobFromReboot" Lavigne +DM11: "Spamhambled In Space" by Mark "TheMisterCat" McGill-Smith +DM12: dave3d24.mid by jute +DM13: e1m1.mid by Ralph "Ralphis" Vickers +DM14: "Munt Battle" by Mark "TheMisterCat" McGill-Smith +DM16: dave3d02.mid by jute +DM17: d_stlks3.mid by Vincent "Vicious" Fong +DM18: dave3d06.mid by jute +DM19: dave3d27.mid by jute +DM20: dave3d16.mid by jute +DM21: dave3d12.mid by jute +DM23: dave3d17.mid by jute +DM25: dave3d20.mid by jute +DM26: dave3d09.mid by jute +DM27: "Music for Freedoom 7" by Jeremy "Vandalorian" Emerson +DM30: dave3d01.mid by jute +DM32: "Munt Battle" by Mark "TheMisterCat" McGill-Smith + diff --git a/linuxdoom-1.10/freedoom-0.13.0/CREDITS.txt b/linuxdoom-1.10/freedoom-0.13.0/CREDITS.txt new file mode 100644 index 000000000..61aacbb89 --- /dev/null +++ b/linuxdoom-1.10/freedoom-0.13.0/CREDITS.txt @@ -0,0 +1,1030 @@ +[2023-10-07: This credits file contains entries some of which are now decades old. If you have contributed to Freedoom and want to update anything on here, please post an issue or reach out to any active maintainer!] + +[See the CREDITS-MUSIC file for specific track authors and titles.] + +N: Colin Phipps +S: cph +E: cph@cph.demon.co.uk +W: http://www.cph.demon.co.uk/ +D: binary lumps (playpal, colormap etc) + +N: Julian Aubourg +S: Julian +E: julian@doomworld.com +D: sprites, stories, textures + +S: Captain Mellow +E: captainmellow@yahoo.com +D: textures, music + +N: Nick Baker +S: NightMare +E: nick@frad.org +D: textures + +S: Tarin +E: tarin@paci-fist.net +D: textures, sprites, website design, levels + +N: Andrew Stine +S: Linguica +E: linguica@doomworld.com +D: textures + +N: Emmanuel Rousseau +S: GodCells +E: Emmanuel_Rousseau@uqac.ca +D: levels, sprites + +N: Andrew Bassett +S: andrewb +E: orangejuices@icqmail.com +D: music + +S: ravage +E: dragon_69283@yahoo.com +D: Sprites + +S: archvile46 +E: pudge@att.net +D: levels + +S: tony +E: awalker@air-internet.com +D: textures + +S: spaceforce +E: spaceforce@snohost.com +D: levels + +S: CheapAlert +S: gargoylol +S: leileilol +E: cheapalert@gmail.com +D: graphics, sounds, flats, sprites + +N: Michael T. Cole +S: ShadowRunner +E: Clansr03@yahoo.com +D: levels + +N: Kurt Kesler +E: kesler@fidnet.com +D: sprites + +S: Isle +E: isle_bot@hotmail.com +D: textures + +N: Ola Bjorling +S: Citrus +E: ukiro@ukiro.com +D: textures + +S: ZarcyB +E: korgon_iii@hotmail.com +D: textures + +S: diluted +E: shaggs2dope_00@hotmail.com +D: textures + +S: Espi +E: esa.repo@phnet.fi +D: (a lot of) textures + +N: Ralph Vickers +S: Ralphis +E: ralphis@slipgate.org +D: music + +S: Sir Fragsalot +E: bssrpantella@hotmail.com +D: stories, sprites + +N: Jeremy Stepp +E: jeremystepp@hotmail.com +D: textures + +N: Nicholai Main +S: Oblivion +E: uzi666@juno.com +D: levels, fog colormap + +S: KMan +E: kman@valveworld.com +D: textures, sprites + +S: mystic +E: murray6@blueyonder.co.uk +D: levels + +N: Jon Rimmer +S: Amtiskaw +S: Jon_R +E: jonr@frad.org +W: http://destruct.alkali.org/ +D: textures + +N: Vincent Fong +S: Vicious +E: vincentfong@freecall-uk.co.uk +D: musics + +N: Toby Collins Jr. +S: tobester +E: tobester666@yahoo.com +D: music + +N: Andrew Francis +S: locust +E: locust@iinet.net.au +D: textures + +S: AirRaid +E: airraid666@yahoo.com +D: sprites, levels, textures + +S: Jayextee +E: Jxt@Misery.co.uk +D: graphics, levels + +S: Enjay +E: Enjay001@hotmail.com +D: sounds + +N: Jonathan Dowland +E: jon+Chiew6ye@alcopop.org +W: http://jmtd.net/ +D: Former admin, website, FTP host and nightlies; textures; scripts; levels; hires zealotism; sounds + +S: Malice Rancor +E: malicerancor@hotmail.com +D: sprites + +N: Dale Sells +S: mmnpsrsoskl +E: mmnpsrsoskl@hotmail.com +D: textures, graphics + +S: Meat_Head +E: Forbidden_Planet@prodigy.net +D: textures + +S: kaiser +E: kaiser@newdoom.com +D: levels + +S: Slayer226 +E: slayer226@hotmail.com +D: textures + +S: Ebola +E: ebola_kaell@home.se +D: textures, sprites + +S: Zeurkous +E: de_zeurkous@zonnet.nl +D: sprites, textures + +N: Fredrik Johansson +E: fredrik.johansson@gmail.com +W: http://fredrikj.net/ +D: textures, sprites + +S: Lazer +E: dafshin@mediaone.net +D: textures, levels + +N: Steve Dudzik +S: Lut +E: toruonda@home.com +D: sprites, levels + +N: Joseph Chang +E: jchang@optusnet.com.au +D: sprites + +S: Csabo +E: wadedit@marchmail.com +D: music + +S: Draconio +E: draconio2001@yahoo.com +D: sounds + +N: Dave Kiddell +S: Mewse +E: umkiddel@cc.umanitoba.ca +W: http://mewse.alkali.org/ +D: graphics, Mewse! + +S: Deathmaster213 +E: deathmaster213@hotmail.com +D: art/textures + +S: Hyena +E: trwhite@fgbc.org +D: sounds, musics, sprites, levels + +S: Nrkn +E: nrkn@ihug.co.nz +D: textures + +N: Tyler Pantella +S: Pickle Hammer +E: pickle_hammer@hotmail.com +D: musics + +N: Alberto Bonis +S: Saint of Killers +E: alberto.bonis@libero.it +D: sprites/art + +S: GeekMarine +E: cooljohn@birdmail.com +D: sprites, sounds + +N: Tom Robinson +E: tom@alkali.org +W: http://www.junked.org/ +D: A chunk of perl code + +N: Patrick "Amarande" Kalinauskas +S: Amarande +E: amarande@gmail.com +D: levels + +N: Sean Gauthier +S: Cacodemon Leader +E: gauthier.home@sympatico.ca +D: levels + +N: Luke Cama +S: Spike +E: spikeycool@hotmail.com +D: sounds + +S: Shaviro +E: maonth@nautrup.com +D: textures + +S: Nightfang +E: nightfang@truelights.com +D: sprites + +S: MDenham +E: tathetriam@aol.com +D: levels + +S: SpinSpyder +E: blcrowley@hotmail.com +D: sprites + +N: Jeremy Elder +S: SgtCrispy +E: sha_nigtha@yahoo.com +D: sounds, levels + +S: Submerge +E: submerge_527@hotmail.com +D: sounds, sprites + +S: Adamizer +E: adamizer9000@yahoo.com +D: aprites + +N: Andrew Apted +E: ajapted@netspace.net.au +D: graphics, levels, patches, sprites + +S: Zigmund +E: z_ozwell@hotmail.com +D: levels + +S: kinkyfriend +N: Patrick Westermark +E: kinkyfriend85@hotmail.com +D: graphics + +S: Railgunner +E: pcclassix@the-any-key.com +D: sprites, levels + +S: bastetfurry +E: bastetfurry@nachtkatzen.de +D: levels + +S: Lurker +E: ssjtrunks37@hotmail.com +D: levels, sprites, sounds + +S: DarkStalker +E: darkstalker81@hotmail.com +D: textures + +S: Scuba Steve +E: ray_stantz@hotmail.com +D: sprites, graphics + +N: Kim Bach +S: Torn +E: Tornthedark@hotmail.com +D: levels + +N: Mike Watson +S: Cyb +E: cyb@frad.org +W: http://cyb.alkali.org/ +D: levels, sprites, lumps + +N: Wouter van Oortmerssen +S: Aardappel +E: aardappel@planetquake.com +D: conceptual work and realisation + +N: Alex Mao +S: Arioch +E: arioch@despayre.org +D: long term server hosting + +N: Bill Koch +S: Bloodshedder +E: bloodshedder@doomcenter.com +D: sounds + +N: Corwin Brence +S: WildWeasel +E: wildweasel_lemon@hotmail.com +D: sounds + +S: WildMan +N: Rick Clark +E: rickclark58@yahoo.com +D: levels + +S: sargebaldy +N: Owen Lloyd +E: lloydo@onid.orst.edu +D: levels + +N: David Aramant +E: david_a00@excite.com +D: sprites + +S: Silverwyvern +E: cindymcc@nbnet.nb.ca +D: graphics (skies) + +S: mouse +S: lilwhitemouse +E: lilwhitemo@midmaine.com +D: sprites + +N: Simon Howard +S: fraggle +E: fraggle@soulsphere.org +W: https://soulsphere.org +D: project admin, scripting, build system, textures, sprites, graphics, lumps, manual, patches + +N: Joe Dowland +E: jon+joefreedoom@alcopop.org +D: sounds + +N: Jim McDougald +S: rellik +E: rellik_jmd@yahoo.com +D: FreeDM levels, graphics + +N: Jason Root +S: hellbent +E: chesterules@yahoo.com +D: FreeDM levels + +N: David Lawrence Ramsey +S: dolorous +E: pooka109@cox.net +D: sounds + +S: Catoptromancy +E: catoptromancy@yahoo.com +D: levels, playtesting, bugfixes, textures + +S: muffins.exe +D: sounds + +S: RjY +E: rjy@users.sourceforge.net +W: http://rjy.org.uk/ +D: levels + +N: Claude A Freeman +S: CSonicGo +D: sounds + +N: Eric Baker +E: eabaker@san.rr.com +S: The Green Herring +D: levels + +E: hawkwinds_messages@hotmail.com +S: Hawkwind +D: levels + +S: acc +D: levels + +S: Siggi +D: levels + +N: Miguel Suarez Gomez +E: thewadsfactorystaff@hotmail.com +S: Zok +D: levels + +E: ghostlydeath@gmail.com +S: GhostlyDeath +D: musics, PC speaker sounds + +N: Mark McGill-Smith +E: isbetterthanyou@hotmail.com +S: TheMisterCat +D: musics + +N: Matthew Cibulas +E: rottking@sbcglobal.net +S: RottKing +D: sounds + +N: Colin Kelly +E: bankthemighty@gmail.com +S: bank +D: sounds + +N: Delano Cuzzucoli +E: delano501@gmail.com +S: Delano +D: sprites + +N: Svante Ekholm +E: svante.ekholm@gmail.com +S: xerent +D: levels + +N: Benjamin Debski +E: benjamin.debski@gmail.com +S: dabski +D: levels + +N: G. Wessner +E: masterstilgar@yahoo.com +S: Stilgar +D: sounds + +S: Jute +E: jutemail@gmail.com +D: music + +N: Wesley D. Johnson +E: johnson2412@usgo.net +D: levels + +N: Ulises Lozano +S: Urric Hammersong +E: calators@hotmail.com +D: sprites + +N: Andrew Rehberger +E: malinku@live.com +S: Malinku +D: levels + +S: Archfile +D: levels + +S: Blastfrog +E: soliver486@gmail.com +D: graphics, sprites, sounds + +N: Brett Harrell +S: Mechadon +E: mekaddonn@gmail.com +D: levels + +S: nivha +D: levels + +S: hex11 +E: hex11@mail.com +D: levels + +N: Luiz Henrique Gasparin Jerônimo +S: Xindage +E: xindage@gmail.com +D: levels, textures + +S: Mithran Denizen +E: jlebl755@mtroyal.ca +D: sprites + +S: Z86 +D: sprites + +N: Matt Cadirao +S: horncomposer +D: genmidi instruments + +S: BaronOfStuff +W: https://www.youtube.com/user/BaronOfStuff +D: sprites + +N: Josef Šustek +S: Paar +E: sustek.josef@gmail.com +D: levels + +N: Dean Joseph +S: deathz0r +E: deathz0r@unidoom.org +D: levels + +N: Alexandre-Xavier Labonté-Lamoureux +S: AXDOOMER +E: alexandrexavier@live.ca +D: patches, levels, graphics, sprites + +N: Daniel Jewell +S: Jewellds +E: jewellds@gmail.com +D: levels + +N: Adrian Cabrera +E: cancer_kaoru@live.com +S: raymoohawk +W: http://raymoohawk.deviantart.com/ +D: sprites + +S: agaures +E: zalsorarakia@gmail.com +D: sprites + +N: Mikael Haladyn +E: mikaelhhome@yahoo.dk +S: nub_hat +D: levels, musics + +S: CaptainW +E: avortement.rate@gmail.com +D: graphics + +N: Ilja Sara +E: ilja.sara@kahvipannu.com +D: levels + +N: Mike Swanson +S: chungy +E: mikeonthecomputer@gmail.com +D: project admin, build system, repo maintenance + +N: Cray Elliott +S: mp2e +E: MP2E@archlinux.us +D: lumps (demos, playtesting) + +S: voltcom9 +E: Earthbound.Glenn@gmail.com +D: level/episode names + +S: jmickle +E: jaymickle@gmail.com +D: music + +S: doomkid +E: thedevilzworker@hotmail.com +D: freedm playtesting and demo participation + +S: mogul +N: Jeremy Emerson +D: music + +S: sergeant_mark_iv +N: Marcos Abenante +E: marcos.mk3@outlook.com +D: sprites + +S: bloax +D: sprites + +S: undead003 +E: undead0003@gmail.com +D: sounds + +S: angry_saint +E: mechanicalambassador@gmail.com +D: levels + +S: noose +E: noozearts@gmail.com +D: sprites + +S: mazmon +N: Maz Hades +E: mazhades@yahoo.com +D: sprites + +S: jaws_in_space +N: Micah Petersen +E: jawsinspace@gmail.com +D: levels + +S: eriance +N: Eric Ou +E: eriance@gmail.com +W: http://amuscaria.deviantart.com/ +D: sprites + +S: zrrion +N: Roth Smith +E: zrrion@gmail.com +W: http://zrrion.deviantart.com/ +D: sprites + +S: kracov +N: Kracov Bolkonski +E: kracov.wolf@gmail.com +W: http://kracov.org/ +D: graphics + +S: robotdog1 +D: sprites, patches + +E: mobiusx49@gmail.com +S: cwolfru +D: levels + +S: Jimmy +N: James Paddock +E: jamespaddock@hotmail.com +D: levels + +N: Michael Jurich +E: midwestgenius@gmail.com +D: levels + +S: LuckyPunk +E: luckypunk322@gmail.com +D: sprites + +S: Blueworrior +N: Lola Harvey +E: BlueWorrior@hotmail.co.uk +D: musics + +S: sajbear +N: Kristian Nilsen +E: sajber@sajber.info +W: http://sajber.info +D: level + +S: Voros +N: Ayub Ahmed +E: ayubahmed2240@gmail.com +D: textures, lumps + +S: Hexereticdoom +N: Angel C.F. +E: hexereticdoom@gmail.com +W: http://www.moddb.com/members/hexereticdoom +D: sprites + +S: SeventhSentinel +N: James Hall +W: http://seventhsentinel.net23.net +D: sounds + +S: Viscra Maelstrom +E: doomhunter_175@hotmail.com +D: musics + +S: bytebeats +E: bytebytebeats@gmail.com +D: musics + +S: KevinHEZ +N: Kevin Martins +E: kevinmss14@gmail.com +D: musics + +S: agenten +E: wagnerc27@gmail.com +W: https://twitch.tv/gajmegenten/profile +D: textures + +S: pan-te +D: levels + +S: YukiHerz +N: Gabriel Antonio +E: gabriel.reinoso.1996@gmail.com +D: levels + +S: JudgeDeadd +E: korodzik@lavabit.com +D: level names + +S: DragonMorpheus +D: level names + +S: cr0wb4r +D: level names + +N: Edgar Muniz Berlinck +E: edgar.vv@gmail.com +D: Appstream XML files + +S: Gentlepoke +E: doom@gpoke.com +W: http://gpoke.com/ +D: level names + +S: Heng +E: heng@deepthought.earth +D: sprites + +S: uhbooh +E: Uhbooh2@hotmail.com +D: textures + +S: Litrivin +D: textures + +S: jupiter_ex +N: Matias M. Roldan +E: ttrgrmmtn@yahoo.com.ar +D: musics, sounds + +N: Fernando Carmona Varo +S: ferk +E: ferkiwi@gmail.com +D: graphics (titlepic) + +N: Kevin Caccamo +S: Talon1024 +E: kevin@ciinet.org +D: textures, flats, sounds + +S: BobFromReboot +N: Bradley Lavigne +E: bradleylavigne@gmail.com +D: musics + +S: Elon_Satoshi +E: elonsatoshi@riseup.net +D: sounds + +S: Eradrop +E: samurai00020@walla.com +D: patches + +S: Hambourgeois +D: flats, textures + +S: Jared Deberjerak +D: textures + +S: Mortrixs +D: E3M5 + +S: GooseJelly +N: Nathaniel Patasky +E: n.patasky@gmail.com +D: buildcfg.txt, CREDITS, levels + +S: Craneo +E: memod_99@hotmail.com +D: sprites (technospider reshade, minigunner, combat slug flash), textures + +S: continuum.mid +S: northivanastan +N: Ivan Stanton +E: northivanastan@gmail.com +D: musics + +S: MothraMaster +D: sprites: Zombieman/Shotgunners boots update + +S: Korp +E: korpkat@gmail.com +D: Sprites, Textures, Musics, buildcfg.txt, patches, sounds + +S: ajanddino +N: Anthony Pierce +E: ajanddino@gmail.com +D: musics + +S: /dev/urandom +E: dev.urandom@posteo.org +D: graphics, patches, sprites + +S: AerialB +D: COPYING.adoc + +S: basedSkeleton +D: sprites + +S: boogiebogus +D: buildcfg.txt, sprites + +S: Chexter +D: patches + +S: ConsumingCritic +D: levels + +S: Eonfge +E: contact@kevindegeling.nl +D: dist + +N: Erick Tenorio +S: guynamederick +E: guynamederick@gmail.com +D: graphics, levels, lumps, sounds, sprites + +N: Fabian Greffrath +E: fabian@greffrath.com +D: buildcfg.txt, graphics, levels, lumps + +S: Rei +N: Reinaldo +E: crumbscrunchydelights@gmail.com +D: buildcfg.txt, lumps, manual, sounds, sprites, flats + +N: Hugo Locurcio +E: hugo.locurcio@hugo.pro +D: buildcfg.txt, dist, manual + +N: Jason Yundt +E: swagfortress@gmail.com +D: levels + +S: kitchen-ace +E: 68k@quikphix.org +D: levels, patches + +S: m +E: verdantdregs@shaw.ca +D: levels, sounds, sprites, textures, manual + +S: mkrupczak3 +E: matthew@krupczak.org +D: manual + +S: Mortrixs19 +D: levels + +N: Nicholas Zatkovich +S: NickZ +E: nzatkovich@gmail.com +D: buildcfg.txt, COMPILING.adoc, CREDITS, .gitattributes, .github, .gitignore, graphics, levels, lumps, patches, scripts, sprites + +S: ObsidainPlague +D: musics + +N: Perry Fraser +S: perry +E: me@pprogs.blog +D: levels + +N: Ada Mackiewicz +S: Shinosarna +E: nobody.shinobi@gmail.com +D: buildcfg.txt, levels, sprites + +N: Steven Elliott +E: selliott512@gmail.com +D: buildcfg.txt, BUILD-SYSTEM.adoc, levels, Makefile, README.adoc, scripts, sprites + +N: Tyler True +D: Makefile + +S: BeachThunder +D: levels + +N: Clayton Sobrino +E: ClaytonSobrino@yahoo.com +D: patches + +N: Colton G. Rushton +E: colton51919@gmail.com +D: lumps + +S: drbugbait +E: arlesschill@hotmail.com +D: lumps + +S: igdegoo +D: COPYING.adoc, lumps, musics + +S: inkoalawetrust +D: levels + +S: MissLav +D: patches + +S: unfa +E: unfa00@gmail.com +D: sounds + +N: William Breathitt Gray +E: vilhelm.gray@gmail.com +D: dist + +S: DOGB01 +D: levels + +S: arborix +D: sprites + +S: Inuk +E: inuquire@gmail.com +D: levels + +S: GojiBerry +E: gojidoesit@proton.me +D: sounds, musics, textures + +N: Jaden LeMieux +S: iRedMC +E: jadenquinn8@hotmail.com +W: http://iredmc.us.to/ +D: levels, musics + +N: Cass Python +S: Owly +E: owlgal69@protonmail.com +W: https://owly.fans +D: Freedoom website + +S: Matzu +D: musics + +S: ZeMystic +D: musics + +S: R0rque +D: musics + +S: rostuhan +E: rostuhan123@gmail.com +D: musics + +S: SuperDave938 +D: textures + +S: Cascade +D: sprites + +S: Berubaretto +D: levels + +N: Enzo Carozza +S: uni +E: dudetank4@gmail.com +D: CREDITS-MUSIC + +S: MoonDeLaAxel +D: sounds, musics, textures + +S: klickach +D: textures + +S: Magnolia +D: sprites + +S: Anonymoister +D: sprites + +N(A): Josephus Astartes +S: DH4050 +D: musics + +S: Scragadelic +D: musics + +S: Woolie Wool +D: musics + +S: wastedjamacan +D: musics + +S: SUNPYG Senpai +D: levels: e2m3, e3m5 + +S: Ospaggi +D: musics + +S: Stratos +D: musics + +S: Hayden49 +D: levels: e2m2 diff --git a/linuxdoom-1.10/freedoom-0.13.0/NEWS.html b/linuxdoom-1.10/freedoom-0.13.0/NEWS.html new file mode 100644 index 000000000..7bca86480 --- /dev/null +++ b/linuxdoom-1.10/freedoom-0.13.0/NEWS.html @@ -0,0 +1,1005 @@ + + + + + + Freedoom project news + + + + + +
+
+

0.13.0 (2024-01-29)

+
+
+

General

+
    +
  • +

    +Improved vanilla compatibility. +

    +
      +
    • +

      +Boom features removed. +

      +
    • +
    • +

      +Hall of mirrors greatly reduced. +

      +
    • +
    • +

      +Visplane overflows fixed. +

      +
    • +
    • +

      +Savegame buffer overflow errors remain. +

      +
    • +
    +
  • +
+
+
+

Levels

+
    +
  • +

    +Relevant Eureka warnings fixed. +

    +
  • +
  • +

    +New levels E1M9, E2M2, E2M3, E2M4, E2M7, E2M8, E3M5, MAP07, MAP21 and MAP27. +

    +
  • +
  • +

    +Various level renames. +

    +
  • +
  • +

    +Numerous vanilla fixes and aesthetic modernizations. +

    +
  • +
  • +

    +Fixed and standardized secret exits. +

    +
  • +
+
+
+

Manual

+
    +
  • +

    +French and Spanish translations. +

    +
  • +
  • +

    +Sections added to highlight project mandate and additional accessibility options. +

    +
  • +
+
+
+

Misc

+
    +
  • +

    +Adds automatic labeling to pull requests. +

    +
  • +
+
+
+

Monsters

+
    +
  • +

    +New minigunner. +

    +
  • +
  • +

    +The hatchling, which replaces the deadflare. +

    +
  • +
  • +

    +The matribite, which replaces the summoner. +

    +
  • +
+
+
+

Music

+
    +
  • +

    +Lots of new music including most of FreeDM music. +

    +
  • +
+
+
+

Sounds

+
    +
  • +

    +New boss brain sounds. +

    +
  • +
+
+
+

Visuals

+
    +
  • +

    +Colorblind-friendly keys and key indicators. +

    +
  • +
  • +

    +Various revisions to sprites and textures. +

    +
  • +
  • +

    +Improved kerning for menu text. +

    +
  • +
+
+
+

Weapons

+
    +
  • +

    +Improved weapon sprites generally. +

    +
  • +
  • +

    +SSG replacement restored to updated take on older version. +

    +
  • +
  • +

    +Revised polaric energy weapon. +

    +
  • +
  • +

    +Double-barreled shotgun flash timing bug fixed in built-in DeHackEd. +

    +
  • +
+
+
+

Textures

+
    +
  • +

    +Esa Repo (Espi)'s old STAR* textures are now included under ESPI*. +

    +
  • +
  • +

    +A STARBR1 texture is now included as a counterpart to STARBR2. +

    +
  • +
  • +

    +Numerous additional grey and METAL2-based textures also available. +

    +
  • +
  • +

    +Boss brain wall found to have Hexen resources and was re-done. +

    +
  • +
  • +

    +Wolfenstein replacements completely redone, designed to work as + seamlessly with other textures as possible. A few are also added. +

    +
  • +
+
+
+
+
+

0.12.1 (2019-10-22)

+
+
+

General

+
    +
  • +

    +The HTML documentation (eg, NEWS and README files) are + generated with a style based on Freedoom’s own website, rather + than the default AsciiDoc styling. +

    +
  • +
  • +

    +Phase 2’s internal DEMO1 has been replaced, thanks to some odd + vanilla quirks that could cause it to desync in some (but not all) + conditions. +

    +
  • +
+
+
+

Levels

+
    +
  • +

    +The sailor monster type is formally banished from Freedoom’s own + levels, and remaining uses of it were removed. +

    +
  • +
+
+
+

Manual

+
    +
  • +

    +Incongruities between the actual game and manual have been fixed. +

    +
  • +
+
+
+

Build system

+
    +
  • +

    +The make install targets have been consolidated to behave more + similarly to how the pre-built zip distributions are: a split + between FreeDM and Phase 1+2, rather than installing each of + the tree IWADs independently (and thus getting their own + /usr/share/doc directories, for instance). +

    +
  • +
+
+
+
+
+

0.12.0 (2019-10-10)

+
+
+

General

+
    +
  • +

    +We now have a manual rendered to beautiful PDF format. Thanks to + Simon Howard, the project’s founder. +

    +
  • +
  • +

    +A strong focus on vanilla compatibility has been sought for this + release. Most, if not all, levels should work now. +

    +
  • +
  • +

    +Final Doom compatibility de-emphasized. Where it creates + conflicts with Doom II mods or texture definitions, we prefer + the Doom II side of things. Final Doom-specific maps and mods + may never look completely right in Freedoom, as a result. +

    +
  • +
+
+
+

Levels

+
    +
  • +

    +FreeDM has seen a major overhaul, with most maps being modified, + with new additions and removals of the weaker levels. It now + benefits from the use of Aquatex and Egyptian textures in some of + its levels, giving a more vibrant feel than before. +

    +
  • +
  • +

    +Phase 1 gets a lot of mapping love in this round, fleshing out + the levels and tweaking difficulty levels so easy, normal, and + hard are all accounted for. There is a new C3M5 by Mortrixs. +

    +
  • +
  • +

    +Phase 2 MAP01 saw an overhaul, simplifying its design in + significant ways to improve the flow around the level. +

    +
  • +
  • +

    +Two maps in Phase 2 were replaced due to being recreations of + Doom II maps. Jayexetee and GooseJelly get credits for the new + ones, in MAP06 and MAP26. +

    +
  • +
  • +

    +Maps in Phase 2 in general have had some slight re-arrangement + based on difficulty levels and themes. A new MAP06 by Jayexetee + is included, the old one taking the MAP18 slot. +

    +
  • +
  • +

    +All levels are now guaranteed to have co-op and deathmatch starts. +

    +
  • +
+
+
+

Graphics

+
    +
  • +

    +New power-up (stealth, overdrive, and ultra-overdrive) sprites. +

    +
  • +
  • +

    +New necromancer (arch-vile) sprites by Urric. +

    +
  • +
  • +

    +Some weapon and ammo sprites have been tweaked and improved. +

    +
  • +
  • +

    +Completed and enhanced set of Evilution and Plutonia textures. +

    +
  • +
  • +

    +New skull-switches by MissLav. +

    +
  • +
  • +

    +New SKY4 based on an astronomy photograph. +

    +
  • +
  • +

    +Tweaked player sprites and HUD face by Ferk. +

    +
  • +
+
+
+

Music

+
    +
  • +

    +New tracks in C1M2, C2M3, C2M8, MAP03, MAP12, MAP22, MAP25, MAP26, + MAP27, DM03, DM06, DM09, DM17, DM24, DM31, and DM32. +

    +
  • +
  • +

    +All files in-tree have been renamed from *.mus to *.mid. The file + format must always be MIDI. This makes it easy on music composers + to actually work with the files. +

    +
  • +
+
+
+

Unix script and metadata

+
    +
  • +

    +Metainfo (formerly appdata) and desktop files have been brought up + to the latest standard specifications and recommendations, using + reverse-DNS for the project identifier, and a self-evaluated + content rating. +

    +
  • +
  • +

    +The launch shell-script changed the PORT environment variable to + DOOMPORT to avoid conflicts with the genericly-named PORT. It + also builds a sensible default DOOMWADPATH environment variable + to assist ports that do not have a hard-coded fallback. +

    +
  • +
  • +

    +The script no longer tries to look for boom, zdoom, nor + prboom by default, as these are ports no longer maintained. +

    +
  • +
+
+
+

Build system

+
    +
  • +

    +Freedoom’s build system now has a hard dependency on Python 3, in + anticipation of Python 2’s end-of-life. +

    +
  • +
  • +

    +We have moved from ImageMagick to Pillow, a Python library for + graphics manipulation. It provides faster build times as well as + API stability. +

    +
  • +
  • +

    +GIF files have been replaced with PNG files. True PNG file format + transparency is used instead of a cyan background. +

    +
  • +
  • +

    +ASCIIDOC and ASCIIDOC_MAN variables have been added to the + Makefile to control the AsciiDoc implementation used to generate + HTML and man page files. +

    +
  • +
+
+
+
+
+

0.11.3 (2017-07-18)

+
+
    +
  • +

    +Builds with DeuTex 5.0 and newer. +

    +
  • +
+
+
+
+

0.11.2 (2017-03-15)

+
+
    +
  • +

    +Missing multiplayer starts have been added to several levels. +

    +
  • +
  • +

    +A few mapping errors were repaired by changing sector heights. + Speedrunners can better appreciate smooth flow through the levels. +

    +
  • +
  • +

    +Easy and normal difficulty levels have been tweaked. +

    +
  • +
  • +

    +Par times for Phase 1 have been added. +

    +
  • +
  • +

    +Cleaned up the title screen using the Freedoom font for “Phase + 1” and “Phase 2” on-screen. +

    +
  • +
+
+
+
+

0.11.1 (2017-02-22)

+
+
    +
  • +

    +1% armor bonus picks are recolored from red to green. They were + too easily confused for health pickups. +

    +
  • +
  • +

    +New TNT: Evilution compatible textures. +

    +
  • +
  • +

    +New pain bringer and pain lord sprites, replacing old concept + art-derived ones. +

    +
  • +
  • +

    +A few mapping errors are fixed, including misaligned textures, + leftover Boom specials, and it should no longer be possible to get + stuck between a rock and a tree in Phase 1 C1M1. +

    +
  • +
  • +

    +Brand-new Phase 1 C3M1, replacing the old Doom-inspired level. +

    +
  • +
  • +

    +Widescreen statusbar for ZDoom removed. This created + incompatibility with some mods. +

    +
  • +
+
+
+
+

0.11 (2017-02-16)

+
+
    +
  • +

    +Freedoom is now a limit-removing game rather than using Boom + specials. +

    +
  • +
  • +

    +Lots of new music. +

    +
  • +
  • +

    +New levels, including a new C1M1 for Phase 1. +

    +
  • +
  • +

    +Aquatex: over 200 new textures for mappers to use. +

    +
  • +
  • +

    +New intermission screens. +

    +
  • +
  • +

    +Some new weapon sprites: new pistol and new pickups. +

    +
  • +
  • +

    +New medkit and armor pickup sprites. +

    +
  • +
  • +

    +New project logo +

    +
  • +
+
+
+
+

0.10.1 (2015-12-23)

+
+
    +
  • +

    +Repairs an incompatibility in Phase 1 C3M7 with Boom 2.02. +

    +
  • +
  • +

    +Fully-completed sprite set for the flame bringer. +

    +
  • +
+
+
+
+

0.10 (2015-12-16)

+
+
    +
  • +

    +Brand new status bar. +

    +
  • +
  • +

    +New sprites for the serpent and orb monsters. +

    +
  • +
  • +

    +New HUD graphics for the single- and double-barreled shotguns, + missile launcher, and SKAG-1337. +

    +
  • +
  • +

    +New pain sounds for many monsters and the player. +

    +
  • +
  • +

    +New maps in Phase 1 and Phase 2. +

    +
  • +
+
+
+
+

0.9 (2014-10-14)

+
+
    +
  • +

    +New file names that no longer conflict with Doom’s +

    +
      +
    • +

      +freedoom1.wad is Freedoom: Phase 1 — compatible with The + Ultimate Doom. +

      +
    • +
    • +

      +freedoom2.wad is Freedoom: Phase 2 — compatible with Doom + II and Final Doom. +

      +
    • +
    +
  • +
  • +

    +FreeDM and Phase 1 have grown out of the shadows of the + project and have seen rapid advances, largely led by Xindage, our + prominent Brazilian contributor. +

    +
  • +
  • +

    +New text font from Mechadon to replace the old one in all menus, + in-game text, and status-bar HUD. +

    +
  • +
  • +

    +New zombie, shotgun zombie, and assault tripod sprites by a + skilled pixel artist, raymoohawk. +

    +
  • +
  • +

    +New sounds for the dark soldier by jewellds. +

    +
  • +
  • +

    +More complete support for Final Doom mods, adding many more + textures missing to support mods for both TNT: Evilution and + The Plutonia Experiment, thanks to fraggle and AXDOOMER. +

    +
  • +
+
+
+
+

0.8 (2014-01-01)

+
+
    +
  • +

    +Ultimate Freedoom’s episode 4 is now the Cacoward-winning Double Impact. +

    +
  • +
  • +

    +Many maps have been updated +

    +
  • +
  • +

    +Improved sprites and sounds +

    +
  • +
  • +

    +FreeDM is now vanilla-compatible and has quite a few new maps. +

    +
  • +
  • +

    +A BEX file is included in the IWADs, which allows compatible + source ports to replace many strings in the game, such as level + names, weapon pickups, and intermission text. +

    +
  • +
+
+
+
+ + diff --git a/linuxdoom-1.10/freedoom-0.13.0/README.html b/linuxdoom-1.10/freedoom-0.13.0/README.html new file mode 100644 index 000000000..ee7908322 --- /dev/null +++ b/linuxdoom-1.10/freedoom-0.13.0/README.html @@ -0,0 +1,623 @@ + + + + + + Freedoom + + + + + +
+
+
+

The Freedoom project aims to create a complete, free content first +person shooter game, but Freedoom by itself is just the raw material +for a game. It must be paired with a compatible Doom engine to be +played.

+

There is a massive back +catalog, spanning over two decades, containing thousands of Doom +levels and other modifications (“mods”) made by fans of the game. +Freedoom aims to be compatible with these and allows most to be +played without the need to use non-free software.

+

Freedoom is actually three games in one, consisting of two +single-player oriented campaigns and one set of levels designed +exclusively for multiplayer deathmatch:

+
+ + + + + + + + + + + + +
+Freedoom: Phase 1 +
+
+

+Four episodes, nine levels each, totalling 36 +levels. This game aims for compatibility with The Ultimate Doom +mods, also known as plain Doom or Doom 1. +

+
+Freedoom: Phase 2 +
+
+

+32 levels in one long episode, featuring extra +monsters and a double-barrelled shotgun. This project aims for +compatibility with Doom II mods. +

+
+FreeDM +
+
+

+A 32-level game designed for competitive deathmatch play. +

+
+

The engine uses a single file, such as freedoom2.wad, that contains +all the game data such as graphics, sound effects, music, and so on. +This file is often called an “IWAD” by those in the Doom and +Freedoom communities. While the Doom engine source code is free, +you would normally still need one of the proprietary data files from +id Software to play Doom. Freedoom +aims to create a free alternative: combined with the GPL-licensed +Doom source code, this results in a completely free game.

+

For more information, see https://freedoom.github.io/.

+
+
+
+

How to play

+
+

Since Freedoom is only the game data, you will still need to +download an engine separately. These are also often termed “source +ports” by the community. There are an overwhelming number of choices +available, a lengthy list of which is available on the +Doom Wiki.

+

One particularly recommended by the Freedoom project is +GZDoom. This engine offers good support for +single-player, multi-player, and the majority of mods created for both +Doom and Freedoom.

+

On Windows, you should place Freedoom’s data files (those ending +with .wad) alongside the engine (eg, odamex.exe). On Unix-like +systems, these data files should go in either /usr/share/games/doom +or your home directory. If Freedoom comes packaged as part of your +operating system distribution, it should already be installed into the +proper location.

+

Hopefully, your engine of choice should already be capable of running +Freedoom without extra configuration. This may not be the case, +however, if the engine does not recognize any of the filenames for +Freedoom, and might require manual intervention to make it so. One +of the following options should solve it:

+
    +
  • +

    +Use the -iwad command line parameter. For example, to play + Phase 2, you can enter -iwad freedoom2.wad either at a command + line, or adding it to an application shortcut. +

    +
  • +
  • +

    +Use the DOOMWADPATH environment variable. Many engines support + this variable to add directories and/or files to their search + path. The exact syntax matches your operating system’s normal + PATH environment variable. +

    +
  • +
  • +

    +Rename the game files. This may be a bit crude, but you can + rename the files to match those of Doom’s. This is often the + easiest quick-fix, although it is normally desirable to use one of + the above methods if possible. +

    +
      +
    • +

      +freedoom1.wad can be renamed to doom.wad +

      +
    • +
    • +

      +freedoom2.wad can be renamed to doom2.wad +

      +
    • +
    • +

      +freedm.wad can be renamed to doom2.wad +

      +
    • +
    +
  • +
+

Additionally, for Unix-like operating systems, such as GNU/Linux or a +BSD variant, Freedoom may be packaged and installed with programs +named freedoom1, freedoom2, and freedm that automatically run an +engine for proper play. Desktop files may also be installed so that +you can start the game using a graphical interface and avoid the +command line altogether.

+
+
+
+

What “free” means

+
+

When we speak of free content or software, we refer to the movement in +which your freedoms to use, copy, modify, and study a work is not +infringed. For example, you may freely use Freedoom for any purpose +you see fit, you may redistribute it to anyone without needing to ask +for permission, you may modify it (provided you keep the license +intact, see COPYING), and you may study it—for example, to see how +an “IWAD” is built. To facilitate this, you can get the full source +code for Freedoom, in this case, in the form of a DeuTex tree.

+

You may read more about free software at the GNU +and Free Software Foundation websites.

+
+
+
+

Contributing to Freedoom

+
+

Contributions to Freedoom are always welcome, however there are a +few guidelines that should be followed:

+
+

Intellectual property

+

We know people hate legalese, but this is important. This applies to +everything which is submitted.

+

You must be careful when basing on existing graphics or sounds. Most +Doom projects are lax on reusing intellectual property—there are +many mods which contain modified Doom sprites, for example. +However, due to the nature of this project, we do not have the same +liberty to rip as we please.

+

The general rules go as follows:

+
    +
  • +

    +You must have permission for everything you submit. If you make + your own resources, do not base on resources from Doom or any + other restricted work. If you take work from other places, please + make sure that the work is freely-licensed or that you obtain + permission to include it in the Freedoom project. They may not + place additional restrictions compared to the normal Freedoom + license. +

    +
  • +
  • +

    +Do not try to emulate Doom resources exactly. Where possible, + put effort to make new versions look visibly different from + Doom. This is a tough call, because our compatibility with + Doom mods limits how far we can deviate, but it is feasible. +

    +
  • +
  • +

    +Be especially careful of “free textures” (or “free sounds” or + “free graphics”) sites. Although these would appear at first to + be okay to use, many are free for “non-commercial use only.” + One of the things we want to be able to do is put this in + GNU/Linux distributions (which can be sold or developed + commercially). +

    +
  • +
+
+
+

Levels

+

All levels for Freedoom must be vanilla-compatible, requiring an +expanded-limits or limit-removing engine is not permissible. This +means you may not exceed the limits of the original Doom engine, and +do not depend on additional mapping features. Levels should be in +Doom’s original format, not in “Hexen”-format.

+

It is sensible to also heed the following guidelines:

+
    +
  • +

    +Make sure that skill levels are implemented, and that all + multiplayer start points, both cooperative and deathmatch, are + present. +

    +
  • +
  • +

    +Try to make levels appropriately difficult for their position + within the progression of the game. Also bear in mind that not + all players may be as skilled a player as you. +

    +
  • +
  • +

    +Do not use tricks that exploit Doom’s software renderer; some + engines, especially those that use hardware accelerated rendering, + may not render it properly. Examples of tricks to avoid include + those used to simulate 3D bridges and “deep water” effects. +

    +
  • +
  • +

    +While unrestricted by limits, do not make excessively complicated + scenes. It is desirable that Freedoom levels should be playable + on low-powered hardware, such as phones and old computers. +

    +
  • +
  • +

    +Test your levels in Chocolate + Doom to make sure that vanilla compatibility is maintained. This + is an engine with strict adherence to vanilla Doom limits and + bugs, and working in it assures that levels can be played with any + Doom engine. +

    +
  • +
  • +

    +Use a Doom editor to check for errors. In + Eureka it’s possible to + check for errors with the Check / All menu, or by pressing F9. +

    +
  • +
  • +

    +If possible run make test and fix any errors found. Note that + some of the errors can be fixed by make fix. +

    +
  • +
+
+
+

Graphics

+

Graphics should generally have the same color and size as the original +Doom graphics, as to remain compatible with mods. Otherwise, levels +may end up looking like a nightmare in design. They may be +thematically different as long as it doesn’t clash.

+

Doom uses a fictional corporation abbreviated as “UAC:” this is +trademarked by id Software and cannot be used in Freedoom. Instead, +use the initials “AGM” for Freedoom.

+
+
+

Documentation

+

Freedoom always needs help with documentation, so please send your +patches, but keep in mind:

+
    +
  • +

    +We use AsciiDoc for writing the + documentation. AsciiDoc is a simple plaintext-based format which + is simple to read and write in its source form, and can generate + nice HTML documents out of them. +

    +
  • +
  • +

    +Headers are formated in a wiki-style format, this makes it easier + for Vim (perhaps other editors, too) to automatically re-format + text. +

    +
  • +
  • +

    +Text is kept at 72 characters wide. In Vim, you can set the + editor to automatically insert line breaks as you’re typing by + performing set textwidth=72. Special exceptions to the width + rule might be allowed when necessary (for example, inserting long + URLs). +

    +
  • +
+
+
+

Submitting your work

+

The most common, and a fairly simple method, to submit your work is by +posting it on the +Freedoom forum on +Doomworld Forums. This allows a great number of people to review the +contribution and provide feedback, although the registration process +is known to be cumbersome.

+

An alternative to using the forum, is to post your submission on the +issue tracker, which may +also be peer-reviewed and provide a feedback cycle.

+

Unfortunately, the Freedoom project cannot provide hosting space in +the form of a web page nor FTP, however there are many free file hosts +to use when you need a location to upload files. Sites and services +such as Dropbox and +Mega, as well as others, are common and should be +simple to use.

+
+

Crediting information

+

Freedoom is made up of submissions from many people all over the +globe. All of them, and you, deserve credit! Please do not forget to +provide your name and email when submitting resources.

+
+
+

Using Git

+

You can also commit on a clone of the Freedoom repository, although +this is a technical task and it is okay to let other Freedoom +maintainers to do it instead: that is our normal mode of operation. +However, pull requests are much appreciated and you may submit them in +any manner you wish, with GitHub’s direct pull requests being the +simplest, but by far not the only means.

+

Freedoom uses the commit message style commonly seen in distributed +version control systems, adopted by projects such as Linux and Git. +For an explanation of this style, see +How to Write a Git Commit +Message.

+

If you create a git commit for someone else it is helpful to set the +author of the commit so that they get credit. Ask them what name/alias +and email they would like to use. For example:

+
+
+
git commit --author "Bob Smith <bob@example.com>" ...
+

If they prefer not to give an email then the email can be omitted, so +just "Bob Smith" in the above example.

+
+
+
+
+
+ + diff --git a/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-en.pdf b/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-en.pdf new file mode 100644 index 000000000..e6fd56411 Binary files /dev/null and b/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-en.pdf differ diff --git a/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-es.pdf b/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-es.pdf new file mode 100644 index 000000000..52aef08e5 Binary files /dev/null and b/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-es.pdf differ diff --git a/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-fr.pdf b/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-fr.pdf new file mode 100644 index 000000000..de3ad5e80 Binary files /dev/null and b/linuxdoom-1.10/freedoom-0.13.0/freedoom-manual-fr.pdf differ diff --git a/linuxdoom-1.10/freedoom-0.13.0/freedoom1.wad b/linuxdoom-1.10/freedoom-0.13.0/freedoom1.wad new file mode 100644 index 000000000..c914e9c8e Binary files /dev/null and b/linuxdoom-1.10/freedoom-0.13.0/freedoom1.wad differ diff --git a/linuxdoom-1.10/freedoom-0.13.0/freedoom2.wad b/linuxdoom-1.10/freedoom-0.13.0/freedoom2.wad new file mode 100644 index 000000000..ad6a1fdda Binary files /dev/null and b/linuxdoom-1.10/freedoom-0.13.0/freedoom2.wad differ diff --git a/linuxdoom-1.10/freedoom1.wad b/linuxdoom-1.10/freedoom1.wad new file mode 100644 index 000000000..c914e9c8e Binary files /dev/null and b/linuxdoom-1.10/freedoom1.wad differ diff --git a/linuxdoom-1.10/i_net_stub.c b/linuxdoom-1.10/i_net_stub.c new file mode 100644 index 000000000..4253cf79d --- /dev/null +++ b/linuxdoom-1.10/i_net_stub.c @@ -0,0 +1,45 @@ +// Single-player network stub for Windows port. +// Avoids POSIX socket dependencies; multiplayer is not supported. + +#include +#include +#include + +#include "i_system.h" +#include "d_event.h" +#include "d_net.h" +#include "m_argv.h" +#include "doomstat.h" + +#ifdef __GNUG__ +#pragma implementation "i_net.h" +#endif +#include "i_net.h" + +void (*netget)(void); +void (*netsend)(void); + +// +// I_InitNetwork +// Sets up single-player mode only. +// +void I_InitNetwork(void) +{ + doomcom = malloc(sizeof(*doomcom)); + memset(doomcom, 0, sizeof(*doomcom)); + + doomcom->ticdup = 1; + doomcom->extratics = 0; + + // Single player always + netgame = false; + doomcom->id = DOOMCOM_ID; + doomcom->numplayers = doomcom->numnodes = 1; + doomcom->deathmatch = false; + doomcom->consoleplayer = 0; +} + +void I_NetCmd(void) +{ + I_Error("I_NetCmd: networking not supported in Windows single-player build"); +} diff --git a/linuxdoom-1.10/i_sound_null.c b/linuxdoom-1.10/i_sound_null.c new file mode 100644 index 000000000..b6e914c43 --- /dev/null +++ b/linuxdoom-1.10/i_sound_null.c @@ -0,0 +1,33 @@ +// Null sound implementation - no audio output +// Stubs out all i_sound.h interface functions. + +#include "i_sound.h" +#include "sounds.h" +#include "doomdef.h" + +// SNDSERV support: define the server filename (unused in null backend) +// This is declared extern in i_sound.h and referenced from m_misc.c when +// SNDSERV is defined in doomdef.h. +char* sndserver_filename = "sndserver"; + +void I_InitSound(void) {} +void I_UpdateSound(void) {} +void I_SubmitSound(void) {} +void I_ShutdownSound(void){} +void I_SetChannels(void) {} + +int I_GetSfxLumpNum(sfxinfo_t *sfxinfo) { (void)sfxinfo; return -1; } +int I_StartSound(int id, int vol, int sep, int pitch, int pri) { (void)id;(void)vol;(void)sep;(void)pitch;(void)pri; return -1; } +void I_StopSound(int handle) { (void)handle; } +int I_SoundIsPlaying(int handle) { (void)handle; return 0; } +void I_UpdateSoundParams(int handle, int vol, int sep, int pitch) { (void)handle;(void)vol;(void)sep;(void)pitch; } + +void I_InitMusic(void) {} +void I_ShutdownMusic(void) {} +void I_SetMusicVolume(int volume) { (void)volume; } +void I_PauseSong(int handle) { (void)handle; } +void I_ResumeSong(int handle) { (void)handle; } +int I_RegisterSong(void *data) { (void)data; return 0; } +void I_PlaySong(int handle, int looping) { (void)handle;(void)looping; } +void I_StopSong(int handle) { (void)handle; } +void I_UnRegisterSong(int handle) { (void)handle; } diff --git a/linuxdoom-1.10/i_system_win.c b/linuxdoom-1.10/i_system_win.c new file mode 100644 index 000000000..23e391bc0 --- /dev/null +++ b/linuxdoom-1.10/i_system_win.c @@ -0,0 +1,136 @@ +// i_system_win.c – SDL2-based system backend (Windows + Emscripten). +// Replaces the Linux-specific gettimeofday / usleep calls. + +#include +#include +#include +#include + +// Only define SDL_MAIN_HANDLED in non-Emscripten builds. +// emcc manages the entry-point separately and doesn't need this. +#ifndef __EMSCRIPTEN__ +#define SDL_MAIN_HANDLED +#endif + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include + +#include "doomdef.h" +#include "m_misc.h" +#include "i_video.h" +#include "i_sound.h" +#include "d_net.h" +#include "g_game.h" + +#ifdef __GNUG__ +#pragma implementation "i_system.h" +#endif +#include "i_system.h" + +int mb_used = 6; + +void I_Tactile(int on, int off, int total) +{ + (void)on; (void)off; (void)total; +} + +ticcmd_t emptycmd; +ticcmd_t* I_BaseTiccmd(void) { return &emptycmd; } +int I_GetHeapSize(void) { return mb_used * 1024 * 1024; } + +byte* I_ZoneBase(int *size) +{ + *size = mb_used * 1024 * 1024; + return (byte *)malloc(*size); +} + +// +// I_GetTime +// Returns time in 1/TICRATE (35 Hz) tics using SDL_GetTicks. +// +int I_GetTime(void) +{ + static Uint32 basetime = 0; + Uint32 now = SDL_GetTicks(); + if (!basetime) + basetime = now; + return (int)((now - basetime) * TICRATE / 1000); +} + +// +// I_Init +// +void I_Init(void) +{ + // Initialize SDL timer (video initialized later in I_InitGraphics) + if (SDL_Init(SDL_INIT_TIMER) < 0) + fprintf(stderr, "SDL_Init(TIMER) failed: %s\n", SDL_GetError()); + I_InitSound(); +} + +// +// I_Quit +// +void I_Quit(void) +{ + D_QuitNetGame(); + I_ShutdownSound(); + I_ShutdownMusic(); + M_SaveDefaults(); + I_ShutdownGraphics(); + SDL_Quit(); +#ifdef __EMSCRIPTEN__ + emscripten_cancel_main_loop(); + emscripten_force_exit(0); +#else + exit(0); +#endif +} + +void I_WaitVBL(int count) +{ + SDL_Delay(count * (1000 / 70)); +} + +void I_BeginRead(void) {} +void I_EndRead(void) {} + +byte* I_AllocLow(int length) +{ + byte *mem = (byte *)malloc(length); + memset(mem, 0, length); + return mem; +} + +// +// I_Error +// +extern boolean demorecording; + +void I_Error(char *error, ...) +{ + va_list argptr; + + va_start(argptr, error); + fprintf(stderr, "Error: "); + vfprintf(stderr, error, argptr); + fprintf(stderr, "\n"); + va_end(argptr); + fflush(stderr); + + if (demorecording) + G_CheckDemoStatus(); + + D_QuitNetGame(); + I_ShutdownGraphics(); + SDL_Quit(); +#ifdef __EMSCRIPTEN__ + emscripten_cancel_main_loop(); + emscripten_force_exit(-1); +#else + exit(-1); +#endif +} diff --git a/linuxdoom-1.10/i_video_sdl.c b/linuxdoom-1.10/i_video_sdl.c new file mode 100644 index 000000000..d8c58843a --- /dev/null +++ b/linuxdoom-1.10/i_video_sdl.c @@ -0,0 +1,276 @@ +// SDL2-based video backend for DOOM (Windows + Emscripten port) +// Replaces X11-based i_video.c + +// Only define SDL_MAIN_HANDLED in non-Emscripten builds. +#ifndef __EMSCRIPTEN__ +#define SDL_MAIN_HANDLED +#endif + +#include +#include + +#include + +#include "doomstat.h" +#include "i_system.h" +#include "v_video.h" +#include "m_argv.h" +#include "d_main.h" +#include "doomdef.h" + +static SDL_Window *sdl_window = NULL; +static SDL_Renderer *sdl_renderer = NULL; +static SDL_Texture *sdl_texture = NULL; + +// 32-bit palette (ARGB) built from the 8-bit DOOM palette +static Uint32 sdl_palette[256]; + +// Window scale multiplier (1 = 320x200, 2 = 640x400, etc.) +static int multiply = 2; + +// +// Translate an SDL key to a DOOM key code +// +static int xlatekey(SDL_Keycode sym) +{ + switch (sym) + { + case SDLK_LEFT: return KEY_LEFTARROW; + case SDLK_RIGHT: return KEY_RIGHTARROW; + case SDLK_DOWN: return KEY_DOWNARROW; + case SDLK_UP: return KEY_UPARROW; + case SDLK_ESCAPE: return KEY_ESCAPE; + case SDLK_RETURN: return KEY_ENTER; + case SDLK_TAB: return KEY_TAB; + case SDLK_F1: return KEY_F1; + case SDLK_F2: return KEY_F2; + case SDLK_F3: return KEY_F3; + case SDLK_F4: return KEY_F4; + case SDLK_F5: return KEY_F5; + case SDLK_F6: return KEY_F6; + case SDLK_F7: return KEY_F7; + case SDLK_F8: return KEY_F8; + case SDLK_F9: return KEY_F9; + case SDLK_F10: return KEY_F10; + case SDLK_F11: return KEY_F11; + case SDLK_F12: return KEY_F12; + case SDLK_BACKSPACE: + case SDLK_DELETE: return KEY_BACKSPACE; + case SDLK_PAUSE: return KEY_PAUSE; + case SDLK_EQUALS: return KEY_EQUALS; + case SDLK_MINUS: return KEY_MINUS; + case SDLK_LSHIFT: + case SDLK_RSHIFT: return KEY_RSHIFT; + case SDLK_LCTRL: + case SDLK_RCTRL: return KEY_RCTRL; + case SDLK_LALT: + case SDLK_RALT: return KEY_RALT; + default: + if (sym >= SDLK_SPACE && sym <= SDLK_z) + { + int rc = (int)sym; + if (rc >= 'A' && rc <= 'Z') + rc = rc - 'A' + 'a'; + return rc; + } + return 0; + } +} + +// +// I_ShutdownGraphics +// +void I_ShutdownGraphics(void) +{ + if (sdl_texture) { SDL_DestroyTexture(sdl_texture); sdl_texture = NULL; } + if (sdl_renderer) { SDL_DestroyRenderer(sdl_renderer); sdl_renderer = NULL; } + if (sdl_window) { SDL_DestroyWindow(sdl_window); sdl_window = NULL; } + SDL_QuitSubSystem(SDL_INIT_VIDEO); +} + +// +// I_StartFrame +// +void I_StartFrame(void) +{ + // nothing +} + +// +// I_StartTic - poll SDL events and post DOOM events +// +void I_StartTic(void) +{ + SDL_Event sdlev; + event_t doom_ev; + + while (SDL_PollEvent(&sdlev)) + { + switch (sdlev.type) + { + case SDL_KEYDOWN: + doom_ev.type = ev_keydown; + doom_ev.data1 = xlatekey(sdlev.key.keysym.sym); + if (doom_ev.data1) D_PostEvent(&doom_ev); + break; + + case SDL_KEYUP: + doom_ev.type = ev_keyup; + doom_ev.data1 = xlatekey(sdlev.key.keysym.sym); + if (doom_ev.data1) D_PostEvent(&doom_ev); + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + int buttons = SDL_GetMouseState(NULL, NULL); + doom_ev.type = ev_mouse; + doom_ev.data1 = ((buttons & SDL_BUTTON_LMASK) ? 1 : 0) + | ((buttons & SDL_BUTTON_MMASK) ? 2 : 0) + | ((buttons & SDL_BUTTON_RMASK) ? 4 : 0); + doom_ev.data2 = doom_ev.data3 = 0; + D_PostEvent(&doom_ev); + break; + } + + case SDL_MOUSEMOTION: + doom_ev.type = ev_mouse; + doom_ev.data1 = ((sdlev.motion.state & SDL_BUTTON_LMASK) ? 1 : 0) + | ((sdlev.motion.state & SDL_BUTTON_MMASK) ? 2 : 0) + | ((sdlev.motion.state & SDL_BUTTON_RMASK) ? 4 : 0); + doom_ev.data2 = sdlev.motion.xrel << 2; + doom_ev.data3 = -sdlev.motion.yrel << 2; + D_PostEvent(&doom_ev); + break; + + case SDL_QUIT: + I_Quit(); + break; + + default: + break; + } + } +} + +// +// I_UpdateNoBlit +// +void I_UpdateNoBlit(void) +{ + // nothing +} + +// +// I_FinishUpdate - convert 8-bit DOOM framebuffer to 32-bit and blit via SDL +// +void I_FinishUpdate(void) +{ + static int lasttic = 0; + int i, tics; + + // Draw benchmark dots in developer mode + if (devparm) + { + i = I_GetTime(); + tics = i - lasttic; + lasttic = i; + if (tics > 20) tics = 20; + for (i = 0; i < tics * 2; i += 2) + screens[0][(SCREENHEIGHT - 1) * SCREENWIDTH + i] = 0xff; + for (; i < 20 * 2; i += 2) + screens[0][(SCREENHEIGHT - 1) * SCREENWIDTH + i] = 0x0; + } + + // Convert 8-bit palettized to 32-bit ARGB + { + static Uint32 argbbuf[SCREENWIDTH * SCREENHEIGHT]; + int p; + for (p = 0; p < SCREENWIDTH * SCREENHEIGHT; p++) + argbbuf[p] = sdl_palette[(unsigned char)screens[0][p]]; + + SDL_UpdateTexture(sdl_texture, NULL, argbbuf, SCREENWIDTH * sizeof(Uint32)); + } + + SDL_RenderClear(sdl_renderer); + SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); + SDL_RenderPresent(sdl_renderer); +} + +// +// I_ReadScreen +// +void I_ReadScreen(byte *scr) +{ + memcpy(scr, screens[0], SCREENWIDTH * SCREENHEIGHT); +} + +// +// I_SetPalette - apply gamma and store 32-bit palette for blitting +// +void I_SetPalette(byte *palette) +{ + int i; + byte *p = palette; + for (i = 0; i < 256; i++) + { + byte r = gammatable[usegamma][*p++]; + byte g = gammatable[usegamma][*p++]; + byte b = gammatable[usegamma][*p++]; + sdl_palette[i] = (0xFFu << 24) | ((Uint32)r << 16) | ((Uint32)g << 8) | b; + } +} + +// +// I_InitGraphics +// +void I_InitGraphics(void) +{ + int W, H; + static int firsttime = 1; + + if (!firsttime) return; + firsttime = 0; + + if (M_CheckParm("-2")) multiply = 2; + if (M_CheckParm("-3")) multiply = 3; + if (M_CheckParm("-4")) multiply = 4; + + W = SCREENWIDTH * multiply; + H = SCREENHEIGHT * multiply; + + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + I_Error("SDL video init failed: %s", SDL_GetError()); + + sdl_window = SDL_CreateWindow( + "DOOM", + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + W, H, 0); + if (!sdl_window) + I_Error("SDL_CreateWindow failed: %s", SDL_GetError()); + + // SDL_RENDERER_PRESENTVSYNC conflicts with emscripten_set_main_loop's + // own RAF timing – use pure accelerated rendering on all platforms. + sdl_renderer = SDL_CreateRenderer( + sdl_window, -1, + SDL_RENDERER_ACCELERATED); + if (!sdl_renderer) + sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0); + if (!sdl_renderer) + I_Error("SDL_CreateRenderer failed: %s", SDL_GetError()); + + // Scale the 320x200 texture up to fill the window + SDL_RenderSetLogicalSize(sdl_renderer, SCREENWIDTH, SCREENHEIGHT); + + sdl_texture = SDL_CreateTexture( + sdl_renderer, + SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + SCREENWIDTH, SCREENHEIGHT); + if (!sdl_texture) + I_Error("SDL_CreateTexture failed: %s", SDL_GetError()); + + screens[0] = (unsigned char *)malloc(SCREENWIDTH * SCREENHEIGHT); + if (!screens[0]) + I_Error("Failed to allocate DOOM screen buffer"); +} diff --git a/linuxdoom-1.10/m_bbox.h b/linuxdoom-1.10/m_bbox.h index 66be2fbd5..bfbff379e 100644 --- a/linuxdoom-1.10/m_bbox.h +++ b/linuxdoom-1.10/m_bbox.h @@ -23,8 +23,7 @@ #ifndef __M_BBOX__ #define __M_BBOX__ -#include - +#include "doomtype.h" // provides MAXINT/MININT on non-Linux #include "m_fixed.h" diff --git a/linuxdoom-1.10/m_misc.c b/linuxdoom-1.10/m_misc.c index 0df4fe57d..014b31895 100644 --- a/linuxdoom-1.10/m_misc.c +++ b/linuxdoom-1.10/m_misc.c @@ -222,79 +222,81 @@ extern char* chat_macros[]; +// 64-bit compatible default_t: string defaults use slocation/strdefault, +// integer defaults use location/defaultvalue. typedef struct { char* name; - int* location; - int defaultvalue; - int scantranslate; // PC scan code hack - int untranslated; // lousy hack + int* location; // set for integer defaults, NULL for string defaults + int defaultvalue; // used when location != NULL + + char** slocation; // set for string defaults, NULL for integer defaults + const char* strdefault; // used when slocation != NULL + + int scantranslate; // PC scan code hack + int untranslated; // lousy hack } default_t; +// Helper macros to shorten the table +#define IDEF(name,loc,val) {name, &(loc), val, NULL, NULL, 0, 0} +#define SDEF(name,loc,val) {name, NULL, 0, &(loc), val, 0, 0} + default_t defaults[] = { - {"mouse_sensitivity",&mouseSensitivity, 5}, - {"sfx_volume",&snd_SfxVolume, 8}, - {"music_volume",&snd_MusicVolume, 8}, - {"show_messages",&showMessages, 1}, - + IDEF("mouse_sensitivity", mouseSensitivity, 5), + IDEF("sfx_volume", snd_SfxVolume, 8), + IDEF("music_volume", snd_MusicVolume, 8), + IDEF("show_messages", showMessages, 1), #ifdef NORMALUNIX - {"key_right",&key_right, KEY_RIGHTARROW}, - {"key_left",&key_left, KEY_LEFTARROW}, - {"key_up",&key_up, KEY_UPARROW}, - {"key_down",&key_down, KEY_DOWNARROW}, - {"key_strafeleft",&key_strafeleft, ','}, - {"key_straferight",&key_straferight, '.'}, - - {"key_fire",&key_fire, KEY_RCTRL}, - {"key_use",&key_use, ' '}, - {"key_strafe",&key_strafe, KEY_RALT}, - {"key_speed",&key_speed, KEY_RSHIFT}, - -// UNIX hack, to be removed. + IDEF("key_right", key_right, KEY_RIGHTARROW), + IDEF("key_left", key_left, KEY_LEFTARROW), + IDEF("key_up", key_up, KEY_UPARROW), + IDEF("key_down", key_down, KEY_DOWNARROW), + IDEF("key_strafeleft", key_strafeleft, ','), + IDEF("key_straferight", key_straferight, '.'), + IDEF("key_fire", key_fire, KEY_RCTRL), + IDEF("key_use", key_use, ' '), + IDEF("key_strafe", key_strafe, KEY_RALT), + IDEF("key_speed", key_speed, KEY_RSHIFT), +// UNIX hack, to be removed. #ifdef SNDSERV - {"sndserver", (int *) &sndserver_filename, (int) "sndserver"}, - {"mb_used", &mb_used, 2}, + SDEF("sndserver", sndserver_filename, "sndserver"), + IDEF("mb_used", mb_used, 2), #endif - #endif #ifdef LINUX - {"mousedev", (int*)&mousedev, (int)"/dev/ttyS0"}, - {"mousetype", (int*)&mousetype, (int)"microsoft"}, + SDEF("mousedev", mousedev, "/dev/ttyS0"), + SDEF("mousetype", mousetype, "microsoft"), #endif - {"use_mouse",&usemouse, 1}, - {"mouseb_fire",&mousebfire,0}, - {"mouseb_strafe",&mousebstrafe,1}, - {"mouseb_forward",&mousebforward,2}, - - {"use_joystick",&usejoystick, 0}, - {"joyb_fire",&joybfire,0}, - {"joyb_strafe",&joybstrafe,1}, - {"joyb_use",&joybuse,3}, - {"joyb_speed",&joybspeed,2}, - - {"screenblocks",&screenblocks, 9}, - {"detaillevel",&detailLevel, 0}, - - {"snd_channels",&numChannels, 3}, - - - - {"usegamma",&usegamma, 0}, - - {"chatmacro0", (int *) &chat_macros[0], (int) HUSTR_CHATMACRO0 }, - {"chatmacro1", (int *) &chat_macros[1], (int) HUSTR_CHATMACRO1 }, - {"chatmacro2", (int *) &chat_macros[2], (int) HUSTR_CHATMACRO2 }, - {"chatmacro3", (int *) &chat_macros[3], (int) HUSTR_CHATMACRO3 }, - {"chatmacro4", (int *) &chat_macros[4], (int) HUSTR_CHATMACRO4 }, - {"chatmacro5", (int *) &chat_macros[5], (int) HUSTR_CHATMACRO5 }, - {"chatmacro6", (int *) &chat_macros[6], (int) HUSTR_CHATMACRO6 }, - {"chatmacro7", (int *) &chat_macros[7], (int) HUSTR_CHATMACRO7 }, - {"chatmacro8", (int *) &chat_macros[8], (int) HUSTR_CHATMACRO8 }, - {"chatmacro9", (int *) &chat_macros[9], (int) HUSTR_CHATMACRO9 } + IDEF("use_mouse", usemouse, 1), + IDEF("mouseb_fire", mousebfire, 0), + IDEF("mouseb_strafe", mousebstrafe, 1), + IDEF("mouseb_forward", mousebforward, 2), + + IDEF("use_joystick", usejoystick, 0), + IDEF("joyb_fire", joybfire, 0), + IDEF("joyb_strafe", joybstrafe, 1), + IDEF("joyb_use", joybuse, 3), + IDEF("joyb_speed", joybspeed, 2), + + IDEF("screenblocks", screenblocks, 9), + IDEF("detaillevel", detailLevel, 0), + IDEF("snd_channels", numChannels, 3), + IDEF("usegamma", usegamma, 0), + + SDEF("chatmacro0", chat_macros[0], HUSTR_CHATMACRO0), + SDEF("chatmacro1", chat_macros[1], HUSTR_CHATMACRO1), + SDEF("chatmacro2", chat_macros[2], HUSTR_CHATMACRO2), + SDEF("chatmacro3", chat_macros[3], HUSTR_CHATMACRO3), + SDEF("chatmacro4", chat_macros[4], HUSTR_CHATMACRO4), + SDEF("chatmacro5", chat_macros[5], HUSTR_CHATMACRO5), + SDEF("chatmacro6", chat_macros[6], HUSTR_CHATMACRO6), + SDEF("chatmacro7", chat_macros[7], HUSTR_CHATMACRO7), + SDEF("chatmacro8", chat_macros[8], HUSTR_CHATMACRO8), + SDEF("chatmacro9", chat_macros[9], HUSTR_CHATMACRO9), }; @@ -317,14 +319,14 @@ void M_SaveDefaults (void) for (i=0 ; i -0xfff - && defaults[i].defaultvalue < 0xfff) + if (defaults[i].slocation) + { + fprintf (f,"%s\t\t\"%s\"\n", defaults[i].name, *defaults[i].slocation); + } + else { v = *defaults[i].location; - fprintf (f,"%s\t\t%i\n",defaults[i].name,v); - } else { - fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name, - * (char **) (defaults[i].location)); + fprintf (f,"%s\t\t%i\n", defaults[i].name, v); } } @@ -351,7 +353,12 @@ void M_LoadDefaults (void) // set everything to base values numdefaults = sizeof(defaults)/sizeof(defaults[0]); for (i=0 ; i #include #include -#include +#ifndef _WIN32 +#include // On Windows, alloca comes from above +#endif #define O_BINARY 0 #endif @@ -64,13 +66,22 @@ int numlumps; void** lumpcache; +#ifdef _WIN32 +#define strcmpi _stricmp // MinGW: use _stricmp instead of strcasecmp +#else #define strcmpi strcasecmp +#endif +#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) +// MinGW provides strupr and filelength in string.h / io.h. +// Emscripten provides its own strupr in compat/string.h. void strupr (char* s) { while (*s) { *s = toupper(*s); s++; } } +#endif +#if !defined(_WIN32) int filelength (int handle) { struct stat fileinfo; @@ -80,6 +91,7 @@ int filelength (int handle) return fileinfo.st_size; } +#endif void diff --git a/linuxdoom-1.10/win/am_map.o b/linuxdoom-1.10/win/am_map.o new file mode 100644 index 000000000..4b8230308 Binary files /dev/null and b/linuxdoom-1.10/win/am_map.o differ diff --git a/linuxdoom-1.10/win/d_items.o b/linuxdoom-1.10/win/d_items.o new file mode 100644 index 000000000..779fd58d8 Binary files /dev/null and b/linuxdoom-1.10/win/d_items.o differ diff --git a/linuxdoom-1.10/win/d_main.o b/linuxdoom-1.10/win/d_main.o new file mode 100644 index 000000000..41f3b6aac Binary files /dev/null and b/linuxdoom-1.10/win/d_main.o differ diff --git a/linuxdoom-1.10/win/d_net.o b/linuxdoom-1.10/win/d_net.o new file mode 100644 index 000000000..3338a96a0 Binary files /dev/null and b/linuxdoom-1.10/win/d_net.o differ diff --git a/linuxdoom-1.10/win/doomdef.o b/linuxdoom-1.10/win/doomdef.o new file mode 100644 index 000000000..7b110593c Binary files /dev/null and b/linuxdoom-1.10/win/doomdef.o differ diff --git a/linuxdoom-1.10/win/doomstat.o b/linuxdoom-1.10/win/doomstat.o new file mode 100644 index 000000000..ae0e8606e Binary files /dev/null and b/linuxdoom-1.10/win/doomstat.o differ diff --git a/linuxdoom-1.10/win/dstrings.o b/linuxdoom-1.10/win/dstrings.o new file mode 100644 index 000000000..18451d8c5 Binary files /dev/null and b/linuxdoom-1.10/win/dstrings.o differ diff --git a/linuxdoom-1.10/win/f_finale.o b/linuxdoom-1.10/win/f_finale.o new file mode 100644 index 000000000..745eb6b60 Binary files /dev/null and b/linuxdoom-1.10/win/f_finale.o differ diff --git a/linuxdoom-1.10/win/f_wipe.o b/linuxdoom-1.10/win/f_wipe.o new file mode 100644 index 000000000..fb7568b9b Binary files /dev/null and b/linuxdoom-1.10/win/f_wipe.o differ diff --git a/linuxdoom-1.10/win/g_game.o b/linuxdoom-1.10/win/g_game.o new file mode 100644 index 000000000..1e62488d8 Binary files /dev/null and b/linuxdoom-1.10/win/g_game.o differ diff --git a/linuxdoom-1.10/win/hu_lib.o b/linuxdoom-1.10/win/hu_lib.o new file mode 100644 index 000000000..cdf988c62 Binary files /dev/null and b/linuxdoom-1.10/win/hu_lib.o differ diff --git a/linuxdoom-1.10/win/hu_stuff.o b/linuxdoom-1.10/win/hu_stuff.o new file mode 100644 index 000000000..e0d7c7ac4 Binary files /dev/null and b/linuxdoom-1.10/win/hu_stuff.o differ diff --git a/linuxdoom-1.10/win/i_main.o b/linuxdoom-1.10/win/i_main.o new file mode 100644 index 000000000..c08c6dad6 Binary files /dev/null and b/linuxdoom-1.10/win/i_main.o differ diff --git a/linuxdoom-1.10/win/i_net_stub.o b/linuxdoom-1.10/win/i_net_stub.o new file mode 100644 index 000000000..144160163 Binary files /dev/null and b/linuxdoom-1.10/win/i_net_stub.o differ diff --git a/linuxdoom-1.10/win/i_sound_null.o b/linuxdoom-1.10/win/i_sound_null.o new file mode 100644 index 000000000..faca78a52 Binary files /dev/null and b/linuxdoom-1.10/win/i_sound_null.o differ diff --git a/linuxdoom-1.10/win/i_system_win.o b/linuxdoom-1.10/win/i_system_win.o new file mode 100644 index 000000000..3dae457ba Binary files /dev/null and b/linuxdoom-1.10/win/i_system_win.o differ diff --git a/linuxdoom-1.10/win/i_video_sdl.o b/linuxdoom-1.10/win/i_video_sdl.o new file mode 100644 index 000000000..8b87b554f Binary files /dev/null and b/linuxdoom-1.10/win/i_video_sdl.o differ diff --git a/linuxdoom-1.10/win/info.o b/linuxdoom-1.10/win/info.o new file mode 100644 index 000000000..b880f3371 Binary files /dev/null and b/linuxdoom-1.10/win/info.o differ diff --git a/linuxdoom-1.10/win/m_argv.o b/linuxdoom-1.10/win/m_argv.o new file mode 100644 index 000000000..9281f5da7 Binary files /dev/null and b/linuxdoom-1.10/win/m_argv.o differ diff --git a/linuxdoom-1.10/win/m_bbox.o b/linuxdoom-1.10/win/m_bbox.o new file mode 100644 index 000000000..7f7f9f0c3 Binary files /dev/null and b/linuxdoom-1.10/win/m_bbox.o differ diff --git a/linuxdoom-1.10/win/m_cheat.o b/linuxdoom-1.10/win/m_cheat.o new file mode 100644 index 000000000..dc3ef05e7 Binary files /dev/null and b/linuxdoom-1.10/win/m_cheat.o differ diff --git a/linuxdoom-1.10/win/m_fixed.o b/linuxdoom-1.10/win/m_fixed.o new file mode 100644 index 000000000..06608df19 Binary files /dev/null and b/linuxdoom-1.10/win/m_fixed.o differ diff --git a/linuxdoom-1.10/win/m_menu.o b/linuxdoom-1.10/win/m_menu.o new file mode 100644 index 000000000..132a999e1 Binary files /dev/null and b/linuxdoom-1.10/win/m_menu.o differ diff --git a/linuxdoom-1.10/win/m_misc.o b/linuxdoom-1.10/win/m_misc.o new file mode 100644 index 000000000..de7560695 Binary files /dev/null and b/linuxdoom-1.10/win/m_misc.o differ diff --git a/linuxdoom-1.10/win/m_random.o b/linuxdoom-1.10/win/m_random.o new file mode 100644 index 000000000..3d78d02fd Binary files /dev/null and b/linuxdoom-1.10/win/m_random.o differ diff --git a/linuxdoom-1.10/win/m_swap.o b/linuxdoom-1.10/win/m_swap.o new file mode 100644 index 000000000..e4fc1df92 Binary files /dev/null and b/linuxdoom-1.10/win/m_swap.o differ diff --git a/linuxdoom-1.10/win/p_ceilng.o b/linuxdoom-1.10/win/p_ceilng.o new file mode 100644 index 000000000..431557fb7 Binary files /dev/null and b/linuxdoom-1.10/win/p_ceilng.o differ diff --git a/linuxdoom-1.10/win/p_doors.o b/linuxdoom-1.10/win/p_doors.o new file mode 100644 index 000000000..8942dad35 Binary files /dev/null and b/linuxdoom-1.10/win/p_doors.o differ diff --git a/linuxdoom-1.10/win/p_enemy.o b/linuxdoom-1.10/win/p_enemy.o new file mode 100644 index 000000000..8f901d569 Binary files /dev/null and b/linuxdoom-1.10/win/p_enemy.o differ diff --git a/linuxdoom-1.10/win/p_floor.o b/linuxdoom-1.10/win/p_floor.o new file mode 100644 index 000000000..afddd42f1 Binary files /dev/null and b/linuxdoom-1.10/win/p_floor.o differ diff --git a/linuxdoom-1.10/win/p_inter.o b/linuxdoom-1.10/win/p_inter.o new file mode 100644 index 000000000..1a14ddbe3 Binary files /dev/null and b/linuxdoom-1.10/win/p_inter.o differ diff --git a/linuxdoom-1.10/win/p_lights.o b/linuxdoom-1.10/win/p_lights.o new file mode 100644 index 000000000..4917b3849 Binary files /dev/null and b/linuxdoom-1.10/win/p_lights.o differ diff --git a/linuxdoom-1.10/win/p_map.o b/linuxdoom-1.10/win/p_map.o new file mode 100644 index 000000000..60f0155b2 Binary files /dev/null and b/linuxdoom-1.10/win/p_map.o differ diff --git a/linuxdoom-1.10/win/p_maputl.o b/linuxdoom-1.10/win/p_maputl.o new file mode 100644 index 000000000..f63b15cb5 Binary files /dev/null and b/linuxdoom-1.10/win/p_maputl.o differ diff --git a/linuxdoom-1.10/win/p_mobj.o b/linuxdoom-1.10/win/p_mobj.o new file mode 100644 index 000000000..0db7d8eb3 Binary files /dev/null and b/linuxdoom-1.10/win/p_mobj.o differ diff --git a/linuxdoom-1.10/win/p_plats.o b/linuxdoom-1.10/win/p_plats.o new file mode 100644 index 000000000..1872fba07 Binary files /dev/null and b/linuxdoom-1.10/win/p_plats.o differ diff --git a/linuxdoom-1.10/win/p_pspr.o b/linuxdoom-1.10/win/p_pspr.o new file mode 100644 index 000000000..a5a1ca15c Binary files /dev/null and b/linuxdoom-1.10/win/p_pspr.o differ diff --git a/linuxdoom-1.10/win/p_saveg.o b/linuxdoom-1.10/win/p_saveg.o new file mode 100644 index 000000000..09d63c882 Binary files /dev/null and b/linuxdoom-1.10/win/p_saveg.o differ diff --git a/linuxdoom-1.10/win/p_setup.o b/linuxdoom-1.10/win/p_setup.o new file mode 100644 index 000000000..8e6d7c2cf Binary files /dev/null and b/linuxdoom-1.10/win/p_setup.o differ diff --git a/linuxdoom-1.10/win/p_sight.o b/linuxdoom-1.10/win/p_sight.o new file mode 100644 index 000000000..6fdac0e54 Binary files /dev/null and b/linuxdoom-1.10/win/p_sight.o differ diff --git a/linuxdoom-1.10/win/p_spec.o b/linuxdoom-1.10/win/p_spec.o new file mode 100644 index 000000000..610a6bee1 Binary files /dev/null and b/linuxdoom-1.10/win/p_spec.o differ diff --git a/linuxdoom-1.10/win/p_switch.o b/linuxdoom-1.10/win/p_switch.o new file mode 100644 index 000000000..2226c3a01 Binary files /dev/null and b/linuxdoom-1.10/win/p_switch.o differ diff --git a/linuxdoom-1.10/win/p_telept.o b/linuxdoom-1.10/win/p_telept.o new file mode 100644 index 000000000..3645f893e Binary files /dev/null and b/linuxdoom-1.10/win/p_telept.o differ diff --git a/linuxdoom-1.10/win/p_tick.o b/linuxdoom-1.10/win/p_tick.o new file mode 100644 index 000000000..1cd4aec57 Binary files /dev/null and b/linuxdoom-1.10/win/p_tick.o differ diff --git a/linuxdoom-1.10/win/p_user.o b/linuxdoom-1.10/win/p_user.o new file mode 100644 index 000000000..75be20a30 Binary files /dev/null and b/linuxdoom-1.10/win/p_user.o differ diff --git a/linuxdoom-1.10/win/r_bsp.o b/linuxdoom-1.10/win/r_bsp.o new file mode 100644 index 000000000..db00367d4 Binary files /dev/null and b/linuxdoom-1.10/win/r_bsp.o differ diff --git a/linuxdoom-1.10/win/r_data.o b/linuxdoom-1.10/win/r_data.o new file mode 100644 index 000000000..a3d18ea8e Binary files /dev/null and b/linuxdoom-1.10/win/r_data.o differ diff --git a/linuxdoom-1.10/win/r_draw.o b/linuxdoom-1.10/win/r_draw.o new file mode 100644 index 000000000..482ab9eef Binary files /dev/null and b/linuxdoom-1.10/win/r_draw.o differ diff --git a/linuxdoom-1.10/win/r_main.o b/linuxdoom-1.10/win/r_main.o new file mode 100644 index 000000000..3638bbb8a Binary files /dev/null and b/linuxdoom-1.10/win/r_main.o differ diff --git a/linuxdoom-1.10/win/r_plane.o b/linuxdoom-1.10/win/r_plane.o new file mode 100644 index 000000000..87401de71 Binary files /dev/null and b/linuxdoom-1.10/win/r_plane.o differ diff --git a/linuxdoom-1.10/win/r_segs.o b/linuxdoom-1.10/win/r_segs.o new file mode 100644 index 000000000..200c2e66a Binary files /dev/null and b/linuxdoom-1.10/win/r_segs.o differ diff --git a/linuxdoom-1.10/win/r_sky.o b/linuxdoom-1.10/win/r_sky.o new file mode 100644 index 000000000..56f573f21 Binary files /dev/null and b/linuxdoom-1.10/win/r_sky.o differ diff --git a/linuxdoom-1.10/win/r_things.o b/linuxdoom-1.10/win/r_things.o new file mode 100644 index 000000000..72250d697 Binary files /dev/null and b/linuxdoom-1.10/win/r_things.o differ diff --git a/linuxdoom-1.10/win/s_sound.o b/linuxdoom-1.10/win/s_sound.o new file mode 100644 index 000000000..f0b35bcf3 Binary files /dev/null and b/linuxdoom-1.10/win/s_sound.o differ diff --git a/linuxdoom-1.10/win/sounds.o b/linuxdoom-1.10/win/sounds.o new file mode 100644 index 000000000..e31f9d24c Binary files /dev/null and b/linuxdoom-1.10/win/sounds.o differ diff --git a/linuxdoom-1.10/win/st_lib.o b/linuxdoom-1.10/win/st_lib.o new file mode 100644 index 000000000..8a2e03127 Binary files /dev/null and b/linuxdoom-1.10/win/st_lib.o differ diff --git a/linuxdoom-1.10/win/st_stuff.o b/linuxdoom-1.10/win/st_stuff.o new file mode 100644 index 000000000..a99ab2e31 Binary files /dev/null and b/linuxdoom-1.10/win/st_stuff.o differ diff --git a/linuxdoom-1.10/win/tables.o b/linuxdoom-1.10/win/tables.o new file mode 100644 index 000000000..099242547 Binary files /dev/null and b/linuxdoom-1.10/win/tables.o differ diff --git a/linuxdoom-1.10/win/v_video.o b/linuxdoom-1.10/win/v_video.o new file mode 100644 index 000000000..98d482c28 Binary files /dev/null and b/linuxdoom-1.10/win/v_video.o differ diff --git a/linuxdoom-1.10/win/w_wad.o b/linuxdoom-1.10/win/w_wad.o new file mode 100644 index 000000000..11aea1328 Binary files /dev/null and b/linuxdoom-1.10/win/w_wad.o differ diff --git a/linuxdoom-1.10/win/wi_stuff.o b/linuxdoom-1.10/win/wi_stuff.o new file mode 100644 index 000000000..d10bc0b16 Binary files /dev/null and b/linuxdoom-1.10/win/wi_stuff.o differ diff --git a/linuxdoom-1.10/win/z_zone.o b/linuxdoom-1.10/win/z_zone.o new file mode 100644 index 000000000..100cc5e24 Binary files /dev/null and b/linuxdoom-1.10/win/z_zone.o differ diff --git a/run_setup.py b/run_setup.py new file mode 100644 index 000000000..aed5f34eb --- /dev/null +++ b/run_setup.py @@ -0,0 +1,45 @@ +""" +run_setup.py - Builds web-doom step by step, writing logs for Copilot to read. +Run via: c:/python314/python.exe run_setup.py +""" +import subprocess, os, json, sys + +ROOT = r"c:\projects\DOOM" +WEB = os.path.join(ROOT, "web-doom") +DOOM = os.path.join(ROOT, "linuxdoom-1.10") +LOG = os.path.join(ROOT, "setup_log.json") + +results = {} + +def run(label, cmd, cwd): + print(f"\n=== {label} ===") + sys.stdout.flush() + r = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, timeout=600) + results[label] = { + "returncode": r.returncode, + "stdout": r.stdout[-4000:], + "stderr": r.stderr[-2000:], + } + print(f"exit: {r.returncode}") + print(r.stdout[-2000:]) + if r.stderr: + print("STDERR:", r.stderr[-500:]) + sys.stdout.flush() + return r.returncode == 0 + +# Step 1: npm install +ok = run("npm-install", ["npm", "install"], WEB) + +# Step 2: emcc build (runs build_em.ps1) +if ok: + ok = run("emcc-build", + ["powershell", "-ExecutionPolicy", "Bypass", "-File", "build_em.ps1"], + DOOM) + +# Save results +with open(LOG, "w") as f: + json.dump(results, f, indent=2) + +print(f"\n\nLog written to: {LOG}") +print("Success:", ok) +sys.exit(0 if ok else 1) diff --git a/setup_web.ps1 b/setup_web.ps1 new file mode 100644 index 000000000..5953530e1 --- /dev/null +++ b/setup_web.ps1 @@ -0,0 +1,81 @@ +# setup_web.ps1 – One-shot script to build DOOM as a web game and launch it +# +# Steps performed automatically: +# 1. Install Emscripten SDK (if not already installed) +# 2. Download Freedoom WAD (if no WAD found) +# 3. Compile DOOM → WebAssembly (linuxdoom-1.10/build_em.ps1) +# 4. Copy WASM output into web-doom/public/ +# 5. npm install (web-doom/) +# 6. npm run dev (opens http://localhost:3000) +# +# Run from the repo root: +# .\setup_web.ps1 + +$ROOT = $PSScriptRoot +Set-Location $ROOT + +# ───────────────────────────────────────────────────────── +# 1. Emscripten SDK +# ───────────────────────────────────────────────────────── +function Find-Emcc { + return Get-Command emcc -ErrorAction SilentlyContinue +} + +if (-not (Find-Emcc)) { + $EMSDK_DIR = "$env:USERPROFILE\emsdk" + + if (-not (Test-Path "$EMSDK_DIR\emsdk.ps1")) { + Write-Host "Installing Emscripten SDK to $EMSDK_DIR ..." -ForegroundColor Cyan + git clone https://github.com/emscripten-core/emsdk.git $EMSDK_DIR + } + + Push-Location $EMSDK_DIR + Write-Host "Activating latest Emscripten..." -ForegroundColor Cyan + & .\emsdk install latest + & .\emsdk activate latest + . .\emsdk_env.ps1 # update $env:PATH for this shell session + Pop-Location +} + +if (-not (Find-Emcc)) { + Write-Error "emcc still not found after emsdk setup. Please activate emsdk manually and re-run." + exit 1 +} + +Write-Host "emcc: $((Get-Command emcc).Source)" -ForegroundColor Green + +# ───────────────────────────────────────────────────────── +# 2. Build DOOM → WASM +# ───────────────────────────────────────────────────────── +Write-Host "" +Write-Host "=== Building DOOM with Emscripten ===" -ForegroundColor Cyan +Push-Location "$ROOT\linuxdoom-1.10" +& .\build_em.ps1 +if ($LASTEXITCODE -ne 0) { + Write-Error "WASM build failed." + exit 1 +} +Pop-Location + +# ───────────────────────────────────────────────────────── +# 3. Install Next.js dependencies +# ───────────────────────────────────────────────────────── +Write-Host "" +Write-Host "=== Installing Next.js dependencies ===" -ForegroundColor Cyan +Push-Location "$ROOT\web-doom" +npm install +if ($LASTEXITCODE -ne 0) { + Write-Error "npm install failed." + exit 1 +} +Pop-Location + +# ───────────────────────────────────────────────────────── +# 4. Start the dev server +# ───────────────────────────────────────────────────────── +Write-Host "" +Write-Host "=== Starting Next.js dev server ===" -ForegroundColor Green +Write-Host "Open http://localhost:3000 in your browser." -ForegroundColor Yellow +Write-Host "Press Ctrl+C to stop." -ForegroundColor Gray +Set-Location "$ROOT\web-doom" +npm run dev diff --git a/web-doom/.gitignore b/web-doom/.gitignore new file mode 100644 index 000000000..dce6fe582 --- /dev/null +++ b/web-doom/.gitignore @@ -0,0 +1,8 @@ +node_modules/ +.next/ +out/ + +# Emscripten build output (generated by build_em.ps1) +public/doom.js +public/doom.wasm +public/doom.data diff --git a/web-doom/next.config.js b/web-doom/next.config.js new file mode 100644 index 000000000..ba640e9c6 --- /dev/null +++ b/web-doom/next.config.js @@ -0,0 +1,18 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + // COOP + COEP are required for SharedArrayBuffer (Emscripten with pthreads). + // They also give a clean isolation context. All assets here are same-origin. + async headers() { + return [ + { + source: '/(.*)', + headers: [ + { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' }, + { key: 'Cross-Origin-Embedder-Policy', value: 'require-corp' }, + ], + }, + ]; + }, +}; + +module.exports = nextConfig; diff --git a/web-doom/package-lock.json b/web-doom/package-lock.json new file mode 100644 index 000000000..7977cb145 --- /dev/null +++ b/web-doom/package-lock.json @@ -0,0 +1,899 @@ +{ + "name": "web-doom", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "web-doom", + "version": "1.0.0", + "dependencies": { + "next": "^15.2.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@next/env": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.12.tgz", + "integrity": "sha512-pUvdJN1on574wQHjaBfNGDt9Mz5utDSZFsIIQkMzPgNS8ZvT4H2mwOrOIClwsQOb6EGx5M76/CZr6G8i6pSpLg==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.12.tgz", + "integrity": "sha512-RnRjBtH8S8eXCpUNkQ+543DUc7ys8y15VxmFU9HRqlo9BG3CcBUiwNtF8SNoi2xvGCVJq1vl2yYq+3oISBS0Zg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.12.tgz", + "integrity": "sha512-nqa9/7iQlboF1EFtNhWxQA0rQstmYRSBGxSM6g3GxvxHxcoeqVXfGNr9stJOme674m2V7r4E3+jEhhGvSQhJRA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.12.tgz", + "integrity": "sha512-dCzAjqhDHwmoB2M4eYfVKqXs99QdQxNQVpftvP1eGVppamXh/OkDAwV737Zr0KPXEqRUMN4uCjh6mjO+XtF3Mw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.12.tgz", + "integrity": "sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.12.tgz", + "integrity": "sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.12.tgz", + "integrity": "sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.12.tgz", + "integrity": "sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.12.tgz", + "integrity": "sha512-Z1Dh6lhFkxvBDH1FoW6OU/L6prYwPSlwjLiZkExIAh8fbP6iI/M7iGTQAJPYJ9YFlWobCZ1PHbchFhFYb2ADkw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001776", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz", + "integrity": "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz", + "integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==", + "license": "MIT", + "dependencies": { + "@next/env": "15.5.12", + "@swc/helpers": "0.5.15", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.5.12", + "@next/swc-darwin-x64": "15.5.12", + "@next/swc-linux-arm64-gnu": "15.5.12", + "@next/swc-linux-arm64-musl": "15.5.12", + "@next/swc-linux-x64-gnu": "15.5.12", + "@next/swc-linux-x64-musl": "15.5.12", + "@next/swc-win32-arm64-msvc": "15.5.12", + "@next/swc-win32-x64-msvc": "15.5.12", + "sharp": "^0.34.3" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + } + } +} diff --git a/web-doom/package.json b/web-doom/package.json new file mode 100644 index 000000000..2bb976de2 --- /dev/null +++ b/web-doom/package.json @@ -0,0 +1,16 @@ +{ + "name": "web-doom", + "version": "1.0.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "next": "^15.2.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } +} diff --git a/web-doom/pages/_app.js b/web-doom/pages/_app.js new file mode 100644 index 000000000..8dba54bdd --- /dev/null +++ b/web-doom/pages/_app.js @@ -0,0 +1,5 @@ +import '../styles/globals.css'; + +export default function App({ Component, pageProps }) { + return ; +} diff --git a/web-doom/pages/index.js b/web-doom/pages/index.js new file mode 100644 index 000000000..32c65c35d --- /dev/null +++ b/web-doom/pages/index.js @@ -0,0 +1,208 @@ +import Head from 'next/head'; +import { useEffect, useRef, useState } from 'react'; +import styles from '../styles/Doom.module.css'; + +export default function DoomPage() { + const canvasRef = useRef(null); + const bootedRef = useRef(false); // guard against React 19 strict-mode double-invoke + const scriptRef = useRef(null); + const [status, setStatus] = useState('idle'); + const [progress, setProgress] = useState(0); + const [errMsg, setErrMsg] = useState(''); + + useEffect(() => { + const canvas = canvasRef.current; + if (!canvas || bootedRef.current) return; + bootedRef.current = true; + + let cancelled = false; + let timeoutId = null; + + async function boot() { + setStatus('loading'); + + // ── 1. Load WAD info ────────────────────────────────────────────── + let iwadPath = '/freedoom1.wad'; + try { + const r = await fetch('/wad-info.json'); + if (r.ok) { + const info = await r.json(); + iwadPath = info.iwad || iwadPath; + } + } catch (_) { /* use default */ } + + if (cancelled) return; + + // ── 2. 60-second safety-net timeout ────────────────────────────── + timeoutId = setTimeout(() => { + if (!cancelled) { + setStatus('error'); + setErrMsg('Timed out — open browser console (F12) for details.'); + } + }, 60_000); + + // ── 3. Configure Emscripten Module BEFORE injecting doom.js ────── + window.Module = { + canvas, + arguments: ['-iwad', iwadPath], + locateFile: (path) => `/${path}`, + + setStatus(text) { + if (cancelled) return; + if (!text) { + // Emscripten calls setStatus("") when fully ready — + // use as fallback in case onRuntimeInitialized was missed. + setStatus('running'); + setProgress(100); + setTimeout(() => canvas.focus(), 50); + return; + } + const m = text.match(/\((\d+(?:\.\d+)?)\/(\d+)\)/); + if (m) setProgress(Math.round((parseFloat(m[1]) / parseFloat(m[2])) * 100)); + }, + + onRuntimeInitialized() { + if (cancelled) return; + clearTimeout(timeoutId); + setStatus('running'); + setProgress(100); + setTimeout(() => canvas.focus(), 50); + }, + + print: (...a) => console.log('[DOOM]', ...a), + printErr: (...a) => console.warn('[DOOM]', ...a), + + onAbort(reason) { + if (cancelled) return; + console.error('[DOOM] abort:', reason); + setStatus('error'); + setErrMsg(`DOOM aborted: ${reason}\nSee browser console (F12) for details.`); + }, + }; + + // ── 4. Inject doom.js ───────────────────────────────────────────── + const script = document.createElement('script'); + script.src = '/doom.js'; + script.async = true; + script.onerror = (e) => { + if (cancelled) return; + console.error('[DOOM] script load failed', e); + setStatus('error'); + setErrMsg('Failed to load /doom.js — run Step 3 to rebuild the WASM bundle.'); + }; + scriptRef.current = script; + document.body.appendChild(script); + } + + boot().catch((err) => { + if (!cancelled) { + console.error('[DOOM] boot error:', err); + setStatus('error'); + setErrMsg(String(err)); + } + }); + + return () => { + cancelled = true; + clearTimeout(timeoutId); + const s = scriptRef.current ?? document.querySelector('script[src="/doom.js"]'); + if (s?.parentNode) s.parentNode.removeChild(s); + delete window.Module; + }; + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + function handleCanvasClick() { + canvasRef.current?.requestPointerLock?.(); + } + + return ( + <> + + DOOM – Web Edition + + + + +
+
+

+ D + O + O + M +

+

Classic Doom · WebAssembly Port

+
+ +
+ {/* Overlay shown while loading */} + {status === 'loading' && ( +
+

Loading DOOM…

+
+
+
+

{progress}%

+
+ )} + + {/* Error state */} + {status === 'error' && ( +
+

💀

+

DOOM Failed to Start

+

{errMsg}

+

+ Build the WASM bundle first:
+ cd linuxdoom-1.10 && .\build_em.ps1 +

+
+ )} + + {/* Idle screen before anything loads */} + {status === 'idle' && ( +
+

Initialising…

+
+ )} + + {/* The actual DOOM render target */} + e.preventDefault()} + /> +
+ +
+

Controls

+
+
↑ ↓ ← → Move / Turn
+
Ctrl Fire
+
Space Use / Open
+
Shift Run
+
Alt + ←/→ Strafe
+
1–7 Weapons
+
Esc Menu
+
Tab Map
+
+

+ Click the game window to capture the mouse (Esc to release). +

+
+ + +
+ + ); +} diff --git a/web-doom/public/README.md b/web-doom/public/README.md new file mode 100644 index 000000000..83c803a01 --- /dev/null +++ b/web-doom/public/README.md @@ -0,0 +1,12 @@ +# web-doom/public/ + +Place the Emscripten build output here after running `build_em.ps1`: + +- `doom.js` – Emscripten JS glue (auto-starts DOOM on page load) +- `doom.wasm` – WebAssembly binary +- `doom.data` – Preloaded filesystem (contains the WAD file) + +Run from `linuxdoom-1.10/`: +```powershell +.\build_em.ps1 +``` diff --git a/web-doom/public/wad-info.json b/web-doom/public/wad-info.json new file mode 100644 index 000000000..4d0d8ae52 --- /dev/null +++ b/web-doom/public/wad-info.json @@ -0,0 +1 @@ +{"iwad":"/freedoom1.wad","name":"freedoom1.wad"} diff --git a/web-doom/styles/Doom.module.css b/web-doom/styles/Doom.module.css new file mode 100644 index 000000000..d1e593296 --- /dev/null +++ b/web-doom/styles/Doom.module.css @@ -0,0 +1,201 @@ +/* Doom.module.css */ + +.main { + display: flex; + flex-direction: column; + align-items: center; + min-height: 100vh; + background: radial-gradient(ellipse at top, #1a0000 0%, #0a0a0a 70%); + padding: 2rem 1rem; + gap: 1.5rem; +} + +/* ── Header ─────────────────────────────────────────── */ +.header { + text-align: center; + user-select: none; +} + +.title { + font-size: clamp(3rem, 10vw, 6rem); + font-weight: 900; + letter-spacing: 0.15em; + line-height: 1; + text-transform: uppercase; +} + +.titleD { color: #ff2200; } +.titleO { color: #ff4400; } +.titleO2 { color: #ff6600; } +.titleM { color: #ff2200; } + +.title span { + display: inline-block; + text-shadow: + 0 0 10px currentColor, + 0 0 30px currentColor, + 0 0 60px currentColor; + animation: flicker 4s infinite alternate; +} + +@keyframes flicker { + 0% { opacity: 1; } + 92% { opacity: 1; } + 93% { opacity: 0.7; } + 94% { opacity: 1; } + 97% { opacity: 0.85; } + 100% { opacity: 1; } +} + +.subtitle { + color: #888; + font-size: 0.85rem; + letter-spacing: 0.25em; + text-transform: uppercase; + margin-top: 0.4rem; +} + +/* ── Canvas wrapper ──────────────────────────────────── */ +.canvasWrapper { + position: relative; + width: 640px; + max-width: 100%; + aspect-ratio: 16 / 10; + background: #000; + border: 2px solid #ff2200; + box-shadow: + 0 0 20px #ff220055, + 0 0 60px #ff220022, + inset 0 0 20px #00000088; + border-radius: 2px; +} + +.canvas { + display: block; + width: 100%; + height: 100%; + image-rendering: pixelated; + image-rendering: crisp-edges; + opacity: 0; + transition: opacity 0.5s ease; +} + +.canvasVisible { + opacity: 1; +} + +/* ── Overlay (loading / error) ───────────────────────── */ +.overlay { + position: absolute; + inset: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1rem; + background: rgba(0, 0, 0, 0.92); + z-index: 10; + padding: 2rem; +} + +.overlayError { + background: rgba(20, 0, 0, 0.96); +} + +.loadingText { + font-size: 1.1rem; + color: #ff6600; + letter-spacing: 0.1em; + animation: pulse 1.5s infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.4; } +} + +.progressBarOuter { + width: 80%; + height: 8px; + background: #1a0000; + border: 1px solid #ff2200; + border-radius: 4px; + overflow: hidden; +} + +.progressBarInner { + height: 100%; + background: linear-gradient(90deg, #ff2200, #ff6600); + transition: width 0.3s ease; + box-shadow: 0 0 8px #ff2200; +} + +.progressLabel { + color: #888; + font-size: 0.8rem; +} + +/* Error overlay */ +.errorIcon { font-size: 3rem; } +.errorTitle { color: #ff2200; font-size: 1.2rem; font-weight: bold; letter-spacing: 0.15em; } +.errorMsg { color: #cc6666; font-size: 0.8rem; text-align: center; max-width: 480px; line-height: 1.5; } +.errorHint { color: #888; font-size: 0.75rem; text-align: center; line-height: 1.8; } +.errorHint code { + display: block; + background: #1a0000; + border: 1px solid #440000; + padding: 0.4rem 0.8rem; + border-radius: 3px; + margin-top: 0.4rem; + color: #ff9966; +} + +/* ── Controls section ────────────────────────────────── */ +.controls { + width: 640px; + max-width: 100%; + background: #0d0d0d; + border: 1px solid #2a0000; + border-radius: 4px; + padding: 1.2rem 1.5rem; +} + +.controls h2 { + color: #ff4400; + font-size: 0.8rem; + letter-spacing: 0.25em; + text-transform: uppercase; + margin-bottom: 0.8rem; + border-bottom: 1px solid #2a0000; + padding-bottom: 0.4rem; +} + +.controlsGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + gap: 0.5rem 1rem; + font-size: 0.8rem; + color: #aaa; +} + +.controlsGrid div { + display: flex; + align-items: center; + gap: 0.5rem; +} + +/* kbd styles are global — defined in globals.css */ + +.mouseNote { + margin-top: 0.8rem; + font-size: 0.72rem; + color: #555; +} + +/* ── Footer ──────────────────────────────────────────── */ +.footer { + color: #333; + font-size: 0.7rem; + text-align: center; + padding-bottom: 1rem; +} diff --git a/web-doom/styles/globals.css b/web-doom/styles/globals.css new file mode 100644 index 000000000..094769f93 --- /dev/null +++ b/web-doom/styles/globals.css @@ -0,0 +1,21 @@ +/* Global reset */ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + +html, body { + background: #0a0a0a; + color: #eee; + font-family: 'Courier New', Courier, monospace; + min-height: 100vh; +} + +kbd { + background: #1e1e1e; + border: 1px solid #444; + border-bottom-width: 2px; + border-radius: 3px; + padding: 1px 6px; + font-family: inherit; + font-size: 0.75em; + color: #ddd; + white-space: nowrap; +}