RSSAmplifier

Blog

smhk

Recent content on smhk

smhk.netRSS feed ↗198 posts

Latest posts

Using Dear ImGui from C

These notes cover how to add Dear ImGui into an existing C project using the SDL3_Renderer backend. Since Dear ImGui is C++, we use the C bindings provided by Dear Bindings . The end result is a C application with a couple of example GUI windows. Bindings Since Dear ImGui is written in C++, we need some bindings to enable us to use it from C. Two popular options are: Dear Bindings cimgui Both of…

Firefox Profile Nomenclature: Traditional vs Fancy

As someone who has been using Firefox Profiles for years, I was initially excited by the announcement of the new profile management feature . It sounded like this was promoting the existing feature with a UI refresh. Confusingly, it’s a completely separate feature that shares the exact same name! Let’s invent some terminology so that we can be clear: Traditional Profiles These have…

Pixel Perfect Rendering in SDL2

TL;DR: To ensure SDL2 rendering is pixel perfect, you must use “nearest pixel sampling” for the render quality, and mark the process as “DPI aware” on Windows. Enable nearest pixel sampling The scale quality must be set to "0" , which is nearest pixel sampling . SDL_SetHint ( SDL_HINT_RENDER_SCALE_QUALITY , "0" ); If set to "1" ( "linear" ) or "2" ( "best" ), SDL2 will use…

Some useful PlantUML architecture diagrams

PlantUML is very useful for creating architecture diagrams using text. However, the official documentation is so big ( a 606 page PDF as of v1.2025.0) that it’s not always easy to find what I’m looking for. Yet, despite being so big, not everything is documented. For example, there are 45 “TODO"s, and norank is not mentioned anywhere (but is mentioned in the unofficial but…

5G: Frames, Subframes, Slots, Minislots, Resource Blocks & Resource Elements

Overview Subcarriers In order to understand frames (and their component parts), it is helpful to first have a refresher on subcarriers : A carrier is formed of multiple smaller subcarriers : The subcarrier : the building blocks of a carrier ; a smaller frequency channel within the larger carrier . The subcarrier spacing (or SCS): the frequency separation between adjacent carriers. e.g. 15kHz,…

C stack trace in Windows

TL;DR: It’s possible to generate a C stack trace in Windows with GCC, but it’s easier with MSVC or LLVM/Clang. Either way, you need to install the Windows SDK and then compile and link against DbgHelp . With GCC, you also need to convert the DWARF debug information to PDB, which can be done with a tool called cv2pdb , but that depends upon installing the Visual Studio build tools.…

Enable British English language in Firefox

TL;DR: To add a British English dictionary for spellchecking in Firefox, first install the British English Language Pack , then install a British English Dictionary such as this one . Finally, go to about:preferences and set the language to “English (GB)”; this sets both the default Language Pack and Dictionary . Overview By default, Firefox provides the English (United States)…

Open5GS: Change WebUI IP and port

TL;DR: To change the IP and port used by Open5GS’s WebUI, modify the service file to set HOSTNAME=x.x.x.x and PORT=yyyy for the Environment field. Situation The Open5GS WebUI binds to localhost:9999 by default. In general, the Open5GS documentation is excellent , however I could not find documentation on how to change the IP and port used by the WebUI. I needed to change the bind IP from…

Setting up a test 5G network

TL;DR: Beware that Android phones may silently ignore your configured MCC/MNC/slice! Monitor their network requests (e.g. via tcpdump or gNB/core logs) to verify what settings the UE is actually using. Following are various notes from setting up a test 5G network. Operating a private 5G network on cellular frequency bands may be tightly regulated in your jurisdiction. Configuration Here are some…

The Important Files (part 11): Fixing Windows 11 Samba share

TL;DR: The Samba share permissions are determined by the TrueNAS user. By default, Windows will user the Windows user to try and authenticate, which may result in a read-only user if this does not match with the corresponding Samba user. A solution is to check “Connect using different credentials” when creating the share and use the correct user. After upgrading from Windows 10 to…

Configure Poetry to use a virtualenv

TL;DR: If you want to configure Poetry to use a local virtualenv (e.g. .venv/ ) instead of storing the virtualenv in the cache, first you must set virtualenvs.in-project = true , second you must then re-create the virtualenv with poetry env remove <...> and poetry install .

