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.

Ghosts of Mars by Faemiyah, on my home FreeBSD.

Ghosts of Mars by Faemiyahon my home FreeBSD.

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:

Dosbox is an emulator, you can download the version for Windows from here.

Dosbox is an emulator, you can download the version for Windows Here from here.

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:

Integrated Intel graphics, 8GB memory and FreeBSD 13.1 14.0 14.1

Integrated Intel graphics, 8GB of memory and FreeBSD 13.1 14.0 14.1

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:

Personal computer BK 0011M (1980s)

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.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *