Haiku-Betriebssystem: Portieren von Anwendungen und Erstellen von Paketen

Im Herbst dieses Jahres wurde nach 6 Jahren Entwicklungszeit die erste Beta-Version von "R1 / beta1" des Haiku- Betriebssystems veröffentlicht. Ich verfolge dieses interessante Projekt seit langer Zeit, das darauf abzielt, das 1994-2000 existierende BeOS- System neu zu erschaffen und weiterzuentwickeln. Sobald ich Nachrichten über die Veröffentlichung der Haiku-Beta-Version auf IT-Nachrichtenseiten sah, entschied ich mich sofort zu sehen, was zu dieser lang erwarteten Veröffentlichung hinzugefügt wurde. Nachdem ich das System in der virtuellen VirtualBox- Maschine installiert und ein wenig mit den Hauptfunktionen vertraut gemacht hatte, dachte ich, es wäre schön, der OpenSource-Community, die dieses Betriebssystem entwickelt, heute ein wenig zu helfen. Ich habe mich entschlossen, mit dem zu beginnen, was ich ein wenig Erfahrung gesammelt habe: einige Spielprojekte zu portieren.


Der Desktop des Haiku-Betriebssystems.

Später habe ich versucht, einige vorhandene Anwendungen und Bibliotheken zu verfeinern. Dies ist meine kleine Aktivität in verschiedenen Open Source-Repositories, denen dieser Artikel gewidmet sein wird. Darin werde ich die Probleme, auf die ich gestoßen bin, konsequent beschreiben und über Methoden zu ihrer Lösung sprechen. Ich habe versucht, die meisten Patches, die während dieser Arbeit erstellt wurden, an vorgelagerte bestehende Projekte zu senden, um Haiku-Unterstützung zu bieten und ihre Entwickler für die Existenz alternativer Betriebssysteme zu interessieren.

Das Haiku-Betriebssystem verwendet einen Hybridkern , bei dem es sich um eine Implementierung der Mikrokernel-Architektur handelt, mit der die erforderlichen Module dynamisch geladen werden können. Es basiert auf der Verzweigung des NewOS- Kernels, der von einem ehemaligen Be Inc.- Ingenieur entwickelt wurde Von Travis Geiselbrecht. Heute arbeitet dieser Entwickler bei Google an einem Kernel namens Zircon für das neue Google Fuchsia- Betriebssystem, aber das ist eine andere Geschichte. Da Haiku-Entwickler die Binärkompatibilität mit BeOS deklarieren, müssen sie nicht zwei bekannte Architekturzweige unterstützen, sondern drei: x86_64, x86 und x86_gcc2. Die letztere Architektur ist eine Menge Kompatibilität mit dem Compiler der alten Version von GCC 2.95. Ihr ist es zu verdanken, dass es möglich ist, Anwendungen auszuführen, die für das ursprüngliche BeOS-Betriebssystem geschrieben wurden. Leider können Haiku-Entwickler aufgrund dieser Kompatibilitätslast die modernen Funktionen der Programmiersprache C ++ nicht in System-APIs verwenden. Sie bereiten jedoch Installationsimages für nur zwei Architekturen vor: x86_64 und x86. Die Haiku-Distribution für x86 ist hybride: Trotz der Tatsache, dass alle Systemkomponenten aus Gründen der Binärkompatibilität unter x86_gcc2 erstellt wurden, hat der Benutzer die Möglichkeit, moderne Anwendungen zu installieren oder zu erstellen, die für moderne Compiler und x86-Architekturen entwickelt wurden . Die Haiku-Distribution für die x86_64-Architektur ist vollständig 64-Bit und kann keine 32-Bit-BeOS- und Haiku-Anwendungen ausführen. Es gibt jedoch Kompatibilität auf API-Ebene. Wenn Sie also den Quellcode der Anwendung für BeOS oder Haiku x86 zur Hand haben, können Sie ihn einfach unter Haiku x86_64 kompilieren und alles sollte funktionieren. Ein Betriebssystem-Image für die x86_64-Architektur wird für die Installation auf realer Hardware empfohlen, wenn Sie keine Unterstützung für bestimmte BeOS-Anwendungen oder 32-Bit-Haiku-Anwendungen benötigen.

Es ist erwähnenswert, dass in diesem Betriebssystem der POSIX- Standard teilweise unterstützt wird. Diese Grundlage ähnelt UNIX-ähnlichen Systemen und erleichtert die Portierung ihrer Software. Die Hauptprogrammiersprache ist C ++, sie wird aktiv verwendet, da die öffentlichen APIs von Haiku hauptsächlich ein objektorientiertes Programmierparadigma verfolgen. Trotzdem verbietet niemand die Verwendung der Programmiersprache C, nur in den meisten Fällen müssen die entsprechenden Kompatibilitätsebenen geschrieben werden. Die Softwareschnittstelle des Betriebssystems ist in separaten Systemframeworks zusammengefasst, die für eine bestimmte Gelegenheit verantwortlich sind, z. B. für eine Schnittstelle oder Netzwerkunterstützung. Dies ist ein bisschen wie das, was unter macOS oder im Qt- Framework verfügbar ist. Es muss beachtet werden, dass dieses Betriebssystem Einzelbenutzer ist, obwohl einige Entwicklungen in Richtung der Bereitstellung eines Mehrbenutzer-Arbeitsmodus für Haiku-Entwickler verfügbar sind.

Ich kann den Lesern dieses Artikels nur die positiven Erfahrungen mit der Verwendung des in Haiku verfügbaren erweiterten Anwendungsfenster-Verwaltungssystems mitteilen. Meiner Meinung nach ist es eines der bequemsten und in seiner Art das Markenzeichen dieses Betriebssystems.


Erweiterte Fensterverwaltung im Haiku-Betriebssystem: Unterstützung für Kacheln und Registerkarten.

Fenster können wie in modernen Browsern in Registerkarten miteinander verbunden, miteinander verbunden und bequem in der Größe geändert werden. Einfache Kacheln , das Übertragen der Kontexte einiger Anwendungen von einem Fenster in ein anderes und Replikanten werden unterstützt. Weitere Informationen zu allen Funktionen des lokalen Fenstersystems finden Sie in der offiziellen Dokumentation . Dort werden alle erforderlichen Tastenkombinationen beschrieben.

Ich werde in diesem Artikel keinen vollständigen Überblick über alle Funktionen und Fähigkeiten von Haiku schreiben, da diejenigen, die daran interessiert sind, die erforderlichen Informationen im Internet selbst leicht finden können.

Inhalt:


1. Pakete und Repositories in Haiku
2. Erste Schritte: Portierung des Adamant Armor Affection Adventure
3. Änderung des vorhandenen NXEngine-Ports (Cave Story)
4. Portierung des Gish-Spiels
5. Das BeGameLauncher-Projekt, mit dem Sie schnell Starter für Spiele erstellen können
6. Portierung von Xash3D: Legendäres Half-Life-Spiel und offizielle Add-Ons
7. Portierung der beiden Teile des Spiels Serious Sam: The First Encounter und The Second Encounter
8. Portierung des Vangers-Spiels
9. Implementierung von Dialogen in der SDL2-Bibliothek für Haiku
10. Portieren Sie meine Gabel von Cool Reader
11. Fertigstellung des KeymapSwitcher-Programms
12. Schlussfolgerung

1. Pakete und Repositories in Haiku


Im Vergleich zum ursprünglichen BeOS ist in Haiku eine bedeutende Innovation aufgetaucht: ein Paketverwaltungssystem, das verschiedene Tools zum Abrufen und Installieren von Software aus verschiedenen Quellen enthält. Solche Quellen können die offiziellen Haiku- und HaikuPorts- Repositories, inoffizielle Repositories und einfach separate und speziell vorbereitete HPKG-Pakete sein. Solche Funktionen zum Installieren und Aktualisieren von Software sind in der Welt der Unix-ähnlichen Betriebssysteme seit langem bekannt, aber jetzt hat Haiku mit all ihrer Leistung und Bequemlichkeit erfolgreich erreicht, was gewöhnlichen Benutzern dieses Betriebssystems nur gefallen kann. Dank der Infrastruktur, die auf dem Paketmanager basiert, kann jetzt jeder Entwickler problemlos eine neue oder vorhandene Open Source-Anwendung portieren oder die Ergebnisse seiner Arbeit zum HaikuPorts-Softwareport-Repository hinzufügen. Danach stehen sie allen Haiku-Benutzern zur Verfügung. Infolgedessen ähnelt das resultierende Ökosystem dem von MacOS-Betriebssystemen mit Homebrew , FreeBSD mit ihren Ports , Windows mit MSYS2 oder Arch Linux mit AUR .

Ein Tool zum Erstellen von Paketen und Portierungssoftware namens HaikuPorter wird separat vom Betriebssystem geliefert und mithilfe eines kleinen Handbuchs im Repository auf GitHub installiert. Nach der Installation dieses Dienstprogramms von demselben GitHub wird der gesamte Rezeptbaum heruntergeladen, an dem der Entwickler arbeitet. Das Rezept ist ein reguläres Shell-Skript mit Anweisungen, anhand derer HaikuPorter das erforderliche HPKG-Paket sammelt. Es ist bemerkenswert, dass das Tool selbst in der Programmiersprache Python 2 geschrieben ist , eng mit dem vorhandenen Paketverwaltungssystem interagiert und das Standardtool Git intern verwendet, um Änderungen am Quellcode der Software zu korrigieren und eine Reihe von Patches zu generieren. Dank dieses Technologie-Stacks ist das Erstellen von Rezepten zum Erstellen von HPKG-Paketen und Software-Patches in Form von Patchset-Dateien sehr bequem und einfach. In den meisten Fällen musste ich bei der Arbeit mit HaikuPorter nur drei Befehle verwenden:

alias hp="haikuporter -S -j4 --get-dependencies --no-source-packages" hp libsdl2 hp libsdl2 -c hp libsdl2 -e 

Der erste Befehl sammelt einfach das ausgewählte Paket, der zweite Befehl löscht das Build-Verzeichnis und der dritte Befehl erstellt oder aktualisiert eine Reihe von Patches entsprechend Ihren Änderungen, die im Git-Repository des Arbeitsverzeichnisses durch Commits aufgezeichnet wurden.

Um ein Paket im HaikuPorts-Repository zu veröffentlichen und allen Haiku-Benutzern zur Verfügung zu stellen, muss der Entwickler HaikuPorter installieren, den Rezeptbaum erweitern, das HPKG-Paket lokal sammeln und testen und sich dann auf die Verzweigung des Rezeptbaums festlegen. Stellen Sie dann eine Pull-Anfrage auf GitHub. Haiku-Entwickler sollten die veröffentlichten Arbeiten berücksichtigen. Anschließend entscheiden sie, Ihre Änderungen im Repository zusammenzuführen oder zur Überarbeitung zu senden. Wenn die Änderungen akzeptiert werden, sammelt derselbe auf dem Build-Server installierte HaikuPorter das Paket remote und veröffentlicht es automatisch im Repository.

Der Beta-Version von „R1 / beta1“ des Haiku-Betriebssystems wurde ein spezielles HaikuDepot- Programm hinzugefügt, mit dem Pakete und Repositorys über eine grafische Benutzeroberfläche und nicht über Konsolenbefehle im Terminal bearbeitet werden können.


Das HaikuDepot-Programm, das auf dem Haiku-Betriebssystem ausgeführt wird.

Dank dieses Tools können unerfahrene und unerfahrene Haiku-Benutzer ihre Paketbasis bequem verwalten. Es ist erwähnenswert, dass diese Anwendung nicht nur eine GUI-Shell über dem vorhandenen Paketmanager ist, sondern auch zusätzliche Funktionen implementiert. Beispielsweise können autorisierte Benutzer Bewertungen für Pakete bewerten und schreiben, die für die Installation verfügbar sind. Darüber hinaus verfügt HaikuDepot über eine spezielle Haiku Depot- Website, auf der Sie Paketänderungen im Internet anzeigen oder einzelne HPKG-Pakete herunterladen können.

