2026 currently in progress...

Now with even more vulkan_examples!
Recently a post processing example was added, to demonstrate 2d rotation and zoom. An even bigger change was made to move all common context code into it's own source file, and enable the validation layers found in the official SDK, but not available by default with mesa3d/linux... Yeah that's right by default vulkan only does superficial error checking which is quite dangerous and a confusing choice for them to make considering the lack of implementation diversity. At least now we can see warnings, errors, and hints on how to solve spec violations. You can find the SDK including links to it's source code at https://vulkan.lunarg.com/sdk/home

Next up is either texture support, or figuring out how to get my required API version down from 1.3(2022? wow.) which I learned is required to write to a StorageImage without an explicit format set (mesa/linux/SDL3 surface format uses bgra but there is no way to specify that format in glsl since it only cares about rgba, ARGH!!!)




vulkan_examples gains a semi-usable octree implementation
The fifth example has been pushed to vulkan_examples on codeberg In this example we simulate an imaginary massless 200x200x200 cube containing spheres with the density of solid gold (au79). Simulation time is increased by 2000x to keep things interesting. Please disregard my improper glitchy gamedev physics code ;)

[ Image, an octree containing some multi-colored spheres ]

What next, a better camera, or upscaling so people with cheap old hardware like me can enjoy a full screen 60fps experience?


Third and fourth installment of vulkan_examples
Another ray marching example was added, which enables a shared cpu/gpu buffer containing globular objects that are animated by the CPU.
[ Image, rendered globs from shared memory ] vulkan_examples on codeberg

For my next trick, I will be posting an octree implementation to boost performance, instead of checking distance on every object multiple times for every pixel.


tplane and adventure now available on codeberg
   Two new projects, hot off the presses!

tplane
   A small nearly featureless display server for linux-drm, linux-fbdev still needs to be implemented for fallback support. Most of the testing has been done with an xorg-server as the only client, so there are bugs and memory leaks to be fixed some day.
      tplane git trunk

adventure
   A web browser written in qt6 + qtwebengine which is a chromium fork (which is a webkit fork). You have to enable javascript, webgl, etc, through the settings menu.
      adventure git trunk


libiberated, a static C/Linux library
Finally published the library I've been using to replace libc in my low level system projects to codeberg. Ultimately it will become a new language runtime library, but I have a ton of design work left to finish, and need to crack open the gcc frontend after it's been hibernating since gcc-9.x! libiberated is usable, but note that I have not done an adequate amount of testing yet and it probably only works on x86_64 at this time.


Another SDL3 Vulkan example published on codeberg
This one is a raymarching example, based on Inigo Quilez's work found at his site and youtube streams. I want to turn this into a "lunar lander" type game eventually. I think it's amazing how much detail can be rendered from a simple distance function! it's in the same repo as the other example


Minimal SDL3 Vulkan example written in C published
I've been doing graphics programming on and off for as long as I could write programs, so recently decided to start learning vulkan. Well that was quite the rabbit hole of examples that didn't compile or run, or were thousands of lines of convoluted c++ code in mixed styles just to draw simple graphics on screen. I don't have many resources here so I pretty much had to go the extra mile and distil my experience down to a minimal SDL3 example project. Here on codeberg is the opening salvo of a probably short series on how to render like it's 2025. There should be an article posted detailing how it works in the following days. I wrote up my own license too, that was another side quest I completed recently and should probably explain more thoroughly than in this blurb.


Code syntax coloring is working, with a few minor quirks
Wrote an AWK script to convert source code to html colored text. There is a bug when not using plentiful spaces, it only colors the element with highest precedence. I need to spend some more time to completely fix it by splitting the tokens further, or maybe another way is possible. Here is some C code for example:
 
// (c) Copyright 2025
#include <stdio.h> 
#include <stdint.h> 

#define TEX_W 800 
#define TEX_H 600 

uint32_t world[TEX_H][TEX_W]; /* 8888RGBA pixels */ 
float t = 3.0f; 

void draw_world() 
{ 
        printf("does it work?\n"); 
        /* explore new worlds */ 
        for (int y = 0; y < TEX_H; ++y) 
        { 
                for (int x = 0; x < TEX_W; ++x) 
                { 
                        float fx = (float)x / (float)TEX_W * 255; 
                        float fy = (float)y / (float)TEX_H * 255; 
                        //float ftmp = fx * fy;
                        float ftmp = (fx * fx) + (fy * fy); 
                        //float ftmp = (fx * fx) - (fy * fy);
                        ftmp *= (float)t; 
                        uint32_t r = (uint32_t)( (ftmp + fx)) % 256; 
                        uint32_t g = (uint32_t)( (ftmp + fy)) % 256; 
                        uint32_t b = (uint32_t)( (ftmp     )) % 256; 
                        world[y][x] = (r << 24) |(g << 16) | (b << 8) | 0x000000FF; 
                } 
        } 
        t += 0.0012f; 
} 



