BCC demo party 2026

A photo of the award we got. A printout of the PETSCII logo for the Demo party that has the text "BCC #20".
Two pieces of paper are put on top of that, one saying "2nd place DEMO Compo "
The other " 21.02.2026"

Pixel punx at BCC

I consider myself a ‘real’ part of the demoscene since 2020, when I got asked to join F4CG. Forward to 2025 and jmin and I started a new group “Pixel Punx”. A few months later LDX#40 joined and things really started to roll.

The BCC demo party had its 20th edition 20-22 february 2026 in Berlin and we were present. The first time we three were together in physical form, by the way.

We had a big presence, with LDX#40 entering 2 PETSCII pieces, jmin one and I with 3 graphics (which ended up last second to last and third to last :)).

The demo

And then there was our demo, simply called “demo.” (the dot at the end was intentional). We didn’t want to give too much away with the name, so this was what we ended up with.

You can download the demo from CSDb or run it from a browser from here (A youtube video is here: https://www.youtube.com/watch?v=Oxm76ALs0Wg).

A bit of background: “The Greetings” have been a standard part of Commodore 64 demos since the beginning. Since it is a kind of cliché I thought it would be funny if the whole demo was nothing but greetings.
I also had made a scroller consisting of two characters sets just before and thought we could use it for our demo. And that’s what we decided.

The D64 image has some nice DIR-art by jmin, made at the venue while we were finishing up our demo.

Picture of the directory listing of our demo disk. Using PETSCII chars it spells the words in big curly letters: 
Listen up... here are the Pixel Punx @ BCC (yay) with "demo."" 
enjoy


The demo starts with a nice little intro made by LDX#40 (attaching the intro to the main demo part was a surprisingly tricky thing for me, I never did that before).
A text appears line by line accompanied by a few ominous chords setting up the rest of the demo, then the letters fly off to the right one by one leaving a black screen before the main part.

First sceeen of the demo. It shows the text
"AI
FPGA's
C++ build tools
everything has become
so complicated!
let's go back
to simpler times
to the very code 
of demos ...
the greetings!

The main part

The main scrolling bit gives a scrolling area of 320×96 unique pixels, a lot smaller than a complete bitmap, but requiring a lot less data to move, so it can reach speeds of up to 8 pixels per frame (16 or 24 should be possible too) and still be at 50 Hz.
New content is “streamed in” on one side and the size of the graphics is only limited by memory (a limit we actually reached).

Graphically I thought it would be great to combine the strengths of jmin and me so, try to combine hires and PETSCII. In the end version there was also a PETSCII by LDX#40.

A screenshot of the main part running. The text Pixel horizontally mirrored in the top part, with a spectacled punk lying on his stomach next to it.
On the bottom the text Punx, with two other punx, one winking and standing on his head the other wearing a camouflage pattern suit, on bare feet and wearing a cap.
The center part shows the scroller part with a logo for F4CG and the text "putting the crack into cracking" underneath it.
Next to that text you can see the bare bottom of a man, the suggestion of his member and you can just about see a diskette between his clenched buttocks

The main demo consist of a centre part that scrolls left to right and back and is 12 characters high. The screen is in character mode, with two character sets shown. The top 6 lines of the scroll are from characters set 1 (240 characters) and the lower 6 from the other character set. That leaves 16 characters for other things. We use it for the letters in the top and bottom part (takes 1 character) an empty character and 12 characters for the animated conveyor belt (4 frames of 3 characters).
The top part shows a laying Pixel Punk (that would be me) and the lower part shows 2 Punx standing up (LDX#40 and jmin). The punx are done in sprites (4 sprites per punk).

From one end to the other is in total 960 pixels wide. 480 in “fake” PETSCII, 480 of hires chars. The whole thing uses black as background colour. The choice of a width of 60 characters wasn’t that concious, jmin came up with a first picture and thought it would go well with that width.

It is not real PETSCII, though. Just like the hires part it’s bitmap (converted at compile time), but with added colours.

I thought I would be able to create graphics in this widescreen resolution, but wasn’t sure if creating nice PETSCIIs in 60×12 chracters would be possible too.
I shouldn’t have worried. jmin is extremely talented (only started a two years ago!) and he had no trouble creating the PETSCIIs.

We used Excel to come up with a table of speeds to have a visually pleasing speeding up and slowing down and still ending up with the correct number of pixels moved.

Timings

Timing everything was obviously doable but adding sprites certainly made it more complicated. Depending on the speed and the current scroll position the demo needed to do a “big scroll”: moving all character data and colour data 1 character to the left or right. That is 2×480 bytes. The characters that were moved off-screen were re-used on the other side so you could always use the same 240 characters of a charset.
The reused characters needed to get new definitions, which is 2x6x8 =96 bytes.
Since you don’t want the updates to be visible and I didn’t want to use double buffering to save on memory, updating chars and colours needed to happen outside the screen area where the scroller was displayed.

I used scripts to convert the bitmap or PETSCII data to a format that would be fast to copy to the character sets.

So far so good, but when we added sprites on the top and bottom bit we needed a multiplexer (there are 12 sprites shown in total). Switching positions, pointers for the top sprites needed to happen after displaying the bottom sprites, but before the top sprites would be drawn.
When there is a large scroll happening there is very little time for that. In the end we had move the top sprites down to make it happen: that’s why the top Punk is lying down 🙂
Demo scener Trident had done a talk about combining several screenline-dependent interrupts, which I watched and got working, but it didn’t help here. There were just not enough cycles for that.

Changing the graphics

To be able to fit so many graphics in the demo the data is packed. At the moment the whole screen is completely filled with one picture half (so PETSCII or hires), Exomizer starts to unpack the next picture for the other half. Almost all code is running from the interrupt, but unpacking is done outside the interrupt because we want to do it in parallel to the other stuff and it is not timing-critical. We also use the memory underneath IO ($d000-$dfff), which means changing $01 to $34 but we only do that for unpacking. Outside the irq we don’t need to access any IO registers, so that means we can set $01 to $35 when we enter the irq and set it to $34 when leaving and we don’t need to worry about it anymore (but make sure you set up the next interrupt before you set $01 to $34 or the set up doesn’t work, as I found out 🙂 ).

When the scroller has reached its leftmost or rightmost position it stops scrolling for a bit, giving people time to watch the picture properly while also unpacking the next picture.
Because at that moment there is no big scroll we also have time for other stuff.
To add a little more entertainment to the viewer we change the position of the sprites and mirror the top and bottom text and there is a very simple two-frame animation for each character. The sprites are actually a co-op from jmin and me. We edited all sprites both and I’m quite pleased with the result.

Memory

The size of demo when loading is about 40K. It consists of the intro with the main part packed with Exomizer . The code to unpack it is also there. Exomizer is moved to a part in memory where it doesn’t interfere with the main part unpacking.

The memory layout of the main part:

  $0400-$0800 screen RAM
  $0801-$080c Basic start stuff
  $080d-$0812 start stuff
  $0813-$091b exomizer
  $091c-$09aa main loop
  $09ab-$0dcc irq code
  $0dcd-$0dcc scrollcode
  $0dcd-$0faa doLargeColourScroll
  $1000-$1e2c SID
  $1e2d-$1ef5 reverseScrollCode
  $1ef6-$2006 doLargeScrollReverse
  $2100-$2cff sprites
  $2d00-$2fff free space
  $3000-$35ef charset0, 240 chars
  $3780-$37ff characters for top and bottom bit, 14 chars
  $3800-$37ff charset1,240 chars
  $3800-$392f init code
  $3f80-$3fff unused
  $4000-$6fcf scrollData0, unpacked data for one hires and one PETSCII 
  $6fd0-$f31f compressed pictures
  $f320-$f51f speedTable
  $f520-$f5e7 top endchars, for PIXEL PUNX text 
  $f5e8-$f6ca bottom end chars, for GREET BERLIN text
  $f6cb-$f834 invertcode
  $f835-$f834 sprites code and tables
  $f835-$f914 sprite code
  $f915-$f96f fadeCode
  $f970-$f9fe restore color code

As you can see most of the memory is used. There potentially could have been space for one more bitmap and there is one unused PETSCII piece in memory. But I had no time left to finish the last bitmap and we wanted an equal amount of PETSCIIs and bitmaps.

The scrollData memory is already loaded up with one hires and one PETSCII pic. It is also setup in such a way so that it would be possible to unpack the left or right side without affecting the other half. This allows unpacking the next picture while the other one is shown.

The memory for charset0 and charset1 contains one-time-use initialization code which can be overwritten later on.

The memory used for the scrolldata is quite big, more than a full bitmap. That is caused by our choice to have a 120 characters wide working area. Both the PETSCII and hires part take 60x12x8 = 5760 bytes. The PETSCII takes another 480 bytes for colour information. But the PETSCII data packs a lot better than my messy bitmaps.
The PETSCIIs are actually stored as bitmaps. Maybe they could have been even smaller if I stored them as characters/colour and converting them to bitmap format at runtime (reading the ROM charset), but it packed so well, I didn’t want to make it more complicated (and the added cycles that would need probably would have been a problem too).

120.000!

In total the demo contains a whopping 120.000 bytes of picture data!! And that’s excluding the sprites.

Bugs

I’m sure there are bugs that I’m not aware of, but it seems to run quite well.
During development I ran into a bug that cropped up at unexpected times and I didn’t understand untill the night before I left for Berlin.
I use a Kickassembler plugin for packing and including data in my project using Exomizer. A part can be exomized using 3 settings. Quite early on in the project I changed the default settings which seemed to lead to better compression.
What I didn’t think about, was that you also have to change the unpacking code to reflect those settings.
I missed this, because in most cases it just worked. There were just certain pictures where it lead to problems (of the crashing kind).
I’m very VERY glad my unconcious was able to remember the changes I did a few weeks before, in time! The fix was easy and from that moment I wasn’t anxious to change the pictures.

There is also a ‘tweaky bit’ (see explanation below), which I don’t really understand properly. Halfway the project I found I needed to change it from ‘one tweak’ to ‘two tweaks’ to keep it working and I don’t know why. Not exactly a bug but certainly a worry.

The pictures

The choice of groups was a bit random. We made a list of potential groups we wanted to include and then anyone could claim one if he had an idea for it and draw it. I didn’t dare to try doing PETSCII and jmin and LDX#40 didn’t dare to imitate my messy style.
I included Hotline altough I don’t know any of the members (that I’m aware of), but I have fond memories of their intros (and cracks 😉 )

We made a concious decision to make the demo wide-screen and speeding up, then slowing down. It means you won’t always see all details we put in there. So there is a chance you will see new details the next time you view the demo (keep watching it!).

An example:

A picture for the group Dinasours, showing a sauce bottle on its end leaking a bit It has the brand "Dinasauce" and features a grinning dinosaur pooping something dark. The cap shows a Best before date of -65e6, so 65 million years ago.
A picture for the group Dinasours, The grinning dinosaur poops something dark, the sauce. The cap shows a Best Before date of -65e6, so 65 million years ago.

Of course you can always look at the extracted pictures at C64Gfx

Conclusion

In the end we were very pleased with the result. We hoped to do well in the competition, but didn’t expect to make a big splash with this.
There weren’t that many entries in the demo competition, only 6. At the moment the results were shown, we got more and more excited (I was already pleased not to end up last, like I did in the graphics compo), while the positions were announced … 6th place… 5th.. 4th .. (WE’RE IN THE TOP THREE!).. 3rd (WHAT THE F*CK!).
Second place was unexpected and we only had a few points less than the number one (an entry by the elite group Genesis Project)!

We had fun making it, it turned out good and we got a good result so to quote jmin: “yay!”.

That tweaky bit

When I made the scroller bi-directional a column was drawn two times at the turning point and I needed an extra inc/dec of a certain counter to prevent that. I wasn’t sure why, but it worked. Then when I worked on it some more, the double column popped up again and I needed another inc/dec 🫤

Leave A Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.