Plug-in-Schnittstelle
Hinweis: Änderungen dieses Artikels wurden noch nicht ins Englische übersetzt!
OMSI-Version: 1.00 - 2.00, für OMSI 2 bitte letztes Kapitel beachten!
Inhaltsverzeichnis
Allgemeines Prinzip
Es besteht die Möglichkeit, für den OMSI Plugin-DLLs zu programmieren, welche Lese- und Schreibzugriff auf die Fahrzeugvariablen haben und Fahrzeug-Trigger auslösen können.
Jedes Plugin besteht aus einer Konfigurationsdatei mit der Dateiendung *.opl und einer zugehörigen DLL. Beide Dateien müssen im Verzeichnis "OMSI\plugins" liegen.
Beschreibung des Beispiels
In OMSI enthalten ist bereits ein Beispiel-Plugin enthalten. Um es zu aktivieren, muss die Datei "test.txt" im "<OMSI>\plugins"-Verzeichnis in "test.opl" umbenannt werden.
Funktionsumfang
Dieses Plugin hat drei Funktionen: Einen Tacho (analog und digital) ganz oben, einen Sollwertregler für den roten Heizungsregler (obwohl da falscherweise "Rollband-Sollwert" steht) und einen Türtaster "Button1" (der aber trotzdem nur funktioniert, wenn die Haltestellenbremse aktiv und die Elektrik an ist).
Aufbau der *.opl-Datei
To activate, rename this file to "test.opl" [dll] Test.dll [varlist] 2 Velocity cockpit_heizregler_temp [triggers] 1 bus_doorfront0
Die erste Zeile ist nur eine Kommentarzeile. Der [dll]-Befehl gibt den Dateinamen der zugehörigen DLL an.
Der [varlist]-Befehl beginnt mit der Anzahl der zu erwartenden (lokalen) Fahrzeugvariablen. Hierbei können auch User-Variablen eines bestimmten Busses angegeben werden. Wenn der tatsächlich gefahrene Bus dann diese Variable nicht hat, dann werden die zugehörigen Zugriffe natürlich nicht durchgeführt.
Die Variable mit dem Index 0 ist also bei dieser DLL "Velocity", die Variable mit dem Index 1 ist "cockpit_heizregler_temp".
Der [triggers]-Befehl beginnt ebenfalls mit der Anzahl der zu erwartenden Fahrzeugtrigger. In diesem Fall ist dies nur ein Trigger: "bus_doorfront0" mit dem Index 0.
Aufbau der DLL
Anhand der Beispiel-DLL wird nun erklärt, wie der zugehörige Delphi-Code aussehen soll. Im Allgemeinen sollte es möglich sein, auch mit anderen Programmiersprachen passende DLLs zu programmieren. Ausprobiert habe ich dies allerdings nicht.
Die DLL besteht aus zwei Units. Erklärt wird aber nur die Hauptunit (Test.dpr) (die zweite Unit enthält nur einige wenige nicht-relevante Implementierungen für die Form):
library Test; uses SysUtils, Dialogs, Classes, TestU in 'TestU.pas' {Form1}; {$R *.res} procedure Start( AOwner: TComponent ); stdcall; begin form1 := TForm1.Create( AOwner ); form1.Show; end; procedure Finalize; stdcall; begin form1.Free; end; procedure AccessVariable( varindex: word; var value: single; var write: boolean ); stdcall; begin case varindex of 0: begin form1.Label2.Caption := floattostrF( value, ffFixed, 5, 1 ) + ' km/h'; form1.Gauge1.Progress := round( value ); write := false; end; 1: begin value := form1.TrackBar1.Position / 30; write := true; end; end; end; procedure AccessTrigger( triggerindex: word; var active: boolean ); stdcall; begin case triggerindex of 0: begin active := form1.button1_pressed; end; end; end; exports AccessVariable, AccessTrigger, Start, Finalize; begin end.
Zunächst ist der letzte Abschnitt "exports" zu beachten: Die vier gelisteten Prozeduren sollen von der DLL angeboten werden: AccessVariable, AccessTrigger, Start und Finalize.
Die vier Prozeduren haben folgenden Aufbau:
Aufbau der Prozedur Start
Start( AOwner: TComponent ) wird am Anfang aufgerufen und ermöglicht es der DLL, sich zu initialisieren. In diesem Fall wird Form1 erzeugt und der gleichnamigen Variable zugeordnet, welche sich jedoch in der Unit TestU befindet. Als zweiter Schritt wird der Show-Befehl aufgerufen, um die Form1 anzuzeigen. Start übergibt den Parameter "AOwner", welcher der Handler des Hauptprogramms von OMSI darstellt.
Aufbau der Prozedur Finalize
Finalize dagegen wird beim Schließen aufgerufen. Hier wird schlicht das Objekt Form1 zerstört.
Aufbau der Prozedur AccessVariable
Im Betrieb ruft OMSI diese Prozedur für alle in der *.opl-Datei gelisteten lokalen Variablen auf. Sie übergibt dabei stets den Index der Variable (varindex). Die Prozedur kann nun ihrerseits die Variablen value und write schreiben.
Bei einem Lesezugriff kann die Prozedur wie im Beispiel unter "0:" die Variable über value einfach auslesen. Es ist aber wie unter "1" auch möglich, dem Wert von value einen neuen Wert zuzuweisen. Dann aber muss die Variable write auch auf wahr gesetzt werden, damit der Wert von OMSI übernommen wird. Im Beispiel wird die TrackBar ausgelesen und der Wert auf den Wert von value geschrieben.
Aufbau der Prozedur AccessTrigger
Diese Prozedur arbeitet recht ähnlich. Hier allerdings wird die Triggerliste durchgearbeitet. Die DLL kann bei Aufruf dieser Funktion den Wert active auf true setzen; dann löst OMSI den gewünschten Trigger aus.
Ausführliches Tutorial
Ein ausführliches Tutorial zur Nutzung dieser Schnittstelle - allerdings mit der Programmiersprache C++ - ist hier im Wiki in der Kategorie Tutorials zu finden.
Neuerungen OMSI2
Aus Gründen der Kompatibilität wurden die folgenden Prozedurnamen geändert:
Start ==> PluginStart sowie
Finalize ==> PluginFinalize.
Außerdem wurde die *.opl-Datei um die Schlüsselworte [stringvarlist] und [systemvarlist] ergänzt, mit denen nun auch auf String- und Systemvariablen zugegriffen werden kann. Deren Syntax entspricht der von [varlist]. Dementsprechend wurden folgende Methoden ergänzt:
AccessSystemVariable( varindex: word; var value: single; var write: boolean ); AccessStringVariable( varindex: word; str: PWideChar; var write: boolean );