ARTIKEL 5- Compilieren auf anderen Plattformen/Compilern
( Teil II )
von HypoThermia
Wenn du der Anleitung im ersten Teil dieses Artikels gefolgt bist, sollten die Q3Sourcen jetzt
ordentlich auf der Virtual Machine laufen. Dieser Teil des Artikel erläutert, wie du den Code auf
deiner Plattform zu Binaries compilierst.
Ich gehe davon aus, das du alle bisher nötigen Änderungen am Code in einem Extraverzeichnis unterhalb
von \Quake3\source vorgenommen hast.
1. Die Binaries compilieren
Die Möglichkeit, Bytecode für die QVM zu compilieren, ist die minimale Voraussetzung,
um vernünftig arbeiten
zu können. Um dir die Arbeit aber um einiges zu erleichtern, solltest du es
dir ermöglichen, Binaries aus den
Q3Sourcen zu compilieren.
Wie du das anstellst ist stark Compiler- und Plattformabhängig. Für Kommandozeilen
Tools solltest du Makefiles bereitstellen, die die Beziehung zwischen den
Q3Sourcen und den compilierten Binaries definieren. Falls deine
Plattform eine graphische Entwicklungsumgebung bietet, wäre eine Projektdatei
wünschenswert.
1.1 Projektdateien
Die Projektdatei sollte sich als einzige ausserhalb deines Compilerverzeichnisses befinden. Genau wie das
Microsoft Visual C++ Projekt sollte sich auch deines in \Quake3\source befinden. Wenn es ein Makefile ist,
sollte sein Name auch darauf hinweisen (z.B. makefile.gcc.linux).
Der Aufwand, den du in das Verständnis der Header investiert hast, sollte sich
nun auszahlen. Falls du irgendwelche Änderungen an den Sourcen vornehmen musstest,
sollten sie keine Fehlermeldungen erzeugen. Versuche wieder, bereits definierte
Konstanten (deiner Plattform) in den Q3Sourcen zu nutzen, um den Code zum laufen
zu bringen.
Du wirst es nicht vermeiden können, dich intensiv mit den Tools deines Compilers vertraut zu machen.
Beachte, dass einige der Dateien aus source\game auch beim Erstellen von
cgame und ui eingebunden werden.
Es wäre ausserdem von Vorteil, auch jede von deinem Compiler erzeugte Zwischendatei in deinem Compilerordner
zu haben.
Beispiel:
Die Borland Tools nutzen eine Integrierte Entwicklungsumgebung (IDE). Jedes der drei Module muss zu einer
Win32 DLL compiliert werden.
Microsoft nutzt WIN32 um Compilierung für Win32 anzuzeigen. Die Q3Sourcen-Header reagieren darauf, also muss
es definiert werden.
Die Borland IDE erlaubt es, solche Variablen als Teil des Projektes zu definieren, ohne Änderungen an den
Q3Sourcen vornehmen zu müssen. Das entspricht in etwa den -Dxxxx, die du an lcc.exe übergeben hast.
Die Borland Compiler setzen einen Unterstrich vor exportierte Funktionen. Das verträgt sich aber nicht mit
Microsofts Namensgebung, also müssen alle exportierten Definitionen in den *.def Dateien folgendermassen verändert
werden:
[EXPORTS]
vmMain=_vmMain
dllEntry=_dllEntry |
Noch einmal, diese Dateien (für jedes Binary eine) gehören in den compilerspezifischen
Ordner.
1.2 C_ONLY im Projekt verwenden
Es wird höchstwahrscheinlich nötig sein, folgende Definition für jedes Binary
in das Projekt einzufügen:
#define C_ONLY
id hat einige Intel-optimierte Assemblerroutinen für die Performancekritischen
Bereiche geschrieben. Falls sich diese nicht compilieren lassen, definiere
diese Konstante.
1.3 Konstanten definieren
Wenn sich die Q3Sourcen bereits mit einem anderen Compiler auf deiner Plattform
compilieren lassen, ist es sicher hilfreich, einige oder alle der von diesem
Compiler benutzten Konstanten zu definieren. Deine Änderungen können
dann darauf aufbauen.
1.4 system calls in die quake3.exe handhaben
WICHTIG: Eine entscheidende Compiler Option der Wintel Version ist "Datenstrukturen werden an 4-Byte Grenzen
ausgerichtet". Ohne diese Option wird sich der Code unregelmässig und unvorhergesehen verhalten.
Die drei von dir erstellten Binaries entsprechen den drei Bytecode Dateien für die QVM. Auf der Wintel Plattform
heissen sie qagamex86.dll, cgamex86.dll, and uix86.dll.
Für jede von ihnen muss eine Datei namens xx_syscalls.c eingebunden sein. Sie ermöglicht es dem Binary, auf stark
optimierten Code innerhalb der quake3.exe zuzugreifen. Stelle sicher, dass QDECL definiert ist, damit die
Schnittstelle zwischen dem Binary und der exe besteht. Die Definition von QDECL befindet sich in game\q_shared.h.
Falls das schief geht, wird das Spiel abstürzen.
Die Funktion dllEntry() nimmt die callback-Funktion in der quake.exe entgegen. Verwechsle sie nicht mit der
Namensverwandten Funktion aus den Win32 DLLs, DllEntryPoint().
1.5 Versichere dich, dass Quake3 deine Binaries nutzen kann
Nur zwei Funktionen müssen für quake3.exe Sichtbar sein: vmMain() und dllEntry().
Prüfe, ob sie so von den
Binaries exportiert werden, dass Quake3 sie sehen kann.
1.6 Nur zu Entwicklungszwecken
Erstelle den Server, Client und UI-Code nur zum Debuggen und testen. Veröffentlichen solltest du nur .qvm's.
2. Modifikationen
Du wirst bemerken, dass die Q3Sourcen beim Compilieren einige Warnung produzieren. Schau dir an, ob sie
unzusammenhängend sind. Normalerweise sollten sie das.
Da sich die Q3Sourcen bereits zu Bytecode compilieren liessen, sollten keine grossen Probleme auftauchen.
Achte bei notwendigen Codeänderungen auf Portabilität.
Falls sich plattformspezifischer Code nicht vermeiden lässt, schreibe ihn in eine eigene Datei in dem
Compilerverzeichnis.
3. Erwartete Fehler
Einige Compiler interpretieren den C Standard strikter als andere. Falls möglich solltest du feststellen, ob sich
dein Compiler in der erwarteten Weise verhält.
3.1 Einige Warnungen in den Q3Sourcen
id Software hat einige Programmierstile verwendet, die Warnungen auslösen können. Manche können ignoriert
werden, andere solltest du überprüfen.
Fehler wie "Variable wird in Funktion xyz deklariert, aber nicht benutzt" kannst du ruhig ignorieren.
Andererseits solltest du Fehlern wie "bei Konvertierung von x nach y können Informationen verloren gehen"
auf den Zahn fühlen.
Eine weitere Warnung, die auftauchen könnte ist "mögliche fehlerhafte Zuweisung". Sie wird z.B. von
folgendem Code erzeugt:
for( j = 0; control = controls[j]; j++ )
Irgendwo im Feld controls[] ist ein Element 0, das wird durch die vorherige Nutzung des Feldes garantiert.
Die Zuweisung fungiert gleichzeitig als Schleifenbedingung. Sobald das ersten Element den Wert 0 hat, wird
die Schleife abgebrochen. Man könnte es auch so schreiben:
for( j = 0; (control = controls[j])==0; j++ )
Du kannst auch diese Warnung ignorieren.
3.2 Prüfe deine Implementierung der math Bibliothek
Abhängig davon, wie deine math Bibliothek implementiert ist, wirst du sqrt:DOMAIN Fehler erhalten, wenn du
cgame compilierst.
Das resultiert scheinbar aus einem Fehler in der Quake3.exe (v1.15c), der bewirkt, dass in den Q3Sourcen
ein zu {0,0,0} senkrechter Vektor gesucht wird.
Die Behebung des Fehlers ist compilerabhängig. Du musst einen Weg finden, ihn
abzufangen und zu ignorieren: sieh dir die Hilfedateien deines Compilers und
seiner math Bibliothek an. Du solltest deine Lösung in den
compilerabhängigen Dateien platzieren.
Der Bug offenbart sich beim Abspielen der demo001.dm3 mit "timedemo 1".
Beispiel: Mit der Borland math Implementierung entsteht dieser Fehler. Die Lösung ist einfach, diese Datei
beim Erstellen von cgame mit "include" einzubinden.
// borland_hack.c
#include
int _RTLENTRY _EXPFUNC _matherr(struct exception* e)
{
e->retval=1.0;
return 1;
}
|
4. Die Binaries testen
Verschiebe die erzeugten Binaries in den Ordner der quake3.exe und starte quake3.
Um sicherzustellen das die Binaries getestet werden, setze sv_pure auf 0.
Besonders wichtig ist das Testen der demo001.dm3 mit "timedemo 1". Wenn du
einen sqrt:DOMAIN Fehler bekommst, musst du diesen Fehler deiner math Bibliothek
abfangen.
5. Veröffentlichen deines Projektes
Wenn du dein Werk zur Veröffentlichung vorbereitest, solltest du versuchen die Änderungen an den Q3Sourcen
so gering wie möglich zu halten. Es wird sicher nicht nötig sein das Schlachtermesser auszupacken und Unmengen
an Änderungen über die Sourcen zu verteilen.
5.1 Nutze ein Extraverzeichnis für deine Arbeit
Die Organisation der Änderungen wird erheblich leichter, wenn du dir unter
quake3\source ein eigenes Verzeichnis anlegst, um die zum Erstellen nötigen
Dateien zu speichern.
Dadurch wird es erstens für mehrere Compiler möglich, mit der selben Sourcenversion zu arbeiten. Und zweitens
bleiben die Verzeichnisse \game, \cgame und \ui sauber.
Die einzige Ausnahme bildet die Projektdatei, die du für Binaries auf deiner Plattform erstellt hast. Diese
gehört in quake3\source und sollte einen sinnvollen, beschreibenden Namen haben.
5.2 Dokumentiere deine Änderungen
Es ist besser, die verwendeten Änderungen zu dokumentieren, und on anderen
anwenden zu lassen, als veränderte
Sourcen zu veröffentlichen. Auf diese Weise können sie viel sauberer in bestehende
Projekte eingearbeitet werden.
Beispiel:
Öffne die Headerdatei game\q_shared.h, gehe zu Zeile 424, da sollte stehen:
float Q_crandom(int* seed);
füge folgendes direkt dahinter ein:
#ifdef __BORLANDC__
#ifdef random
#undef random
#endif
#endif
Du solltest auch in Erwägung ziehen, DIFF Dateien zu Veröffentlichen.
5.3 Stelle deine Arbeit ins Internet
Dadurch können auch andere von deiner harten Arbeit profitieren. Melde dich
bei Portalen, damit die gesamte Community von deiner Arbeit profitieren kann.
6. Glückwunsch !
Du hast die Q3Sourcen erfolgreich portiert.
Jetzt kannst du dich in die Sourcen graben, und deinen Mod entwickeln. Den Mod, auf den das Netz wartet !
<< zurück/back >>