<< Zum Inhalt springen

2. Erste Schritte: Portierung des Adamant Armor Affection Adventure


Nachdem ich mich mit der Funktionalität des Betriebssystems in der virtuellen VirtualBox-Maschine vertraut gemacht hatte, beschloss ich, die darin enthaltene SDL2-Bibliothek zu evaluieren und das Spiel Adamant Armor Affection Adventure nach Haiku zu portieren, das ich zuvor über die Übertragung auf die Android-Plattform geschrieben hatte. Für die Erstellung des Programms waren keine Änderungen am Quellcode erforderlich. Ich habe lediglich alle erforderlichen Tools, Bibliotheken und deren Header-Dateien aus dem Repository installiert und Folgendes ausgeführt:

 cmake -DCMAKE_BUILD_TYPE=Release -DGLES=off -DANDROID=off -DCMAKE_C_FLAGS="-D__linux__" -DSDL2_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` -DSDL2_MIXER_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` ../aaaa/src/main/cpp cmake --build . = off -DCMAKE_C_FLAGS = "- D__linux__" -DSDL2_INCLUDE_DIR = `finddir B_SYSTEM_HEADERS_DIRECTORY` -DSDL2_MIXER_INCLUDE_DIR =` finddir B_SYSTEM_HEADERS_DIRECTORY` ../aaaa/src/main/cpp cmake -DCMAKE_BUILD_TYPE=Release -DGLES=off -DANDROID=off -DCMAKE_C_FLAGS="-D__linux__" -DSDL2_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` -DSDL2_MIXER_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` ../aaaa/src/main/cpp cmake --build . 

Da Haiku über POSIX verfügt, lösen die Definitionen -D__linux__ oder -D__unix__ viele der Probleme, die mit der Definition einer Plattform verbunden sind. Es ist jedoch anzumerken, dass es am besten ist, die Verwendung aufzugeben und die Haiku-Unterstützung im Projektquellcode zu implementieren, wenn ähnliche Buildprobleme auftreten. Wenn Sie das Dienstprogramm finddir mit einem bestimmten Argument aufrufen , können Sie den richtigen Pfad zu den Header-Dateien für verschiedene Architekturen ermitteln.

Durch Ausführen der obigen Befehle habe ich eine ausführbare Datei kompiliert, die perfekt lief, und das Spiel hat perfekt funktioniert. Ich dachte, es wäre cool, ein autarkes HPKG-Paket mit dem Spiel vorzubereiten, und dafür ging ich tief ins Internet, um nach den Informationen zu suchen, die ich brauchte. Dann kannte ich keine praktischen Tools für die Portierung von Software wie HaikuPorter, über die ich im obigen Abschnitt geschrieben habe. Um mein Ziel zu erreichen, habe ich mich entschlossen, ein Systempaket zu betrügen und zu zerlegen, um zu sehen, wie es in und angeordnet ist in Analogie tun.

Im Internet fand ich die gewünschten Informationen , entpackte dann ein zufälliges Systempaket mit dem im lokalen Dateimanager integrierten Expander- Archivierungsprogramm, fand die .PackageInfo- Datei, bearbeitete sie und ersetzte die Dateien gemäß der Struktur meiner Anwendung. Dann habe ich einfach die Befehle ausgeführt, um das HPKG-Paket zu erstellen und auf dem System zu installieren:

 package create -C AAAA/ aaaa.pkg pkgman install aaaa.pkg 

Leider war das Starten des Spiels über das Menü "Anwendungen" nicht erfolgreich. Beim Ausführen der ausführbaren Datei im Terminal wurde die Fehlermeldung angezeigt, dass die zum Ausführen und Ausführen der Anwendung erforderlichen Datendateien nicht gefunden werden konnten. Wenn in diesem Fall im Terminal in das Verzeichnis des Anwendungspakets gewechselt wird, hat alles einwandfrei begonnen. Dies führte mich zu der Idee, dass Sie beim Starten des Spiels über das Menü eine erzwungene Änderung des Anwendungsverzeichnisses vornehmen müssen. Dies kann entweder mit einem Shell-Skript oder durch Ändern der Quelle des Spiels erfolgen. Ich habe die zweite Option gewählt und etwas Ähnliches zu diesem Code hinzugefügt:

 #ifdef __HAIKU__ // To make it able to start from Deskbar chdir(dirname(argv[0])); #endif 

Ganz am Anfang der Startfunktion main () , die dieses Problem vollständig löste und das Paket als funktionsfähig erwies. In den Kommentaren zu den Nachrichten über die Veröffentlichung der Haiku-Beta-Version auf Linux.org.ru habe ich den Link zu meinem zusammengestellten Paket gelöscht und jemanden gebeten, mich an einige aktive Benutzergemeinschaften dieses Betriebssystems zu senden , und bin dann ins Bett gegangen.


Adamant Armor Affection Adventure-Spielport auf Haiku.

Am Morgen schrieb mir eine Person mit dem Spitznamen 3dEyes eine E-Mail. Wie sich später herausstellte, versteckte sich Gerasim Troeglazov , einer der aktiven Haiku-Entwickler und Autor des Qt-Framework-Ports für dieses Betriebssystem, hinter diesem Namen. Er zeigte mir das HaikuPorts-Repository und erklärte mir, wie man das HaikuPorter-Dienstprogramm verwendet. Außerdem schrieb er ein Rezept für die Erstellung des HPKG-Pakets für Adamant Armor Affection Adventure und fügte es HaikuDepot hinzu.

Nachdem ich alle von diesem Entwickler vorgenommenen Änderungen analysiert hatte, stellte ich fest, dass mein manuell zusammengestelltes Paket einige Nachteile aufwies. Beispielsweise wurden die Einstellungen nicht gespeichert, da die bereitgestellten Verzeichnisse der installierten Pakete keine Schreibfunktionen hatten. Dieses Problem beim Schreiben von Einstellungen oder Speichern in seinem Paket wurde elegant mithilfe von Symlinks in einem speziellen Verzeichnis gelöst, auf das zur Aufzeichnung zugegriffen werden kann und das zum Speichern von Benutzerdaten vorgesehen ist. Mein Paket hatte auch kein eigenes Originalsymbol.

Außerdem habe ich erfahren, dass Haiku keine Hardwarebeschleunigung für 3D-Grafiken hat und dass dieselbe OpenGL programmgesteuert mit CPU-Leistung gerendert wird. Für schwere Grafikanwendungen ist dies natürlich nicht gut, aber für ältere Spiele ist dies mehr als genug. Ich entschied mich sogar, das Spielpaket speziell zu überprüfen und installierte Haiku auf meinem alten Laptop, dh auf echter Hardware. Zu meiner Überraschung wurde das Bild von Adamant Armor Affection Adventure so schnell gerendert, dass ich nicht bemerkt hätte, dass das Rendern von meinem Prozessor durchgeführt wird, wenn sie mir nicht von der fehlenden Hardwarebeschleunigung erzählt hätten.

Projektquelle: https://github.com/EXL/AdamantArmorAffectionAdventure

Ich habe die manuelle Erstellung von HPKG-Paketen bis zu besseren Zeiten verschoben und bin vollständig auf die Verwendung des HaikuPorter-Tools und das Schreiben von Rezepten umgestiegen. Manchmal gibt es jedoch Situationen, in denen eine manuelle Neuerstellung des Pakets erforderlich ist. Wenn HaikuPorter beispielsweise die Haiku-Nachtversion in der .PackageInfo- Datei zu hoch einstellt und das Paket auf der Release-Version des Betriebssystems getestet werden muss. Es ist erwähnenswert, dass ich dank der Reaktionsfähigkeit und Erfahrung von Gerasim die vielen Feinheiten beim Erstellen von Paketen für das Haiku-Betriebssystem verstehen und meine Arbeit fortsetzen konnte.

<< Zum Inhalt springen

3. Änderung des vorhandenen NXEngine-Ports (Cave Story)


Ich war unglaublich überrascht, im HaikuPorts-Repository ein Rezept zu finden, das auf meine Abzweigung der NXEngine- Engine für das Spiel Cave Story verweist , das ich schon sehr lange in meinem Blog analysiert hatte. Das Rezept und die Patches wurden von einem Entwickler namens Zoltán Mizsei erstellt , der den Spitznamen extrowerk verwendet und viele Pakete für Haiku aktiv verwaltet.

Eine oberflächliche Analyse, die Installation des Pakets und das Starten der Anwendung ergaben dieselben Probleme, die ich im vorherigen Abschnitt dieses Artikels beschrieben habe: Das Speichern des Spiels funktionierte nicht, die Einstellungen wurden auch nicht gespeichert und das Paket hatte nicht das ursprüngliche Symbol. Ich entschied mich, diese Mängel zu beheben und begann an dem Patch zu arbeiten, wobei ich zuerst alle Ideen des Extrowerks integrierte. Ich habe das Original- Makefile für das Haiku-Betriebssystem geschrieben und das Schreiben und Speichern verschiedener Benutzerdaten korrigiert.


Port des Cave Story-Spiels basierend auf der NXEngine-Engine, die im Haiku-Betriebssystem gestartet wurde.

Da das Spiel die russische und die englische Version mit unterschiedlichen ausführbaren Dateien und Datendateien voraussetzte, entschied ich mich für ein gemeinsames Paket, das zwei Versionen gleichzeitig kombiniert und automatisch die richtige basierend auf der vom Benutzer gewählten Systemsprache auswählt. Dies wurde mit dem einfachsten Shell-Skript implementiert:

 #!/bin/bash if [[ `locale -l` == ru* ]] ; then EXE="`finddir B_SYSTEM_APPS_DIRECTORY`/NXEngine/RUS/Cave Story" else EXE="`finddir B_SYSTEM_APPS_DIRECTORY`/NXEngine/ENG/Cave Story" fi "$EXE" $@ 

Dieses Skript wird gestartet, wenn ein Spielelement im Menü "Anwendungen" ausgewählt wird und das aktuelle Systemgebietsschema bestimmt. Für den Fall, dass der Benutzer Russisch als Systemsprache gewählt hat, wird die russische Version des Spiels und in allen anderen Fällen die englische Version gestartet.

Aber mit der Erstellung des ursprünglichen Symbols für die Anwendung musste ich ziemlich basteln. Tatsache ist, dass im Haiku-Betriebssystem nur Vektorsymbole des speziellen HVIF- Formats zulässig sind , die als Attribute des Be File System- Dateisystems festgelegt werden. In der offiziellen Dokumentation finden Sie zwei große Handbücher zum Erstellen eigener Symbole für Anwendungen: Das erste Handbuch beschreibt den Zeichen- und Entwurfsstil und das zweite Handbuch enthält ausführliche Informationen zur Verwendung des Icon-O-Matic- Systemprogramms zum Erstellen von Symbolen.

Mit Icon-O-Matic können Sie die einfachsten SVG-Dateien importieren und das resultierende Symbol in das für HaikuPorter erforderliche Format exportieren, das als HVIF RDef bezeichnet wird und dasselbe HVIF darstellt, jedoch in eine Textansicht konvertiert wurde. RDef-Dateien können nicht nur Bilder enthalten, sondern auch zusätzliche Informationen, z. B. die Version der Anwendung und ihre Beschreibung. In gewisser Weise ähneln diese Dateien RES-Dateien, die in Windows verwendet werden. Die folgenden Befehle im Rezept kompilieren die RDef-Dateien und setzen das Ergebnis auf spezielle Attribute:

 rc nxengine-launcher.rdef resattr -o "$appsDir/NXEngine/Cave Story" nxengine-launcher.rsrc addResourcesToBinaries $sourceDir/build/nxengine-rus.rdef "$appsDir/NXEngine/RUS/Cave Story" 