There are probably other bugs I have not noticed yet.



I have acquired a codeberg account
   I have finally created a codeberg account and will now begin the process of converting my projects to git repositories. The only code available right now is a bare SDL3 test project featuring a weird way to render colorful orb-like patterns I somehow discovered a few years ago. I say discovered because I have no idea how it actually works, but if anyone has the time to figure it out let me know, no trig functions required! After learning about SDF's I realized this is similar to a 2d circle SDF but uses squared distance instead of magnitude/length for distance. https://codeberg.org/m2rad0/SDL_2D_Skeleton



GNU toolchain build order
   So you want to cross compile a glibc system from a musl system? I won't pretend to know all the answers, but the hardest part is correctly bootstrapping a new toolchain to later build the new system with. Say we are building a toolchain with target NEW_HOST="i686-nu-linux-gnu" into an isolated SYSROOT="/nu". First, extract the source code and create out of tree build directories because yes I've run into weird problems specifically when cross compiling gcc with new libc if building from the source directory. Don't forget you need to extract gmp, mpc, and mpfr and manually place them into the gcc source dir. The following configuration was tested with gcc-15.2, glibc-2.42, binutils-2.45

There are two phases at this stage, lets call them phase0 and phase1. phase0 is where we are using the current host system compiler, in my case it looks like this.
INITIAL_PATH=$PATH 
... 
phase0_env() { <<<<<<<<< 
   export CPP="x86_64-pc-linux-gnu-cpp" 
   export CC="x86_64-pc-linux-gnu-gcc" 
   export CXXCPP="x86_64-pc-linux-gnu-cpp" 
   export CXX="x86_64-pc-linux-gnu-gxx" 
   export NM="x86_64-pc-linux-gnu-nm" 
   export AR="x86_64-pc-linux-gnu-ar" 
   export AS="x86_64-pc-linux-gnu-as" 
   export LD="x86_64-pc-linux-gnu-ld" 
   export RANLIB="x86_64-pc-linux-gnu-ranlib" 
   export OBJCOPY="x86_64-pc-linux-gnu-objcopy" 

   export PATH="$INITIAL_PATH:$SYSROOT/bin" <<<<<<<<< 
}


1) linux headers:
make ARCH=x86 INSTALL_HDR_PATH=/nu headers_install

Then I move /nu/usr/include to /nu/include because /usr is not needed in a new clean sysroot. in practice we could symlink /usr to /nu if really required.

2) binutils:
configure 
   --prefix=$SYSROOT 
   --target=$NEW_HOST 
   --program-prefix=$NEW_HOST- 
   --with-lib-path=$SYSROOT/lib 
   --enable-static 
   --disable-shared 
   --disable-gprofng 
   --disable-lto 
   --disable-nls 
if make fails because of a missing makeinfo you can fix it with
sed -i "s|MAKEINFO = .*makeinfo$|MAKEINFO = /bin/true|" Makefile


After it installs, create symlinks to the binaries with the program-prefix.
 
ln -sv $NEW_HOST-strings   $SYSROOT/bin/strings 
ln -sv $NEW_HOST-objcopy   $SYSROOT/bin/objcopy 
ln -sv $NEW_HOST-elfedit   $SYSROOT/bin/elfedit 
ln -sv $NEW_HOST-addr2line $SYSROOT/bin/addr2line 
ln -sv $NEW_HOST-strip     $SYSROOT/bin/strip 
ln -sv $NEW_HOST-c++filt   $SYSROOT/bin/c++filt 
ln -sv $NEW_HOST-objdump   $SYSROOT/bin/objdump 
ln -sv $NEW_HOST-nm        $SYSROOT/bin/nm 
ln -sv $NEW_HOST-size      $SYSROOT/bin/size 
ln -sv $NEW_HOST-readelf   $SYSROOT/bin/readelf 
ln -sv $NEW_HOST-gprof     $SYSROOT/bin/gprof 
ln -sv $NEW_HOST-ar        $SYSROOT/bin/ar 
ln -sv $NEW_HOST-ld        $SYSROOT/bin/ld 
ln -sv $NEW_HOST-ranlib    $SYSROOT/bin/ranlib 
ln -sv $NEW_HOST-as        $SYSROOT/bin/as 

3) gcc:
configure  
   --with-sysroot=  
   --without-headers 
   --with-newlib 
   --target=$NEW_HOST 
   --prefix=$SYSROOT 
   --program-prefix=$NEW_HOST- 
   --with-gxx-include-dir=$SYSROOT/include/c++ 
   --with-native-system-header-dir=$SYSROOT/include 
   --with-local-prefix=$SYSROOT 
   --enable-languages=c,c++ 
   --enable-static 
   --disable-shared 
   --disable-bootstrap 
   --disable-libssp 
   --disable-libvtv 
   --disable-libsanitizer 
   --disable-gcov 
   --disable-multilib 
   --disable-libquadmath 
   --disable-libgomp 
   --disable-plugin 
   --disable-libmpx 
   --disable-libitm 
   --disable-threads 
   --disable-libatomic 
   --disable-lto 
   --disable-libstdcxx 
   --disable-libstdcxx-pch 
   --disable-libstdcxx-threads 
   --disable-nls 


Create symlinks for program-prefix binaries
 
ln -sv $NEW_HOST-cc  $SYSROOT/bin/cc 
ln -sv $NEW_HOST-gcc $SYSROOT/bin/gcc 
ln -sv $NEW_HOST-g++ $SYSROOT/bin/g++ 
ln -sv $NEW_HOST-c++ $SYSROOT/bin/c++ 
ln -sv $NEW_HOST-cpp $SYSROOT/bin/cpp 


Now we are on to phase1, which starts using the new gcc and binutils
phase1_env() { <<<<<<<<< 
   export CPP="i686-nu-linux-gnu-cpp" 
   export CC="i686-nu-linux-gnu-gcc" 
   export CXXCPP="i686-nu-linux-gnu-cpp" 
   export CXX="i686-nu-linux-gnu-gxx" 
   export NM="i686-nu-linux-gnu-nm" 
   export AR="i686-nu-linux-gnu-ar" 
   export AS="i686-nu-linux-gnu-as" 
   export LD="i686-nu-linux-gnu-ld" 
   export RANLIB="i686-nu-linux-gnu-ranlib" 
   export OBJCOPY="i686-nu-linux-gnu-objcopy" 

   export PATH="$SYSROOT/bin:$INITIAL_PATH" <<<<<<<<< 
}


4) glibc:
configure 
   --prefix=$SYSROOT 
   --disable-werror 
   --target=$NEW_HOST 
   --with-headers=$SYSROOT/include 


5) binutils:
configure 
   --prefix=$SYSROOT 
   --target=$NEW_HOST 
   --program-prefix=$NEW_HOST- 
   --with-lib-path=$SYSROOT/lib 
   --with-sysroot= 
   --enable-static 
   --disable-shared 
   --disable-gprofng 
   --disable-lto 
   --disable-multilib 
   --disable-nls 


6) libstdc++:
gcc/libstdc++-v3/configure 
   --with-sysroot= 
   --prefix=$SYSROOT 
   --target=$NEW_HOST 
   --with-native-system-header-dir=$SYSROOT/include 
   --with-gxx-include-dir=$SYSROOT/include/c++ 
   --with-local-prefix=$SYSROOT 
   --enable-static 
   --disable-shared 
   --disable-multilib 
   --disable-nls 


7) gcc:
configure 
   --with-sysroot= 
   --prefix=$SYSROOT 
   --build=$NEW_HOST 
   --host=$NEW_HOST 
   --target=$NEW_HOST 
   --with-gxx-include-dir=$SYSROOT/include/c++ 
   --with-native-system-header-dir=$SYSROOT/include 
   --with-local-prefix=$SYSROOT 
   --enable-languages=c,c++ 
   --enable-static 
   --disable-shared 
   --disable-bootstrap 
   --disable-libssp 
   --disable-libvtv 
   --disable-libsanitizer 
   --disable-gcov 
   --disable-multilib 
   --disable-libgomp 
   --disable-plugin 
   --disable-libmpx 
   --disable-libitm 
   --enable-threads=posix 
   --disable-lto 
   --disable-nls 


Now you can build the rest of the temporary toolchain as needed. You want to keep it isolated from the host system when finally building the new system, so you need to build coreutils, bash, awk, make, etc, etc, etc. GNU toolchain additionally requires m4, autoconf, automake, perl, texinfo, bison, python, and flex. You can either chroot, boot directly into it, or load into a sandbox, container, or VM.

A critical file needed by GNU toolchain is $SYSROOT/include/gnu/stubs-32.h, or stubs-64.h depending on your target. If those files are missing, gcc will not be able to replicate itself and leave you with a broken system. AFAICT multilib is not needed and I am not sure it's worth the trouble, but if you want multilib you will need both 32 and 64 bit versions.

This toolchain is only temporary, but some misconfiguration here can trickle down to the new system, so just because it compiles does not mean it's correct! Always test it out before continuing to the real system. There are some options I listed here that may or may not be required, I will update this if/when I find the time.



Shout out to our web hosting friends

Hosting is brought to you by https://x10hosting.com


This site is written in gAWK + bash
    Most of these popular scripting languages include too much baggage. Let's take it back to the unix epoch and use AWK for this site. No reason in particular other than I always wanted to learn how write AWK scripts.