flowOfControl
extrazi edited this page Jul 1, 2023
·
17 revisions
EN PL |
Content |
Introduction |
Na przykład, rysunek po lewej stronie przedstawia łańcuch sterowania z jego różnorodnymi blokami funkcyjnymi (callback(), cargo(), getubits(), year(), yearbuilt() ) dla silnika wysokoprężnego DB Set V200. Jak widać, przepływ kontroli rozgałęzia się również wzdłuż łańcucha, wyświetlając "drzewo" ('do góry nogami'), z każdym jego liściem kończącym się "wynikiem wywołania zwrotnego" (cbr) lub 'real sprite' (grafika).
Funkcja | Opis |
---|---|
def( [,]) | Zdefiniuj odniesienie |
ref(<Byte> | <Label>) | Odniesienie do funkcji |
deflabel() | Zdefiniuj etykietę gałęzi |
placelabel() | Umieść etykietę 'gałęzi' |
getothergrfparameter(<target-param>, <grf-ID>, <grf-param> | VERSION) | Odczytaj parametr innego newGRF |
pcalc(<expression>) | Przypisz nowe parametry GRF i oblicz wyniki |
setparameter(, ) / setparameterbits(, ) | Ustaw wartość parametru / bity dla tego nowego GRF |
skip(<Byte>) | Bezwarunkowo pomiń tę liczbę sprite'ów |
skipif(, , , ) | Zmień przepływ kontroli |
getowngrfparameter() | Pobierz parametr dla tego newGRF |
patchvar() | Użyj flagi TTDPatch jako zmiennej dla skipif() |
reflabel() | Odniesienie do etykiety oddziału |
setbit() | Ustaw bit w parametrze |
Opis |
Prośba odnotowania, że referencje mogą być 'etykietowane', a nawet 'szablonowane' przez funkcje makr m4nfo.
Przykład (etykietowane referencje): def(0xB0, FP_RHEIN) callback( ref(6) if(CB_LOAD) // ilość załadunku ref(3) if(CB_RCAP) // pojemność ref(4) if(CB_TSFX) // text suffix ref(5) else // graphics ) ... // mail def(3) yearbuilt( ref(FP_RHEIN) if(1928 .. 1940) // Rheingold refit ref(FP_) else // generic ) |
Parametr tej funkcji, a także parametrów placelabel() i reflabel() jest ciągiem tekstowym, który można dowolnie wybrać. Jest wewnętrznie tłumaczony na unikalny identyfikator o rozmiarze bajtu, stąd tylko 255 różnych etykiet jest dozwolonych w nowym pliku GRF.
Używanie etykiet skoku to jedyny sposób na pominięcie więcej niż 255 'sprites' naraz. Parametr <num-skip> skipif() pozwala tylko na ustawienie 255 elementów.
W rzadkich przypadkach, gdy chcesz użyć etykiet skoku w rozproszonych plikach źródłowych, jest to możliwe w ograniczony sposób. Zobacz przykład w sekcji dotyczącej obsługi tekstu. Ta funkcja umieszcza etykietę rozgałęzienia w określonym miejscu w newGRF. Zobacz przykład poniżej . Ta funkcja odczytuje podany parametr innego newGRF i zapisuje go do podanego parametru docelowego. W przypadku podania VERSION jako innego parametru newGRF, zwracane jest version newGRF, podane w funkcji grfinit() . W przypadku, gdy numer wersji nie został ustawiony dla tego newGRF, zwracane jest 0 (tylko OpenTTD). Funkcja ta pozwala na ustawienie wartości parametrów newGRF (tj. Tych zwykle ustawianych jako opcje w pliku newgrf(w).cfg ), a także na wykonywanie na nich operacji matematycznych. </p>
Format |
pcalc(<target> := <source1> [<operator> <source2>]) |
<target> - parametr docelowy
<operator> - obliczenia do wykonania
<source1> - pierwszy argument
<source2> - drugi argument
Opis |
Operator | Operacja | Wynik |
---|---|---|
:= | Przypisanie | target := source1 |
+ | Dodanie | target := source1 + source2 |
- | Odejmowanie | target := source1 - source2 |
* | Mnożenie bez znaku | target := source1 * source2 |
S* | Mnożenie 'ze znakiem' | |
<< | Przesunięcie bitu 'bez znaku' | target := source1 << source2 if source2>0, or target = source1 >> abs(source2) if source2 < 0. source1 jest uważane za bez znaku |
S<< | Przesunięcie bitu ze znakiem | tak samo jak 05, ale source1 jest uważane za 'ze znakiem |
AND | Bitowo AND | target := source1 AND source2 |
NOT | Bitowo NOT | target := NOT source1 |
OR | Bitowo OR | target := source1 OR source2 |
/ | Dzielenie bez znaku | target := source1 / source2 |
S/ | Signed division | |
MOD | Unsigned modulo | target := source1 % source2 |
SMOD | Signed modulo |
Notes |
Jeśli na przykład parametr(0) i parametr(1) są ustawione w pliku newgrf(w).cfg, a pcalc() ustawia parametr(4), to parametr(2) i parametr(3) zostaną automatycznie zdefiniowane i uzyskać wartość zero.
Przykłady |
Przykład: ustawienie parametrów, które mają być używane w obliczeniach linii śniegu:
define(SLOW,2) // min snowline define(SHI,8) // max snowline// define named parameters define(max_height, param(0))
define(min_height, param(1))
define(diff, param(2)) define(step, param(3))pcalc(min_height := eval(SLOW * 8)) // snowline is multiple of 8 pcalc(max_height := eval(SHI * 8)) // ditto pcalc(diff := max_height - min_height) pcalc(step := diff / 12) ... |
Przykład: ustawianie i odczytywanie bitów parametrów: skipif(6,CLIMATE,==,TEMPERATE) // skip if temperate // not temp, now check for AlpineClimate active? skipif(2,GRFACTIVE,+,GRF_ALPINESET) // not temp, check for AlpineClimate inactive but will be activated? skipif(1,GRFACTIVE,-+,GRF_ALPINESET) skip(EXIT) // neither temp nor alpineclimate setparameterbits(2,_ALPINE) // mark it skipif(1,getowngrfparameter(2),BITSET,_ALPINE)skip(EXIT) // Parameter not set ... skipif(1,getowngrfparameter(2),BITSET,_ALPINE)definevehicle(_SELF2, {""}, cargotype(COAL) ) |
Parametry są następujące:
Parametr | Opis |
---|---|
<num-skip> | Liczba elementów do pominięcia |
<variable> | Na której zmiennej należy podjąć decyzję |
<condition> | Jaki stan sprawdzić |
<value> | Wartość do porównania |
<mask> | Maska bitowa używana podczas porównywania wartości |
Jeśli <condition> ma wartość false, przetwarzanie jest kontynuowane w następnym elemencie.
Począwszy od TTDPatch 2.0.1 alpha 49, można przeskoczyć do określonej pozycji w pliku newGRF poprzez zdefiniowanie "etykiet" za pomocą funkcji deflabel() . Jeśli parametr <num-skip> jest ustawiony na etykietę przez funkcję reflabel() , znajdującą się gdzieś w pliku newGRF, to przetwarzanie pliku newGRF zostaje wznowione z elementem następującym po tej etykiecie, zamiast pomijania tylu elementów. Tylko w ten sposób można pominąć więcej niż 255 elementów naraz.
Od wersji 2.0.1 alfa 70 zduplikowane etykiety są w pełni obsługiwane. Skok będzie zawsze do pierwszej pasującej etykiety, która następuje. Jeśli nie nastąpi żadna pasująca etykieta, zamiast niej zostanie użyta pierwsza pasująca etykieta w pliku newGRF.
Note: Zwykle nie jest bezpieczne przeskakiwanie do tyłu, tj. Do wcześniejszej pozycji w pliku newGRF. Chociaż TTDPatch z radością to zrobi, otrzymasz dziwne wyniki, jeśli pewne funkcje zostaną powtórzone przez taki skok. |
Zmienna | Opis |
---|---|
CLIMATE | Obecny klimat |
WINDOS | TTD version, "DOS" lub "WIN" |
PLATFORM | TTDPatch ("TTDPATCH") lub OpenTTD ("OTTD") |
TTDPATCHVERSION | TTDPatch version |
OTTDVERSION | OpenTTD version |
FLAGS | flagi TTDPatch (lub TTDPatchFlags) |
MULTIHEAD | |
STARTYEAR | |
NEWTRAINS | |
NEWRVS | |
NEWSHIPS | |
SIGNALSONTRAFFICSIDE | |
ELECTRIFIEDRAILWAY | |
BUILDONSLOPES | |
NEWSTATIONS | |
BUILDONCOASTS | |
CANALS | |
FREIGHTTRAINS | |
NEWHOUSES | |
SPEEDLIMIT | |
PBSIGNALLING | |
NEWINDUSTRIES | |
TEMPSNOWLINE | |
NEWCARGOS | |
NEWSOUNDS | |
TRAMS | |
SHORTRVS | |
ARTICULATEDRVS | |
DYNAMIC | |
VARRUNNINGCOST | |
GRFACTIVE | Sprawdza, czy nowyGRF-ID jest aktywny, czy nie |
CARGO | Sprawdza, czy typy ładunku jest dostępny, czy nie |
RAILTYPE | Sprawdza, czy typ szyny jest dostępny, czy nie |
'Warunek' | Opis |
---|---|
BITSET | Sprawdź bit podany przez ustawianą wartość |
BITCLR | Sprawdź, czy bit podany przez wartość jest czysty |
== | Parametr jest równy wartości |
!= | Parametr nie jest równy wartości |
< | Parametr jest mniejszy niż wartość |
> | Parametr jest większy niż wartość |
+ | GRF-ID jest aktywny (tylko dla zmiennej GRFACTIVE) |
- | GRF-ID nie jest aktywny (tylko dla zmiennej GRFACTIVE) |
-+ | GRF-ID nie jest jeszcze aktywny, ale zostanie aktywowany (tylko dla zmiennej GRFACTIVE) |
++ | GRF-ID jest lub będzie aktywne (tylko dla zmiennej GRFACTIVE) |
-- | GRF-ID nie jest i nie będzie aktywne (tylko dla zmiennej GRFACTIVE) |
+ | Typ ładunku jest dostępny (zmienna jest ignorowana; wartością jest etykieta) |
- | Typ ładunku jest niedostępny (zmienna jest ignorowana; wartością jest etykieta) |
+ | Zdefiniowano etykietę typu szyny (zmienna jest ignorowana; wartością jest etykieta)* |
- | Etykieta typu szyny nie jest zdefiniowana (zmienna jest ignorowana; wartością jest etykieta)* |
- Dostępne tylko w OpenTTD
W przypadku testów bitowych (BITSET, BITCLR) zawsze musi to być pojedynczy bajt z zakresu 0 .. 7, określający bit do przetestowania.
Na potrzeby testowania dostępności typów ładunku i kolei wartość musi określać etykietę ładunku / rodzaju kolei. Aby to zadziałało, etykieta musi być "zacytowana" w ten sposób: {WATER} , w przeciwnym razie byłaby traktowana jako indeks tabeli tłumaczeń.
Jeśli w przypadku warunku "+" nie jest zdefiniowany ładunek ani typ szyny z tą etykietą, podana liczba elementów jest pomijana. Dla warunku "-", elementy są pomijane, jeśli została zdefiniowana etykieta typu ładunku lub szyny. Oba testy działają niezależnie od kolejności plików newGRF w newgrf(w).cfg; ładunek jest uważany za dostępny, nawet jeśli jest zdefiniowany w późniejszym pliku newGRF. Aby to działało poprawnie, nie wolno pomijać definicji ładunku z warunkami "+" lub "-". To samo dotyczy typów szyn.
Od TTDPatch r1384 możliwe jest użycie maski bitowej, nadanej przez dodatkowy parametr, podczas dostępu do zmiennej. Jest to przydatne podczas sprawdzania szeregu nowych identyfikatorów GRF. Należy pamiętać, że parametr podany jako maska musi być uporządkowany w taki sam sposób, jak podana wartość, patrz przykłady.
Przykłady |
Parametr | Opis |
---|---|
skip(5) | pomiń 5 |
skip(EXIT) | Zakończ nowy plik GRF |
skipif(1, FLAGS, BITSET, NEWTRAINS) | pomiń 1, jeśli ustawiony jest bit dla „nowych pociągów” |
skipif(1, patchvar(MULTIHEAD), ==, 0) | pomiń 1, jeśli TTDPatch var "multihead" jest ustawione na zero |
skipif(6, CLIMATE, ==, TEMPERATE) | pomiń 6, jeśli aktywny jest klimat umiarkowany |
skipif(1, TTDPATCHVERSION, >, 2359) | pomiń 1, jeśli wersja TTDPatch jest wyższa niż r2359 |
skipif(1, OTTDVERSION, <, 0x14080000) | pomiń 1, jeśli wersja OpenTTD jest niższa niż stabilna 1.4.0 |
skipif(reflabel(noDBrails), PLATFORM, ==, TTDPATCH) | pomiń do etykiety "noDBrails", jeśli TTDPatch |
skipif(2, GRFACTIVE, +, GRF_ALPINESET) | pomiń 2, jeśli AlpineSet jest aktywny |
skipif(2, GRFACTIVE, +, 6d 62 04 00, FF FF 00 00) | pomiń 2, jeśli jakikolwiek newGRF z ID "6d 62 xx xx" jest aktywny |
skipif(1, GRFACTIVE, -+, GRF_ALPINESET) | pomiń 1, jeśli AlpineSet jest nieaktywny, ale zostanie aktywowany później |
skipif(1, getowngrfparameter(0), BITSET, _ALPINE) | pomiń 1, jeśli ustawiony jest specjalny bit w newGRF parametr 0 |
skipif(reflabel(noDBrails), getowngrfparameter(1), BITCLR, _DBRAILS) | pomiń do etykiety "noDBrails", jeśli specjalny bit ("_DBRAILS") w newGRF parametr 1 nie jest ustawiony |
skipif(reflabel(WINJMP), WINDOS, ==, WIN) | pomiń do etykiety WINJMP, jeśli gra działa w systemie Windows (nie DOS) |
skipif(33, CARGO, -, {BRCK}) | pomiń 33, jeśli typ ładunku "BRCK" jest nieznany |
skipif(EXIT, TRAFFICSIDE, ==, LEFT) | wznowić nowyGRF, jeśli "jazda po stronie ruchu" jest ustawiona na "lewo" |
Przykład: obsługa etykiet skoku: |
deflabel(noDBrails) // not for TTDPatch! skipif(reflabel(noDBrails),PLATFORM,==,TTDPATCH) skipif(2,GRFACTIVE,+,GRF_DBRAILS) skipif(1,GRFACTIVE,-+,GRF_DBRAILS) skip(reflabel(noDBrails)) // no DBrails skipif(reflabel(noDBrails),getowngrfparameter(0),BITSET,_DBRAILS) // parameter set to "no DBrails" // branch line setproperties(_BR92 .. _BR38, tracktype(SABN) ) ... setproperties(_BR111, tracktype(SACE) ) placelabel(noDBrails)
Te funkcje pomocnicze są używane w kontekście funkcji skipif () do oceny niektórych jej parametrów. Powinny być używane tylko w tym kontekście.
Ta funkcja uzyskuje dostęp do podanego parametru newGRF i udostępnia go jako drugi parametr funkcji skipif() . Zobacz przykład powyżej .
Ta funkcja pobiera flagę TTDPatch ( lub link TTDPatchFlags ) i udostępnia ją do użycia przez skipif(). Zobacz tabelę powyżej dla użytecznych flag TTDPatch.
Ta funkcja odwołuje się do wstępnie zdefiniowanej etykiety. Musi być użyty jako pierwszy parametr w funkcji skipif().
Ta funkcja ustawia określony bit w danym parametrze swojej funkcji nadrzędnej. Musi być używany jako drugi parametr w funkcji setparameter() .