Darüber hinaus ist in den Rezepten die Funktion addResourcesToBinaries definiert, mit der diese Arbeit automatisiert werden kann. Es gibt ein, aber sehr ernstes Problem mit Icon-O-Matic: Die SVG-Dateien, die der beliebte Inkscape- Vektoreditor speichert, werden entweder nicht geöffnet oder importiert, ohne einige erforderliche Funktionen zu unterstützen, z. B. Farbverläufe. Daher ist eine Abenteuerquest mit der Konvertierung von Rasterbildern in Vektorbilder mithilfe verschiedener kostenpflichtiger und kostenloser Online- und Offline-Konverter und dem anschließenden Öffnen der resultierenden SVG-Dateien in Icon-O-Matic kläglich gescheitert. Später habe ich das Problem des Öffnens von SVG-Dateien gelöst und eine Problemumgehung gefunden, aber ich werde weiter unten darüber schreiben. In der Zwischenzeit habe ich beschlossen, die Standardfunktionen von Icon-O-Matic zu nutzen und das Symbol selbst zu zeichnen. Nach einer halben Stunde hartem Kopieren von Pixeln erhielt ich die folgende Grafik:


Das Standard-Icon-O-Matic-Programm im Haiku-Betriebssystem.

Ja, ich habe einen Vektoreditor verwendet, um ein Bild im Pixel Art-Genre zu erstellen. Meiner amateurhaften Ansicht nach ein Mann, der sich mit Kunst nur schlecht auskennt, hat sich als recht gut herausgestellt. Ich habe dieses Symbol im erforderlichen Format gespeichert, alle Änderungen vorbereitet, das Rezept aktualisiert und alles an das HaikuPorts-Repository gesendet.

Projektquellcode: https://github.com/EXL/NXEngine

Ich habe die resultierenden Pakete für alle Fälle und an die Fanseite des Spiels Cave Story (Doukutsu Monogatari) gesendet , dessen Verwaltung das Haiku-Betriebssystem zum Download-Bereich hinzugefügt hat.

<< Zum Inhalt springen

4. Portierung des Gish-Spiels


Das nächste Projekt, das ich auf Haiku übertragen wollte, war das Gish- Spiel, das ich zuvor auf Android portiert hatte. Das HaikuPorts-Repository hatte ein Rezept für eine unvollendete kostenlose Implementierung eines Spiels namens Freegish , daher habe ich beschlossen, das ursprüngliche Spiel auch dort hinzuzufügen, jedoch ohne Datendateien, da diese im Gegensatz zur Engine separat geliefert werden und überhaupt nicht kostenlos sind.


Gish Game Port läuft unter Haiku Betriebssystem.

