Author |
Message |
wallyweb
|
Posted: 04 Aug 2016, 08:52 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Recently cirdan added bridges to his New Map Features (NMF) fork of OpenTTD, extending the number of bridges to the maximum of 16 bridges as well as allowing bridges over stations. This encouraged me to get into the bridge building business. GarryG saw a need for an Australian bridge set and I agreed to code it for him. His first bridge was a lesson for both of us and that prompted a need for a tutorial in case others would like to follow in his steps. This tutorial is in three parts: 1. Overview: The basic structure of a bridge set. 2. Graphics: Developing a bridge sprite sheet. 3. Coding: How to code a bridge in NFO. (i)(ii) (i) Currently NML does not support bridges. (ii) Michael Blunck has included bridge support with tutorial in his m4nfo upper level language. Reference: NewGRF SpecificationsWhile this tutorial topic is locked there will be a companion topic for comments and questions and answers as soon as part 2 is completed.
|
|
Top |
|
|
wallyweb
|
Posted: 04 Aug 2016, 18:16 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
1. Overview: The basic structure of a bridge set. The Transport Tycoon game code structure can support 16 bridges in 4 types (rail, road, monorail, maglev) each, for a total of 64 bridges. T - Transport Tycoon accesses only 11 bridges. O - OpenTTD adds two bridges for 13. N - JGR PatchPack and New Map Features each add the final 3 slots for 16. ID (dec) | ID (hex) | Description | Platform | Year | 0 | 00 | Wooden Bridge | T,O,N | 1920 | 1 | 01 | Concrete Bridge | T,O,N | 1920 | 2 | 02 | Girder, Steel Bridge | T,O,N | 1930 | 3 | 03 | Suspension, Concrete Bridge (1) | T,O,N | 1920 | 4 | 04 | Suspension, Steel (Bronze) Bridge | T,O,N | 1930 | 5 | 05 | Suspension, Steel (Golden) Bridge (1) | T,O,N | 1930 | 6 | 06 | Cantilever, Steel (Bronze) Bridge | T,O,N | 1930 | 7 | 07 | Cantilever, Steel (Brown) Bridge (2) | T,O,N | 1930 | 8 | 08 | Cantilever, Steel (Red) Bridge (2) | T,O,N | 1930 | 9 | 09 | Girder, Steel Bridge | T,O,N | 1930 | 10 | 0A | Tubular, Steel (Bronze) Bridge | T,O,N | 1995 | 11 | 0B | Tubular, Steel (Golden) Bridge (3) | O,N | 2005 | 12 | 0C | Tubular, Silicon Bridge (3) | O,N | 2010 | 13 | 0D | To be drawn | N | Open | 14 | 0E | To be drawn | N | Open | 15 | 0F | To be drawn | N | Open |
(1) Recolour of Suspension, Steel (Bronze) Bridge (2) Recolour of Cantilever, Steel (Bronze) Bridge (3) Recolour of Tubular, Steel (Bronze) Bridge There are no sprites for the recolour bridges, nor for bridges 13, 14 or 15. A bridge is an assembly of tiles arrayed North to South in the X or Y directions. There are four tile types: Rail; Road; Monorail; MagLev. The first and last tiles of the assembly are flat or sloped ramp (bridgehead) sprites. Between the ramps we have an odd or even number of flat deck tiles. Each deck tile is made up of three sprites: Back/Floor; Front; Pillars. The tiles are grouped into sieven tables (8 rows x 4 columns) numbered 0 (00h) through 6 (06h). Tables 0 through 5 are for the deck tiles with table 6 for the ramp tiles. Each table, 0 through 5: Rail X direction: Back/Floor; Front; Pillars; Empty Cell; Rail Y direction: Back/Floor; Front; Pillars; Empty Cell; Road X direction: Back/Floor; Front; Pillars; Empty Cell; Road Y direction: Back/Floor; Front; Pillars; Empty Cell; Mono X direction: Back/Floor; Front; Pillars; Empty Cell; Mono Y direction: Back/Floor; Front; Pillars; Empty Cell; MagL X direction: Back/Floor; Front; Pillars; Empty Cell; MagL Y direction: Back/Floor; Front; Pillars; Empty Cell; Table 6: Rail Flat: North X; North Y; South X; South Y; Rail Sloped: North X; North Y; South X; South Y; Road Flat: North X; North Y; South X; South Y; Road Sloped: North X; North Y; South X; South Y; Mono Flat: North X; North Y; South X; South Y; Mono Sloped: North X; North Y; South X; South Y; MagL Flat: North X; North Y; South X; South Y; MagL Sloped: North X; North Y; South X; South Y; The empty cells are always void and never used. To assemble a bridge, the game code references the tables in a manner consistent with the length of the bridge: Layout | Description | __ | Bridge without middle part | _0_ | Bridge of length 3 | _0(23)1_ | Bridge of even length | _0(23)4(23)1_ | Bridge of (uneven) lengths 5, 9, 13, 17 etc. | _0(23)253(23)1_ | Bridge of (uneven) lengths 7, 11, 15, 19 etc. |
_ is used as a symbol to indicate ramps (bridgeheads) (as defined in table 6). Part 0 is always at the farthest end from the viewer. Parts (23) are repeated n times as necessary, where n is any number equal or greater than 0.
|
|
Top |
|
|
wallyweb
|
Posted: 06 Aug 2016, 06:32 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
2. Graphics: Developing a bridge sprite sheet. Now that we have our basics we can begin to develop our first sprite sheet. References:trg1r.grf - This is the Transport Tycoon basic graphics file. Transport Tycoon is proprietary and the game's CD is required to copy it in order to extract the pcx/png graphics and nfo code for reference purposes. infra08.png - This is the OpenGFX infrastructure sprite sheet. It is GPL and is available here. defaultbridges.png - This is a typical bridge sprite sheet. It was assembled from the Transport Tycoon trg1r file and is proprietary and is for reference only. It shows the sprite numbers used by NFO ActionA for simple sprite replacement. OTTD's sprite numbers are different but the OTTD code knows how to translate them. It is available in the attached zip file. Attachment:
defaultbridges.zip [226.67 KiB]
Downloaded 2509 times
Tile Grids - TTDX and OTTD share 19 tile shapes. This file contains a PCX graphics sheet as well as the newobject grf. It is available here. Bridges use only the following five tile shapes: Attachment:
BridgesTutorial01.png [ 1.52 KiB | Viewed 40040 times ]
|
|
Top |
|
|
wallyweb
|
Posted: 06 Aug 2016, 07:12 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
This part of the tutorial demonstrates how to make a template for a road bridge. Rail, Monorail, and MagLev templates would follow a similar process. For consistency and alignment we derive our templates from the game's road tiles. First we compare road/grass, road/sidewalk and rail tiles to see where we can get the best definition: Attachment:
BridgesTutorial02.png [ 17.79 KiB | Viewed 40040 times ]
Attachment:
BridgesTutorial03.png [ 21.06 KiB | Viewed 40040 times ]
It appears that the road/sidewalk tiles give us what we need. So, let's compare TTDX to OGFX: Attachment:
BridgesTutorial04.png [ 6.61 KiB | Viewed 40040 times ]
Let's add some yellow lines to see where we get the best fit: Attachment:
BridgesTutorial05.png [ 7.73 KiB | Viewed 40040 times ]
We see that the OGFX road is narrower and should give the best universal fit. We will use OGFX. Attachment:
BridgesTutorial06.png [ 6.42 KiB | Viewed 40040 times ]
Just to be sure, let's add TTDX and OGFX road/grass tiles. Attachment:
BridgesTutorial07.png [ 6.06 KiB | Viewed 40040 times ]
Attachment:
BridgesTutorial08.png [ 6.06 KiB | Viewed 40040 times ]
In the next post we will begin to work on the template.
|
|
Top |
|
|
wallyweb
|
Posted: 06 Aug 2016, 14:33 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Beginning work on the template ... We add grids in line with the road tiles and extend the yellow lines into the grids: Attachment:
BridgesTutorial09.png [ 4.99 KiB | Viewed 40036 times ]
Now we fill in the space between the yellow lines and add colour to the margins: Attachment:
BridgesTutorial10.png [ 2.52 KiB | Viewed 40036 times ]
We now have a workable template for the road bridge floor/deck. Just to be sure, let's line them up and see what we get: Attachment:
BridgesTutorial11.png [ 1.9 KiB | Viewed 40036 times ]
|
|
Top |
|
|
wallyweb
|
Posted: 06 Aug 2016, 20:37 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Similarly we create a template for a Rail bridge: Attachment:
BridgesTutorial12.png [ 3.88 KiB | Viewed 40032 times ]
When you add colour and texture and shadows and sleepers/ties and replace the remaining light gray with transparent blue you will be able to look between the rails and see the water or whatever is below. Monorail and MagLev are a bit different. The track is layed on a solid deck. Here we get the appropriate sprites from the game's spritesheet and overlay them with the road bridge templates: Attachment:
BridgesTutorial13.png [ 8.86 KiB | Viewed 40032 times ]
Attachment:
BridgesTutorial14.png [ 8.27 KiB | Viewed 40032 times ]
A little graphical clean-up will rid us of the grassy bits. I'll leave that for you to do. Up next: Adding superstructure
_________________ Visit SimuSchool - Tutorials, Questions and AnswersTTDPatch Nightlies Downloads are backThrive
|
|
Top |
|
|
wallyweb
|
Posted: 09 Aug 2016, 23:33 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Alignments in bridge building is critical. In preparation for adding superstructure let's add some dimension to what has been done. We begin by making boxes from our tile shapes. The boxes are 8 pixels high which is the height of a standard slope and the clearance required to allow a vehicle to pass underneath the bridge. We then add the road bridge tiles to the boxes and assemble the boxes in yet another test to confirm alignments. Attachment:
BridgesTutorial15.png [ 6.09 KiB | Viewed 40015 times ]
We do the same for the rail bridges, but just for fun we add a little variation. We'll make the rail bridge narrower. We'll centre our rail boxes onto standard tile grids and assemble them for another alignment test using an OTTD flat rail tile for reference. Attachment:
BridgesTutorial16.png [ 15.82 KiB | Viewed 40015 times ]
Now we can move on to the superstructure.
_________________ Visit SimuSchool - Tutorials, Questions and AnswersTTDPatch Nightlies Downloads are backThrive
|
|
Top |
|
|
wallyweb
|
Posted: 13 Aug 2016, 21:11 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
The ramps do not support superstructure. Only the spans do this. student wrote: But with only one span in X or Y, wouldn't that a very boring bridge? Yes, it would, but remember this from the second post: second post wrote: Each table, 0 through 5: Rail X direction: Back/Floor; Front; Pillars; Empty Cell; Rail Y direction: Back/Floor; Front; Pillars; Empty Cell; Road X direction: Back/Floor; Front; Pillars; Empty Cell; Road Y direction: Back/Floor; Front; Pillars; Empty Cell; Mono X direction: Back/Floor; Front; Pillars; Empty Cell; Mono Y direction: Back/Floor; Front; Pillars; Empty Cell; MagL X direction: Back/Floor; Front; Pillars; Empty Cell; MagL Y direction: Back/Floor; Front; Pillars; Empty Cell; Each bridge can have 6 (yes ... six) different spans to work with, not to mention 4 (yes ... four) road/rail types. Note that there are two parts to a span: Back/Floor and Front A vehicle appears in front of the back and above the floor. That same vehicle will simultaneously appear behind the front and below whatever is attached above the front. The following image demonstrates how the two parts are drawn by the artist and assembled by the game code: Attachment:
BridgesTutorial17.png [ 4.1 KiB | Viewed 40000 times ]
Lets do a mockup to see it in pseudo-action: Attachment:
BridgesTutorial18.png [ 3.74 KiB | Viewed 40000 times ]
Wait a minute! Those don't look very stable. We'd best add some pillars to support the spans and prevent disasters. We'll do that in the next post.
_________________ Visit SimuSchool - Tutorials, Questions and AnswersTTDPatch Nightlies Downloads are backThrive
|
|
Top |
|
|
wallyweb
|
Posted: 25 May 2018, 15:12 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
The final pieces of the bridge are the pillars. Each span of a bridge accommodates one pillar positioned under the near end of the span. The absolute height of a pillar is 8 pixels so that vehicles can pass underneath the bridge. For higher bridges the game mechanics stacks the pillars one atop the other. There are three ways to draw a pillar: 1. A single pillar sprite (like a utility pole) towards the front side of the bridge with the game mechanics positioning the back side pillar with a 16 pixel separation between the pillars. Note that the back pillars are only placed for level 3 or higher. Attachment:
BridgesTutorial19.png [ 26.9 KiB | Viewed 36735 times ]
The left sprite is for bridges in the Y direction. The right sprite is for bridges in the X direction. (the one in the screenshot). Note that the default pillars can only be 2 pixels wide, but they can be as long as a tile. See the next image: Attachment:
BridgesTutorial20.png [ 26.98 KiB | Viewed 36735 times ]
2. Two pillars in one sprite with far pillar positioning turned off. The switch will be described in the section on coding. The next screenshot shows two pillars in one sprite. The separation can be any value as long as both pillars remain within the width of a groundtile. Attachment:
BridgesTutorial21.png [ 26.23 KiB | Viewed 36735 times ]
3. A pier, which is essentially one very wide pillar. Far pillar positioning is turned off. This is similar to the previous screenshot except that the sprite is all one piece: Attachment:
BridgesTutorial22.png [ 25.89 KiB | Viewed 36735 times ]
_________________ Visit SimuSchool - Tutorials, Questions and AnswersTTDPatch Nightlies Downloads are backThrive
|
|
Top |
|
|
wallyweb
|
Posted: 13 Mar 2020, 22:51 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
3. Coding: How to code a bridge in NFO
This is where the fun begins. First, we will present a brief discussion on hexadecimal notation (hex) which is required for NFO coding. Why hex? Because its the easiest way to address the microprocessors in your computer. A microprocessor is just a box full of switches called transistors. Each of these switches can be off (0) or on (1) and is said to be binary. One switch is a bit. 0 or 1 Eight bits is a byte. 0000 0000 = 00 = 0 [binary = hex = decimal] 0000 0001 = 01 = 1 0000 0010 = 02 = 2 0000 0011 = 03 = 3 0000 0100 = 04 = 4 0000 0101 = 05 = 5 0000 0110 = 06 = 6 0000 0111 = 07 = 7 0000 1000 = 08 = 8 0000 1001 = 09 = 9 0000 1010 = 0A = 10 0000 1011 = 0B = 11 0000 1100 = 0C = 12 0000 1101 = 0D = 13 0000 1110 = 0E = 14 0000 1111 = 0F = 15 0001 0000 = 10 = 16 0001 1111 = 1F = 31 0010 0000 = 20 = 32 0010 1111 = 2F = 47 0011 0000 = 30 = 48 0011 1111 = 3F = 63 ~ 1111 1111 = FF = 255 There is an easier way to do this. If you use Windows 10, set the calculator to programmer.
Two bytes is a word. 0000 0000 0000 0000 = 00 00 = 0 Two words is a d-word. 0000 0000 0000 0000 0000 0000 0000 0000 = 00 00 00 00 = 0
_________________ Visit SimuSchool - Tutorials, Questions and AnswersTTDPatch Nightlies Downloads are backThrive
|
|
Top |
|
|
wallyweb
|
Posted: 05 Apr 2020, 14:26 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
d and hd is for decimal (d123) h is for hexadecimal (h123) hex can also be 0x123 To show 0x123 in bytes, write 1 23, then pad the 1 with 0 for 01 and we now have 01 23 Note that 0x4123 is 41 23, no padding needed. Numbers have significanceNumbers on the left are more significant than numbers on the right. left = most significant (msb) right = least significant (lsb) For hexadecimal, we will be considering byte significance, i.e. in hex values large enough to require two or more bytes (word or d-word). In the word value 01 23, 01 is most significant and 23 is least significant. Numbers have endianessDifferent CPUs read hex values differently. Some read msb first. (big endian). Some read lsb first. (little endian). For our purposes, we will use little endian. 0x123 = 01 23 = 23 01An example:The sprite number for OTTD's temperate flat grass tile is d3981. Sometimes we will need this decimal value to be in little endian hexadecimal. d3981 = hF8D = 0xF8D = 0F 8D = 8D 0FNow that was simple, wasn't it? (Everybody say YES SIR!)
_________________ Visit SimuSchool - Tutorials, Questions and AnswersTTDPatch Nightlies Downloads are backThrive
|
|
Top |
|
|
wallyweb
|
Posted: 06 Apr 2020, 05:17 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Now we will examine the structure of an NFO file for bridges: An NFO file is made up from a series of Actions that are described in the NewGRF Specifications. The Actions are selected and organized as appropriate for each feature. With a few exceptions, the order of the selected Actions is important. We will organize the order of Actions in a logical sequence. Today's feature is Bridges. The feature number for Bridges is 0x06, or simply 06.
|
|
Top |
|
|
wallyweb
|
Posted: 06 Apr 2020, 06:01 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Here is the list of the Actions for any one of the default OpenTTD Bridges: - Header - Not an action, but appears automatically in every NFO file.
- Action 14 - Static NewGRF information
- Action 8 - Defines GRFID, Name and Description
- Action 4 - Defines text strings
- Action 0 - Defines new properties for anything added or changed by the NewGRF
- Global Settings - Bridges - Bridges - Tables - Action A - Replaces base set sprites
- RealSprites - Sprites that actually are drawn on the screen
|
|
Top |
|
|
wallyweb
|
Posted: 08 Apr 2020, 23:53 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Header - Not an action, but appears automatically in every NFO file The header specifies the Info version: 7 or 32 and the corresponding realsprite format and the escapes: Code: // Automatically generated by GRFCODEC. Do not modify! // (Info version 7) // Escapes: 2+ 2- 2< 2> 2u< 2u> 2/ 2% 2u/ 2u% 2* 2& 2| 2^ 2sto = 2s 2rst = 2r 2psto 2ror = 2rot 2cmp 2ucmp 2<< 2u>> 2>> // Escapes: 71 70 7= 7! 7< 7> 7G 7g 7gG 7GG 7gg 7c 7C // Escapes: D= = DR D+ = DF D- = DC Du* = DM D* = DnF Du<< = DnC D<< = DO D& D| Du/ D/ Du% D% // Format: spritenum pcxfile xpos ypos compression ysize xsize xrel yrel Code: // Automatically generated by GRFCODEC. Do not modify! // (Info version 32) // Escapes: 2+ 2- 2< 2> 2u< 2u> 2/ 2% 2u/ 2u% 2* 2& 2| 2^ 2sto = 2s 2rst = 2r 2psto 2ror = 2rot 2cmp 2ucmp 2<< 2u>> 2>> // Escapes: 71 70 7= 7! 7< 7> 7G 7g 7gG 7GG 7gg 7c 7C // Escapes: D= = DR D+ = DF D- = DC Du* = DM D* = DnF Du<< = DnC D<< = DO D& D| Du/ D/ Du% D% // Format: spritenum imagefile depth xpos ypos xsize ysize xrel yrel zoom flags A header is followed by the first pseudosprite which tells GRFCodec how many lines of code will follow: Code: 0 * 4 0B 00 00 00 The value is in hex. 0x0B (= 11 decimal) nforenum will note the line numbers in decimal.
|
|
Top |
|
|
wallyweb
|
Posted: 09 Apr 2020, 00:10 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Action 14 - Static NewGRF information This Action is not germane to this part of the tutorial. Refer to the NewGRF specifications for details. It will be revisited towards the end of the tutorial in a section describing bridges in JGRPatchPack.
|
|
Top |
|
|
wallyweb
|
Posted: 09 Apr 2020, 00:16 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Action 8 - Defines GRFID, Name and Description This Action is not germane to this tutorial. Refer to the NewGRF specifications for details.
|
|
Top |
|
|
wallyweb
|
Posted: 09 Apr 2020, 11:46 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
Action 4 - Defines text strings Syntax: <Sprite-number> * <Length> 04 <feature> <language-id> <num-ent> <offset> <text> -1*00 // <Sprite-number> * <Length> - running nforenum will insert the proper values. 04 // This is Action 4 06 // <feature> - 06 is bridges FF // <language-id> - Use FF or read this. 01 // <num-ent> - How many consecutive entries to change. 00 DC // <offset> The ID of the first string to change The offset is called from Action 0 "Bridge 00 Name" // <text> The name of this bridge. examples: Code: 6 * 24 04 06 FF 01 00 DC "Bridge 00 Name" 00 7 * 31 04 06 FF 01 01 DC "Bridge 00 Name - Rail" 00 8 * 31 04 06 FF 01 02 DC "Bridge 00 Name - Road" 00 There are three Action 4's per bridge. If you are coding more than one bridge, then the <offset>s are incremented: Second bridge: 03 DC 04 DC 05 DC Third bridge: 06 DC 07 DC 08 DC etc. ...
|
|
Top |
|
|
wallyweb
|
Posted: 09 Apr 2020, 11:54 |
|
Master Mentor |
|
Joined: 27 Feb 2012, 22:45 Posts: 1880 Location: Canada
|
|
Top |
|
|