Demoscene and FreeBSD
I decided to remember my happy childhood and browse demoscene sites – I was surprised to find that many people post releases under… FreeBSD.
FreeBSD is, to put it mildly, not the most suitable system for working with optimized graphics, so the presence of so many demos specifically created for this system was puzzling.
Since I know a little about computers and use FreeBSD as one of my main OS, I decided to immediately build and run the most interesting projects.
For the uninitiated
Demoscene[1][2][3][4] (English demoscene) — cyberculturewhich originated at the end 1970s along with the spread of the first home computers. This is the direction computer artthe main feature of which is the construction of a plot video sequence created in real time by a computer, according to the operating principle computer games.
Demoscene it was and is and will be cool.
Probably all serious game engines and all computer special effects were created (and are still being made) by former scriptwriters:
4players.de reported that “numerous” demo and intro programmers, artists, and musicians were employed in the games industry by 2007. Video game companies with demoscene members on staff included Digital Illusions, Starbreeze, Ascaron,[43] 49Games, Remedy, Techland, Lionhead Studios,[44] Bugbear, Digital Reality, Guerrilla Gamesand Akella.[45]
The Tracker music which is part of Demoscene culture could be found in many Video games of the late 1990s and early 2000s, such as the Unreal, Unreal Tournament, Deus Ex, Crusader: No Remorse, One Must Fall: 2097, Jazz Jackrabbit and Uplink.[46]
In a word, demoscene is about special effects and overcoming — how to squeeze the unsqueezable into a place where it doesn't belong, so that it becomes cool and everyone freaks out. And everyone really freaks out. Seriously.
Below are some classic examples to illustrate this.
fr-041: debris. by Farbrausch
Everything you see in the video is done by the “programmer” 177 kilobytes. This is almost 10 times smaller than the size of a 3.5 inch floppy disksif anyone still remembers such a device.
The sources are already there too postedif anyone is interested.
Lifeforce by Andromeda Software Development
This is already a big demo – as many as 26 megabytes! True, this is still ten times less than your usual assembly of another corporate shitproject, but nevertheless.
The group also has its own very cool site with a bunch of other beautiful demos.
heaven seven by Exceed
And again 172kb binary draws and sings all this beauty.
Craft by lft
Let me quote the author:
Craft is a demo running on its own minimalistic demo platform. The demo platform is based on an ATmega88 microcontroller.
At the very beginning of the video, the very same “own minimalistic demo platform” is demonstrated, on which all this beauty is launched.
After the article was published on LOREpeople have thrown in a couple more interesting projects that simply need to be mentioned.
Dírojed by Řrřola
32 bytes:
echo 'B013CD10C51F380F10276BDBE58A0F0209028FBFFE02483F4BE460FEC875E7C3' | xxd -r -p - dirojed.com
dosbox dirojed.com
This is what it looks like in real life:
Hoody by Rgba
4kb the application generates such beauty:
This is not a static picture or a 3D model – this is algorithmspure mathematics, the same “matan” that you disliked so much all your years at the university.
Here here the algorithm from the demo is repeated using WebGL:
Below is a detailed step-by-step analysis of the algorithm, from the author himself:
Test environment
The test car is my combat car necroLenovo T440 laptop:
Loaded i915kms, xorg configured via modesetting:
[alex@cruella ~]$ cat /usr/local/etc/X11/xorg.conf.d/20-intel.conf
Section "Device"
Identifier "Intel Graphics"
Driver "modesetting"
Option "DRI" "true"
EndSection
All demos run in fullscreen mode by default, but I ran them in a window (-w key) (for most) to create more dramatic screenshots.
Planet Hively by Illi Recentes ImperatoreS & Up Rough
This demo may not look so cool:
But as they say, there is one nuance, in the form of a list of supported platforms:
#PLATFORM = os4
# PLATFORM = win32
# PLATFORM = linux
# PLATFORM = aros
# PLATFORM = aros64
# PLATFORM = ppc-aros
# PLATFORM = morphos-cross
# PLATFORM = beos
# PLATFORM = ppc-beos-cross
# PLATFORM = gp2x
# PLATFORM = alpha-linux-cross
# PLATFORM = ia64-linux-cross
# PLATFORM = amd64-linux-cross
# PLATFORM = s390-linux-cross
# PLATFORM = s390x-linux-cross
# PLATFORM = arm-linux-cross
# PLATFORM = sparc-linux-cross
# PLATFORM = psp
# PLATFORM = hppa-linux-cross
# PLATFORM = ppc-linux-cross
# PLATFORM = m68k-linux-cross
# PLATFORM = mips-linux-cross
# PLATFORM = mipsel-linux-cross
# PLATFORM = sh3-linux-cross
# PLATFORM = sh4-linux-cross
# PLATFORM = ppc64-linux-cross
# PLATFORM = sparc64-linux-cross
# PLATFORM = avr32-linux-cross
# PLATFORM = bsdi
# PLATFORM = qnx6
# PLATFORM = solaris
# PLATFORM = skyos
# PLATFORM = openserver5
# PLATFORM = openserver6
# PLATFORM = unixware7
# PLATFORM = mint
PLATFORM = i386-freebsd7
# PLATFORM = amd64-freebsd7-cross
# PLATFORM = sparc64-freebsd7-cross
# PLATFORM = ia64-freebsd6-cross
# PLATFORM = alpha-freebsd5-cross
# PLATFORM = riscos-cross
# PLATFORM = hppa-hpux
# PLATFORM = ia64-hpux
# PLATFORM = zaurus-cross
# PLATFORM = syllable
# PLATFORM = netbsd
# PLATFORM = alpha-netbsd4-cross
# PLATFORM = amd64-netbsd4-cross
# PLATFORM = hppa-netbsd4-cross
# PLATFORM = m68k-netbsd4-cross
# PLATFORM = mipseb-netbsd4-cross
# PLATFORM = mipsel-netbsd4-cross
# PLATFORM = ns32k-netbsd2-cross
# PLATFORM = ppc-netbsd4-cross
# PLATFORM = sh3eb-netbsd4-cross
# PLATFORM = sh3le-netbsd4-cross
# PLATFORM = sh5le-netbsd3-cross
# PLATFORM = sparc-netbsd4-cross
# PLATFORM = sparc64-netbsd4-cross
# PLATFORM = vax-netbsd4-cross
# PLATFORM = arm-netbsd4-cross
# PLATFORM = m68010-netbsd4-cross
# PLATFORM = xbox
# PLATFORM = i386-openbsd
# PLATFORM = alpha-openbsd-cross
# PLATFORM = amd64-openbsd-cross
# PLATFORM = arm-openbsd-cross
# PLATFORM = hppa-openbsd-cross
# PLATFORM = ppc-openbsd-cross
# PLATFORM = mips64-openbsd-cross
# PLATFORM = sh4-openbsd-cross
# PLATFORM = sparc64-openbsd-cross
# PLATFORM = m68k-openbsd-cross
# PLATFORM = sparc-openbsd-cross
# PLATFORM = aix
# PLATFORM = irix
# PLATFORM = irix_marq
# PLATFORM = pandora
If you thought you knew anything about porting and cross-platforming, start looking for a new job. Because I, for example, have never seen such diversity in my life, let alone been able to repeat it.
This is what the demo looks like when running on a Raspberry Pi:
Sources and assembly
The source code was posted relatively recently, you can download it here hereUnfortunately, there are a number of problems with the assembly.
Firstly, the authors forgot to upload some resources and the demo will complain when launched. To fix this, you need to extract the folder tunes from this pull request and add it to the root of the project.
Next, you will need to uncomment the line in the makefile:
PLATFORM = i386-freebsd7
And replace gcc with gcc12:
####### DEFAULT SETTINGS HERE #######
CFLAGS = -Wall -O2
LFLAGS =
CC = gcc12
DEBUGLIB =
TARGET = planethively
FASTMATH = -ffast-math
You need to build it using gmake, the standard FreeBSD make won't work.
The demo is written entirely in pure C using SDL (for those platforms where it exists, of course).
Below are a couple of interesting tricks found in the source code.
Fast calculation square root:
static inline int fastsqrt( int n )
{
if( n > 32767 ) return sqrt( n );
return isqrt[n];
}
Generation white noise:
void hvl_GenWhiteNoise( int8 *buf, uint32 len )
{
uint32 ays;
ays = 0x41595321;
do {
uint16 ax, bx;
int8 s;
s = ays;
if( ays & 0x100 )
{
s = 0x80;
if( (LONG)(ays & 0xffff) >= 0 )
s = 0x7f;
}
*buf++ = s;
len--;
ays = (ays >> 5) | (ays << 27);
ays = (ays & 0xffffff00) | ((ays & 0xff) ^ 0x9a);
bx = ays;
ays = (ays << 2) | (ays >> 30);
ax = ays;
bx += ax;
ax ^= bx;
ays = (ays & 0xffff0000) | ax;
ays = (ays >> 3) | (ays << 29);
} while( len );
}
But let's move on.
Chrysler by Fit & Bandwagon
Motorola Inside 2004, 1st place
The source code is here heredespite the fact that the archive dates back to 2009, everything is perfectly assembled in a modern environment.
The number of supported platforms is once again impressive:
I wish I could live the way you port in general.
This is how this demo looks live on my FreeBSD:
Assembly and sources
This demo is also built only with gmake, you need to correct the Makefile by setting CC=gcc12:
CC = gcc12
CFLAGS = -O2 -ffast-math `sdl-config --cflags`
#LDFLAGS = `sdl-config --libs` -lm
LDFLAGS = `sdl-config --static-libs` -lm
OBJ = data.o kirjaimet2.o kokko.o maf.o main.o mosaic.o pallot.o plasma.o\
ratas.o stripes.o video.o cool_mzx/cool_mzx.a
...
Everything is written in pure C (and you doubted it?), also using SDL for supported platforms. Below are some interesting points in the sources.
Given PI– constant for Amiga:
#ifdef AMIGA
#define M_PI 3.1415927
#endif
An elegant way to check the correctness of several calls in a row:
int readall(void)
{
int val=0;
val+=readfile("data/tehas2.mod",&musakki);
val+=readfile("data/dd.raw",&dd);
val+=readfile("data/na_eka.raw",&na_eka);
val+=readfile("data/na_toka.raw",&na_toka);
val+=readfile("data/onnettomuus.raw",&onnettomuus);
val+=readfile("data/paa.raw",&paa);
val+=readfile("data/siunaus.raw",&siunaus);
val+=readfile("data/ukko.raw",&ukko);
val+=readfile("data/ratas.raw",&ratas);
val+=readfile("data/kooste.raw",&kooste);
val+=readfile("data/chrysler.raw",&chrysler);
return(val);
}
And the call itself with verification:
if(readall()!=0)
{
printf("Problem loading datas\n");
return(0);
}
Displaying a frame from a video:
src=frame[no]*40*200;
dst =buffer;
for (y=0; y<AH; y++)
for (x=0; x<(AW/8); x++) {
ip1=bitti_muunnos+video[src]*8;
*dst++ = *ip1++;
*dst++ = *ip1++;
src++;
}
As they say, good luck figuring out the referential logic, this is exactly the case when understanding cannot be achieved with a sober head.
Hex Pistols by Fit
Motorola Inside 2005, 1st place, release on Amiga yes.
This is what the launch looks like against the background of your own sources:
Assembly and sources
The source code can be downloaded here here.
To build, you need to replace CC=gcc with CC=gcc12 in Makefile again, it's simple. Everything is written again in pure C and SDL (for all platforms except Amiga).
Some interesting techniques include reading RGB color and packing it into one variable with a bit shift:
/* Background */
if(!strcmp("backcolr",str))
{
fscanf(s,"%d%d%d",&r,&g,&b);
cgm->back=(r<<16)+(g<<8)+b;
}
Faemiyah
This is a whole groupwhich steadily sculpts and publishes releases for FreeBSD. Completely crazy Finnish comrades, the sources of all demos are available at link.
Yog-Sothoth by Faemiyah
2nd place on Assembly, 2013
Unfortunately, this demo didn’t work properly for me, although it came together – there was something subtle with the video.
Ghosts of Mars by Faemiyah
4th place on Assembly 2015
The shot with her is right in the header of the article, fortunately it looks as epic as possible:
Assembly and sources
The source code can be downloaded here here.
The project is built in a “modern” way – using cmake:
mkdir build
cd build
cmake ..
Launch:
./ghosts_of_mars -w -r 800x600
Windowed mode is specified here -w
and resolution -r 800x600
The source code is already in several languages: C, C++ plus special Python script to minimize.
The graphics are still on SDL, but shaders and Boost are already used.
Everything is more complicated and serious – the guys are on their way to success
But the problems are the same, for example, your own random number generator:
/// More random random.
///
/// It's better to discard a few bottom-most bits to achieve better randomness.
///
/// \param op Modulator for random.
/// \return Random value in range [0, op[.
static int irand(int op)
{
return (dnload_rand() >> 4) % op;
}
Debug blocks on hardcore macros:
#if 1
{
const float mul = 65535.0f / largest;
for(unsigned ii = 0; (IMAGE_SIDE * IMAGE_SIDE > ii); ++ii)
{
g_image_data[ii] = static_cast<uint16_t>(65535 - g_image_preprocess[ii] * mul);
}
}
#else
{
const float mul = 255.0f / largest;
for(unsigned ii = 0; (IMAGE_SIDE * IMAGE_SIDE > ii); ++ii)
{
g_image_data[ii] = 255 - static_cast<uint8_t>(g_image_preprocess[ii] * mul);
}
}
gfx::image_png_save(std::string("lol.png"), IMAGE_SIDE, IMAGE_SIDE, 8, g_image_data);
#endif
What's happened #if 1:
Only the first block will be processed — until someone changes the 1 to a 0. Then the other block will be compiled. This is a convenient way to temporary switch blocks of code in and out while testing different algorithms.
Adarkar Wastes by Faemiyah
Instances 2018, 1st place
This is what the demo looks like running on my FreeBSD:
Assembly and sources
All sources there the same, assembly and launch are similar to the previous work.
The project is implemented in C++, SDL and Boost, plus a small insert in assembler appeared – for the synthesizer. And a lot of shaders.
Below I will describe several interesting solutions found in the source code. Again a custom random number generator, but a different implementation:
/** BSD random var. */
static bsd_u_long bsd_rand_next = 2;
int bsd_rand(void)
{
/*
* Compute x = (7^5 * x) mod (2^31 - 1)
* without overflowing 31 bits:
* (2^31 - 1) = 127773 * (7^5) + 2836
* From "Random number generators: good ones are hard to find",
* Park and Miller, Communications of the ACM, vol. 31, no. 10,
* October 1988, p. 1195.
*/
long hi, lo, x;
/* Must be in [1, 0x7ffffffe] range at this point. */
hi = (long)(bsd_rand_next / 127773);
lo = (long)(bsd_rand_next % 127773);
x = 16807 * lo - 2836 * hi;
if (x < 0)
x += 0x7fffffff;
bsd_rand_next = (bsd_u_long)x;
/* Transform to [0, 0x7ffffffd] range. */
return (int)(x - 1);
}
void bsd_srand(bsd_u_int seed)
{
/* Transform to [1, 0x7ffffffe] range. */
bsd_rand_next = (seed % 0x7ffffffe) + 1;
}
Processing the specified permission (key -r 800×600 remember?):
/// Parse resolution from string input.
///
/// \param op Resolution string.
/// \return Tuple of width and height.
boost::tuple<unsigned, unsigned> parse_resolution(const std::string &op)
{
size_t cx = op.find("x");
if(std::string::npos == cx)
{
cx = op.rfind("p");
if((std::string::npos == cx) || (0 >= cx))
{
std::ostringstream sstr;
sstr << "invalid resolution string '" << op << '\'';
BOOST_THROW_EXCEPTION(std::runtime_error(sstr.str()));
}
std::string sh = op.substr(0, cx);
unsigned rh = boost::lexical_cast<unsigned>(sh);
unsigned rw = (rh * 16) / 9;
unsigned rem4 = rw % 4;
return boost::make_tuple(rw - rem4, rh);
}
std::string sw = op.substr(0, cx);
std::string sh = op.substr(cx + 1);
return boost::make_tuple(boost::lexical_cast<int>(sw), boost::lexical_cast<int>(sh));
}
Preprocessing (macros) directly in the shader code:
float i_fov = 1.73;
//float i_fov = 1.0 / tan(60.0 / 180.0 * PI * 0.5);
#if defined(USE_LD)
perspective[0][0] = i_fov / (float(screen_size.x) / float(screen_size.y));
#elif (DISPLAY_MODE == -800) || (DISPLAY_MODE == 800) || (DISPLAY_MODE == -1200) || (DISPLAY_MODE == 1200)
perspective[0][0] = i_fov / 1.6;
#else // Assuming 16/9.
perspective[0][0] = i_fov / 1.78;
#endif
Is the demoscene dead?
You probably noticed that all the projects described in the article are quite old?
If you dig around on the net, it turns out that most of the sites dedicated to the demoscene are in an archived state, scene festivals are no longer held, and so on.
In short, you might get the unpleasant feeling that the demoscene is dead. I actually thought so too, and then I found something fresh and beautiful:
A word from the author:
Decided to implement a new concept on BK0011 – drawing pictures to music. I hope for a continuation:) Release and source texts: https://www.pouet.net/prod.php?which=… Track: https://zxart.ee/rus/avtory/k/kuvo/ar…
If anyone doesn't know, here's what it is BK0011:
So the spirit of hardcore is still very much alive.
P.S.
This is a slightly edited and edited version of the article, original which is available on our blog.
0x08 Software
We are a small team of IT industry veterans, we create and refine a wide variety of software, our software automates business processes on three continents, in a wide variety of industries and conditions.
Bringing it to life long dead, we fix what never worked and we create impossible — then we talk about it in our articles.