Ich hatte keine besonderen Probleme mit der Portierung dieses Spiels. Die ausführbare Datei wurde unmittelbar nach Ausführung der folgenden Erstellungsbefehle kompiliert:

 cmake gish/src/main/cpp/ \ -DGLES=0 \ -DANDROID=0 \ -DSDL2_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` \ -DCMAKE_C_FLAGS="`sdl2-config --cflags` -D__linux__" \ -DCMAKE_BUILD_TYPE=Release cmake --build . 

Als Nächstes implementierte ich die Möglichkeit, das Spiel über das Menü "Anwendungen" zu starten, und unterstützte das Speichern von Benutzerdaten in einem Verzeichnis, auf das zur Aufzeichnung zugegriffen werden kann und das dafür vorgesehen ist:

 char* getHaikuSettingsPath() { char path[PATH_MAX]; find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, path, sizeof(path)); strcat(path, "/Gish/"); return strdup(path); } 

Die Funktion getHaikuSettingsPath () unter Verwendung der Funktion find_directory () der Haiku-API bildet den vollständigen Pfad zu dem Verzeichnis, das ich benötige.

Projektquellcode: https://github.com/EXL/Gish

Es blieb die folgende Frage zu lösen: Wie sollte der Benutzer das Verzeichnis mit den Originaldateien des Spiels Gish auswählen? Sie könnten versuchen, das Problem mithilfe von Shell-Skripten und dem Dienstprogramm für Warnsysteme zu lösen, aber ich habe mich entschlossen, dieses Problem gründlicher anzugehen und einen praktischen GUI-Launcher mithilfe der Haiku-API und des Interface Kit- Frameworks zu implementieren.

<< Zum Inhalt springen

5. Das BeGameLauncher-Projekt, mit dem Sie schnell Starter für Spiele erstellen können


Es wurde beschlossen, mein BeGameLauncher-Projekt in C ++ des alten Standards von 1998 zu schreiben und dabei die nativen Tools des Betriebssystems zu verwenden, um Anwendungen mit einer grafischen Benutzeroberfläche zu erstellen. Da die Namen vieler Programme für Haiku und BeOS mit dem Präfix „Be“ beginnen, habe ich mich auch entschieden, einen solchen Namen für das Projekt zu wählen. Ich habe mich zunächst mit dem Interface Kit-Framework vertraut gemacht, das Teil der Haiku-API ist. Zusätzlich zu der ziemlich detaillierten Dokumentation auf der offiziellen Haiku-Website fand ich zwei einfach ausgezeichnete DarkWyrm- Unterrichtskurse, mit denen ein Anfänger schnell verstehen kann, wie bestimmte Systemklassen funktionieren. Der erste Kurs heißt Programmieren lernen mit Haiku und behandelt zu Beginn die Grundlagen der Programmiersprache C ++, die für Anfänger sehr nützlich sein wird. Der zweite Kurs heißt Programmieren mit Haiku und richtet sich an Personen, die bereits mit C ++ vertraut sind und Grundkenntnisse in dieser Sprache haben. Beide Kurse befassen sich mit den unterschiedlichsten Aspekten der Haiku-API und sind daher für alle sehr nützlich, die Anwendungen für dieses Betriebssystem erstellen möchten.

Nachdem ich dieses hervorragende Material diagonal gelesen hatte, machte ich einen allgemeinen Eindruck von der Haiku-API und begann über meine nächsten Schritte nachzudenken. Ich hatte bereits einige Erfahrungen mit der Entwicklung von Anwendungsanwendungen mit dem Qt-Framework, das ebenfalls in der Programmiersprache C ++ geschrieben ist und das objektorientierte Programmierparadigma verwendet. Daher ist die Haiku-API sehr ähnlich, abgesehen vom Fehlen eines Signalsystems und von Slots. Daher werde ich häufig Parallelen und Vergleiche mit Qt ziehen. Darüber hinaus ist die Verwendung des in der Haiku-API üblichen ereignisgesteuerten Programmierprinzips zu beachten, mit dem verschiedene Entitäten durch die Übertragung von Ereignissen oder Nachrichten miteinander interagieren können. Ein Analogon zur QEvent- Klasse ist hier die BMessage- Klasse, um die das System der Interaktion von Objekten aufgebaut ist. Eine Instanz der BMessage- Klasse erhält im Allgemeinen eine eindeutige Nummer, mit der Sie den Absender und seine Aktion in einem allgemeinen Ereignisfilter identifizieren können.

Für mein Projekt musste ich die entsprechenden Haiku-API-Klassen auswählen, mit denen ich die beabsichtigte Funktionalität implementieren konnte. Um eine externe Anwendung zu starten, musste zunächst ein Analogon der QProcess- Klasse oder der execve () - POSIX-Funktion gefunden werden, die übrigens auch im Haiku-Betriebssystem einwandfrei funktioniert. Ich entschied jedoch, dass die Verwendung nativer Tools vorzuziehen ist, aber nur für den Fall Der Fall ließ die Möglichkeit, Anwendungen über die POSIX-Funktion zu starten. Die Interprozesskommunikationsklasse BRoster war für diesen Zweck großartig. Es wurde eine geeignete Launch () -Methode gefunden, mit der Sie den Pfad zur ausführbaren Datei angeben und Argumente an diese übergeben können. Da der Launcher in der Lage sein sollte, einige Parameter zu speichern, z. B. ein vom Benutzer ausgewähltes Verzeichnis mit Spieldatendateien, benötigte ich eine Klasse, die all dies erledigt. In Qt heißt eine solche Klasse QSettings , und in der Haiku-API gibt es, wie Gerasim mich dazu aufgefordert hat, eine BMessage- Klasse , die ich bereits kenne und die eine sehr nützliche Funktion hat. Die Sache ist, dass Informationen dieser Klasse einfach serialisiert und beispielsweise auf der Festplatte gespeichert werden können. Dies ist sehr praktisch und wird häufig zum Aufzeichnen von Benutzerdaten in Programmen verwendet. Aus diesem Grund habe ich diese Klasse ausgewählt, um die Einstellungen in meinem Projekt für die Implementierung von Startern zu speichern.Leider hat die Haiku-API kein Analogon zur QDebug- Klasse gefunden , daher habe ich mir die Debug-Ausgabe während der Entwicklung mit der Funktion fprintf () aus der Standard-Programmiersprache C an stderr gesendet :

 // .h #if __cplusplus >= 201103L #define BeDebug(...) fprintf(stderr, __VA_ARGS__) #else extern void BeDebug(const char *format, ...); #endif // __cplusplus == 201103L // .cpp #if __cplusplus < 201103L #include <cstdarg> void BeDebug(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); } #endif 

Ich habe diese Funktion in eine für mich geeignete BeDebug () - Entität eingeschlossen , die je nach ausgewähltem Sprachstandard entweder ein Makro oder auch eine Funktion ist. Dies geschah aufgrund der Tatsache, dass C ++ 98 keine Makros mit einer variablen Anzahl von Argumenten unterstützt.

Das Qt-Framework verfügt außerdem über eine nützliche QMessageBox- Klasse, über die Sie einen modalen Dialog mit allen Informationen erstellen können, auf die der Benutzer achten sollte, z. B. auf einen Fehler oder eine Warnung. Die Haiku-API verfügt zu diesem Zweck über eine BAlert- Klasse .deren Implementierung unterscheidet sich etwas von der in Qt verfügbaren. Beispielsweise muss ein Objekt dieser Klasse auf dem Heap und nicht auf dem Stapel erstellt werden, da es sich nach einer Benutzeraktion selbst löschen muss. Was die anderen Klassen der grafischen Oberfläche betrifft, hatte ich hier absolut keine Schwierigkeiten und fand alles, was ich brauchte, ohne Probleme.

Jetzt hätte ich über die einfache Architektur des Projekts nachdenken sollen. Ich beschloss, mich auf die Erstellung einer statischen Bibliothek zu konzentrieren, in der zwei Klassen ihre eigenen abgeleiteten Klassen von ihnen erben sollten. Die erste und wichtigste Klasse, BeLauncherBase, ist verantwortlich für die Erstellung des Hauptstartfensters, die Übertragung aller Benutzerparameter und bietet die Möglichkeit, eigene GUI-Elemente hinzuzufügen. Die zweite Klasse, BeAboutWindow , ist einfach dafür verantwortlich, das Dialogfeld "Über das Programm ..." mit Informationen zu öffnen, die in einem separaten Fenster angezeigt werden. Daher muss ein Programmierer zwei einfache Schritte ausführen, um seinen Launcher zu erstellen, beispielsweise um Gish zu spielen:

 class GishAboutWindow : public BeAboutWindow { ... }; class GishLauncher : public BeLauncherBase { ... }; int main(void) { BeApp *beApp = new BeApp(SIGNATURE); GishLauncher *gishLauncher = new GishLauncher(BeUtils::GetPathToHomeDir()); beApp->SetMainWindow(gishLauncher); beApp->Run(); delete beApp; beApp = NULL; return 0; } 


Erstellen Sie zunächst eine entsprechende Startfunktion main () und erben Sie dann einfach von den beiden oben genannten Klassen und implementieren Sie die erforderlichen Methoden in diese. Danach kompilieren wir die resultierende C ++ - Datei mit einem Link zu meiner statischen Bibliothek und unser Launcher für das Gish-Spiel ist fertig.


Dialog "Über das Programm ..." im Launcher des Ports des Spiels Gish.

Als nächstes überlegte ich, wie ich Parameter von meinem Launcher auf die Engine selbst oder in die ausführbare Datei des Spiels übertragen kann. Ich habe nur zwei Möglichkeiten gesehen, um dieses Problem zu lösen. Der erste Weg bestand darin, die Umgebungsvariablen zu ändern. In der Praxis fügt der Launcher nach dem Klicken auf die Schaltfläche „Ausführen“ einfach alle Parameter in Umgebungsvariablen ein, indem er die Funktion setenv () aufruft , und die Spiel-Engine liest diese Parameter dann mit der Funktion getenv () , die recht einfach aussieht. Das einzige Problem, das hier auftreten konnte, war die BRoster- Klasse und ihre Launch () -Methode: Ich wusste nicht, ob die mit Hilfe dieser Klasse gestartete Anwendung alle Umgebungsvariablen erbt, die im Launcher festgelegt wurden. Nach einem kleinen Experiment wurde die Vererbung von Umgebungsvariablen bestätigt und ich habe diese Methode vollständig in mein Projekt implementiert. Die zweite Möglichkeit, das Problem zu lösen, bestand darin, spezielle Befehlszeilenparameter festzulegen. In der Praxis hat der Launcher einfach alle Einstellungen in die entsprechenden Argumente eingefügt und die mit ihnen ausführbare Anwendung aufgerufen. Die Spiel-Engine musste sie jedoch bereits unabhängig verarbeiten, was einige Schwierigkeiten verursachte. Wenn das Spiel beispielsweise nicht die Möglichkeit angenommen hat, den Pfad zu den Spieledateien über Befehlszeilenparameter anzugeben, musste der Argumentparser in der Engine selbst geändert werden. Trotz dieser ProblemeIch habe diese Art der Interaktion implementiert und dadurch eine großartige Gelegenheit erhalten, alles miteinander zu kombinieren. Dadurch konnte ich in einigen Startern eine Zeichenfolge zum Angeben von Benutzerargumenten erstellen.

Als alles entworfen war, entschied ich mich für ein Montagesystem für mein Projekt. Es wurden nur zwei Optionen in Betracht gezogen: Makefile "auf Steroiden" und CMake . Im ersten Fall haben die Entwickler des Haiku-Betriebssystems ein praktisches Makefile-Engine- Paket vorbereitet, in dem sie alle erforderlichen Funktionen gesammelt haben, mit denen ein Entwickler konfrontiert wäre, wenn er mit dem Schreiben einer Anwendung auf der Haiku-API begonnen hätte, z. B. die automatische Übersetzungsgenerierung und Kompilierung von Anwendungsressourcen. Aber ich gehöre nicht zu denen, die nach einfachen Wegen suchen. Deshalb habe ich mich für CMake entschieden und einen Teil der Arbeit aus dem Makefile-Engine-Paket darauf übertragen. Infolgedessen können Sie sich das resultierende monströse Assembly-Skript im Projekt-Repository ansehen, auf das ich weiter unten verweisen werde.


Screenshot des Gish Game Port Launcher für Haiku.

Ich möchte ein paar Worte zur Anwendungslokalisierung schreiben. Im Qt-Framework gibt es hierfür eine praktische tr () - Wrapper-Funktion , zwei Hilfsdienstprogramme lrelease und lupdate , die an der Generierung von Übersetzungsdateien beteiligt sind. Zum Framework gehört sogar ein spezielles Qt Linguist- Programm mit einer praktischen grafischen Benutzeroberfläche für Übersetzer. In der Haiku-API sind Anwendungslokalisierungstools weniger bequem und archaischer. Es wird vorgeschlagen, die zu übersetzenden Zeilen in ein spezielles Makro B_TRANSLATE () zu verpacken und der Quelldatei die Definition B_TRANSLATION_CONTEXT hinzuzufügen, die eine Gruppe übersetzbarer Zeichenfolgen von einer anderen trennt. Danach muss etwas sehr Seltsames getan werden: Setzen Sie den Compiler-Präprozessor mit dem Flag -DB_COLLECTING_CATKEYS für absolut alle Projektquelldateien , zaubern Sie mit dem Dienstprogramm grep und erhalten Sie schließlich eine riesige PRE-Datei. Mit dieser Datei funktioniert das Dienstprogramm collectcatkeys , mit dem bereits lesbare und einfach zu bearbeitende CATKEYS-Übersetzerdateien erstellt werden. Nach dem Lokalisieren der Zeichenfolgen müssen Sie das Dienstprogramm linkcatkeys verwendenHiermit werden Übersetzungen zu den Ressourcen der ausführbaren Datei hinzugefügt. Bei der Auswahl einer bestimmten Systemsprache zeigt die Anwendung daher die übersetzten Zeilen an. Seltsamerweise enthält die Haiku-API-Dokumentation zur Anwendungslokalisierung nur sehr wenige Informationen. Auf der offiziellen Website fand ich jedoch einen ausgezeichneten Artikel zum Lokalisieren einer Anwendung , in dem viele Aspekte der Anwendungsübersetzung für dieses Betriebssystem beschrieben werden. Soweit ich weiß, verfügte das ursprüngliche BeOS nicht über das Locale Kit- Framework und wurde nur zu Haiku hinzugefügt.

Mein nächster Schritt war die Auswahl einer Umgebung für die Entwicklung von Anwendungen in der Programmiersprache C ++. Aufgrund der Tatsache , dass Haiku hat mit dem Qt - Framework, in Repositories so HaikuPorts die IDE, wie portiert Qt Creator undKDevelop . Darüber hinaus gibt es einen JVM- Port , über den Sie IDEs verwenden können, die in der Programmiersprache Java geschrieben sind, z. B. NetBeans oder IntelliJ IDEA . Ich habe mich für die Qt Creator-Entwicklungsumgebung entschieden, zumal es in den neuesten Versionen eine qualitativ hochwertige Analyse des Codes mit dem LibClang- Parser gibt , der viel genauer und schneller als der Standard-Parser funktioniert.


Die integrierte Entwicklungsumgebung Qt Creator, die auf dem Haiku-Betriebssystem ausgeführt wird.

In Bezug auf bekannte und plattformübergreifende IDEs in Haiku ist alles in Ordnung. Aber was ist mit exklusiven Lösungen? Ich kann nur ein sehr interessantes Projekt erwähnen, das von DarkWyrm gesponsert wird und derzeit Adam Fowler unterstützt. Es heißt Paladin . Dieses Programm macht den Pe- Texteditor in der Betriebssystemdistribution fast zu einer echten IDE.


Paladin IDE für Haiku aus dem HaikuPorts-Repository installiert.

Mithilfe der im Haiku-Fenstersystem integrierten Kacheln können Sie das Paladin-Fenster an der Seite des Pe-Editors anhängen und ein Terminal hinzufügen. Ebenfalls im HaikuPorts-Repository befindet sich ein praktischer Koder- Texteditor , der dem beliebten Notepad ++ - Programm für Windows ähnelt und auf den Erfahrungen des Scintilla- Projekts basiert . Für meine Anwendung habe ich eine Projekt-PLD-Datei erstellt, und jetzt kann jeder Entwickler, der die Paladin-IDE verwendet, mein Projekt problemlos in diesem Programm öffnen.

Als die Qt Creator-Entwicklungsumgebung eingerichtet und betriebsbereit war, begann ich, alle geplanten Funktionen zu realisieren. Das erste Problem, auf das ich gestoßen bin, betraf Skalierungssteuerelemente beim Ändern der Größe der Systemschriftart. Zu Beginn wurde in BeOS der gesamte Platzierungscode für GUI-Elemente explizit in Koordinaten festgelegt. Es war sehr unpraktisch, ausführlich und verursachte eine Vielzahl von Problemen. Beispielsweise wurde bei gleicher Änderung der Schriftgröße die gesamte Form der Anwendung verteilt und unbrauchbar. Glücklicherweise versuchte Haiku, dieses Problem zu lösen, und fügte die Layout-API hinzu , die Teil des Interface Kit-Frameworks ist.


Durch die Verwendung der Layout-API reagieren Starter sehr korrekt auf das Ändern der Größe der Systemschriftart in Haiku.

Diese Innovation löste mein Problem mit Positionierungssteuerelementen vollständig und ich schrieb die Anwendung mithilfe der Layout-API neu, wodurch die Codelänge an einigen Stellen erheblich reduziert wurde. Auf der offiziellen Haiku-Website fand ich eine Reihe interessanter Laying It All Out- Artikel, die die Gründe für die Erstellung dieser Softwareschnittstelle rechtfertigen und Beispiele für ihre Verwendung zeigen.

Ein weiteres Problem wurde von Gerasim identifiziert, als er versuchte, mithilfe meiner Bibliothek einen Launcher für das von ihm portierte Spiel zu erstellen. Die Sache war, dass ich mich oft dem Quellcode des Haiku-Betriebssystems selbst zuwandte, um verschiedene Funktionen zu implementieren. Insbesondere habe ich dort ein Beispiel für die Verwendung der Launch () -Methode für ein Objekt der BRoster- Klasse gefunden . Das Problem manifestierte sich in der Tatsache, dass dieses Beispiel falsch war und die von Gerasim portierte Spiel-Engine die vom Launcher festgelegten Argumente nicht korrekt analysieren konnte. Nachdem ich den Haiku-Quellcode eingehender untersucht hatte, konnte ich feststellen, dass das erste Argument, das den vollständigen Pfad zur ausführbaren Datei enthalten sollte, bei der Launch () -Methode nicht explizit festgelegt werden muss , da es automatisch festgelegt wird.

 // Error const char* args[] = { "/bin/open", fURL.String(), NULL }; be_roster->Launch(&ref, 2, args); // Good const char* args[] = { fURL.String(), NULL }; be_roster->Launch(&ref, 1, args); // See "src/kits/app/Roster.cpp", BRoster::ArgVector::Init() method: if (error == B_OK) { fArgs[0] = fAppPath.Path(); // <= Here if (argc > 0 && args != NULL) { for (int i = 0; i < argc; i++) fArgs[i + 1] = args[i]; if (hasDocArg) fArgs[fArgc - 1] = fDocPath.Path(); } // NULL terminate (eg required by load_image()) fArgs[fArgc] = NULL; } 

Die Dokumentation für die Launch () -Methode besagt nicht, dass das erste Argument nicht erforderlich ist, weshalb der Entwickler diesen Code wahrscheinlich falsch geschrieben hat. Ich habe diesen Fehler in meinem Projekt behoben und das Problem von Gerasim von selbst gelöst. Aber was ist mit diesem kleinen Fehler im Haiku-Betriebssystem selbst? Ich beschloss, sie auch zu reparieren. Zum Glück stellte sich heraus, dass dies sehr einfach war! Sie müssen sich mit GitHub bei der Haiku Code Review Gerrit-Ressource anmelden , Ihren öffentlichen SSH-Schlüssel hinzufügen, den Haiku-Quellcode aufteilen, ein Commit-Commit erstellen und den resultierenden Patch an Code Review an privilegierte Entwickler senden :

 git clone ssh://EXL@git.haiku-os.org/haiku --depth=1 -b master && cd haiku git commit git push origin master:refs/for/master 

Wenn Sie bereits gesendete Patches aktualisieren müssen, müssen Sie vor dem Senden geänderter oder neuer Commits die ID hinzufügen, die uns der Haiku Code Review-Dienst am Ende der Commit-Nachricht gegeben hat. Nach dem Senden des Patches müssen Haiku-Entwickler ihn genehmigen, ablehnen oder zur Überarbeitung einreichen. In meinem Fall wurde die Korrektur sofort akzeptiert und dieser kleine Fehler ist jetzt überall behoben. Wenn Sie Ihre Patches testen müssen, bevor Sie sie an das Repository senden, können Sie versuchen , eine separate Anwendung mit dem Jam- Dienstprogramm zu kompilieren , das ein Zweig des Perforce Jam- Build- Systems ist und zum Erstellen der gesamten Codebasis des Haiku-Betriebssystems verwendet wird. Das Quellcode-Repository enthält die Datei ReadMe.Compiling.md, was Ihnen hilft, mit allen Kompilierungstricks umzugehen.

Beim Abschluss meines Projekts habe ich den Grund gefunden, warum das Programm Icon-O-Matic keine SVG-Dateien öffnet, die mit dem Inkscape-Vektoreditor erstellt wurden. Die Sache ist, dass Icon-O-Matic das viewBox- Attribut nicht verarbeiten kann. Wenn Sie jedoch eine einfache SVG-Datei ohne dieses Attribut finden, sie mit Inkscape bearbeiten und als einfache SVG-Datei speichern , wird sie in Icon-O geöffnet -Matic. Daher habe ich eine solche speziell vorbereitete SVG-Datei in mein Repository gestellt, die bearbeitet werden kann und die problemlos in Icon-O-Matic geöffnet werden kann. Außerdem habe ich der ReadMe-Datei des Projekts eine kleine Anleitung zum Erstellen von Symbolen für meine Starter mit Inkscape hinzugefügt.

Ich habe mich entschlossen, den Code meines Projekts mit verschiedenen statischen Analysegeräten zu überprüfen, aber sie haben keine ernsthaften Probleme festgestellt. Aber ich fand später ein Problem, das sie nicht erkennen konnten. Die Tatsache , dass die statische Methode GetBitmap () der Klasse BTranslationUtils NULL zurückgeben könnte:

 // Somewhere fBitmap = BTranslationUtils::GetBitmap(B_PNG_FORMAT, fIndex); void BeImageView::Draw(BRect rect) { // Fail const BRect bitmapRect = fBitmap->Bounds(); ... } 

Und bei der Draw () -Methode habe ich versehentlich vergessen, das Feld der fBitmap- Klasse auf Gültigkeit zu überprüfen . Daher stürzte die Anwendung erwartungsgemäß ab, wenn sie kein bestimmtes Bild fand, aber laut Plan sollte stattdessen ein rotes Quadrat gezeichnet werden. Ich erzählte diese Geschichte der Tatsache, dass statische Analysegeräte kein Allheilmittel sind und auf jeden Fall Aufmerksamkeit bei der Arbeit mit Code in der Programmiersprache C ++ erforderlich ist.

Der Quellcode des BeGameLauncher-Projekts und alle meine Best Practices werden in das Repository auf GitHub hochgeladen. Ich hoffe, dass dieses Programm für jemanden nützlich ist und eine Art Tutorial als einfache Anwendung für Haiku sein kann:

Quellcode des Projekts: https://github.com/EXL/BeGameLauncher

Ein kleiner Rat für diejenigen, die meinen Launcher in ihren Rezepten für das HaikuPorts-Repository verwenden. Wenn Sie die ausführbare Spieldatei aus der Liste der von einigen Programmen gelesenen Haiku-Anwendungen ausblenden und nur den Launcher dort belassen möchten, können Sie den folgenden Trick verwenden:

 settype -t application/x-vnd.Be-elfexecutable $appsDir/Gish/engine/Gish rc $portDir/additional-files/gish.rdef -o gish.rsrc resattr -o $appsDir/Gish/engine/Gish gish.rsrc 

Dies schließt die Möglichkeit aus, ausführbare Dateien ohne vom Launcher übergebene Parameter aus verschiedenen Programmen wie QuickLaunch auszuführen , die mit dem Schnellstart von Anwendungen befasst sind. In diesem Fall wird Ihr ursprüngliches Symbol in der ausführbaren Datei gespeichert.

<< Zum Inhalt springen

6. Portierung von Xash3D: Legendäres Half-Life-Spiel und offizielle Add-Ons


Das Xash3D- Projekt ist eine kostenlose Implementierung der GoldSrc-Engine, die im Spiel Half-Life und in seinen offiziellen Add-Ons verwendet wird. Hinter der Entwicklung von Xash3D steht der inländische Programmierer Onkel Misha , der seine Entwicklung und Verbesserung noch koordiniert. Wenig später schlossen sich andere Entwickler dem Projekt an, die eine Abzweigung von FWGS Xash3D mit Unterstützung für eine große Anzahl von Nicht-Windows-Betriebssystemen herstellten. Heute sind mittorn und a1batross ( libpony ) die wichtigsten Programmierer des FWGS Xash3D-Projekts. Die letzte Person war ein aktiver Teilnehmer am einst beliebten MotoFan.Ru- Forumwas ich noch in meiner Freizeit verwalte.

Ich fragte mich: Warum nicht diese Engine auf Haiku portieren, das Xash3D-Projekt um die Unterstützung eines so interessanten Betriebssystems erweitern und Haiku-Benutzern die Möglichkeit geben, das legendäre Half-Life, ein Spiel aller Zeiten, zu spielen? Die Angelegenheit blieb klein - es war erforderlich, sofort mit der Arbeit an der Portierung zu beginnen und bei Erfolg die Ergebnisse dieser Arbeit zu veröffentlichen.

Nachdem ich einige Stunden damit verbracht hatte, die Projektstruktur und die Teile des Codes zu studieren, die für die Unterstützung verschiedener Plattformen verantwortlich sind, nahm ich Änderungen an der Xash3D-Engine vor, um das Haiku-Betriebssystem zu unterstützen. Auf die altmodische Weise habe ich den Compiler -D__linux__ definiertund versuchte, eine ausführbare Datei und eine Reihe von Bibliotheken zu erstellen. Überraschenderweise ging es ziemlich schnell und am Abend, nachdem ich Datendateien für das Spiel geworfen hatte, gelang es mir, Half-Life zu starten und mit dem Zug zum Hauptbahnhof in Black Mesa zu fahren.


Der Vorgang des Portierens der Xash3D-Engine nach Haiku in der Qt Creator-IDE.

Aufgrund der Tatsache, dass das Projekt die plattformübergreifende SDL2-Bibliothek verwendet, wird die Portierung der Engine erheblich vereinfacht, da Sie keinen plattformabhängigen Code schreiben müssen, z. B. Sound ausgeben, ein Fenster mit einem OpenGL-Kontext erstellen oder Eingabeereignisse verarbeiten. All dies wurde bereits in der SDL2-Bibliothek implementiert und ist einsatzbereit. Ein kleines Problem trat bei der Netzwerkunterstützung auf, da Haiku über eine separate Bibliothek verfügt, die den Netzwerkstapel implementiert, sodass er mit der Engine verknüpft werden musste.

Das Projekt zur Erstellung von Trägerraketen, über das ich etwas höher geschrieben habe, war für mich sehr nützlich. Durch die Vererbung von C ++ - Klassen habe ich die Funktionalität ernsthaft erweitert und die Möglichkeit implementiert, verschiedene Ergänzungen zum Spiel auszuwählen:


Screenshot des Xash3D Engine Port Launcher für Haiku.

Die Idee war folgende: Definieren Sie drei Umgebungsvariablen, mit denen Sie die Spiel-Engine flexibel konfigurieren können, um ein bestimmtes Add-On zu starten. In diesem Fall wäre es nützlich, den Benutzer mit den verschiedenen Argumenten der ausführbaren Datei spielen zu lassen und die Möglichkeit des tragbaren Startens der Engine zu belassen, wenn sie sich nur im Verzeichnis mit den erforderlichen Datendateien befindet. Die erste Umgebungsvariable XASH3D_BASEDIR ist also für das Verzeichnis mit den Spieledateien verantwortlich, die der Benutzer aus dem Launcher auswählt. Die zweite Variable XASH3D_GAME ist dafür verantwortlich, welchen Zusatz der Benutzer zum Starten im Launcher ausgewählt hat. Und hier ist die dritte Variable XASH3D_MIRRORDIR, nur für fortgeschrittene Benutzer nützlich. Sie können das Xash3D-Systemverzeichnis auf einen beliebigen beschreibbaren Speicherplatz für den Benutzer spiegeln. Daher muss eine Person, die ihr Add-On-Spiel auf der Xash3D-Engine unter Haiku veröffentlichen möchte, nur mehrere dynamische Bibliotheken für verschiedene Architekturen aus dem Quellcode ihres Projekts sammeln:

• ./cl_dlls/libclient-haiku.so
• ./dlls/libserver-haiku .so
• ./cl_dlls/libclient-haiku64.so
• ./dlls/libserver-haiku64.so

Und legen Sie sie dann in den entsprechenden Verzeichnissen Ihres Add-Ons ab. Für meinen Xash3D-Port habe ich mich entschlossen, Bibliotheken mit beliebten Add-Ons für das Half-Life-Spiel vorkompilieren, nämlich Blue Shift und Opposing ForceHiermit können Benutzer einfach ihre Datendateien herunterladen, ein Verzeichnis auswählen und das Spiel ohne Zusammenstellung der Bibliothek starten.

Beim Portieren der Xash3D-Engine stieß ich auf einige lustige Probleme. Es stellt sich heraus, dass die Engine zur Bestimmung der Länge der Hilfemeldung für die Argumente der ausführbaren Datei, die bei der Übergabe des Parameters --help generiert wird , die vordefinierte Größe der Konstante MAX_SYSPATH verwendet hat , die ein Alias ​​einer anderen Konstante MAX_PATH ist , deren Wert bereits aus der Haiku-API übernommen wurde. Daher konnte ich lange Zeit nicht verstehen, warum dieses Zertifikat unvollständig ausgestellt und an der interessantesten Stelle abgeschnitten wurde. Zuerst habe ich das auf seltsame Weise zum Standardfehlerausgabestream gesündigtstderr hat die Pufferung angeschlossen und sogar versucht, sie zwangsweise zu deaktivieren. Nach einiger Zeit fiel mir ein, dass ich von der sehr geringen Größe der MAX_PATH- Konstante im Haiku-Betriebssystem überrascht war . Diese Konstante nimmt eine Pfadgröße von nur 1024 Bytes an. Meine Vermutung hat sich vollständig ausgezahlt. Sobald ich die Nachrichtengröße auf Standard-4096-Bytes erhöht habe, wurde das Problem behoben. Die folgende Schlussfolgerung sollte aus dieser lustigen Geschichte gezogen werden: Sie sollten die Konstante MAX_PATH nicht in Zeichenarrays verwenden, die in keiner Weise mit Dateipfaden verknüpft sind.


Eine Collage von Screenshots des Spiels Half-Life sowie seiner offiziellen Ergänzungen Blue Shift und Opposing Force, die mit der Xash3D-Engine im Haiku-Betriebssystem gestartet wurden (Vorschau, Erhöhung durch Referenz ).

Ein weiteres Problem war der Absturz, wenn die Funktionalität der Engine selbst verwendet wurde, um das Add-On für das Spiel auszuwählen. Es stellte sich heraus , dass , wenn der exponierte defayne XASH_INTERNAL_GAMELIBS Client - Bibliothek nicht einmal geladen , sondern zweimal. Was ein ähnliches Problem mit sich brachte. Wie mir a1batross erklärt hat , wurde dies getan, damit die OpenVGUI- Bibliothek statisch mit der Client-Bibliothek verknüpft werden kann . In meinem Xash3D-Port auf Haiku wird diese Bibliothek in keiner Weise verwendet, daher habe ich nur die Verwendung der Standardeinstellung vermiedenXASH_INTERNAL_GAMELIBS und meldete diesen Fehler den Entwicklern der Engine.

Dann stieß ich auf die Unmöglichkeit, den in Haiku integrierten WebPositive- Browser zu öffnen, wenn ich auf Links in einem in Xash3D laufenden Spiel klickte. Das Problem war wirklich seltsam, denn als die Engine vom Terminal aus gestartet wurde, öffnete sich der Browser, aber als sie mit dem Launcher gestartet wurde, weigerte er sich, dies zu tun. Nachdem ich den Code ein wenig studiert hatte, fand ich dort den Aufruf execve () , den ich durch system () zu ersetzen versuchte. Danach begann der Browser ohne Probleme zu öffnen.

Wenn ein Fehler auftritt, verwendet die Xash3D-Engine aktiv die Funktionsaufrufe SDL_ShowSimpleMessageBox () und SDL_ShowMessageBox ()Nur der aktuelle SDL2-Bibliotheksport für Haiku unterstützt die Erstellung dieser Dialoge nicht. Unsere Version der Bibliothek verfügt einfach nicht über diese Funktionalität. Aber ich werde weiter unten über die Behebung dieses Problems sprechen.


Der Port der Xash3D-Engine, der im Haiku Depot-Repository veröffentlicht wurde.

Es ist auch erwähnenswert, dass Gerasim Troeglazov vor meiner Übertragung der Xash3D-Engine auf Haiku eine Mauscursor-Erfassung in SDL2 implementiert hat. Vorher war das Spielen von 3D-Spielen fast unmöglich. Wenig später behebte er einen kniffligen Fehler, bei dem die Bewegung des Spielers im Weltraum allmählich verlangsamt wurde und das Spiel furchtbar langsamer wurde. Es stellte sich heraus, dass die Mauszeigerereignisse standardmäßig mit ihrer gesamten Bewegungshistorie auf dem Bildschirm übertragen wurden. Dementsprechend wurde diese Geschichte während des Spiels schnell aufgeblasen und alles begann sich stark zu verlangsamen. Durch Deaktivieren dieser Funktion im Haiku SDL2-Port wurde dieses Problem behoben. Jetzt können Sie Half-Life problemlos spielen. Der Mangel an 3D-Beschleunigung auf schwacher Hardware macht sich jedoch bemerkbar. Und wenn das Spiel im Fenster anständig funktioniert und überhaupt nicht langsamer wird, wird im Vollbildmodus die FPS erheblich reduziert.Hier hilft es jedoch nur, dem Grafiktreiber eine Hardwarebeschleunigung hinzuzufügen, zumindest für die GPUs, die in gängigen Intel-Prozessoren integriert sind.



Projektquellcode : https://github.com/FWGS/xash3d Ich habe alle Änderungen am Quellcode an die Entwickler des FWGS Xash3D-Projekts gesendet, die sie im Repository akzeptiert haben. Pakete mit dieser Engine sind seit langem in HaikuPorts und im HaikuDepot-Programm für jeden Haiku-Benutzer verfügbar .

<< Zum Inhalt springen

7. Portierung der beiden Teile des Spiels Serious Sam: The First Encounter und The Second Encounter


Vor kurzem haben Entwickler von Croteam den Quellcode für die Serious Engine veröffentlicht , die in Spielen der Serious Sam-Reihe verwendet wird: The First Encounter und The Second Encounter . Ich beschloss, es auf das Haiku-Betriebssystem zu portieren, lud den Quellcode herunter und begann zu arbeiten.


Screenshot des Serious Engine Port Launcher für Haiku.

Das Zusammenstellen der ausführbaren Datei nach den Änderungen war ohne Probleme möglich, aber es war nicht so einfach, das Spiel zu starten, da Fehler in die SDL2-Dialoge eingefügt wurden, die in der Version dieser Bibliothek für Haiku nicht implementiert sind. Daher musste ich den stderr , den bewährten Standard-Fehlerausgabestream, aufgreifen und die Probleme langsam lösen, was sich hauptsächlich als das Fehlen der erforderlichen Spieldatendateien herausstellte.


Screenshot von Serious Sam: Das zweite Begegnungsspiel, das über den Serious Engine-Port für das Haiku-Betriebssystem gestartet wurde.

Nachdem ich die heruntergeladenen Dateien in die erforderlichen Verzeichnisse zerlegt hatte, konnte ich den zweiten Teil dieses wunderbaren Spiels ohne Probleme ausführen und lief sogar ein wenig durch den wunderschönen Dschungel. Trotz der fehlenden 3D-Beschleunigung zeichnet der Prozessor die grafischen Reize des Spiels, wenn Sie es in einem Fenster und nicht im Vollbildmodus ausführen. Diese Engine arbeitet natürlich mit viel niedrigeren FPS als die Xash3D-Engine, über die ich oben geschrieben habe, aber die Grafiken hier sind moderner und besser. Nach geringfügigen Manipulationen war es möglich, den ersten Teil des Spiels zu starten, für den eine andere ausführbare Datei und ein anderer Satz dynamischer Bibliotheken erforderlich sind. Überraschenderweise hat sie etwas schneller verdient, anscheinend sind die Grafiken darin nicht so anspruchsvoll. Beim Klettern der Motoreinstellungen habe ich eine Vielzahl von Grafikparametern gefunden, die die Belastung des Prozessors erheblich reduzieren können.was sich im Fall von Haiku als sehr nützlich herausstellte.


Screenshot des Spiels Serious Sam: The First Encounter, das über den Port der Serious Engine für das Haiku-Betriebssystem gestartet wurde.

Ich habe beschlossen, ein Paket für zwei Teile des Spiels gleichzeitig zu erstellen. Der Wechsel zwischen ihnen erfolgt einfach durch Auswahl eines Verzeichnisses mit den entsprechenden Datendateien. Wenn beispielsweise ein Benutzer im Launcher das Verzeichnis mit den Dateien des Spiels Serious Sam: The First Encounter auswählt, wird die entsprechende ausführbare Datei gestartet und der entsprechende Satz dynamischer Bibliotheken geladen. Und wenn er das Verzeichnis mit den Dateien des Spiels Serious Sam: The Second Encounter auswählt, startet der Launcher entsprechend eine weitere ausführbare Datei, die seine eigenen gemeinsam genutzten Bibliotheken lädt.

Leider war es nicht ohne Probleme. Eine wiederholte Änderung der Auflösung des Videomodus im Spiel führte zum Ausfall der gesamten Engine. In diesem Fall war dieser Absturz in meiner Linux-Distribution nicht der Fall. Ich habe viel Zeit damit verbracht, das Problem zu lokalisieren und zu beheben. Es stellte sich heraus, dass der springende Punkt war, dass bei jeder Änderung der Auflösung das Fenster SDL_Window zerstört und erneut erstellt wurdeGleichzeitig konnte der OpenGL-Renderer nicht rechtzeitig wechseln und versuchte, dort etwas in das zerstörte Fenster zu zeichnen. Solche Tricks erlaubte der SDL2-Bibliotheksport auf Haiku nicht zu starten. Alle einfachen Versuche, dieses Problem zu lösen, halfen nicht, und ich musste mich ernsthaft mit der Logik befassen und das Verhalten ändern, damit das Fenster beim Ändern der Auflösung nicht kaputt ging, sondern seine Parameter einfach geändert wurden. Dies half, den Absturz zu beseitigen, fügte jedoch eine zusätzliche Einschränkung hinzu: Um den Vollbildmodus zu aktivieren, müssen Sie die Engine neu starten.

Ein weiteres Problem war der Mangel an Musik im Spiel. Unter Linux trat dieses Problem jedoch erneut nicht auf. Bei der Untersuchung des Quellcodes der Engine stellte ich fest, dass das Abspielen von Musik von der libvorbisfile- Bibliothek abhängt, aber die Engine selbst verbindet sich nicht damit, sondern verwendet die Systemfunktion dlopen () , um den OGG-Audiodateistream dieser Bibliothek zuzuführen . Das Problem war, dass die Engine diese Bibliothek auf Haiku nicht finden konnte, da es ohne Version keinen Symlink zur Bibliotheksdatei gab.

 void CUnixDynamicLoader::DoOpen(const char *lib) { // Small HACK for Haiku OS (: #ifdef __HAIKU__ static int vorbis_cnt = 3; char path[PATH_MAX]; char libpath[PATH_MAX]; find_directory(B_SYSTEM_LIB_DIRECTORY, -1, false, libpath, PATH_MAX); if (strstr(lib, "vorbis")) { snprintf(path, sizeof(path), "%s/libvorbisfile.so.%c", libpath, char(vorbis_cnt + '0')); vorbis_cnt++; lib = path; } #endif // fprintf(stderr, "dlopen => %s\n", lib); module = ::dlopen(lib, RTLD_LAZY | RTLD_GLOBAL); SetError(); } 

Ein kleiner Trick, der den vollständigen Pfad zur erforderlichen Bibliothek in die Funktion ersetzte, erwies sich als vollständig funktionierende Lösung. Und da die Bibliothek in ihrer Abwesenheit mehrmals von der Engine durchsucht wird, habe ich für die Zukunft die Möglichkeit gelassen, die nächste Hauptversion zu laden. Ich hoffe, dass sie die API darin nicht brechen.

Das nächste Problem, auf das ich stieß, war die Unfähigkeit, die Prozessorfrequenz auf der x86-Architektur zu bestimmen, obwohl auf x86_64 alles gut funktionierte. Bei der Ausführung unter x86 wurde die Engine aufgefordert, eine Umgebungsvariable mit dem Namen SERIOUS_MHZ festzulegenund stellen Sie die entsprechende Frequenz ein, was mich sehr überrascht hat. Ich habe es versucht und das Spiel hat wirklich begonnen, aber aus irgendeinem Grund hat es zu langsam funktioniert. Als ich den Quellcode des Spiels erklomm, konnte ich lange Zeit die Ursache des Problems nicht finden und schrieb sogar einen Code, der die Haiku-API verwendet, um die richtige Prozessorfrequenz zu erhalten und sie in die Spiel-Engine zu ersetzen. So sah es aus:

 #include <kernel/OS.h> #include <stdio.h> ... uint64 cpuFreq = 0; uint32 count = 0; get_cpu_topology_info(NULL, &count); if (count != 0) { cpu_topology_node_info *topology = new cpu_topology_node_info[count]; get_cpu_topology_info(topology, &count); for (uint32 i = 0; i < count; ++i) { if(topology[i].type == B_TOPOLOGY_CORE) { cpuFreq = topology[i].data.core.default_frequency; } } delete[] topology; } fprintf(stderr, "%llu\n", cpuFreq); 

Aber das hat nicht geholfen. Dann habe ich die Engine-Protokolle auf x86_64 überprüft und festgestellt, dass dort die CPU-Frequenz im Allgemeinen bei 1 MHz bestimmt wird, aber alles funktioniert einwandfrei. Als ich den Code weiter untersuchte, stieß ich auf eine Ablehnung der Definition __GNU_INLINE_X86_32__ , die automatisch verfügbar gemacht wird, wenn die Anwendung für die x86-Architektur erstellt wird, nicht jedoch für x86_64. Unterhalb dieser Definition wurde das Flag, das früher SDL2-Timer verwendete, ausgeblendet, anstatt die Prozessorfrequenz mithilfe verschiedener magischer Methoden wie Inline-Assembler und rdtsc- Anweisungen zu ermitteln oder die Datei / proc / cpuinfo zu lesen. Daher habe ich dieses Flag aktiviert und aktiviert für x86, was mein Problem gelöst hat.

Der letzte Mangel hing mit meiner Nachlässigkeit zusammen. Ich habe in der Assembly-Datei verpasstCMakeLists.txt setzt das native Flag -march = , das dem Compiler buchstäblich mitteilt: Verwenden Sie beim Generieren von Maschinencodeblöcken alle anspruchsvollen und modernen Anweisungen, die auf dem Prozessor Ihres Computers verfügbar sind.

 if(NOT PANDORA AND NOT HAIKU) message("Warning: arch-native will be used!") add_compile_options(-march=native) endif() if(HAIKU) if(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32-bit message("Warning: Will building 32-bit executable with MMX, SSE, SSE2 support.") add_compile_options(-mmmx -msse -msse2) else() # 64-bit message("Warning: Will building 64-bit executable.") endif() endif() 

Aus diesem Grund wurden Pakete im Repository ausschließlich unter dem leistungsstärksten Build-Server gesammelt und weigerten sich, auf den Computern gewöhnlicher Sterblicher ausgeführt zu werden, wobei sie auf die falschen Anweisungen und Opcodes schworen. Das Deaktivieren dieses Flags und das manuelle Hinzufügen von Unterstützung für MMX-, SSE- und SSE2-Anweisungen löste nicht nur dieses Problem, sondern ermöglichte es uns auch, eine große Anzahl von Inline-Assemblern in diesem Projekt zu kompilieren, die nach dem Entfernen dieses Flags abfielen.

Zu meinem großen Bedauern akzeptieren Croteam-Entwickler keine Patches im Engine-Repository. Deshalb habe ich meine gesamte Arbeit dort abgelegt

: Projektquellcode : https://github.com/EXLMOTODEV/Serious-Engine

Installationsfertige Pakete zum Starten von Serious Sam-Spielen sind bereits im HaikuPorts-Repository verfügbar. Denken Sie daran, die Spieldatendateien herunterzuladen.

<< Zum Inhalt springen

8. Portierung des Vangers-Spiels


Ehrlich gesagt war ich bis vor kurzem mit diesem Spiel, das in den fernen 90ern vom heimischen Entwicklungsstudio KD Lab entwickelt wurde, völlig unbekannt. Die Teilnehmer der Konferenz in Telegram IM , die sich mit der Diskussion des Haiku-Betriebssystems befasst, baten mich jedoch, Vangerov zu portieren, und gaben mir einen Link zum GitHub-Repository , in dem sich die Quellen dieses Spiels befanden.


Screenshot des Vanger Game Port Launcher für Haiku.

Nachdem ich den Quellcode in Haiku gezogen hatte, versuchte ich ihn zu kompilieren und es gelang mir ohne besondere Probleme. Ich musste ein bisschen am Fehlen einiger Header-Dateien und an den Pfaden zu den FFmpeg-Bibliotheken basteln , die von der Engine dieses Spiels verwendet werden. Ich habe sofort damit begonnen, den Quellcode für das Packen vorzubereiten, also habe ich die Umgebungsvariable VANGERS_DATA hinzugefügt und das Engine-Protokoll in das beschreibbare Benutzerverzeichnis verschoben.


Der Vorgang des Portierens eines Vanger-Spiels nach Haiku in der Qt Creator-IDE.

Ich habe das Spiel selbst gestartet und nach einer Weile habe ich die ganze Atmosphäre geschätzt, die die Jungs von KD Lab geschaffen haben. Nach einiger Zeit begann ich, den Nimbus munter zum Inkubator und den Schleim nach Podish zu tragen, wonach ich es sogar schaffte, den Elik zum dritten zu bringen. Nachdem ich genug gespielt hatte, begann ich, basierend auf meiner Bibliothek, über die ich oben geschrieben habe, einen Launcher für dieses Spiel vorzubereiten.


Ein Spielport für Vanger, der auf dem Haiku-Betriebssystem ausgeführt wird.

Das erste Problem, auf das ich stieß, war, dass die Spieldatendateien, die offiziell über die digitalen Vertriebsdienste GOG.com und Steam abgerufen werden konnten , nicht mit der Engine funktionieren wollten. Ich musste mich an eine Person wenden, die den Spitznamen stalkerg verwendet und Wanger auf Linux portiert. Er sagte mir, welche Dateien ersetzt werden sollen, damit alles beginnt und funktioniert. Ich folgte seinen Empfehlungen und bekam, was ich brauchte.

Wie im Fall des NXEngine-Ports (Cave Story), über den ich oben geschrieben habe, unterscheiden sich die russische und die englische Version in verschiedenen ausführbaren Dateien, aber das Verzeichnis mit den Datendateien ist üblich, die Unterschiede bestehen nur in den Skripten. An der Spitze von stalkerg habe ich versucht, die Spiel-Engine mit der Option -DBINARY_SCRIPT = Off zu kompilieren , wodurch die dynamische Kompilierung dieser Skripte zur Laufzeit aktiviert wurde, wenn sie sich im Verzeichnis der Spieldatendateien befinden. All dies ermöglichte es mir, einen Launcher zu erstellen, in dem die Sprache gewechselt werden kann. Die Idee ist folgende: Das Spielverzeichnis wird vorab überprüft, und wenn es nicht über die erforderlichen Skripte verfügt, werden sie aus den Eingeweiden des Pakets kopiert, wonach die ausführbare Datei der russischen oder englischen Version bereits ausgeführt wird.


Der Spielehafen von Vanger, veröffentlicht im Haiku Depot-Repository.

Bei der Portierung von Wanger habe ich eine interessante Funktion verwendet, die sich auf gemeinsam genutzte Bibliotheken bezieht, die ich an Haiku mag. Die Spiel-Engine hängt von der dynamischen Bibliothek libclunk.so ab , die für die Erzeugung binauraler Sounds in Echtzeit verantwortlich ist. Und wenn ich unter Linux meine Finger brechen muss , indem ich den Pfad zu dieser Bibliothek in der Umgebungsvariablen LD_LIBRARY_PATH ersetze , damit auch das, was zuvor in dieser Variablen war, gespeichert wird, dann geschieht dies in Haiku bequem wie in Windows. Es reicht aus, die gemeinsam genutzte Bibliothek neben die ausführbare Datei zu stellen, und sie wird abgeholt. Der einzige Unterschied besteht darin, dass im Fall von Haiku die Bibliothek im Verzeichnis ./lib/ abgelegt werden muss., was meiner Meinung nach viel Zeit und Nerven sparen kann. Daher habe ich beschlossen, die statische Kompilierung dieser Bibliothek nicht in Betracht zu ziehen.

Projektquellcode: https://github.com/KranX/Vangers

Wanger-Entwickler haben meine Änderungen an ihrer Spiel-Engine akzeptiert, und einbaufertige Pakete können aus dem HaikuPorts-Repository oder dem HaikuDepot-Programm heruntergeladen werden, obwohl in der Repository-Infrastruktur kürzlich ein Fehler aufgetreten ist Aktualisieren der Fedora Linux-Distribution auf die neue Version.

<< Zum Inhalt springen

9. Implementierung von Dialogen in der SDL2-Bibliothek für Haiku


Beim Portieren der Xash3D- und Serious Engine-Engines, über die ich oben geschrieben habe, bin ich auf einen lokalen Port in der SDL2- Bibliothek gestoßen, bei dem die Implementierung von Dialogen völlig fehlte. Dialoge werden von zwei Funktionen aufgerufen: SDL_ShowSimpleMessageBox () und SDL_ShowMessageBox () , mit denen der Benutzer über wichtige Informationen, beispielsweise über einen Fehler, informiert werden kann. Die Implementierung dieser Dialoge ist auf vielen Plattformen und Betriebssystemen verfügbar: Windows, MacOS, iOS, X11 und Android, fehlt jedoch aus irgendeinem Grund in Haiku. Ich habe beschlossen, dieses Versäumnis zu beheben und diese Funktionalität dem SDL2-Bibliotheksport hinzuzufügen.

In der Haiku-API oder besser gesagt im Interface Kit-Framework gibt es eine wunderbare Klasse BAlertDas ist großartig für die Implementierung solcher Dialoge. Ich entschied mich, es als Basis zu wählen. Das einzige, was mich störte, war, dass ich nicht sicher war, ob mehr als drei Schaltflächen in dem von BAlert erstellten Dialog platziert werden konnten . Ich erinnerte mich auch an die Speicherverwaltungsfunktionen in dieser Klasse, über die ich oben geschrieben habe: Die Objekte können nur auf dem Heap und nicht auf dem Stapel erstellt werden, da sie sich nach dem Aufrufen der Go () -Methode und der nachfolgenden Benutzeraktion selbst löschen. Nachdem ich einige Experimente durchgeführt hatte, zerstreute ich alle meine Zweifel, erbte von dieser Klasse und begann eine Implementierung zu schreiben.


Implementierung von Dialogen in der SDL2-Bibliothek für das Haiku-Betriebssystem.

Die erste Schwierigkeit, auf die ich stieß, bestand darin, dass bei Verwendung eines Objekts der BAlert- Klasse oder ihrer Nachkommen eine Instanz der BApplication-Systemklasse erstellt werden musste , anscheinend um die Anwendung in app_server zu registrieren , um mit ihr interagieren zu können. Ich habe eine Instanz dieser Klasse erstellt, aber beim Aufrufen des BAlert- Dialogfelds aus einem anderen Prozess oder aus dem erstellten Fenster ist ein weiterer Fehler aufgetreten , der darauf zurückzuführen ist, dass die Anwendung nicht über zwei Objekte der BApplication- Klasse verfügen kann. Glücklicherweise habe ich eine Lösung für dieses Problem gefunden. Die Haiku-API verfügt über einen globalen Zeiger auf die aktuelle Instanz der KlasseDie BApplication mit dem Namen be_app , ihr Gegenstück im Qt-Framework, ist ein spezielles qApp- Makro , das auch einen Zeiger auf das aktuelle Anwendungsobjekt definiert. Es reicht also aus, einfach den be_app- Zeiger auf NULL zu überprüfen. Wenn die Prüfung erfolgreich ist, erstellen Sie das erforderliche Objekt. Damit waren alle diese Probleme gelöst.

Es ist erwähnenswert, dass die SDL2-Bibliothek in der Programmiersprache C geschrieben ist und die Haiku-API, wie Sie wissen, die Programmiersprache C ++ verwendet. Aus diesem Grund sollten einige Teile des Codes mit externen "C" -Bindungskonventionen beschichtet werden, damit beim Verknüpfen keine Probleme mit der Zeichenauflösung auftreten. Auch anstelle vonneu um den Bediener zu verwenden neu (die std :: nothrow) , die Lage sein , den zugewiesenen Speicher für ein NULL zu überprüfen, anstatt die Ausnahmen der Freigabe , dass SDL2, natürlich, nicht unterstützt.

Der Rest war nichts kompliziertes. Wir schreiben verschiedene Funktionen, die SDL2-Entitäten und -Darstellungen so konvertieren, dass sie mit der Haiku-API kompatibel sind, und überprüfen, ob sie ordnungsgemäß funktionieren. Für verschiedene Prüfungen habe ich den kleinen Test erweitert., die ich regelmäßig auf verschiedenen Betriebssystemen ausführte, analysierte die Ergebnisse und bewertete meine Arbeit. Am Ende war ich so begeistert, dass ich sogar die Anpassung unterstützte, z. B. das Festlegen verschiedener Farben für die Schaltflächen und den Hintergrund des Dialogfelds. Dies wird in der SDL2-Bibliotheks-API unterstützt, aber ursprünglich hatte ich nicht vor, solche Dinge zu implementieren.

Wenn der Programmierer beschließt, eine sehr, sehr lange Zeile in diesen Dialog zu spucken, muss das BTextView- Klassenobjekt , das im BAlert- Klassenobjekt verwendet wird , die SetWordWrap () -Methode mit dem Argument true aufrufeneinen solchen Programmierer in seine Arme zu schlagen und den Dialog auf den Bildschirm zu bringen. Es scheint, dass es nichts Einfacheres gibt: Wir überprüfen die Länge des Strings mit der Funktion strlen () und tun das Richtige. Das einzige Problem ist, dass SDL2 auch mit UTF-8 funktioniert. Dies bedeutet, dass die Funktion strlen () die Anzahl der Bytes und nicht die Anzahl der Zeichen zurückgibt . Die Haiku-API und die BString- Zeichenfolgenklasse helfen mit der CountChars () -Methode , mit der Sie die Länge der Zeichenfolge in Zeichen und nicht in Bytes ermitteln können:

 bool CheckLongLines(const char *aMessage) { int final = 0; // This UTF-8 friendly. PS G_MAX_STRING_LENGTH = 120 BString message = aMessage; int32 length = message.CountChars(); for (int i = 0, c = 0; i < length; ++i) { c++; if (*(message.CharAt(i)) == '\n') { c = 0; } if (c > final) { final = c; } } return (final > G_MAX_STRING_LENGTH); } 

Diese Funktion überprüft den Nachrichtentext auf Zeilen mit mehr als 120 Zeichen und gibt, falls vorhanden, true zurück. In Bezug auf UTF-8 gab es immer noch einen solchen Moment, dass in einigen Haiku-Systemschriftarten chinesische Schriftzeichen nicht unterstützt werden. Daher können Sie beispielsweise keine chinesische Inschrift im Fenstertitel festlegen. Der Text in russischer Sprache wird jedoch problemlos installiert.

Bei der Vorbereitung des Pakets ist ein Erstellungsfehler für die x86_gcc2-Architektur aufgetreten, der im Rezept der SDL2-Bibliothek aktiviert ist. Es stellte sich heraus, dass der älteste GCC 2.95-Compiler nicht erraten konnte, dass der kommentierte Code dem folgenden entspricht:

 rgb_color ConvertColorType(const SDL_MessageBoxColor *aColor) const { // return { aColor->r, aColor->g, aColor->b, 255 }; rgb_color color = { aColor->r, aColor->g, aColor->b, color.alpha = 255 }; return color; } 

Daher musste ich dieses Fragment im alten Stil umschreiben und trotzdem die Initialisierung einiger Konstanten in der Klasse direkt in ihren Deklarationen entfernen, der alte Compiler mochte dies auch nicht.

Ich habe Patches für die Implementierung von SDL2-Dialogen an das HaikuPorts-Repository gesendet, damit die Xash3D- und Serious Engine-Engines jetzt alle Informationen korrekt an den Benutzer ausgeben können, z. B. über Fehler. Ich habe die SDL2-Entwickler noch nicht kontaktiert, aber es wäre schön, alle Patches aus dem HaikuPorts-Repository in die vorgelagerte SDL2-Bibliothek zu übertragen. Obwohl die Portierung unserer Patches aufgrund der kürzlich erfolgten Umbenennung der Funktionspräfixe von BE_ * in HAIKU_ * etwas komplizierter geworden ist, ist dies kein so ernstes Problem.

<< Zum Inhalt springen

10. Portieren Sie meine Gabel von Cool Reader


Ich habe lange Zeit eine Abzweigung des Cool Reader- Programms entwickelt , die von Vadim Lopatin ( Buggins ) geschrieben wurde. Der entsprechende Artikel dazu ist auf meiner Website verfügbar. In den Kommentaren zu diesem Artikel melden sich Leser meines Blogs ständig ab, die entweder eine neue Funktion in ihrer Lieblingsanwendung zum Lesen elektronischer Bücher sehen oder Fehler und Mängel in den bereits implementierten Programmfunktionen beheben möchten.


Meine Gabel von Cool Reader läuft auf Haiku.

Im HaikuPorts-Repository habe ich ein Rezept zum Erstellen des ursprünglichen Cool Reader-Programms gefunden. Aufgrund einiger ständiger Änderungen an der SourceForge- Ressource erwies sich dieses Rezept jedoch als nicht funktionsfähig, da der Quellcode der Anwendung nicht mehr zum Herunterladen verfügbar war. Dann habe ich beschlossen, meine Gabel als neue Version von Cool Reader in das HaikuPorts-Repository zu übertragen. Ich habe alle Gerasim-Patches in den Code eingefügt, einige Mängel im Rezept behoben und darauf basierend ein neues Paket erstellt, das bereits allen Haiku-Benutzern zur Verfügung steht. Den Quellcode für meine Cool Reader-Gabel finden Sie in diesem GitHub-Repository:

Projektquellcode: https://github.com/EXLMOTODEV/coolreader

Das einzige Problem, auf das ich stieß, waren die Ungenauigkeiten bei der Übertragung von Gerasims Patches. Zusätzlich zur __HAIKU__- Definition wurde an einer anderen Stelle im Build-System auch die _LINUX- Definition festgelegt, und da in den meisten Fällen die letzte in der Quellcodeliste die erste war, ließ mich die bedingte Kompilierung im Stich . In Übereinstimmung mit den Präprozessor-Prioritätsregeln wurden für Haiku genau die Codeteile kompiliert, die von der _LINUX- Definition umrahmt wurden , obwohl ich etwas völlig anderes brauchte. Trotzdem startete und funktionierte das Programm, speicherte seine Einstellungen jedoch nur dort, wo es benötigt wurde. Ich habe die Prioritäten richtig gesetzt, das Paket neu erstellt und das Problem wurde vollständig behoben.

<< Zum Inhalt springen

11. Fertigstellung des KeymapSwitcher-Programms


In letzter Zeit haben viele gängige Betriebssysteme auf eine neue Tastenkombination Meta / Opt / Cmd / Win + Space umgestellt , um das Tastaturlayout zu wechseln. Es schien mir sehr praktisch, dass ich jetzt nichts mehr ändern und konfigurieren muss. Sie setzen sich an jeden Computer, auf dem MacOS, Windows oder Linux mit der GNOME 3-Shell ausgeführt wird, und diese praktische Kombination aus Ändern der Eingabesprache funktioniert einfach überall. Auch das mobile Android-Betriebssystem hat sein Analogon. Im Allgemeinen habe ich vor langer Zeit zu dieser Tastenkombination gewechselt und mich sehr daran gewöhnt.

Zu meinem großen Bedauern, KeymapSwitcherMit Haiku konnte ich keine so bequeme Tastenkombination für das Wechseln von Layouts festlegen, weshalb ich mich bei der Arbeit mit Text in diesem Betriebssystem ständig unwohl fühlte. Aus diesem Grund habe ich beschlossen, diese Anwendung ein wenig zu ändern, und nach dem Quellcode gesucht. Es stellte sich heraus, dass dieses Programm, obwohl es in der Haiku-Distribution enthalten ist, separat vom Quellcode des Betriebssystems selbst bereitgestellt wird. Darüber hinaus ist die Anwendung im HaikuPorts-Repository verfügbar und wird auch über dieses aktualisiert. Wie mir mitgeteilt wurde, war KeymapSwitcher nicht in Haiku enthalten, da geplant ist, eine spezielle API zum Ändern von Tastaturlayouts zu implementieren, und eines Tages die Notwendigkeit für dieses Programm vollständig verschwinden wird.


KeymapSwitcher auf Haiku mit einer beliebten Tastenkombination zum Wechseln des Tastaturlayouts.

Trotz der Tatsache, dass ich Angst vor der Komplexität des KeymapSwitcher-Codes hatte, fand ich dank der Kommentare schnell den richtigen Ort und führte einen kleinen Patch in den Programmcode ein, der das Schreiben von Texten in Haiku erheblich erleichterte. Der einzige kleine Fehler, den ich nicht überwinden konnte, ist, dass der Opt- Schlüssel losgelassen werden muss, um die Sprache zu wechseln. Halten Sie also Optund ein Leerzeichen zum Umschalten zwischen den ausgewählten Sprachen funktioniert nicht. Dies beeinträchtigt jedoch absolut nicht die Sprachumschaltung während der Eingabe. Daher habe ich den Patch an das Programm-Repository gesendet und das Anwendungspaket in HaikuPorts aktualisiert. Danach wurde die neue Version von KeymapSwitcher für alle Haiku-Benutzer zur Installation verfügbar.

Projektquellcode: https://github.com/HaikuArchives/KeymapSwitcher

Ich hoffe, ich bin nicht der einzige Benutzer dieser Tastenkombination, der Tastaturlayouts wechselt.

<< Zum Inhalt springen

12. Schlussfolgerung


Das Studium der Haiku-API sowie das Lösen verschiedener exotischer Probleme, die durch das Portieren neuer und das Aktualisieren vorhandener Anwendungen für dieses Betriebssystem entstanden sind, brachte mir viele wertvolle Erfahrungen und Freude. Ich konnte Haiku-Support-Patches im Quellcode-Repository einiger großer Projekte bewerben und traf neue interessante Leute, die irgendwie mit diesem schönen Betriebssystem verwandt waren.


Verschiedene Anwendungen, die auf dem Haiku-Betriebssystem ausgeführt werden.

Ich hoffe aufrichtig, dass in Zukunft alle heutigen Probleme, wie das Fehlen von 3D-Hardwarebeschleunigung und gängigen Browsern sowie die schlechte Unterstützung für moderne Hardware, erfolgreich gelöst werden und Haiku von Entwicklern und Anwendern, die seine einzigartigen Fähigkeiten und sein originelles Design schätzen werden, einen Nachwuchs erhalten wird . Glücklicherweise steht die Entwicklung noch lange nicht still und heute werden auf dem lokalen Forum dieses Betriebssystems heiße Themen zur 3D-Beschleunigung und Portierung der GTK + 3- Bibliothek angesprochen , und die Möglichkeit der Portierung der QtWebEngine- Komponente wird in den HaikuPorts-Repositories erörtert. Der GTK + 3-Port bietet möglicherweise die Möglichkeit, die beliebten Firefox- und Chromium-Browser zu starten und zu verwenden. QtWebEngine ermöglicht die Verwendung der Blink-Engine in modernen Browsern, die auf dem Qt-Framework wie Otter Browser oder Falkon basieren .

Bereits jetzt kann ich dieses Betriebssystem allen empfehlen, die beispielsweise alte und schwache Laptops oder Netbooks anstelle der Lubuntu- Distribution oder Windows XP haben. Sie werden erstaunt sein, wie schnell und reaktionsschnell es funktioniert. Ja, Sie müssen sich aufgrund alter Browser und einer Reihe von damit verbundenen Störungen ein wenig auf das Anzeigen einiger Websites beschränken. In den meisten Fällen ist diese Einschränkung bei alter Hardware jedoch nicht von Bedeutung.

Alle meine Ports und Verbesserungen wurden bereits veröffentlicht und stehen allen Haiku-Benutzern zur Installation zur Verfügung. Alle Änderungen am Quellcode sind in den jeweiligen Repositorys unter ihren ursprünglichen Lizenzen verfügbar. In dieser Arbeit habe ich eine große Menge an Materialien verwendet, von denen ich die wichtigsten in den nützlichen Links unten hervorheben werde. Vielen Dank an stackoverflow.com und google.com für ihre Anwesenheit .

1. Die offizielle Website des Haiku-Betriebssystems .
2. Das offizielle Forum des Haiku-Betriebssystems .
3. Offizielle Dokumentation für Haiku-Benutzer .
4. Offizielle Dokumentation für Haiku-Entwickler .
5. Beschreibung der Funktionen der grafischen Benutzeroberfläche von Haiku .
6. Empfehlungen zum Erstellen von Symbolen für Haiku-Anwendungen .
7. Beschreibung des Icon-O-Matic-Programms und Tipps zu seiner Verwendung .
8. Beschreibung des Formats der Vektor-HVIF-Symbole .
9. Die offizielle Dokumentation zum Interface Kit Framework .
10. Die offizielle Dokumentation für das Locale Kit-Framework .
11. Artikel zu Aspekten der Anwendungslokalisierung für Haiku .
12. Die offizielle Dokumentation für die Layout-API .
13. Eine Reihe von Artikeln, die die Implementierung der Layout-API in Haiku beschreiben .
14. GitHub-Repository des Quellcodes des Haiku-Betriebssystems .
15. GitHub-Repository des HaikuPorts-Rezeptbaums .
16. Die Internetversion des Repositorys der vorgefertigten HPKG-Pakete Haiku Depot Web .
17. Ein interessanter Artikel "Haiku: Lamp Geek-OS" im Blog des INSTEAD-Entwicklers Peter Kosykh .
18. Der Haiku: Immersion-Artikel auf INSTEADs Entwicklerblog Pyotr Kosykh .
19. Der Programmierkurs "Lernen, mit Haiku zu programmieren" von DarkWyrm .
20. Der Programmierunterricht "Programmieren mit Haiku" von DarkWyrm .
21. Veröffentlichung „Gibt es Leben auf Haiku?“ auf der Ressource Linux.org.ru, von mir .
22. Konferenz in Telegram IM, die der Diskussion des Haiku-Betriebssystems gewidmet ist .

Herzlichen Glückwunsch an alle Benutzer der Ressourcehabr Frohes Neues Jahr und wünsche ihnen frohe Weihnachten! Viel Glück euch im neuen Jahr 2019!

<< Zum Inhalt springen

Source: https://habr.com/ru/post/de434690/


All Articles