Skip to content

basiConcepts

extrazi edited this page Jul 1, 2023 · 10 revisions
original    original
EN     PL
Introduction
Dla tych, którzy nie są zaznajomieni z Transport Tyoon, GRF lub standardowymi informacjami, przydatne może być krótkie wprowadzenie do terminologii:

Opis

Transport Tycoon's GRF files

Transport Tycoon (TTD) wykorzystuje tak zwane 'Pliki Zasobów Gry' , które są zbiorem 'sprite'ów', z których większość to prostokątne obiekty graficzne, które są wyświetlane na ekranie przez silnik gry. Przykładami są grafika pojazdu, kafle krajobrazu i prawie wszystko, co można zobaczyć na ekranie w grze. Te pliki GRF składają się po prostu z jednego sprite'a po drugim, aż do końca pliku bez dołączonych metainformacji. Istnieją jednak sprite'y, które nie przedstawiają grafiki do wyświetlenia, ale służą do innych celów, np. tak zwane 'sprite'y recolour' , które są odwzorowaniami sprite'ów graficznych 'recolouring' lub mapami wysokości TTD. Zobacz tutaj (lub ang. , format .GRF) szczegółowy format plików GRF.

TTDPatch's newGRF files

Pliki newGRF TTDPatch są bardziej wyrafinowane: w rzeczywistości są 'rozszerzeniami gier' dla TTD. W przeciwieństwie do oryginalnych plików TTD GRF, nowy format zawiera zarówno grafikę ('realne sprite'y'), jak robią to pliki TTD GRF, jak i kod programu nfo ('pseudo sprites'). Tak więc, używając newGRF, można zrobić wiele interesujących rzeczy:
  • dodawanie nowych pojazdów z nowatorskimi funkcjami i grafiką w zależności od zmiennych gry,
  • dodawanie nowych budynków i/lub gałęzi przemysłu z nowatorskimi funkcjami, takimi jak animacje graficzne i/lub właściwości i mechanika produkcji/obsługi ładunku,
  • dodawanie nowych stacji i/lub nowych rodzajów torów, w tym niestandardowych sygnałów i tuneli,
  • graficzne zamienniki kafli krajobrazowych, dróg, mostów, kanałów i/lub rzek,
  • dodawanie wszelkiego rodzaju 'nowych obiektów' , zarówno wodnych, jak i/lub lądowych,
  • modyfikacja cen i/lub kosztów,
  • etc, pp.
Podczas opracowywania TTDPatch, nowe specyfikacje GRF uległy dużym zmianom. Dlatego wersja GRF musi określać wersję specyfikacji, która ma być używana podczas kodowania nowego zestawu GRF. Oczywiście wersja GRF wpływa na funkcjonalność newGRF, ponieważ z czasem mogą wystąpić zmiany w zachowaniu różnych funkcji NewGRF. W przypadku TTDPatch aktualna wersja GRF to wersja 7, a dla OpenTTD najnowsza wersja GRF to wersja 8.

W m4nfo numer wersji GRF jest automatycznie określany w grf_init() funkcji zestawu. Ponieważ m4nfo r96, domyślną wersją GRF jest 8, tj. Podczas kodowania zestawu dla TTDPatch należy go ustawić na wersję 7, za pomocą funkcji setgrfversion() przed grfinit(). W przypadku rozproszonych plików źródłowych należy również użyć setgrfversion() w każdym pliku źródłowym, dla różnych wersji GRF niż wersja 8.

Język programowania 'pseudo sprite'ów' newGRF nazywa się nfo. Typowa instrukcja nfo jest zbudowana z kolejnego 'numeru sprite' , liczby określającej długość 'sprite' i samego pseudo 'sprite' , w tym etykiety dla bieżącej funkcji (lub feature ) i określonego numeru, 'c-ID' , używanego jako odniesienie cele. Ten pseudo 'sprite' jest podawany jako zwykły strumień bajtów, który wygląda bardziej czytelnie maszynowo niż przyjemnie dla ludzkiego oka.

Słownik nfo podzielony jest na tak zwane 'actions' , z których każda odpowiada za określone zadania, takie jak inicjalizacja obiektów (akcja0), deklaracja prawdziwych 'sprites' (akcja1), zarządzanie zestawami 'sprites' (akcja2), obsługa wariacji na podstawie zmiennych i parametry (varaction2), łączenie identyfikatorów cech z odpowiednimi łańcuchami wariacji i zestawami sprite (akcja3), administrowanie ciągami tekstowymi (akcja4), obsługa rozgałęzień (akcja7 i akcja9), obsługa błędów (akcjaB) itp., str.

Pełną specyfikację nfo można znaleźć tutaj . Jest to lektura obowiązkowa dla udanego kodowania newGRF przy użyciu zwykłego nfo i cenne źródło informacji dla pomyślnego kodowania newGRF przy użyciu m4nfo.

Zarówno w TTDPatch, jak i OpenTTD, wersja NFO definiuje format plików nfo, czyli wejście / wyjście GRFCodec i nforenum. Obecny numer wersji to 7. Ponieważ nowsze wersje OpenTTD obsługują grafikę 32bpp z wyraźnymi poziomami powiększenia, istnieje inna wersja NFO 32, która również obsługuje/wymaga nowego formatu pliku GRF (wersja kontenera 2.0).

W m4nfo obsługiwane są wszystkie wersje GRF i NFO.

m4nfo language structure

Głównymi cechami m4nfo są koncepcje ' bloków ' i ' łańcuchów ' . Obie są dziedziczone z nfo. 'Blok' w m4nfo odpowiada ocenie 'pseudosprite' nfo, a 'łańcuchowanie' (reprezentujące przepływ kontroli) przez nfo za pomocą tak zwanych 'c-ID' jest realizowane przy użyciu 'referencji' .

W przypadku, gdy funkcja m4nfo jest częścią 'łańcucha', musi zadeklarować odniesienie, aby stała się dostępna i zawierać jedno lub więcej odniesień, aby uzyskać dostęp do innych funkcji m4nfo. To znaczy.:
 def(<reference>, <m4nfo-function>({<parameter>},{<reference>}>)

Dla lepszej czytelności, w m4nfo początkowe odniesienie do funkcji jest wizualnie oddzielone od funkcji:

 def(<reference>) <m4nfo-function({<parameter>},{<reference>}>

Więc,

 Format (function chaining):
 
 def(<Byte>[, <Label>]) - defines a reference for a function
 ref(<Byte> | <Label>) - references a function

W poniższym przykładzie istnieją dwa łańcuchy kontroli, jeden jest podświetlony na niebiesko, a drugi na żółto. Niebieska łączy def(5) <- ref(5) <- def(6) <- ref(6) <- def(8) <- ref(8), a żółta łączy def(7) <- ref(7) <- def(8) <- ref(8).

Należy odnotować, że przepływ kontroli, zarówno w nfo, jak i m4nfo, jest zawsze 'do góry nogami' , tj. Jego źródłem (w tym przykładzie) jest funkcja makevehicle() , łącząca ID-pojazdu z powiązanymi ikonkami graficznymi za pomocą tego zilustrowanego 'łańcucha kontroli' . Potraktuj to jako drzewo 'odwrócone' , w którym liście muszą być zdefiniowane przed pniem.

W ten sposób w przypadku wywołania zwrotnego CB_POWR wykonywane są efekty steam w def(7) ('effect()' zwraca wynik callback), podczas gdy w gałęzi graphics w def (8) łańcuch punktów kontrolnych do def(6) i - poprzez gałąź 'else' - wskazuje na funkcję animacji (def(5)).

 Przykład (chaining):
 
 // graphics
 def(5) animation(
      ref(0) if(3) 
      ref(1) if(2)
      ref(2) if(1)
      ref(3) else
 )
 
 def(6) flipped(
 	ref(4) if(FORWARD) // offsets, animation and lights "forwards"
 	ref(5) else	   // offsets, animation and lights "backwards"
 )
 
 // effect
 def(7) flipped(
 	effect(steam(4)) if(FORWARD)
 	effect(steam(8)) else
 )
 
 // callbacks engine
 def(8) callback(
 	ref(7) if(CB_POWR)      // steam position
 	ref(LIGHTS) if(CB_RCOL) // switch lights
 	ref(6) else	        // graphics  
 )
 
 makevehicle(_030TRAMWAY,
 	link(ref(1),MENU)     // purchase menu
 	default(ref(8))       // locomotive
 	override(_MSP,ref(4)) // tramway coach
 )

Blok stanowi wewnętrzną część funkcji, chociaż technicznie rzecz biorąc jest jednym z parametrów funkcji (chociaż nie jest ograniczony do wartości liczbowej, ciągu tekstowego lub funkcji). Blok ( 'podświetlony' na żółto) zawiera jedną lub więcej funkcji if() i dokładnie jedną 'else':

 Przykład (block):
 def(20) veh_cargotype(
 	ref(1) if(FERT)	      // fertilizer (ECS)
 	ref(2) if(FMSP)	      // farm supplies (FIRS)
 	ref(3) if(CERE, GRAI) // cereals (ECS), grain
 	ref(4) if(IORE)	      // iron ore
 	ref(5) else
 )

Nie każda funkcja w m4nfo potrzebuje lub może używać bloku. Blok jest potrzebny tylko dla funkcji zwracających wartość, na podstawie której musi zostać podjęta decyzja, przez większość czasu powodując powiązanie z inną funkcją. Na przykład funkcje losowe lub spriteset nie mają bloku:

 Przykład (functions w/o a block):
 
 def(5) randomrel(LOAD,0,ref(1),ref(2),ref(3),ref(4))
 
 def(2) spriteset(move(1,23,25,27,5),load(1,23,25,27,5)) // blue

W rzeczywistości m4nfo używa całkiem różnych typów funkcji, które zostaną szczegółowo wyjaśnione, a mianowicie:

  • funkcje właściwości - do definiowania właściwości w różnych funkcjach określających cechy (np. w definevehicle() ),
  • funkcje układu - w celu zdefiniowania układu sprite'ów na podstawie ich grafiki, współrzędnych i informacji 3D, jak np. spriteset() powyżej,
  • funkcje wydajności - aby uzyskać szczegółowe informacje o danej funkcji (np. aktualna prędkość pociągu), a także uzyskać dostęp do zmiennych związanych z grą, takich jak aktualna data, klimat itp.
  • funkcje pomocnicze - z których korzystają te dwa poprzednie typy funkcji,
  • funkcje globalne - funkcje, które mogą być używane przez wiele funkcji, np. funkcje losowe,
  • funkcje ogólne - są niezależne od funkcji, np. obsługa błędów lub rozgałęzianie wewnątrz newGRF.

m4nfo Features

Pojęcie 'features' w m4nfo jest 'dziedziczone' z nfo (lub link action0 feature ), ponieważ całkiem dobrze pasuje do jego modułowego podejścia. Aby obsłużyć funkcję w m4nfo, należy załadować skojarzony z nią plik biblioteki M4, a odpowiednią funkcję należy wypowiedzieć, wywołując funkcję setfeature() z odpowiednim parametrem (patrz tabela poniżej).

Funkcje obecnie obsługiwane przez m4nfo to:

Feature keyword support module
trains _TRAIN   trains.m4
road vehicles _ROADVEHICLE roadvehs.m4
ships _SHIP ships.m4
stations _STATION stations.m4
canals _CANAL canals.m4
bridges _BRIDGE bridges.m4
houses _HOUSE houses.m4
global variables   header.m4
cargoes _CARGO cargos.m4
sound effects _SOUND
newobjects _OBJECT objects.m4
rail types _RAILTYPE railtypes.m4
aircraft _AIRCRAFT    
industry tiles _INDUSTRYTILE
industries _INDUSTRY
airports _AIRPORT  
signals _SIGNAL
airport tiles _AIRPORTTILE

Typy danych, stałe i funkcje używane wspólnie przez którąkolwiek z tych funkcji są zawarte w module 'header.m4' . Musi to być zawsze dołączone do modułu określonej funkcji:

 Przykład (ustawienie i używanie funkcji):
 
 // start of file
 include(names.m4) // local stuff
 
 setfeature(_TRAIN)
 
 ...
 
 definevehicle(...)
 
 ...
 
 makevehicle(...)

Odnotowując, że gdy używane "prekompilowanego" modułu, np. m4nfo_trains.m4 , nie musisz dołączać ani tego, ani nagłówka m4nfo, ani pliku funkcji, ale tylko "prywatne" pliki dołączane (np. names.m4 powyżej).

Structuring m4nfo source files

Introduction
W m4nfo, w przeciwieństwie do zwykłego nfo, nie jest możliwe mieszanie 'funkcji' w jednym i tym samym newGRF lub w jednym i tym samym pliku źródłowym. Pierwsze ograniczenie jest słabe, ale chociaż nie jest powszechnie akceptowane projektowanie nowych GRF-ów zawierających różne funkcje ze względu na kompatybilność, możesz to zrobić, zachowując każdą funkcję we własnym pliku źródłowym.

Jednak drugie ograniczenie jest trudne. Istnieje kilka przyczyn tego 'ograniczenia', z których najważniejsze to fakt, że m4nfo nie musi sprawdzać rzeczywistej funkcji dla każdej funkcji i nie musi sprawdzać poprawności funkcji dla określonej funkcji : moduły funkcji zawierają tylko funkcje, które są gwarantowane dla wstępnie ustawionej funkcji.

Zaleca się podzielenie dużego projektu na kilka plików źródłowych, aby ułatwić obsługę całego projektu. Na przykład w przypadku dużego zestawu pociągów te pliki mogą być:

  • plik 'ogólny' , odpowiedzialny za sprawdzanie takich rzeczy, jak wersja TTDPatch/OTTD, klimat lub różne flagi TTDPatch (np. newtrains ), w tym inicjalizacja newGRF, w tym specjalne grafiki, takie jak sprite void, set basecosts, tablice tracktype , translacja ładunku tabele , ciągi tekstowe dla przyrostków tekstowych ładunku, ciągi tekstowe dla komunikatów o błędach, ciągi dla tekstów pomocy lokomotywy i tabele zmiany koloru,
  • plik z definicjami dla wszystkich lokomotyw i wagonów,
  • plik zawierający grafikę i kod dla 'wagony pas.',
  • plik zawierający grafikę i kod dla lokomotyw
  • plik z definicjami dla wszystkich wagonów towarowych,
  • plik zawierający grafikę i kod dla wagonów towarowych,
  • plik z dodatkowymi udogodnieniami takimi jak bramki czy ... ,