Skip to article
RSS

~neon/thoughts

A blog about game development, real-time computer graphics, and programming.


Writing a Gemini client

I have officially gone off the deep end. I am writing a C program just for fun. And it has been fun! I will admit, the experience of writing and debugging the code is much more frustrating than Rust, but the results are very rewarding. My client is currently clocking at 99KB, dynamically linking against libssl, libcrypto, and SDL2. And it’s a fully visual Gemini client! It’s always pleasant to write dense software.

Find it here, though at the time of writing, it’s not usable yet:

=> https://git.sr.ht/~neon/nemini

Here’s a bag of assorted thoughts I came across development.

Oops, apparently I’m not the only one who thought this is a great idea

About a week into development, I learned of Lagrange.

=> https://gmi.skyjake.fi/lagrange/

It uses SDL and OpenSSL, is written in C, and made by a finnish person as well. It’s one thing to make “yet another program to do X”, and another thing to make “yet another program to do X based on Y written in Z”. Oh well. Good thing I’m writing this client for fun, then ;)

TCC scripting

Here’s a trick I learned many moons ago, which I finally got to use during this project:

#!/usr/bin/tcc -run

You know, if you want to write a quick little script, but want to do it in style, with C. I wrote a short script to encode a binary file into a C source file with this:

#!/usr/bin/tcc -run
/* Reads bytes from stdin and prints them out as C source code to stdout. */

#include <stdio.h>
#include <unistd.h>

int main(void) {
    int bytes_read;
    unsigned char buf[75 / 5]; /* 5 chars per byte: 0xFF, */
    printf("const unsigned char data[] = {");
    do {
        printf("\n");
        bytes_read = read(STDIN_FILENO, buf, sizeof(buf));
        for (int i = 0; i < bytes_read; i++) {
            unsigned char byte = buf[i];
            printf("0x%02X,", byte);
        }
    } while (bytes_read != 0);
    printf("};\n");
    return 0;
}

Usage:

clangifyer.c <binaryfile.bin >cfilewiththedata.c

There might be bugs, but it seemed to work for me. I included the Atkinson Hyperlegible Font into my client with it!

=> https://www.brailleinstitute.org/freefont

You might ask: is this really the first time you had the opportunity to use C for scripting, after having learned of this “trick” “many” “moons” ago? No, not really, but I had C on my mind this time.

OpenSSL isn’t that bad

It’s actually quite a simple library to use. I based my code completely on gmni’s TLS code, and I’m not sure I know how the whole thing works yet, so I won’t write a tutorial here. But it wasn’t that much code! Don’t be intimidated by the fact that it’s a big scary system library like I was initially.

=> https://git.sr.ht/~sircmpwn/gmni

C woes

Writing C sure has been an adventure. Here’s some highlights:

This will be on my gemlog as well

Do you have a Gemini client handy? Are you from the future? You could read this blog post on my gemlog too:

=> gemini://gemlog.neon.moe

If there’s nothing there, I haven’t set it up yet. Likely because I’m still hacking away at Nemini instead. I’ll probably make another post when I set that up, so sign up to my Atom feed if you’re interested.

=> /feed.xml