Valgrind 'Invalid read' with SDL2

TL;DR: Old versions of Valgrind detect false positive memory issues in SDL2 applications. This was fixed in Valgrind v3.20, but unfortunately v3.19 is the latest available version on Debian stable apt . A solution is to build & install Valgrind from source .

Pylint: Use source-roots instead of init-hook to fix E0401 'import-error'

TL;DR: Instead of using sys.path.append(<path>) in init-hook to configure Pylint, use source-roots = "<path>" .

Convert a Python script into a Poetry package

Tl;DR: Run poetry init convert a Python script into a Poetry package, then edit the resulting pyproject.toml to define the package , entry points ( scripts ), dependencies and more. A new Python project can easily begin as a single script.py , but there soon becomes a point where it&rsquo;s worth packaging up the script. That way you can benefit from proper dependency management, entry points,…

CMake and coverage with gcov

TL;DR: To generate coverage data in CMake: enable CTest, enable debug, build and link all relevant targets with --coverage , then run ctest --test-dir build -T Coverage . Use gcov or lcov to generate a CLI or HTML coverage report respectively.

Setting up Unity test framework for CMake

Unity is a test framework written in C, which is commonly used for unit testing embedded software. It can be integrated with CMake, but official support is &ldquo;a work in progress and not suitable for use yet&rdquo; . However, as shown by this blog post from November 2022 and its corresponding example project , Unity can integrate well with CMake. It&rsquo;s been two years since that blog post…

Installing Docker Desktop using local admin

TL;DR: If you installed Docker Desktop with a local admin account, you must manually add your (non-admin) user account to the docker-users group. This is mentioned in the official docs , but is easy to miss.

Zig: First impressions

I have been working through the excellent Crafting Interpreters by Robert Nystrom. Specifically, &ldquo;part III: A Bytecode Virtual Machine&rdquo;. For this part the book uses C, but I decided to use Zig. I&rsquo;ve never used Zig before. Following are some rough notes from my first experience of using Zig.

C memory layout

The memory used by a C program is laid out in various segments :

Switching from Netlify to Uberspace

