mirror of
https://github.com/skoelle/moonweb-site.git
synced 2026-09-17 17:00:25 +00:00
413 lines
16 KiB
HTML
Executable File
413 lines
16 KiB
HTML
Executable File
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>PHOBIA DemoGroup Archive - Nostalgic PC Intros from 1994</title>
|
|
<meta name="description" content="Explore the PHOBIA DemoGroup Archive, showcasing the 1994 PC intros, including the notable Phobia Welcome Intro. Relive the early days of PC intros with source code and more.">
|
|
<link rel="canonical" href="https://www.moonweb.org/phobia/" />
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap" rel="stylesheet">
|
|
<style>
|
|
body {
|
|
background-color: #1a1a1a;
|
|
margin: 0;
|
|
color: #f0f0f0;
|
|
font-family: 'VT323', monospace;
|
|
line-height: 1.6;
|
|
font-size: 20px;
|
|
overflow-x: hidden;
|
|
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
|
}
|
|
.header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background-color: #000071;
|
|
padding: 10px 0;
|
|
}
|
|
.header img, .header canvas {
|
|
height: 120px;
|
|
margin-right: 0;
|
|
}
|
|
.header a {
|
|
margin: 0 15px;
|
|
color: #518DAF;
|
|
text-decoration: none;
|
|
font-size: 1.2em;
|
|
}
|
|
.header a:hover {
|
|
color: #f0f0f0;
|
|
}
|
|
.content {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
padding: 20px 15px;
|
|
max-width: 1000px;
|
|
margin: 0 auto;
|
|
}
|
|
.program {
|
|
display: flex;
|
|
flex: 1 1 100%;
|
|
margin-bottom: 40px;
|
|
}
|
|
.program-image {
|
|
flex: 1 1 150px;
|
|
margin-right: 20px;
|
|
}
|
|
.program-image img {
|
|
width: 100%;
|
|
height: auto;
|
|
border-radius: 10px;
|
|
}
|
|
.program-description {
|
|
margin-top: 10px;
|
|
font-size: 1.1em;
|
|
line-height: 1.4;
|
|
}
|
|
.program-description p {
|
|
margin: 0.3em 0;
|
|
}
|
|
.program-info {
|
|
flex: 2 1 300px;
|
|
}
|
|
.program-info h2 {
|
|
font-size: 1em;
|
|
margin-top: 0;
|
|
margin-bottom: 10px;
|
|
}
|
|
.footer {
|
|
font-size: 0.9em;
|
|
text-align: center;
|
|
padding: 20px;
|
|
background-color: #333;
|
|
margin-top: 20px;
|
|
}
|
|
h1, h2 {
|
|
font-family: 'Press Start 2P', cursive;
|
|
}
|
|
@media (max-width: 600px) {
|
|
h1 {
|
|
font-size: 1.7em;
|
|
}
|
|
.program-info h2 {
|
|
font-size: 1.2em;
|
|
margin-bottom: 10px;
|
|
}
|
|
.header img, .header canvas {
|
|
width: 100%;
|
|
height: auto;
|
|
}
|
|
.content {
|
|
padding: 15px 10px;
|
|
flex-direction: column;
|
|
align-items: left;
|
|
}
|
|
.program {
|
|
flex-direction: column;
|
|
align-items: left;
|
|
}
|
|
.program-image {
|
|
margin-right: 0;
|
|
margin-bottom: 20px;
|
|
}
|
|
.program-info {
|
|
text-align: left;
|
|
}
|
|
.content table {
|
|
width: 100%;
|
|
}
|
|
.content table tr {
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin-bottom: 0.8em;
|
|
}
|
|
.content table td {
|
|
padding-right: 0;
|
|
}
|
|
.content table td:first-child {
|
|
margin-bottom: 0.2em;
|
|
}
|
|
}
|
|
th, td {
|
|
text-align:left;
|
|
vertical-align: top;
|
|
padding-right: 20px;
|
|
overflow-wrap: break-word;
|
|
}
|
|
a {
|
|
color:#00A6FF;
|
|
}
|
|
|
|
.lightbox {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.8);
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
.lightbox-content {
|
|
position: relative;
|
|
width: 80%;
|
|
max-width: 800px;
|
|
}
|
|
.lightbox-content iframe {
|
|
width: 100%;
|
|
height: 450px;
|
|
}
|
|
.close {
|
|
position: absolute;
|
|
top: 10px;
|
|
right: 10px;
|
|
font-size: 30px;
|
|
color: #fff;
|
|
cursor: pointer;
|
|
}
|
|
</style>
|
|
<script>
|
|
function openLightbox() {
|
|
document.getElementById('lightbox').style.display = 'flex';
|
|
document.getElementById('video').src = 'https://www.youtube.com/embed/Cj3RgjVs5dk?autoplay=1';
|
|
}
|
|
|
|
function closeLightbox(event) {
|
|
if (event.target.id === 'lightbox' || event.target.className === 'close') {
|
|
document.getElementById('lightbox').style.display = 'none';
|
|
document.getElementById('video').src = '';
|
|
}
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<a href="index.html">
|
|
<canvas id="phobialogo" style="margin-right:20px;image-rendering:pixelated;"></canvas>
|
|
<img id="phobialogo-fallback" src="phobialogo.png" alt="PHOBIA" style="display:none;">
|
|
</a>
|
|
</div>
|
|
<div class="content">
|
|
|
|
<div class="welcome">
|
|
<h1>PHOBIA DemoGroup Archive</h1>
|
|
|
|
<p>This site showcases the releases from my DemoGroup, PHOBIA. Although PHOBIA existed only briefly on the PC in 1994, it made a notable impact with its focus on PC intros. The highlight of our work was the major release, the Phobia Welcome Intro.</p>
|
|
<p>Feel free to explore and enjoy the nostalgia of the early days of PC intros.</p>
|
|
<p style="margin-bottom: 1.5em;">Best regards, Stefan Koelle</p>
|
|
</div>
|
|
|
|
<div class="program">
|
|
<div class="program-image">
|
|
<img src="welcomeintro.png" alt="Program 1 Image" onclick="openLightbox()">
|
|
<div class="program-description">
|
|
<p><b>Phobia Welcome Intro</b></p>
|
|
<p><a href="#" onclick="openLightbox()">YouTube Video of the Intro</a></p>
|
|
<p><a href="https://github.com/skoelle/dos-phobia-welcome-intro" target="_blank">GitHub Source Code</a></p>
|
|
</div>
|
|
</div>
|
|
<div class="program-info">
|
|
<h2>Phobia Welcome Intro</h2>
|
|
<p>The Phobia Welcome Intro was programmed in 1994 using Turbo Pascal, with inline assembler for the graphics routines. The idea for this intro was inspired by an Amiga demo, though the specific name of the demo has been forgotten. All graphics and programming were done by Stefan Koelle on a 486 DX2-66 DOS PC.</p>
|
|
<p>This intro utilized an early version of the X-LIB unit, specifically the TextGraf.pas, which was also developed by Stefan Koelle. The source code for the intro is available on GitHub. The primary technique used in this intro to create the illusion of movement was through color palette changes, rather than altering the pixels on the screen.</p>
|
|
<p>The music for the intro was borrowed from an old Amiga demo and played using a public Mod-Player. The font used in the intro was custom-created and compiled into the executable as an object, along with the music and graphics.</p>
|
|
|
|
<h2>Facts</h2>
|
|
<table>
|
|
<tr>
|
|
<td><b>Language</b></td>
|
|
<td>Turbo Pascal with inline assembler</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Year</b></td>
|
|
<td>1994</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Developer</b></td>
|
|
<td>Stefan Koelle</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Development Machine</b></td>
|
|
<td>486 DX2-66 DOS PC</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Graphics Technique</b></td>
|
|
<td>Color palette changes</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Music Source</b></td>
|
|
<td>Old Amiga demo</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Music Player</b></td>
|
|
<td>Public Mod-Player</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Custom Font</b></td>
|
|
<td>Compiled into the executable as an object</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Graphics Library</b></td>
|
|
<td>Early version of X-LIB unit (TextGraf.pas)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>Source Code</b></td>
|
|
<td>Available on GitHub<br><a href="https://github.com/skoelle/dos-phobia-welcome-intro" target="_blank">https://github.com/skoelle/dos-phobia-welcome-intro</a></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<!--
|
|
<div class="program">
|
|
<div class="program-image">
|
|
<img src="program2.jpg" alt="Program 2 Image">
|
|
<div class="program-description">
|
|
<p><b>Program 2</b></p>
|
|
<p>Kurze Beschreibung des zweiten Programms.</p>
|
|
</div>
|
|
</div>
|
|
<div class="program-info">
|
|
<h2>Program 2 Information</h2>
|
|
<p>Hier steht der Infotext zum zweiten Programm. Dieser Text enthält detaillierte Informationen über das Programm, seine Funktionen und andere relevante Details.</p>
|
|
</div>
|
|
</div>
|
|
<div class="program">
|
|
<div class="program-image">
|
|
<img src="program3.jpg" alt="Program 3 Image">
|
|
<div class="program-description">
|
|
<p><b>Program 3</b></p>
|
|
<p>Kurze Beschreibung des dritten Programms.</p>
|
|
</div>
|
|
</div>
|
|
<div class="program-info">
|
|
<h2>Program 3 Information</h2>
|
|
<p>Hier steht der Infotext zum dritten Programm. Dieser Text enthält detaillierte Informationen über das Programm, seine Funktionen und andere relevante Details.</p>
|
|
</div>
|
|
</div>-->
|
|
</div>
|
|
<canvas id="copperbars" style="position:fixed;top:0;left:0;width:100%;height:100%;z-index:-1;pointer-events:none;"></canvas>
|
|
<div class="footer">
|
|
PHOBIA website - initially created November 1999 - code from 1994 - Stefan Koelle<br>
|
|
Part of <a href="/">moonweb.org</a> · <a href="/retro/">Retro Corner</a> · <a href="/impressum/">Legal Notice</a>
|
|
</div>
|
|
<div id="lightbox" class="lightbox" onclick="closeLightbox(event)">
|
|
<div class="lightbox-content">
|
|
<span class="close" onclick="closeLightbox()">×</span>
|
|
<iframe id="video" src="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
(function() {
|
|
var canvas = document.getElementById('phobialogo');
|
|
var fallback = document.getElementById('phobialogo-fallback');
|
|
var ctx = canvas.getContext('2d');
|
|
var img = new Image();
|
|
img.crossOrigin = 'anonymous';
|
|
img.onload = function() {
|
|
canvas.width = img.width;
|
|
canvas.height = img.height;
|
|
fallback.style.display = 'none';
|
|
canvas.style.display = 'inline';
|
|
var origData = null;
|
|
try {
|
|
ctx.drawImage(img, 0, 0);
|
|
origData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
} catch(e) {
|
|
fallback.style.display = 'inline';
|
|
canvas.style.display = 'none';
|
|
return;
|
|
}
|
|
var pixels = origData.data;
|
|
var blueMap = {};
|
|
for (var i = 0; i < pixels.length; i += 4) {
|
|
var r = pixels[i], g = pixels[i+1], b = pixels[i+2];
|
|
if (b > 30 && b > r * 1.3 && b > g * 1.2) {
|
|
var key = r + ',' + g + ',' + b;
|
|
if (!blueMap[key]) blueMap[key] = { r: r, g: g, b: b, count: 0 };
|
|
blueMap[key].count++;
|
|
}
|
|
}
|
|
var palette = [];
|
|
for (var k in blueMap) {
|
|
if (blueMap[k].count >= 500) palette.push(blueMap[k]);
|
|
}
|
|
palette.sort(function(a, b) {
|
|
var la = a.r * 0.299 + a.g * 0.587 + a.b * 0.114;
|
|
var lb = b.r * 0.299 + b.g * 0.587 + b.b * 0.114;
|
|
return la - lb;
|
|
});
|
|
var origColors = palette.map(function(c) { return { r: c.r, g: c.g, b: c.b }; });
|
|
var rotColors = origColors.slice();
|
|
var offset = 0;
|
|
function draw() {
|
|
var out = ctx.createImageData(canvas.width, canvas.height);
|
|
out.data.set(pixels);
|
|
var d = out.data;
|
|
for (var i = 0; i < palette.length; i++) {
|
|
rotColors[i] = origColors[(i + offset) % palette.length];
|
|
}
|
|
var lookup = {};
|
|
for (var i = 0; i < palette.length; i++) {
|
|
var oc = origColors[i];
|
|
var rc = rotColors[i];
|
|
lookup[oc.r + ',' + oc.g + ',' + oc.b] = rc;
|
|
}
|
|
for (var i = 0; i < d.length; i += 4) {
|
|
var key = d[i] + ',' + d[i+1] + ',' + d[i+2];
|
|
if (lookup[key]) {
|
|
d[i] = lookup[key].r;
|
|
d[i+1] = lookup[key].g;
|
|
d[i+2] = lookup[key].b;
|
|
}
|
|
}
|
|
ctx.putImageData(out, 0, 0);
|
|
offset = (offset + 1) % palette.length;
|
|
setTimeout(function() { requestAnimationFrame(draw); }, 120);
|
|
}
|
|
draw();
|
|
};
|
|
img.onerror = function() {
|
|
fallback.style.display = 'inline';
|
|
canvas.style.display = 'none';
|
|
};
|
|
img.src = 'phobialogo.png';
|
|
})();
|
|
</script>
|
|
<script>
|
|
(function() {
|
|
var canvas = document.getElementById('copperbars');
|
|
var ctx = canvas.getContext('2d');
|
|
var w, h;
|
|
function resize() { w = canvas.width = window.innerWidth; h = canvas.height = window.innerHeight; }
|
|
resize();
|
|
window.addEventListener('resize', resize);
|
|
var bars = [
|
|
{ baseY: 0.45, amplitude: 0.18, speed: 0.7, r: 255, g: 199, b: 0, barH: 50 },
|
|
{ baseY: 0.55, amplitude: 0.15, speed: 1.1, r: 239, g: 0, b: 0, barH: 50 },
|
|
{ baseY: 0.52, amplitude: 0.20, speed: 0.9, r: 4, g: 203, b: 0, barH: 50 },
|
|
];
|
|
function draw(t) {
|
|
ctx.clearRect(0, 0, w, h);
|
|
for (var i = 0; i < bars.length; i++) {
|
|
var bar = bars[i];
|
|
var y = h * bar.baseY + Math.sin(t * 0.001 * bar.speed) * h * bar.amplitude;
|
|
var halfH = bar.barH / 2;
|
|
for (var row = -halfH; row <= halfH; row++) {
|
|
var rel = row / halfH;
|
|
var alpha = 1 - rel * rel;
|
|
var py = Math.round(y + row);
|
|
if (py < 0 || py >= h) continue;
|
|
ctx.fillStyle = 'rgba(' + bar.r + ',' + bar.g + ',' + bar.b + ',' + alpha.toFixed(3) + ')';
|
|
ctx.fillRect(0, py, w, 1);
|
|
}
|
|
}
|
|
requestAnimationFrame(draw);
|
|
}
|
|
requestAnimationFrame(draw);
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html> |