Merge branch 'newgrf-property-mapping' into jgrpp
# Conflicts: # docs/newgrf-additions.html # src/newgrf.cpp
This commit is contained in:
@@ -25,7 +25,7 @@
|
|||||||
<p>See <a href="https://newgrf-specs.tt-wiki.net/wiki/Action14">Action 14 Specification</a> for background information.</p>
|
<p>See <a href="https://newgrf-specs.tt-wiki.net/wiki/Action14">Action 14 Specification</a> for background information.</p>
|
||||||
<h4>Feature Test: C "FTST"</h4>
|
<h4>Feature Test: C "FTST"</h4>
|
||||||
<p>Each FTST chunk (type C) describes an individual feature test.<br />
|
<p>Each FTST chunk (type C) describes an individual feature test.<br />
|
||||||
Sub-chunks with each FTST chunk may appear in any order, however each sub-chunk SHOULD only appear ONCE within an individual FTST chunk.</p>
|
Sub-chunks within each FTST chunk may appear in any order, however each sub-chunk SHOULD only appear ONCE within an individual FTST chunk.</p>
|
||||||
<p>Feature tests can be safely used on implementations which do not implement the described feature test mechanism because unknown Action 14 blocks are ignored,
|
<p>Feature tests can be safely used on implementations which do not implement the described feature test mechanism because unknown Action 14 blocks are ignored,
|
||||||
and the observable result (in global variable 0x9D) is equivalent to the case where all feature tests have failed, indicating that the feature is not present.</p>
|
and the observable result (in global variable 0x9D) is equivalent to the case where all feature tests have failed, indicating that the feature is not present.</p>
|
||||||
<h4>Feature Name: C "FTST" -> T "NAME"</h4>
|
<h4>Feature Name: C "FTST" -> T "NAME"</h4>
|
||||||
@@ -58,7 +58,6 @@
|
|||||||
"B" "MINV" \w2 \w4
|
"B" "MINV" \w2 \w4
|
||||||
"B" "SETP" \w1 04
|
"B" "SETP" \w1 04
|
||||||
00
|
00
|
||||||
00
|
|
||||||
"C" "FTST"
|
"C" "FTST"
|
||||||
"T" "NAME" 00 "sample_feature_2" 00
|
"T" "NAME" 00 "sample_feature_2" 00
|
||||||
"B" "MINV" \w2 \w5
|
"B" "MINV" \w2 \w5
|
||||||
@@ -70,6 +69,75 @@
|
|||||||
// Skip 1 sprite if bit 4 of global variable 0x9D is not set (indicating that sample_feature_1 with a version of at least 4 is NOT present)
|
// Skip 1 sprite if bit 4 of global variable 0x9D is not set (indicating that sample_feature_1 with a version of at least 4 is NOT present)
|
||||||
-1 * -1 07 9D 01 \70 04 01
|
-1 * -1 07 9D 01 \70 04 01
|
||||||
</pre>
|
</pre>
|
||||||
|
<br />
|
||||||
|
<h3 id="feature-test">Action 14 - Property Mapping for Action 0</h3>
|
||||||
|
<p>See <a href="https://newgrf-specs.tt-wiki.net/wiki/Action14">Action 14 Specification</a> and <a href="https://newgrf-specs.tt-wiki.net/wiki/Action0">Action 0 Specification</a> for background information.</p>
|
||||||
|
<p>The property mapping mechanism has the feature name: <font face="monospace">property_mapping</font>, this document describes version 1.</p>
|
||||||
|
<p>Users of this mechanism SHOULD at minimum use test for the presence of the feature above or test variable 8D, below.</p>
|
||||||
|
<h4>Property Mapping: C "A0PM"</h4>
|
||||||
|
<p>Each A0PM chunk (type C) describes an individual property mapping.<br />
|
||||||
|
Sub-chunks within each A0PM chunk may appear in any order, however except where otherwise noted each sub-chunk SHOULD only appear ONCE within an individual A0PM chunk.</p>
|
||||||
|
<p>Property mapping can be safely used on implementations which do not implement the property mapping mechanism if Action 0 sprites which use mapped property IDs are skipped if one or more of:
|
||||||
|
<ul>
|
||||||
|
<li>The global variable 0x8D is checked to determine whether the property mapping operation was successful.</li>
|
||||||
|
<li>The feature name <font face="monospace">property_mapping</font> is checked for.</li>
|
||||||
|
</ul>
|
||||||
|
Unknown Action 14 blocks are ignored, and do not need to be skipped.</p>
|
||||||
|
<h4>Property Name: C "A0PM" -> T "NAME"</h4>
|
||||||
|
<p>Within an A0PM chunk, the NAME text (type T) field contains the name of the property to map. The value of the language ID byte is ignored.</p>
|
||||||
|
<h4>Action 0 Feature ID: C "A0PM" -> B "FEAT"</h4>
|
||||||
|
<p>Within an A0PM chunk, the FEAT binary (type B) field contains the <a href="https://newgrf-specs.tt-wiki.net/wiki/Action0#Feature">Action 0 feature ID</a>. This is 1 byte.</p>
|
||||||
|
<h4>Property ID: C "A0PM" -> B "PROP"</h4>
|
||||||
|
<p>Within an A0PM chunk, the PROP binary (type B) field contains the property ID to allocate to the named property, this value can used in Action 0 sprites. This is 1 byte.<br />
|
||||||
|
It is possible to override existing properties, however this use is not recommended.</p>
|
||||||
|
<h4>Success Indicator Global Variable 0x8D Bit: C "A0PM" -> B "SETT"</h4>
|
||||||
|
<p>Within an A0PM chunk, the SETT binary (type B) field contains the bit number to set/clear in
|
||||||
|
<a href="https://newgrf-specs.tt-wiki.net/wiki/GlobalVariables">global variable</a> 0x8D (TTD version) to store whether the mapping operation was successful. This is 1 byte.<br />
|
||||||
|
If the operation is successful, the bit is set (to 1), otherwise the bit is cleared (to 0).<br />
|
||||||
|
The bit number MUST be in the range: 4 ≤ bit number ≤ 31. These bits can be assumed to be 0 on implementations which do not support this property mapping mechanism.<br />
|
||||||
|
Global variable 0x8D can then be tested by using a standard <a href="https://newgrf-specs.tt-wiki.net/wiki/Action7">Action 7 or 9</a>, or a standard <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2">Variational Action 2</a>.<br />
|
||||||
|
If this field is omitted, no bit is set or cleared.
|
||||||
|
</p>
|
||||||
|
<h4>Fallback Mode: C "A0PM" -> B "FLBK"</h4>
|
||||||
|
<p>Within an A0PM chunk, the FLBK binary (type B) field contains the fallback mode. This is 1 byte.<br />
|
||||||
|
The fallback mode may take the following values:
|
||||||
|
<table>
|
||||||
|
<tr><th>Value</th><th>Behaviour</th></tr>
|
||||||
|
<tr><td>0</td><td>Attempts to map an unknown property name are ignored. Use of the mapped property in an Action 0 is ignored. This is the default.</td></tr>
|
||||||
|
<tr><td>1</td><td>Attempts to map an unknown property name are ignored. Use of the mapped property in an Action 0 is an error.</td></tr>
|
||||||
|
<tr><td>2</td><td>Attempting to map an unknown property name is an error.</td></tr>
|
||||||
|
</table>
|
||||||
|
Attempts to set a fallback mode other than those listed above are silently ignored. More fallback modes MAY be added in future versions of this mechanism.<br />
|
||||||
|
This chunk MAY be specified more than once, in which case the last specified valid value is used.<br />
|
||||||
|
Note that even when using fallback mode 0, above, if the property mapping feature is not present, then use of the mapped property ID in an Action 0 is an error.
|
||||||
|
</p>
|
||||||
|
<h4>Format of remapped properties</h4>
|
||||||
|
All properties which are mapped by the mechanism have the format:
|
||||||
|
<table>
|
||||||
|
<tr><th>Size</th><th>Name</th><th>Meaning</th></tr>
|
||||||
|
<tr><td>B*</td><td>num</td><td>Size of the data in bytes</td></tr>
|
||||||
|
<tr><td>V</td><td>data</td><td>Property data</td></tr>
|
||||||
|
</table>
|
||||||
|
Note that num is an extended byte, see <a href="https://newgrf-specs.tt-wiki.net/wiki/GRFActionsDetailed">GRFActionsDetailed</a>.<br />
|
||||||
|
If the size of the data does provided is not valid for the given property, the attempt to set the property MAY be ignored or partially applied.
|
||||||
|
<h4>Example NFO:</h4>
|
||||||
|
<pre>
|
||||||
|
// Map station property "sample_station_property" to property id 0xF8, and set bit 4 of global variable 0x8D if successful
|
||||||
|
-1 * -1 14
|
||||||
|
"C" "A0PM"
|
||||||
|
"T" "NAME" 00 "sample_station_property" 00
|
||||||
|
"B" "FEAT" \w1 04
|
||||||
|
"B" "PROP" \w1 F8
|
||||||
|
"B" "SETT" \w1 4
|
||||||
|
00
|
||||||
|
00
|
||||||
|
....
|
||||||
|
// Skip 1 sprite if bit 4 of global variable 0x8D is not set (indicating that station property sample_station_property is NOT present)
|
||||||
|
-1 * -1 07 8D 01 \70 04 01
|
||||||
|
// Set sample_station_property for station ID 10 to 2 byte value: AB CD
|
||||||
|
-1 * -1 00 04 01 01 10 F8 02 AB CD
|
||||||
|
</pre>
|
||||||
|
<br />
|
||||||
<h3><a href="https://newgrf-specs.tt-wiki.net/wiki/Action0/Stations">Action 0 - Stations</a></h3>
|
<h3><a href="https://newgrf-specs.tt-wiki.net/wiki/Action0/Stations">Action 0 - Stations</a></h3>
|
||||||
<h4><a href="https://newgrf-specs.tt-wiki.net/wiki/Action0/Stations#Minimum_bridge_height_.281B.29">Minimum bridge height (1B)</a></h4>
|
<h4><a href="https://newgrf-specs.tt-wiki.net/wiki/Action0/Stations#Minimum_bridge_height_.281B.29">Minimum bridge height (1B)</a></h4>
|
||||||
<p>This is indicated by the feature name: <font face="monospace">action0_station_prop1B</font>, version 1</p>
|
<p>This is indicated by the feature name: <font face="monospace">action0_station_prop1B</font>, version 1</p>
|
||||||
|
@@ -1,3 +1,15 @@
|
|||||||
|
openttd (1.8.0-0) unstable; urgency=low
|
||||||
|
|
||||||
|
* New upstream release 1.8.0
|
||||||
|
|
||||||
|
-- OpenTTD <info@openttd.org> Sun, 01 Apr 2018 14:00:00 +0200
|
||||||
|
|
||||||
|
openttd (1.8.0~RC1-0) unstable; urgency=low
|
||||||
|
|
||||||
|
* New upstream release 1.8.0-RC1
|
||||||
|
|
||||||
|
-- OpenTTD <info@openttd.org> Wed, 21 Mar 2018 21:00:00 +0100
|
||||||
|
|
||||||
openttd (1.7.2-0) unstable; urgency=low
|
openttd (1.7.2-0) unstable; urgency=low
|
||||||
|
|
||||||
* New upstream release 1.7.2
|
* New upstream release 1.7.2
|
||||||
@@ -1002,4 +1014,3 @@ openttd (0.3.5-1) unstable; urgency=low
|
|||||||
* Initial Release.
|
* Initial Release.
|
||||||
|
|
||||||
-- Matthijs Kooijman <m.kooijman@student.utwente.nl> Fri, 24 Dec 2004 02:58:47 +0100
|
-- Matthijs Kooijman <m.kooijman@student.utwente.nl> Fri, 24 Dec 2004 02:58:47 +0100
|
||||||
|
|
||||||
|
@@ -3064,6 +3064,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Pročitaj nakon
|
|||||||
STR_NEWGRF_ERROR_GRM_FAILED :Zatraženi GRF resursi nisu dostupni (sprite {3:NUM})
|
STR_NEWGRF_ERROR_GRM_FAILED :Zatraženi GRF resursi nisu dostupni (sprite {3:NUM})
|
||||||
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} je isključen od strane {STRING}
|
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} je isključen od strane {STRING}
|
||||||
STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Pogrešan/nepoznat format raspored sprite-a (sprite {3:NUM})
|
STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Pogrešan/nepoznat format raspored sprite-a (sprite {3:NUM})
|
||||||
|
STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Previše elemenata na listi postavki varijabli (sprite {3:NUM}, postavka {4:HEX})
|
||||||
|
STR_NEWGRF_ERROR_INDPROD_CALLBACK :Pogrešna callback funkcija za industrijsku proizvodnju (sprite {3:NUM}, "{1:STRING}")
|
||||||
|
|
||||||
# NewGRF related 'general' warnings
|
# NewGRF related 'general' warnings
|
||||||
STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Oprez!
|
STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Oprez!
|
||||||
|
@@ -3457,7 +3457,7 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{RAW_ST
|
|||||||
STR_NEWGRF_ERROR_MSG_WARNING :{RED}Warning: {SILVER}{RAW_STRING}
|
STR_NEWGRF_ERROR_MSG_WARNING :{RED}Warning: {SILVER}{RAW_STRING}
|
||||||
STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{RAW_STRING}
|
STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{RAW_STRING}
|
||||||
STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{RAW_STRING}
|
STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{RAW_STRING}
|
||||||
STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}A fatal NewGRF error has occurred: {}{STRING5}
|
STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}A fatal NewGRF error has occurred: {}{STRING7}
|
||||||
STR_NEWGRF_ERROR_VERSION_NUMBER :{1:RAW_STRING} will not work with the TTDPatch version reported by OpenTTD
|
STR_NEWGRF_ERROR_VERSION_NUMBER :{1:RAW_STRING} will not work with the TTDPatch version reported by OpenTTD
|
||||||
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:RAW_STRING} is for the {RAW_STRING} version of TTD
|
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:RAW_STRING} is for the {RAW_STRING} version of TTD
|
||||||
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:RAW_STRING} is designed to be used with {RAW_STRING}
|
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:RAW_STRING} is designed to be used with {RAW_STRING}
|
||||||
@@ -3470,6 +3470,7 @@ STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Too many NewGRF
|
|||||||
STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {1:RAW_STRING} as static NewGRF with {RAW_STRING} could cause desyncs
|
STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {1:RAW_STRING} as static NewGRF with {RAW_STRING} could cause desyncs
|
||||||
STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Unexpected sprite (sprite {3:NUM})
|
STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Unexpected sprite (sprite {3:NUM})
|
||||||
STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Unknown Action 0 property {4:HEX} (sprite {3:NUM})
|
STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Unknown Action 0 property {4:HEX} (sprite {3:NUM})
|
||||||
|
STR_NEWGRF_ERROR_UNIMPLEMETED_MAPPED_PROPERTY :Unimplemented remapped Action 0 property feature: {4:HEX}, name: {2:RAW_STRING}, mapped to: {5:HEX} (sprite {3:NUM})
|
||||||
STR_NEWGRF_ERROR_INVALID_ID :Attempt to use invalid ID (sprite {3:NUM})
|
STR_NEWGRF_ERROR_INVALID_ID :Attempt to use invalid ID (sprite {3:NUM})
|
||||||
STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{RAW_STRING} contains a corrupt sprite. All corrupt sprites will be shown as a red question mark (?)
|
STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{RAW_STRING} contains a corrupt sprite. All corrupt sprites will be shown as a red question mark (?)
|
||||||
STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contains multiple Action 8 entries (sprite {3:NUM})
|
STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contains multiple Action 8 entries (sprite {3:NUM})
|
||||||
|
278
src/newgrf.cpp
278
src/newgrf.cpp
@@ -998,6 +998,24 @@ enum ChangeInfoResult {
|
|||||||
|
|
||||||
typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
|
typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
|
||||||
|
|
||||||
|
static ChangeInfoResult HandleAction0PropertyDefault(ByteReader *buf, int prop)
|
||||||
|
{
|
||||||
|
switch (prop) {
|
||||||
|
case A0RPI_UNKNOWN_IGNORE:
|
||||||
|
buf->Skip(buf->ReadExtendedByte());
|
||||||
|
return CIR_SUCCESS;
|
||||||
|
|
||||||
|
case A0RPI_UNKNOWN_ERROR:
|
||||||
|
return CIR_DISABLED;
|
||||||
|
|
||||||
|
case A0RPI_SKIPPED_IGNORE:
|
||||||
|
return CIR_SUCCESS;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CIR_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define properties common to all vehicles
|
* Define properties common to all vehicles
|
||||||
* @param ei Engine info.
|
* @param ei Engine info.
|
||||||
@@ -1034,7 +1052,7 @@ static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteRe
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CIR_UNKNOWN;
|
return HandleAction0PropertyDefault(buf, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CIR_SUCCESS;
|
return CIR_SUCCESS;
|
||||||
@@ -2094,7 +2112,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2132,7 +2150,7 @@ static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteRead
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2249,7 +2267,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2312,7 +2330,7 @@ static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -2544,7 +2562,7 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2806,7 +2824,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2868,7 +2886,7 @@ static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, B
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3007,7 +3025,7 @@ static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteRea
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3065,7 +3083,7 @@ static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, B
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3105,7 +3123,7 @@ static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -3243,7 +3261,7 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3336,7 +3354,7 @@ static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -3761,7 +3779,7 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3964,7 +3982,7 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4009,7 +4027,7 @@ static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4139,7 +4157,7 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4277,7 +4295,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4357,7 +4375,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4447,7 +4465,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = HandleAction0PropertyDefault(buf, prop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4455,7 +4473,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
|
static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, int property)
|
||||||
{
|
{
|
||||||
switch (cir) {
|
switch (cir) {
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
@@ -4484,6 +4502,42 @@ static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ReadAction0PropertyID(ByteReader *buf, uint8 feature)
|
||||||
|
{
|
||||||
|
uint8 raw_prop = buf->ReadByte();
|
||||||
|
const GRFFilePropertyRemapSet &remap = _cur.grffile->action0_property_remaps[feature];
|
||||||
|
if (remap.remapped_ids[raw_prop]) {
|
||||||
|
auto iter = remap.mapping.find(raw_prop);
|
||||||
|
assert(iter != remap.mapping.end());
|
||||||
|
const GRFFilePropertyRemapEntry &def = iter->second;
|
||||||
|
int prop = def.id;
|
||||||
|
if (prop == A0RPI_UNKNOWN_ERROR) {
|
||||||
|
grfmsg(0, "Error: Unimplemented mapped property: %s, feature: %X, mapped to: %X", def.name, def.feature, raw_prop);
|
||||||
|
GRFError *error = DisableGrf(STR_NEWGRF_ERROR_UNIMPLEMETED_MAPPED_PROPERTY);
|
||||||
|
error->data = stredup(def.name);
|
||||||
|
error->param_value[1] = def.feature;
|
||||||
|
error->param_value[2] = raw_prop;
|
||||||
|
} else if (prop == A0RPI_UNKNOWN_IGNORE) {
|
||||||
|
grfmsg(2, "Ignoring unimplemented mapped property: %s, feature: %X, mapped to: %X", def.name, def.feature, raw_prop);
|
||||||
|
} else {
|
||||||
|
if (HasBit(def.flags, GFPRE_CHECK_SIZE)) {
|
||||||
|
uint length = buf->ReadExtendedByte();
|
||||||
|
if (length != def.expected_size) {
|
||||||
|
grfmsg(2, "Ignoring use of mapped property: %s, feature: %X, mapped to: %X, with incorrect data size: %u instead of %u",
|
||||||
|
def.name, def.feature, raw_prop, length, def.expected_size);
|
||||||
|
buf->Skip(length);
|
||||||
|
prop = A0RPI_SKIPPED_IGNORE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prop |= A0RPI_CHECK_PROPERTY_LENGTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prop;
|
||||||
|
} else {
|
||||||
|
return raw_prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Action 0x00 */
|
/* Action 0x00 */
|
||||||
static void FeatureChangeInfo(ByteReader *buf)
|
static void FeatureChangeInfo(ByteReader *buf)
|
||||||
{
|
{
|
||||||
@@ -4518,6 +4572,7 @@ static void FeatureChangeInfo(ByteReader *buf)
|
|||||||
/* GSF_RAILTYPES */ RailTypeChangeInfo,
|
/* GSF_RAILTYPES */ RailTypeChangeInfo,
|
||||||
/* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
|
/* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
|
||||||
};
|
};
|
||||||
|
static_assert(lengthof(handler) == lengthof(_cur.grffile->action0_property_remaps));
|
||||||
|
|
||||||
uint8 feature = buf->ReadByte();
|
uint8 feature = buf->ReadByte();
|
||||||
uint8 numprops = buf->ReadByte();
|
uint8 numprops = buf->ReadByte();
|
||||||
@@ -4536,7 +4591,7 @@ static void FeatureChangeInfo(ByteReader *buf)
|
|||||||
SetBit(_cur.grffile->grf_features, feature);
|
SetBit(_cur.grffile->grf_features, feature);
|
||||||
|
|
||||||
while (numprops-- && buf->HasData()) {
|
while (numprops-- && buf->HasData()) {
|
||||||
uint8 prop = buf->ReadByte();
|
int prop = ReadAction0PropertyID(buf, feature);
|
||||||
|
|
||||||
ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
|
ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
|
||||||
if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
|
if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
|
||||||
@@ -4552,12 +4607,12 @@ static void SafeChangeInfo(ByteReader *buf)
|
|||||||
buf->ReadExtendedByte(); // id
|
buf->ReadExtendedByte(); // id
|
||||||
|
|
||||||
if (feature == GSF_BRIDGES && numprops == 1) {
|
if (feature == GSF_BRIDGES && numprops == 1) {
|
||||||
uint8 prop = buf->ReadByte();
|
int prop = ReadAction0PropertyID(buf, feature);
|
||||||
/* Bridge property 0x0D is redefinition of sprite layout tables, which
|
/* Bridge property 0x0D is redefinition of sprite layout tables, which
|
||||||
* is considered safe. */
|
* is considered safe. */
|
||||||
if (prop == 0x0D) return;
|
if (prop == 0x0D) return;
|
||||||
} else if (feature == GSF_GLOBALVAR && numprops == 1) {
|
} else if (feature == GSF_GLOBALVAR && numprops == 1) {
|
||||||
uint8 prop = buf->ReadByte();
|
int prop = ReadAction0PropertyID(buf, feature);
|
||||||
/* Engine ID Mappings are safe, if the source is static */
|
/* Engine ID Mappings are safe, if the source is static */
|
||||||
if (prop == 0x11) {
|
if (prop == 0x11) {
|
||||||
bool is_safe = true;
|
bool is_safe = true;
|
||||||
@@ -4592,7 +4647,7 @@ static void ReserveChangeInfo(ByteReader *buf)
|
|||||||
uint8 index = buf->ReadExtendedByte();
|
uint8 index = buf->ReadExtendedByte();
|
||||||
|
|
||||||
while (numprops-- && buf->HasData()) {
|
while (numprops-- && buf->HasData()) {
|
||||||
uint8 prop = buf->ReadByte();
|
int prop = ReadAction0PropertyID(buf, feature);
|
||||||
ChangeInfoResult cir = CIR_SUCCESS;
|
ChangeInfoResult cir = CIR_SUCCESS;
|
||||||
|
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
@@ -5963,7 +6018,7 @@ bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 0x0D: // TTD Version, 00=DOS, 01=Windows
|
case 0x0D: // TTD Version, 00=DOS, 01=Windows
|
||||||
*value = _cur.grfconfig->palette & GRFP_USE_MASK;
|
*value = (_cur.grfconfig->palette & GRFP_USE_MASK) | grffile->var8D_overlay;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 0x0E: // Y-offset for train sprites
|
case 0x0E: // Y-offset for train sprites
|
||||||
@@ -7891,6 +7946,7 @@ struct GRFFeatureInfo {
|
|||||||
/** Action14 feature list */
|
/** Action14 feature list */
|
||||||
static const GRFFeatureInfo _grf_feature_list[] = {
|
static const GRFFeatureInfo _grf_feature_list[] = {
|
||||||
GRFFeatureInfo("feature_test", 1),
|
GRFFeatureInfo("feature_test", 1),
|
||||||
|
GRFFeatureInfo("property_mapping", 1),
|
||||||
GRFFeatureInfo("action0_station_prop1B", 1),
|
GRFFeatureInfo("action0_station_prop1B", 1),
|
||||||
GRFFeatureInfo("varaction2_station_var42", 1),
|
GRFFeatureInfo("varaction2_station_var42", 1),
|
||||||
GRFFeatureInfo("more_bridge_types", 1),
|
GRFFeatureInfo("more_bridge_types", 1),
|
||||||
@@ -7967,7 +8023,7 @@ static bool ChangeGRFFeatureMaxVersion(size_t len, ByteReader *buf)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Callback function for 'FTST'->'SETP' to set the maximum version of the feature being tested. */
|
/** Callback function for 'FTST'->'SETP' to set the bit number of global variable 9D (platform version) to set/unset with the result of the feature test. */
|
||||||
static bool ChangeGRFFeatureSetPlatformVarBit(size_t len, ByteReader *buf)
|
static bool ChangeGRFFeatureSetPlatformVarBit(size_t len, ByteReader *buf)
|
||||||
{
|
{
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
@@ -8004,10 +8060,177 @@ static bool HandleFeatureTestInfo(ByteReader *buf)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Action14 Action0 remappable property list */
|
||||||
|
static const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = {
|
||||||
|
GRFPropertyMapDefinition(),
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Action14 Action0 property map action instance */
|
||||||
|
struct GRFPropertyMapAction {
|
||||||
|
int feature;
|
||||||
|
int prop_id;
|
||||||
|
std::string name;
|
||||||
|
Action0RemapFallbackMode fallback_mode;
|
||||||
|
uint8 ttd_ver_var_bit;
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
this->feature = -1;
|
||||||
|
this->prop_id = -1;
|
||||||
|
this->name.clear();
|
||||||
|
this->fallback_mode = A0REM_IGNORE;
|
||||||
|
this->ttd_ver_var_bit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute()
|
||||||
|
{
|
||||||
|
if (this->feature < 0) {
|
||||||
|
grfmsg(2, "Action 14 property remapping: no feature defined, doing nothing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->prop_id < 0) {
|
||||||
|
grfmsg(2, "Action 14 property remapping: no property ID defined, doing nothing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->name.empty()) {
|
||||||
|
grfmsg(2, "Action 14 property remapping: no name defined, doing nothing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool success = false;
|
||||||
|
const char *str = this->name.c_str();
|
||||||
|
for (const GRFPropertyMapDefinition *info = _grf_action0_remappable_properties; info->name != NULL; info++) {
|
||||||
|
if (info->feature == this->feature && strcmp(info->name, str) == 0) {
|
||||||
|
GRFFilePropertyRemapEntry &entry = _cur.grffile->action0_property_remaps[this->feature].Entry(this->prop_id);
|
||||||
|
entry.name = info->name;
|
||||||
|
entry.id = info->id;
|
||||||
|
entry.feature = this->feature;
|
||||||
|
entry.flags = 0;
|
||||||
|
if (info->expected_size >= 0) {
|
||||||
|
SetBit(entry.flags, GFPRE_CHECK_SIZE);
|
||||||
|
entry.expected_size = info->expected_size;
|
||||||
|
}
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this->ttd_ver_var_bit > 0) {
|
||||||
|
SB(_cur.grffile->var8D_overlay, this->ttd_ver_var_bit, 1, success ? 1 : 0);
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
if (this->fallback_mode == A0REM_ERROR_ON_DEFINITION) {
|
||||||
|
grfmsg(0, "Error: Unimplemented mapped property: %s, feature: %X, mapped to: %X", str, this->feature, this->prop_id);
|
||||||
|
GRFError *error = DisableGrf(STR_NEWGRF_ERROR_UNIMPLEMETED_MAPPED_PROPERTY);
|
||||||
|
error->data = stredup(str);
|
||||||
|
error->param_value[1] = this->feature;
|
||||||
|
error->param_value[2] = this->prop_id;
|
||||||
|
} else {
|
||||||
|
const char *str_store = stredup(str);
|
||||||
|
grfmsg(2, "Unimplemented mapped property: %s, feature: %X, mapped to: %X, %s on use",
|
||||||
|
str, this->feature, this->prop_id, (this->fallback_mode == A0REM_IGNORE) ? "ignoring" : "error");
|
||||||
|
*(_cur.grffile->action0_unknown_property_names.Append()) = str_store;
|
||||||
|
GRFFilePropertyRemapEntry &entry = _cur.grffile->action0_property_remaps[this->feature].Entry(this->prop_id);
|
||||||
|
entry.name = str_store;
|
||||||
|
entry.id = (this->fallback_mode == A0REM_IGNORE) ? A0RPI_UNKNOWN_IGNORE : A0RPI_UNKNOWN_ERROR;
|
||||||
|
entry.feature = this->feature;
|
||||||
|
entry.flags = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static GRFPropertyMapAction _current_grf_property_map_action;
|
||||||
|
|
||||||
|
/** Callback function for 'A0PM'->'NAME' to set the name of the property to be mapped. */
|
||||||
|
static bool ChangePropertyRemapName(byte langid, const char *str)
|
||||||
|
{
|
||||||
|
_current_grf_property_map_action.name = str;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Callback function for 'A0PM'->'FEAT' to set which feature this property mapping applies to. */
|
||||||
|
static bool ChangePropertyRemapFeature(size_t len, ByteReader *buf)
|
||||||
|
{
|
||||||
|
if (len != 1) {
|
||||||
|
grfmsg(2, "Action 14 property mapping: expected 1 byte for 'A0PM'->'FEAT' but got " PRINTF_SIZE ", ignoring this field", len);
|
||||||
|
buf->Skip(len);
|
||||||
|
} else {
|
||||||
|
uint8 feature = buf->ReadByte();
|
||||||
|
if (feature >= GSF_END) {
|
||||||
|
grfmsg(2, "Action 14 property mapping: invalid feature ID: %u, in 'A0PM'->'FEAT', ignoring this field", feature);
|
||||||
|
} else {
|
||||||
|
_current_grf_property_map_action.feature = feature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Callback function for 'A0PM'->'PROP' to set the property ID to which this property is being mapped. */
|
||||||
|
static bool ChangePropertyRemapPropertyId(size_t len, ByteReader *buf)
|
||||||
|
{
|
||||||
|
if (len != 1) {
|
||||||
|
grfmsg(2, "Action 14 property mapping: expected 1 byte for 'A0PM'->'PROP' but got " PRINTF_SIZE ", ignoring this field", len);
|
||||||
|
buf->Skip(len);
|
||||||
|
} else {
|
||||||
|
_current_grf_property_map_action.prop_id = buf->ReadByte();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Callback function for 'A0PM'->'FLBK' to set the maximum version of the feature being tested. */
|
||||||
|
static bool ChangePropertyRemapSetFallbackMode(size_t len, ByteReader *buf)
|
||||||
|
{
|
||||||
|
if (len != 1) {
|
||||||
|
grfmsg(2, "Action 14 property mapping: expected 1 byte for 'A0PM'->'FLBK' but got " PRINTF_SIZE ", ignoring this field", len);
|
||||||
|
buf->Skip(len);
|
||||||
|
} else {
|
||||||
|
Action0RemapFallbackMode mode = (Action0RemapFallbackMode) buf->ReadByte();
|
||||||
|
if (mode < A0REM_END) _current_grf_property_map_action.fallback_mode = mode;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/** Callback function for 'A0PM'->'SETT' to set the bit number of global variable 8D (TTD version) to set/unset with whether the remapping was successful. */
|
||||||
|
static bool ChangePropertyRemapSetTTDVerVarBit(size_t len, ByteReader *buf)
|
||||||
|
{
|
||||||
|
if (len != 1) {
|
||||||
|
grfmsg(2, "Action 14 property mapping: expected 1 byte for 'A0PM'->'SETT' but got " PRINTF_SIZE ", ignoring this field", len);
|
||||||
|
buf->Skip(len);
|
||||||
|
} else {
|
||||||
|
uint8 bit_number = buf->ReadByte();
|
||||||
|
if (bit_number >= 4 && bit_number <= 31) {
|
||||||
|
_current_grf_property_map_action.ttd_ver_var_bit = bit_number;
|
||||||
|
} else {
|
||||||
|
grfmsg(2, "Action 14 property mapping: expected a bit number >= 4 and <= 32 for 'A0PM'->'SETT' but got %u, ignoring this field", bit_number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Action14 tags for the A0PM node */
|
||||||
|
AllowedSubtags _tags_a0pm[] = {
|
||||||
|
AllowedSubtags('NAME', ChangePropertyRemapName),
|
||||||
|
AllowedSubtags('FEAT', ChangePropertyRemapFeature),
|
||||||
|
AllowedSubtags('PROP', ChangePropertyRemapPropertyId),
|
||||||
|
AllowedSubtags('FLBK', ChangePropertyRemapSetFallbackMode),
|
||||||
|
AllowedSubtags('SETT', ChangePropertyRemapSetTTDVerVarBit),
|
||||||
|
AllowedSubtags()
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function for 'A0PM' (action 0 property mapping)
|
||||||
|
*/
|
||||||
|
static bool HandleAction0PropertyMap(ByteReader *buf)
|
||||||
|
{
|
||||||
|
_current_grf_property_map_action.Reset();
|
||||||
|
HandleNodes(buf, _tags_a0pm);
|
||||||
|
_current_grf_property_map_action.Execute();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/** Action14 root tags */
|
/** Action14 root tags */
|
||||||
AllowedSubtags _tags_root_static[] = {
|
AllowedSubtags _tags_root_static[] = {
|
||||||
AllowedSubtags('INFO', _tags_info),
|
AllowedSubtags('INFO', _tags_info),
|
||||||
AllowedSubtags('FTST', SkipInfoChunk),
|
AllowedSubtags('FTST', SkipInfoChunk),
|
||||||
|
AllowedSubtags('A0PM', SkipInfoChunk),
|
||||||
AllowedSubtags()
|
AllowedSubtags()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -8015,6 +8238,7 @@ AllowedSubtags _tags_root_static[] = {
|
|||||||
AllowedSubtags _tags_root_feature_tests[] = {
|
AllowedSubtags _tags_root_feature_tests[] = {
|
||||||
AllowedSubtags('INFO', SkipInfoChunk),
|
AllowedSubtags('INFO', SkipInfoChunk),
|
||||||
AllowedSubtags('FTST', HandleFeatureTestInfo),
|
AllowedSubtags('FTST', HandleFeatureTestInfo),
|
||||||
|
AllowedSubtags('A0PM', HandleAction0PropertyMap),
|
||||||
AllowedSubtags()
|
AllowedSubtags()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
65
src/newgrf.h
65
src/newgrf.h
@@ -19,6 +19,8 @@
|
|||||||
#include "core/bitmath_func.hpp"
|
#include "core/bitmath_func.hpp"
|
||||||
#include "core/alloc_type.hpp"
|
#include "core/alloc_type.hpp"
|
||||||
#include "core/smallvec_type.hpp"
|
#include "core/smallvec_type.hpp"
|
||||||
|
#include "3rdparty/cpp-btree/btree_map.h"
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of different canal 'features'.
|
* List of different canal 'features'.
|
||||||
@@ -101,6 +103,65 @@ struct GRFLabel {
|
|||||||
struct GRFLabel *next;
|
struct GRFLabel *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Action0RemapPropertyIds {
|
||||||
|
A0RPI_CHECK_PROPERTY_LENGTH = 0x10000,
|
||||||
|
A0RPI_UNKNOWN_IGNORE = 0x200,
|
||||||
|
A0RPI_UNKNOWN_ERROR,
|
||||||
|
A0RPI_SKIPPED_IGNORE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Action0RemapFallbackMode {
|
||||||
|
A0REM_IGNORE,
|
||||||
|
A0REM_ERROR_ON_USE,
|
||||||
|
A0REM_ERROR_ON_DEFINITION,
|
||||||
|
A0REM_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GRFPropertyMapDefinition {
|
||||||
|
const char *name; // NULL indicates the end of the list
|
||||||
|
int id;
|
||||||
|
uint8 feature;
|
||||||
|
int expected_size;
|
||||||
|
|
||||||
|
/** Create empty object used to identify the end of a list. */
|
||||||
|
GRFPropertyMapDefinition() :
|
||||||
|
name(NULL),
|
||||||
|
id(0),
|
||||||
|
feature(0),
|
||||||
|
expected_size(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
GRFPropertyMapDefinition(uint8 feature, int id, const char *name, int expected_size = -1) :
|
||||||
|
name(name),
|
||||||
|
id(id),
|
||||||
|
feature(feature),
|
||||||
|
expected_size(expected_size)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GFPRE_Flags {
|
||||||
|
GFPRE_CHECK_SIZE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GRFFilePropertyRemapEntry {
|
||||||
|
const char *name = nullptr;
|
||||||
|
int id = 0;
|
||||||
|
uint8 feature = 0;
|
||||||
|
uint8 flags = 0;
|
||||||
|
uint16 expected_size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GRFFilePropertyRemapSet {
|
||||||
|
std::bitset<256> remapped_ids;
|
||||||
|
btree::btree_map<uint8, GRFFilePropertyRemapEntry> mapping;
|
||||||
|
|
||||||
|
GRFFilePropertyRemapEntry &Entry(uint8 property)
|
||||||
|
{
|
||||||
|
this->remapped_ids.set(property);
|
||||||
|
return this->mapping[property];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** Dynamic data of a loaded NewGRF */
|
/** Dynamic data of a loaded NewGRF */
|
||||||
struct GRFFile : ZeroedMemoryAllocator {
|
struct GRFFile : ZeroedMemoryAllocator {
|
||||||
char *filename;
|
char *filename;
|
||||||
@@ -118,6 +179,9 @@ struct GRFFile : ZeroedMemoryAllocator {
|
|||||||
struct AirportSpec **airportspec;
|
struct AirportSpec **airportspec;
|
||||||
struct AirportTileSpec **airtspec;
|
struct AirportTileSpec **airtspec;
|
||||||
|
|
||||||
|
GRFFilePropertyRemapSet action0_property_remaps[GSF_END];
|
||||||
|
AutoFreeSmallVector<const char *, 8> action0_unknown_property_names;
|
||||||
|
|
||||||
uint32 param[0x80];
|
uint32 param[0x80];
|
||||||
uint param_end; ///< one more than the highest set parameter
|
uint param_end; ///< one more than the highest set parameter
|
||||||
|
|
||||||
@@ -139,6 +203,7 @@ struct GRFFile : ZeroedMemoryAllocator {
|
|||||||
uint32 grf_features; ///< Bitset of GrfSpecFeature the grf uses
|
uint32 grf_features; ///< Bitset of GrfSpecFeature the grf uses
|
||||||
PriceMultipliers price_base_multipliers; ///< Price base multipliers as set by the grf.
|
PriceMultipliers price_base_multipliers; ///< Price base multipliers as set by the grf.
|
||||||
|
|
||||||
|
uint32 var8D_overlay; ///< Overlay for global variable 8D (action 0x14)
|
||||||
uint32 var9D_overlay; ///< Overlay for global variable 9D (action 0x14)
|
uint32 var9D_overlay; ///< Overlay for global variable 9D (action 0x14)
|
||||||
|
|
||||||
GRFFile(const struct GRFConfig *config);
|
GRFFile(const struct GRFConfig *config);
|
||||||
|
@@ -109,7 +109,7 @@ struct GRFError : ZeroedMemoryAllocator {
|
|||||||
char *data; ///< Additional data for message and custom_message
|
char *data; ///< Additional data for message and custom_message
|
||||||
StringID message; ///< Default message
|
StringID message; ///< Default message
|
||||||
StringID severity; ///< Info / Warning / Error / Fatal
|
StringID severity; ///< Info / Warning / Error / Fatal
|
||||||
uint32 param_value[2]; ///< Values of GRF parameters to show for message and custom_message
|
uint64 param_value[4]; ///< Values of GRF parameters to show for message and custom_message
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The possible types of a newgrf parameter. */
|
/** The possible types of a newgrf parameter. */
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
* \b 1.8.0
|
* \b 1.8.0
|
||||||
*
|
*
|
||||||
* 1.8.0 is not yet released. The following changes are not set in stone yet.
|
* No changes
|
||||||
*
|
*
|
||||||
* \b 1.7.0 - 1.7.2
|
* \b 1.7.0 - 1.7.2
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user