From a49603890b69fb9fb466961b1935b08c83f7c912 Mon Sep 17 00:00:00 2001 From: kgva CMS Date: Mon, 10 Aug 2026 23:03:53 +0000 Subject: [PATCH] feat: add simcity, pacman, tetris as inline retro-game easter eggs Generalized the doom launcher into launchGame(name) keyed by archive.org identifier; each cds into a fake . folder and runs .sh, same as doom. --- assets/css/custom.css | 9 ++++---- assets/js/shell.js | 49 +++++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/assets/css/custom.css b/assets/css/custom.css index ea37b32..b6307df 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -276,14 +276,15 @@ body:not(.home) .menu { display: none; } } .proj-path__seg--last { font-weight: 700; } -/* secret `doom` — runs inline as doom.sh inside a fake .doom folder, same - file-listing chrome as any other page. sized to the classic 4:3 game. */ -.doom-player { +/* secret retro games (doom, simcity, pacman, tetris) — each runs inline as + .sh inside a fake . folder, same file-listing chrome as any + other page. sized to the classic 4:3 DOS/arcade aspect ratio. */ +.game-player { width: 100%; aspect-ratio: 4 / 3; background: #000; } -.doom-player iframe { +.game-player iframe { width: 100%; height: 100%; border: 0; diff --git a/assets/js/shell.js b/assets/js/shell.js index de549d6..116d721 100644 --- a/assets/js/shell.js +++ b/assets/js/shell.js @@ -203,38 +203,50 @@ setTimeout(function () { pre.remove(); }, 4200); } - // secret: `doom` cds into a fake ".doom" folder and runs doom.sh — shareware - // DOOM (id Software), embedded inline in the same file-listing chrome as any - // other page (not a floating window). ".." is a real link back to wherever - // you typed the command from, so leaving is just normal navigation — nav.js's - // pjax swap restores the real page (and real breadcrumb) on its own. - function doom() { + // secret: retro games (doom, simcity, pacman, tetris) cd into a fake + // "." folder and run ".sh" — archive.org DOSBox emulators + // embedded inline in the same file-listing chrome as any other page (not a + // floating window). ".." is a real link back to wherever you typed the + // command from, so leaving is just normal navigation — nav.js's pjax swap + // restores the real page (and real breadcrumb) on its own. archive.org + // still gates each one behind its own "click to begin" — that's the + // emulator requiring a real user gesture before it can play audio, a + // cross-origin iframe we can't click into or configure around. + var GAMES = { + doom: "DoomsharewareEpisode", + simcity: "msdos_SimCity_1989", + pacman: "msdos_Pac-Man_1983", + tetris: "msdos_Tetris_1987" + }; + function launchGame(name) { + var archiveId = GAMES[name]; var main = document.getElementById("main-content"); - if (!main || document.querySelector(".doom-embed")) return; + if (!archiveId || !main || document.querySelector(".game-embed")) return; var back = window.location.pathname + window.location.search; + var file = name + ".sh"; var pathEl = document.querySelector(".prompt__path"); if (pathEl && /\$$/.test(pathEl.innerHTML)) { - pathEl.innerHTML = pathEl.innerHTML.replace(/\$$/, '/.doom$'); + pathEl.innerHTML = pathEl.innerHTML.replace(/\$$/, '/.' + name + '$'); } main.innerHTML = - '
' + + '
' + '

$ ls

' + '

total 1

' + '' + '
' + - '
' + - '' + + '
' + + '' + '
' + - '
doom.sh — running
' + + '
' + file + ' — running
' + '
' + '
'; @@ -243,9 +255,9 @@ document.dispatchEvent(new CustomEvent("pjax:load")); // the home page's always-open menu lives in the header, not #main-content - // — hide it too, otherwise its own "$ ls" sits right above doom's and + // — hide it too, otherwise its own "$ ls" sits right above the game's and // the listing looks doubled. restored on the next real navigation - // (leaving doom), which also fires pjax:load — registered after the + // (leaving the game), which also fires pjax:load — registered after the // dispatch above so it doesn't just catch its own event. if (menu && !menu.hidden) { menu.hidden = true; @@ -275,7 +287,7 @@ // tab-completion over known commands + navigable routes var COMMANDS = ["help", "man", "info", "contact", "date", "time", "tree", "fetch", "neofetch", "uname", "history", "clear", "echo", "pwd", "whoami", "ls", "cd", "cat", "open", - "dark", "light", "theme", "sl", "doom", "coffee"]; + "dark", "light", "theme", "sl", "doom", "simcity", "pacman", "tetris", "coffee"]; function complete() { var val = input.textContent; var parts = val.split(" "); @@ -303,7 +315,8 @@ remember(cmd); if (lc === "clear") { say(""); input.textContent = ""; return; } - if (lc === "doom") { doom(); say(""); input.textContent = ""; return; } + if (lc === "doom" || lc === "simcity" || lc === "tetris") { launchGame(lc); say(""); input.textContent = ""; return; } + if (lc === "pacman" || lc === "pac-man") { launchGame("pacman"); say(""); input.textContent = ""; return; } if (lc === "sl") { sl(); say(""); input.textContent = ""; return; } if (lc === "dark" || lc === "light") { setTheme(lc); say(""); input.textContent = ""; return; } if (lc === "theme") { var next = document.documentElement.classList.contains("dark") ? "light" : "dark"; setTheme(next); say("theme: " + next); input.textContent = ""; return; }