TL;DR: Some rough notes on how I switched hosting this website from Netlify to Uberspace, and analytics from Plausible to Goatcounter. Background I have been hosting this website with Netlify since January 2018, which has in general been a great experience! It was easy, convenient and free to host a static website. While some features were quite useful (e.g. branches automatically creating website…

Hugo: How to create a post series

TL;DR: Follow these steps to implement a post series in Hugo, just like the one at the top of this page! A few years back I followed this blog post to implement support for post series in Hugo. However, when I upgraded to Hugo 0.136.2 recently, this broke, and the series was just blank. I found this more recent blog post helpful in coming up with the following solution.

FDM, OFDM & OFDMA

Following is an interactive overview of OFDMA , which is used many wireless standards, including 5G NR, to enable efficient use of bandwidth for multiple users.

Debian: Upgrading Dropbox

TL;DR: Dropbox on my Debian machine had stopped syncing. Turns out it had not been updated in 4 years. Fix was to update Dropbox.

Upgrading Node, Go and Hugo for this website

Time for some routine maintenance. Need to upgrade the dependencies for this website and fix any resulting issues.

Ubuntu: allow a port through the firewall

To allow TCP port 12345 : $ sudo ufw allow 12345/tcp

Setting up Zig on Windows for VS Code

TL;DR: On Windows, I recommend installing Zig via Scoop, then setting up the ZLS (Zig Language Server) with VS Code.

The Important Files (part 10): Fixing borg backup

TL;DR: Tried to run backup, it failed because the rsync.net username and hostname have changed. Updated the script and re-ran the backup, and it completed successfully after 3.5 hours. It took so long because this is the first time it has been run (successfully) in a few months.

Git: display current branch in Bash

To show the current Git branch in Bash, e.g.: user@host:/path/to/directory ( branch_name ) $

Jupyter: plot multiple layers on a single map

TL;DR: Create a map ( m ) in a Jupyter Notebook by calling m = explore(...) on a geopandas.GeoDataFrame . Add multiple layers to the map by passing the m object back in for each layer, e.g. m = explore(m=m, ...) .

Box2D v3 is released

I was excited today to see that Box2D v3.0 has been released .

Docker: understanding it

It&rsquo;s common to see docker run -it or docker run -itd , but what do those arguments actually mean?

Setting up Rye on Windows

TL;DR: Do not run pipx install rye . Instead, first enable Developer Mode in Windows , and then use the official Rye installer .

Recursively update Git submodules

To recursively update Git submodules: git submodule update --init --recursive

Python forward reference

Prior to Python 3.12 , recursive type require from __future__ import annotations : Example of a recursive type from __future__ import annotations class Something : def __init__ ( self , parent : Something | None ) -> None : self . parent : Something | None = parent

Python argparse

In Python, there is no need to write arguments --like_this . You can do arguments --like-this , and argparse will convert the - characters to _ . For example: >>> import argparse >>> parser = argparse . ArgumentParser () >>> parser . add_argument ( "--like-this" , type = int ) >>> args = parser . parse_args ( "--like-this=123" . split ()) >>> args Namespace ( like_this = 123 ) >>> args . like_this…

What is O-RAN?

The terms Open RAN and OpenRAN are often used interchangeably, but can have different meanings depending upon the context 1 : Open RAN ( with a space): Refers to the general concept of an open Radio Access Network (RAN) architecture, which can be disaggregated into component parts, with openly defined interfaces between them. OpenRAN ( without a space): Refers to the specific implementation of an…

Getting started with clang-format

Just as Black and isort can be used to format Python code, clang-format can be used to format C/C++/C# code (and more 1 ).

pytest: Selectively mark values as xfail in parametrize

In these notes, we use the pytest parametrize decorator to apply marks to some values for that parameter, rather than marking the whole test.

Xming: bind to IP

Xming is a server 1 that can be used to display X11 applications on a Windows machine. The last release of Xming was on 9th August 2016 (almost 8 years ago), but still works just fine on Windows 10. For comparison, the last release of X11 was on 6th June 2012 2 (12 years ago today!).

Directory specific environment variables with direnv

direnv is a very simple but useful tool. Create a .envrc file that defines some environment variables, e.g.: export MY_VAR = 123 export SOMETHING_ELSE = blah When you cd into that directory, the environment variables are loaded. When you cd out, they are unloaded.

VirtualBox VM freezes at 'Loading essential drivers'

TL;DR: If a VM gets stuck during boot, simply pausing and resuming can get it unstuck.

Hugo: Global resources

In February 2018, I used a bit of a hack to create a global resources object by using Hugo v0.32 page resources, i.e. .Resources.Get . In July 2018, Hugo v0.43 was released, which added resources.Get . This uses the global resources object rather than a page-specific .Resources . Using resources.Get instead of .Resources.Get makes it trivial to use global resources. As the docs say: This function…

Pure CSS dark mode support for code highlighting

These notes cover how to add support for code highlighting that automatically respects the user&rsquo;s light☀️/dark🌑 mode configuration using pure CSS. No JavaScript!

Upgrade version of pkginfo used by Poetry

Some Poetry issues 1 are fixed by upgrading pkginfo. However, the method for upgrading the verison of pkginfo used by Poetry depends upon how you installed Poetry:

Interactive geodetic coordinates

For some applications of geodesy , the Earth is modelled as an ellipsoid, since the planet bulges at the equator .

Python: mock reading and writing files

Since Python 3.3, the standard library has included unitest.mock , which provides utilities for mocking out parts of the system for testing. These notes cover how to use unittest.mock when reading from one or more files, or writing to a single file.

Pure CSS dark mode support

It is easy to support dark mode with pure CSS. No JavaScript required.

Hugo: Migrating from Pygments to Chroma

These notes cover how this website switched from Pygments to Chroma for code syntax highlighting.

The Important Files (part 9): Updating rsync.net account

TL;DR: Backup status was showing as &ldquo;Idle&rdquo; even though logs indicate backups had been succeeding. Decided to accept the rsync.net request to update my account to the new format in case that was (in part) responsible.

Trying out Coolify

TL;DR: I attempt installing Coolify on Raspberry Pi OS, but it fails because my OS turns out to be 32-bit, and Coolify requires 64-bit. In future, I would use an OS such as Ubuntu Server instead of Raspberry Pi OS. I like the idea of self-hosting, but since 2018 I&rsquo;ve been using Netlify. Some features of Netlify I find useful are: Upon commit to main the website is automatically re-built and…