Dieses Forum nutzt Cookies
Dieses Forum nutzt Cookies um Anmeldeinformationen (keine Passwörter) zu speichern. Dabei werden diese Informationen als kleine Textdateien auf deinem Endgerät abgelegt. Sie können nur durch dieses Forum ausgelesen werden und stellen kein Sicherheitsrisiko dar. Neben deinem letzten Login wird auch abgespeichert, welche Themen du bereits gelesen hast.

Zudem wird ein Cookie angelegt, in dem abgespeichert wird, ob du diesen Hinweis gelesen hast. Damit wird er nicht jedes mal angezeigt.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
M4nfo - a macro library for generating nfo code for TTDPatch and OpenTTD newgrfs
Verfasser Nachricht
mb
Tycoon
*****

Beiträge: 5.054
Registriert seit: Mar 2005
Beitrag #2
RE: M4nfo - a macro library for generating nfo code for TTDPatch and OpenTTD newgrfs
--------- Fortsetzung -----------------------

Das Ganze ist im Prinzip lediglich eine Makro-Sammlung, die unter dem Makroprozessor "M4" lauffähig ist. Die Nutzung eines Makroprozessors mit naturgemäss eingeschränktem Funktionsumfang für einen solchen Zweck gilt gemeinhin als eine weniger elegante und zuverlässige Lösung als zB die Entwicklung einer dem Problem bestmöglich angepassten Speziallösung, am besten in einer weitverbreiteten und leistungsfähigen Hochsprache (zB C/C++), aber die technisch simplere Lösung erzwingt auch die Konzentration auf das Wesentliche. Ein Fakt der häufig übersehen wird.

Ein zentrales Problem bei einer Compilerlösung war zB immer die Umsetzung der nfo-Spritenummern in eine vom Compiler verwaltete Befehlskette. In meinem Ansatz habe ich davon ganz abgesehen (weil technisch nicht machbar) und die Definition und Referenzierung der .nfo Sprite-Nummern einfach manuell belassen. Dies hat durchaus Vorteile, denn der neue Code ist dadurch wesentlich lesbarer als wenn man zB eine Lisp-artige Schachtelung der Befehlsketten implementieren würde. Zudem ist die eigenständige Verwaltung (Neuvergabe, Wiederbenutzung) von Sprite-Nummern durch einen Compiler auch nicht gerade einfach zu implementieren und ohne explizite Sprite-Nummern würde man ein zusätzliches Debugging-Tool benötigen, etc ..., und eine Makro-Bibliothek ist leicht erweiterbar und veränderbar, im Gegensatz zu einem Compiler.


Die Definition von Sprite-Nummern (c-IDs) und ihre Referenzierung habe ich sinnvollerweise in zwei verschiedene Funktionen getrennt:

def(<n>) definiert eine Sprite-Nummer,
ref(<n>) referenziert eine Sprite-Nummer.

Die in nfo vorhandenen "properties" können nun ganz einfach durch einen Katalog von Funktionen abgebildet werden. Abgesehen von einer besseren Lesbarkeit des Codes kann man zusätzlich eine gewisse "Automatisierung" durch die Art und Weise ihrer Implementierung erreichen.

ZB sind in einem grossen Fahrzeugset Ketten aus "varaction2" mit schätzungsweise 90% der Codezeilen, bzw Spritenummern beteiligt. Kern einer varaction2 ist (in nfo Syntax) ein Konstrukt dass in etwa einem "C" switch/case Block entspricht.

Dies habe ich auch entsprechend so implementiert, nur dass eben das zentrale Konstrukt eines solchen Blocks, das neue "if" Statement, sehr flexibel implementiert ist und dadurch, wie oben beschrieben, dem Programmierer überflüssige Arbeit ersparen hilft.

Sehen wir uns dies einmal genauer an.

1. Syntax für varaction2

1.1 Das "if" Statement

if(<Ganzzahl Konstante> | <Bereich> | <Liste>)

Das "if" Statement vereinfacht den nfo "switch/case" Block.

ZB kann der nfo-Block

Code:
-1 * 0   00 02 00 81 40 00 03 03
    03 00 03 03
    02 00 02 02
    01 00 01 01
    00 00

nun einfach als

Code:
def(0)  vehpos(MOD4,
    ref(3) if(3)
    ref(2) if(2)
    ref(1) if(1)
    ref(0) else
)

geschrieben werden. Hier zeigt sich deutlich die Trennung zwischen der Referenz einer c-ID und der Auswertung der "property" auf dem die erfolgende Referenz beruht.

Die Idee lässt sich verbessern:

Aus

Code:
-1 * 0   00 02 00 81 10 00 FF 01
    62 80 01 03
    FF 80

wird

Code:
def(0) articulated(
    addveh(0x62) if(1 .. 3)
    ENDLIST else
)

Das "if" Statement kennt als Parameter auch einen Bereich, genauso wie nfo das auch implementiert. Hier sieht man ausserdem, dass sich recht einfach Konstanten per Textersatz lesbarer gestalten lassen, wie zB das "FF 80" am Ende einer Liste von artikulierten Teilfahrzeugen oder am Ende einer Liste von "text suffixes".

Das "if" ist aber noch nicht am Ende, es kennt auch Listen als Parameter:

Aus dem nfo-Block

Code:
-1 * 0   00 02 00 81 B9 00 FF 03
    FE 80 00 00
    FE 80 02 02
    FE 80 0A 0A
    20 80

wird

Code:
def(0) cargo(
    ATT_OK if(PASS, MAIL, VALU)
    ATT_VAN else
)

D.h. wenn verschiedenen Ergebniswerten ein und dieselbe Referenz zugeordnet werden soll, müssen diese Werte nicht einzeln aufgeführt werden wie zB hier:

Code:
def(0) cargo(
    ATT_OK if(PASS)
    ATT_OK if(MAIL)
    ATT_OK if(VALU)
    ATT_VAN else
)

sondern das "if" Statement ermöglicht eine kompaktere Notation als die einer 1:1 Abbildung auf die nfo. Auch hier sind die "ATT_*" übrigens wieder (frei vereinbare) Konstanten, die zB Referenzen oder Callback-Resultate sein können. Hier sind es Resultate für den callback 1D ("wagon attach"), die angeben ob ein bestimmtes Fahrzeug angehängt werden kann ("ATT_OK") oder nicht ("ATT_VAN": "Güterwagen kann nicht angehängt werden").

--------- Ende Teil 2 -----------------------

Gruß
Michael

Zitat:EU-Wirtschaft- und Währungskommissar Joaquin Almunia hat alle Besorgnisse über den Schuldnerstatus Griechenlands als unbegründet zurückgewiesen.
22.10.2009 22:11
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Nachrichten in diesem Thema
RE: M4nfo - a macro library for generating nfo code for TTDPatch and OpenTTD newgrfs - mb - 22.10.2009 22:11

Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
Hilfe Diverse Fragen zu OpenTTD, TTD und TTDPatch Steinborg 7 6.667 22.07.2013 18:26
Letzter Beitrag: Steinborg

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste