Das Rad neu erfinden
Für die häufigstens Probleme gibt es akzeptierte Lösungen oder fertige Tools. Dazu gehört das Packen von Sprites oder Texturen in eine große Textur oder Sprite-Sheet. Kein Grund also wieder einmal das Rad neu zu erfinden. Ausser man hält es wie Richard Feynman:
What I cannot create, I do not understand.
In meinem Fall hatte ich etwas überspezifische Anforderungen, die keines der verfügbaren Tools für mich bot. Die Informationen der Subtexturen sollten im JSON-Format vorliegen und die Möglichkeit diese über numerische IDs zu finden. FSM sei Dank, hat Nicolas Perdu genug Vorarbeit geleistet um meine Wunsch-Features einfach selber zu implementieren ohne alles drum herum neu zu machen. (Mal wieder ein Paradadebeispiel für die Vorteile von FOSS).
Schwuppdiwupp, und der Sprite Sheet Packer ist fertig! Das JSON-Format ist sehr einfach und sieht so aus:
{"TextureAtlas":
{
"imagePath": "example",
"SubTexture":
[
{ "name": "img17", "x": 235, "y": 149,
"width": 58, "height": 59,
"rotation": 0, "id": 2822025959 },
{ "name": "img18", "x": 470, "y": 0,
"width": 29, "height": 76,
"rotation": 0, "id": 948678518 }
]
}}
Die numerischen IDs sind einfache CRC32-Summen der Dateinamen. Das ist einfach genug, ich erwarte da sobald keine Kollisionen. Man kann sich auch gleich eine C++-Header mit allen IDs generieren lassen. Einfacher geht es wirklich nicht. Durch die großartige Vorarbeit von Jukka Jylänk ist auch auf der algorithmischen Seite alles erschlagen. Das Packergebnis sieht gut aus und ich muss kein weiteres Gehirnschmalz in dieses Problem investieren.
Podcasts mit Bash abonnieren
Podcatcher gibt es wie Sand am mehr. Bisher habe ich gPodder auf dem Desktop und AntennaPod für Android verwendet. Auf dem Smartphone ist aber der Speicherplatz begrenzt und der Desktop wird gar nicht mehr so oft verwendet wie früher. Ideal wäre auf dem Server per cronjob Podcasts zu abonnieren. Vor allem das öffentlich-rechtliche Angebot wird regelmäßig wieder de-publiziert. Glück, wer ein Archive hat.
Dafür gibt es sicher schon was, bestimmt auch in Bash?Tatsächlich gibt es was, aber entweder ist der Funktionumfang zu gering oder das Projekt wird nicht mehr gepflegt. Also schnell was selbst (nein, nicht neu geschrieben) geforkt und angepasst. Taadaa, willkommen DashPodder!
Jetzt hat man ein einfaches Skript auf dem Server, das Podcasts aus Feeds heraus speichert. Warum nicht auch auf dem Desktop genauso Podcasts abonnieren? Mit Hilfe von Argos kann man seine Skripte einfach in die Gnome Shell integrieren. Das sieht dann etwa so aus:
Nächster Halt Bash auf Android! :-)
Tags: Bash, Podcast, DashPodder, Argos
Rückblick Wolfenstein 3D
Eine nostalgische Fahrt zurück an den Anfang der 1990er beginnt mit dem ersten Game Engine Black Book von Fabien Sanglard. Darin beschreibt er im technischen und historischen Kontext wie Wolfenstein 3D enstand und den Grundstein sowohl für id Software als auch für das Genre des Ego-Shooters legte. Zu Beginn werden die Grundlagen zur damaligen PC-Technik gelegt bzw. aufgefrischt. Bereits hier kann der Leser in wohligen Kindheitserinnerung schwelgen. Ordentlich sortierte Diskettenboxen, stundenlanges Kopieren für den nächsten Schultag oder vergebliches Optimieren des freien Arbeitsspeichers kommen zurück in Gedächtnis.
Besonders die Einordnung der Hardware der damaligen Zeit erlaubt dem Leser die Errungenschaften von Wolfenstein 3D technisch einzuordnen. Dabei wird nicht an Details gespart, egal ob 286, 386, Real Mode, Protected Mode oder VGA Graphik. Zusammen mit den Unmengen Trivia und Kommentaren von John Carmack bekommt man nicht nur ein Gefühl für die Zeit, sondern man versteht im Detail die Technik. Was Raycasting leistet und was nötig war um Wolfenstein wieder und wieder zu portieren. Die Tools die für Wolfenstein 3D verwendet wurden, sagen in ihrer Einfachheit viel über das Spiel selbst. Dieses Buch behandelt die Technik erschöpfend und konservierend für die Zukunft.
Für mich war Wolfenstein 3D nicht der einschneidende Meilenstein, auch nicht Doom. Das war für mich doch erst Quake. Die unzähligen Stunden mit diesen Spielen haben viele aus meiner Generation nachhaltig geprägt. Der sozio-kulturelle Aspekte kommen hier in diesem Buch nicht vor. Es geht nicht um das Spiel oder die Kunst. Fabien Sanglard nimmt eine rein technische Nerdperspektive ein und beschreibt Wolfenstein 3D einzig aus dieser Sicht aber umfassend. So ist das Buch fast schon eine Pflichtlektüre für interesseierte Programmierer unabhänngig vom Alter. Die Leistungen, die id Software damals vollbracht hat, ist auch ihne Nostalgie heute noch lehrreich. In dieser komprimierten Form ist das Buch einzigartig. Eine klare Leseempfehlung!
C++-Projekte mit CMake
Makefiles von Hand schreiben ist einfach nur nervig. Je mehr Dateien das Projekt hat, umso nerviger wird es korrekte Abhängigkeiten oder Unittests zu pflegen. Die Liste an Alternativen zu GNU Make ist natürlich sehr lang. Da ich in der Regel nur C++-Projekte unter Linux bauen will, landete ich letztendlich bei CMake. Dabei erzeugt CMake in meinem Fall auch nur wieder ein Makefile, ach die Ironie.
Aufteilung
Das Beispiel hier zeigt einen Auszug für ein Programm, das in einen Library-Teil mylib
und einen Executable-Teil myprg
aufgeteilt ist. Den Einstieg enthält dann die Datei main.cpp
und wird gegen mylib
gelinkt. Die statische Bibliothek kann man später genauso nutzen um gegen die Unittests zu linken.
# target CMakeLists.txt
add_library(mylib STATIC
DataItem.cpp
DataItemManager.cpp
)
add_executable(myprg main.cpp)
target_link_libraries(myprog mylib)
Unity Build
Unity Builds sind auch als Single Compilation Unit Builds bekannt und können die Kompilierzeit verkürzen und bessere Optimierungen ermöglichen. Mit einem Modul wie cotire ist es mit wenigen Zeilen eingerichtet. Man erhält damit neue Build-Targets, die auf _unity
enden.
# top level CMakeLists.txt
include(cotire)
# target CMakeLists.txt
cotire(myprg)
Testabdeckung
Mit Unittests bin ich eher bereit größere Änderungen am Code vorzunehmen. Damit man mögliche Regressionen sehr früh findet, sollten die Unittest möglichst alle/viele Pfade abdecken. Auch für die Testabdeckung gibt es ein passendes CMake-Modul. Mit nur drei Zeilen gibt es ein weiteres Maketarget coverage
dafür.
# top level CMakeLists.txt
include(CodeCoverage)
APPEND_COVERAGE_COMPILER_FLAGS()
SETUP_TARGET_FOR_COVERAGE(NAME "coverage" EXECUTABLE "unittest")
Statische Analyse
Zur statischen Code-Analyse mit cppcheck genügt das Erzeugen der Kompilierungs-Kommandos, da es CMake bereits unterstützt.
$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
$ cppcheck --project=compile_commands.json
Ich bin sehr zufrieden mit CMake und seinen Möglichkeiten. Letztendlich kopiere ich mir zwar immer noch die nötigen Dateien aus alten Projekten zusammen und am Ende führe ich ein Makefile aus, aber alles funktioniert zuverlässig und ich habe nützliche Zusatzfunktionen, die ich niemals selbst mit make
umgesetzt hätte. Selbst Boost wird auf CMake umsatteln. So erwarte ich eine noch besser Unterstützung von C++ in der Zukunft.
Zuletzt gelesen
Auf erzählerische und einfache Weise gelingt es Gregory T. Brown den nicht technischen Alltag bei der Softwareentwicklung einzufangen. Die einzelnen Episoden geben dem Leser eine Gelegenheit den eigenen Arbeitsalltag zu reflektieren. Nicht jeder hat zwar direkt mit einem Kunden zu tun, aber die Beispiele lassen sich leicht auf "Fachbereiche" oder andere Teilnehmer übertragen. Die kleinen Geschichten geben einem auch einen guten Ansatz, wenn man mal das eigene Schaffen einem Laien näher bringen möchten. Programmieren ist für ein Programmieräffchen dann doch nicht alles (^_^)
Die Bücher von Scott Meyers gehören einfach zu den Standardwerken, die jeder C++-Programmierer mindestens einmal in der Hand hatte. Dieses gehört ganz klar dazu. Gerade zum Nachschlagen ist es ideal. Vor dem Hintergrund von C++14 und C++17 frage ich mich aber schon, ob eine Überarbeitung und Erweiterung der alten Bücher nicht der bessere Weg wäre. Auch wenn das Wissen in den alten Büchern nicht obsolet ist, so ist zumindest etwas "gealtert". Trotzdem bleibt dieses Buch vorerst eine Pflichtlektüre.
Richtig Pferd Batterie Heftklammer
Das wohl bekannteste Webcomic zur Passwortsicherheit regt an, leichter zu merkende Passwörter zu verwenden, die auch eine hohe Sicherheit bieten. Je nach Bedrohungsmodell kann dies eine gute Wahl für den geneigten Nutzer sein. Die Festplattenverschlüsselung meines Laptops dient in erster Linie dazu einem Dieb den Zugriff auf meine privaten Daten zu verweigern. Hier bietet sich so ein Passwort an. Auch kann man mit einem leicht zu merkenden Passwort seinen Passwortspeicher wie z.B. KeePassX schützen, der die wirklich langen und zufälligen Passworte mit hoher Entropie enthält. Dazu sind vier Worte ausreichend. Allerdings müssen diese Worte zufällig gewählt sein. Denn Menschen neigen dazu Worte aus ihrem aktiven Wortschatz auszuwählen. Damit verringert man die Sicherheit des Passworts und macht es einfacher zu erraten. So hätte ich vor 25 Jahren möglicher weiße als Passwort TarzanKarlKlößchenGaby
gewählt. Das Beispiel zeigt zwei weiter wichtige Aspekte. Am einfachsten merkt man sich das Passwort, wenn aus Worten der eigenen Muttersprache gebildet wird. Daraus folgt leider auch, dass man Umlaute und Eszett besser vermeiden sollte. Denn bis heute sind Passworte in UTF-8 nicht die Regel und gelegentlich hat man auch gar kein deutsches Tastaturlayout zur Hand.
Das folgende Bash-Skript erzeugt in solches Passwort. Zunächst benötigt man ein Wörterbuch, aus dem die Worte dann zufällig gewählt werden. Da bietet sich z.B. das wngerman-Paket an oder jede andere vergleichbare Datei.
$ apt install wngerman
Daraus werden zufällig vier Worte mit drei bis sechs Buchstaben ausgewählt. Als Entropiequelle wird /dev/urandom
genutzt. Dann werden Umlaute und Eszett ersetzt und die Worte mit einem Trennzeichen verknüpft. Das Ergebnis sieht dann so aus.
$ ./passwort.sh
Bieter-Putzer-Faxt-Bambus
Titos-Tanjas-Reimen-Endung
Kehlen-Oxyde-Jaulte-Leimte
Gas-Hoehe-Erbebt-Stande
Ledige-Bonner-Kaemt-Patch
Zuvor-Paarst-Axel-Metern
Verb-Iran-Wohnst-Matter
Waermte-Anhabe-Stocks-Brueske
Beim überfliegen der Ausgaben sticht einem meistens eine Passwort ins Auge, dieses kann man sich dann besonders gut merken. Das Trennzeichen kann man auch weg lassen. Die Groß- und Kleinschreibung kann man nach belieben anpassen. Und so sieht das komplette Skript aus:
Problemlos tippen am Laptop
Auf den meistens Laptops sind sehr brauchbare Tastaturen angebracht, so auch auf meinem neuen XMG. So braucht man zum Arbeiten als Extra nur noch eine Maus, da Touchpads eher unhandlich zu bedienen sind. Nun tippe ich in der Regel mit abgespreizten Daumen (aus Gründen), die gelegentlich das Touchpad berühren. Dann springt der Cursor wo auch immer der Mauszeiger gerade ist und man tippt fröhlich ins falsche Feld 🙁 Also schaltet man das Touchpad aus. Sobald man aber mal seine Maus vergessen hat oder man zu faul ist wegen einer kurzen Email die Maus zu suchen, muss man sich mit der Tastatur zu den Einstellungen des Touchpads quälen. Das nervt! Das folgende Bash-Skript deaktiviert das Touchpad falls eine Maus angeschlossen ist. Problem gelöst.
Come In And Find Out
Es gibt meine Implementierung auf GitLab. Das Programm ist in C# geschrieben und erzeugt nicht nur Bilder sondern auch Maps für Tiled.
Wenn man aus dem alltäglichen Irrgarten von ASP.Net und Backendsystemen mal ausbrechen will, hilft es sich mal ein fachfremdes Buch zu greifen. An dieser Stelle möchte ich Mazes for Programmers von Jamis Buck empfehlen.

Es gibt dem geneigten Programmierer einen Einstieg in die Erzeugung von Labyrinthen verschiedener Arten. Ob mit vielen Sackgassen oder mit wenigen Windungen, die detaillierten Beschreibungen der Algorithmen erleichtern die Implementierung. Jamis Buck hat sich entschieden die Beispiele in Ruby zu schreiben. Ich beherrsche kein Ruby und finde es gelegentlich verwirrend zu lesen, aber die Beispiele in C# zu implementieren war ein Kinderspiel. Sehr schnell stellt sich der Spieltrieb ein und man möchte an den Labyrinthen rumspielen und diese den eigenen Wünschen anpassen. Das Buch unterhält mehr als nur einen Nachmittag und ist eine klare Empfehlung von mir. Wer weiß, vielleicht komme ich mal in die Verlegenheit ein Labyrinth zu erzeugen.