Difference between revisions of "NML:Alternative sprites"
Planetmaker (talk | contribs) (adjust description somewhat towards current syntax) |
|||
(9 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{NMLNavBlocksyntax}} |
{{NMLNavBlocksyntax}} |
||
+ | |||
+ | == alternative_sprites == |
||
A <code style="color:darkgreen">alternative_sprites</code> block allows you to specify alternative sprites (zoom levels and / or 32bpp) that are drop-in replacements for some real sprites in your grf. The syntax is as follows: |
A <code style="color:darkgreen">alternative_sprites</code> block allows you to specify alternative sprites (zoom levels and / or 32bpp) that are drop-in replacements for some real sprites in your grf. The syntax is as follows: |
||
− | alternative_sprites(block_name, zoom_level, type[, filename]) { |
+ | alternative_sprites(block_name, zoom_level, type[, filename[, mask_filename]]) { |
[[NML:Realsprites|list of realsprites]] |
[[NML:Realsprites|list of realsprites]] |
||
} |
} |
||
+ | === block_name === |
||
− | block_name is the name of the replace/replace_new |
+ | block_name is the name of the [[NML:Replace_TTD_sprites|replace / base_graphics]], [[NML:Replace_new_sprites|replace_new]], [[NML:Add_font_glyphs|font_glyph]] or [[NML:Spriteset|spriteset]]-block for which you want to provide alternative sprites. zoom_level can be |
+ | |||
+ | === zoom_level === |
||
{| |
{| |
||
+ | !name !!zoom level!!Grid size !!Groundsprite with zig-zag border!!Groundsprite with smooth border!!offset_x, offset_y with smooth border!!Description |
||
− | !name !! tile size !! description |
||
|- |
|- |
||
− | |<code style="color:darkgreen"> |
+ | |<code style="color:darkgreen">ZOOM_LEVEL_OUT_8X</code> |
+ | | 8x out || 8 x 4 || 8 x 3 || 8 x 3 || -3, 0 |
||
+ | |rowspan="3"| zoomed-out |
||
|- |
|- |
||
− | |<code style="color:darkgreen"> |
+ | |<code style="color:darkgreen">ZOOM_LEVEL_OUT_4X</code> |
+ | | 4x out || 16 x 8 || 16 x 7 || 16 x 7 || -7, 0 |
||
|- |
|- |
||
− | |<code style="color:darkgreen"> |
+ | |<code style="color:darkgreen">ZOOM_LEVEL_OUT_2X</code> |
+ | | 2x out || 32 x 16 || 32 x 15 || 32 x 15 || -15, 0 |
||
+ | |- style="background:lightblue" |
||
⚫ | |||
+ | | (normal) || 64 x 32 || 64 x 31 || 64 x 31 || -31, 0 || The standard |
||
|- |
|- |
||
− | |<code style="color:darkgreen"> |
+ | |<code style="color:darkgreen">ZOOM_LEVEL_IN_2X</code> |
+ | | 2x in || 128 x 64 || 128 x 62 || 128 x 63 || -62, -1 |
||
+ | |rowspan="2"| zoomed-in |
||
|- |
|- |
||
− | |<code style="color:darkgreen"> |
+ | |<code style="color:darkgreen">ZOOM_LEVEL_IN_4X</code> |
+ | | 4x in || 256 x 128 || 256 x 124 || 256 x 127 || -124, -2 |
||
|- |
|- |
||
+ | | || (X)x in || (X*32) x (X*16) || (X*32) x floor(X*15) || (X*32) x (X*16-1) || ceil(X*-31), ceil(X*-1/2) || Generalisation |
||
⚫ | |||
|} |
|} |
||
+ | Hint: |
||
⚫ | |||
+ | If you have a normal-zoom sprite with (offset_x, yel), the 2x zoom-in sprite will have (2*offset_x, 2*offset_y-1), and the 4x zoom-in sprite will have (4*offset_x, 4*offset_y-2). |
||
+ | These conversions are implied by how OpenTTD draws foundations, in particular half-tile foundations. At 1x zoom the vertical slope edge is between two pixels, and the horizontal slope edge is in the middle of a pixel. That is: The middle of the tiles (green line) needs to line up, the top of the tiles (red line) then does not line up: |
||
+ | [[File:Groundsprites_4x.png]] |
||
+ | |||
+ | === type === |
||
⚫ | |||
+ | |||
+ | === filename === |
||
Specifying a filename is optional, it's only useful if you have multiple sprites in the same file. If every sprite is in a separate file you'll have to specify the filename for each realsprite anyway, so you can leave it out of the alternative_sprites-block. |
Specifying a filename is optional, it's only useful if you have multiple sprites in the same file. If every sprite is in a separate file you'll have to specify the filename for each realsprite anyway, so you can leave it out of the alternative_sprites-block. |
||
+ | === mask_filename === |
||
− | An example for an implementation |
||
+ | For 32bpp only, you can also specify a default filename to use for mask sprites. These (8bpp) sprites have the same size and offsets as the normal sprites and are used for recolouring purposes. See the [[NML:Realsprites|real sprites]] page for more info. |
||
+ | |||
+ | === Example === |
||
+ | The block contains a list of [[NML:Realsprites|real]] and/or [[NML:Recolour sprites|recolour]] sprites. An example for an implementation |
||
// Foster Express tram |
// Foster Express tram |
||
spriteset(foster_express_set, "opengfx_generic_trams1.pcx") { |
spriteset(foster_express_set, "opengfx_generic_trams1.pcx") { |
||
Line 62: | Line 89: | ||
[272,56, 20,19, -6, -7] |
[272,56, 20,19, -6, -7] |
||
} |
} |
||
+ | |||
+ | === Advanced example with templates === |
||
+ | Sprites for various zoom-levels and color-depths scale the number of offsets and positions you need to put into the code. |
||
+ | This can be simplified using templates. |
||
+ | Assume you have 3 spritesheets containing vehicle sprites for multiple vehicle and cargos, organised in rows. |
||
+ | * 3 spritesheets for 8bpp 1x-zoom, 32bpp 1x-zoom, 32bpp 4x-zoom |
||
+ | * Spritesheets organised in rows, one vehicle (with 8 orientations) per row |
||
+ | * Rows have height 32 in 1x-spritesheet, and 128 in 4x-spritesheet. |
||
+ | |||
+ | // Template for sprites with multiple zoom levels |
||
+ | // x,y Position in 1x spritesheet |
||
+ | // w,h Size in 1x spritesheet |
||
+ | // ox,oy Offset for 1x sprite |
||
+ | // zoom Zoomlevel |
||
+ | template template_zoom(x, y, w, h, ox, oy, zoom) { |
||
+ | [ x*zoom, y*zoom, w*zoom, h*zoom, ox*zoom, oy*zoom - (zoom/2) ] |
||
+ | } |
||
+ | |||
+ | // Template for a vehicle. |
||
+ | // line Line in spritesheet |
||
+ | // zoom Zoomlevel |
||
+ | template template_vehicle(line, zoom) { |
||
+ | template_zoom( 0, line*32, 8, 18, -3, -10, zoom) // N |
||
+ | template_zoom( 16, line*32, 20, 19, -14, -5, zoom) // NE |
||
+ | template_zoom( 48, line*32, 28, 15, -14, -8, zoom) // E |
||
+ | template_zoom( 96, line*32, 20, 19, -6, -7, zoom) // SE |
||
+ | template_zoom(128, line*32, 8, 18, -3, -10, zoom) // S |
||
+ | template_zoom(144, line*32, 20, 19, -14, -9, zoom) // SW |
||
+ | template_zoom(176, line*32, 28, 15, -14, -8, zoom) // W |
||
+ | template_zoom(224, line*32, 20, 19, -6, -7, zoom) // NW |
||
+ | } |
||
+ | |||
+ | /// Line 0 contains "coal" sprites |
||
+ | spriteset(vehicle_coal, "vehicles_1x_8bpp.png") { |
||
+ | template_vehicle(0, 1) |
||
+ | } |
||
+ | alternative_sprites(vehicle_coal, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "vehicles_1x_32bpp.png") { |
||
+ | template_vehicle(0, 1) |
||
+ | } |
||
+ | alternative_sprites(vehicle_coal, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "vehicles_4x_32bpp.png") { |
||
+ | template_vehicle(0, 4) |
||
+ | } |
||
+ | |||
+ | /// Line 1 contains "mail" sprites |
||
+ | spriteset(vehicle_mail, "vehicles_1x_8bpp.png") { |
||
+ | template_vehicle(1, 1) |
||
+ | } |
||
+ | alternative_sprites(vehicle_mail, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "vehicles_1x_32bpp.png") { |
||
+ | template_vehicle(1, 1) |
||
+ | } |
||
+ | alternative_sprites(vehicle_mail, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "vehicles_4x_32bpp.png") { |
||
+ | template_vehicle(1, 4) |
||
+ | } |
Latest revision as of 16:29, 7 August 2016
Vehicles, Stations, Canals, Bridges, Towns, Houses, Industries (Tiles), Cargos, Airports+Tiles, Objects, Railtypes, Roadtypes, Tramtypes, Terrain
alternative_sprites
A alternative_sprites
block allows you to specify alternative sprites (zoom levels and / or 32bpp) that are drop-in replacements for some real sprites in your grf. The syntax is as follows:
alternative_sprites(block_name, zoom_level, type[, filename[, mask_filename]]) { list of realsprites }
block_name
block_name is the name of the replace / base_graphics, replace_new, font_glyph or spriteset-block for which you want to provide alternative sprites. zoom_level can be
zoom_level
name | zoom level | Grid size | Groundsprite with zig-zag border | Groundsprite with smooth border | offset_x, offset_y with smooth border | Description |
---|---|---|---|---|---|---|
ZOOM_LEVEL_OUT_8X
|
8x out | 8 x 4 | 8 x 3 | 8 x 3 | -3, 0 | zoomed-out |
ZOOM_LEVEL_OUT_4X
|
4x out | 16 x 8 | 16 x 7 | 16 x 7 | -7, 0 | |
ZOOM_LEVEL_OUT_2X
|
2x out | 32 x 16 | 32 x 15 | 32 x 15 | -15, 0 | |
ZOOM_LEVEL_NORMAL
|
(normal) | 64 x 32 | 64 x 31 | 64 x 31 | -31, 0 | The standard |
ZOOM_LEVEL_IN_2X
|
2x in | 128 x 64 | 128 x 62 | 128 x 63 | -62, -1 | zoomed-in |
ZOOM_LEVEL_IN_4X
|
4x in | 256 x 128 | 256 x 124 | 256 x 127 | -124, -2 | |
(X)x in | (X*32) x (X*16) | (X*32) x floor(X*15) | (X*32) x (X*16-1) | ceil(X*-31), ceil(X*-1/2) | Generalisation |
Hint: If you have a normal-zoom sprite with (offset_x, yel), the 2x zoom-in sprite will have (2*offset_x, 2*offset_y-1), and the 4x zoom-in sprite will have (4*offset_x, 4*offset_y-2).
These conversions are implied by how OpenTTD draws foundations, in particular half-tile foundations. At 1x zoom the vertical slope edge is between two pixels, and the horizontal slope edge is in the middle of a pixel. That is: The middle of the tiles (green line) needs to line up, the top of the tiles (red line) then does not line up:
type
The type argument specifies which kind of sprite follows. This may be either BIT_DEPTH_8BPP
or BIT_DEPTH_32BPP
.
filename
Specifying a filename is optional, it's only useful if you have multiple sprites in the same file. If every sprite is in a separate file you'll have to specify the filename for each realsprite anyway, so you can leave it out of the alternative_sprites-block.
mask_filename
For 32bpp only, you can also specify a default filename to use for mask sprites. These (8bpp) sprites have the same size and offsets as the normal sprites and are used for recolouring purposes. See the real sprites page for more info.
Example
The block contains a list of real and/or recolour sprites. An example for an implementation
// Foster Express tram spriteset(foster_express_set, "opengfx_generic_trams1.pcx") { [ 48,56, 8,18, -3,-10] [ 64,56, 20,19, -14, -5] [ 96,56, 28,15, -14, -8] [144,56, 20,19, -6, -7] [176,56, 8,18, -3,-10] [192,56, 20,19, -14, -9] [224,56, 28,15, -14, -8] [272,56, 20,19, -6, -7] } alternative_sprites(foster_express_set, ZOOM_LEVEL_IN_2X, BIT_DEPTH_8BPP, "opengfx_generic_trams1.pcx") { [ 48,56, 8,18, -3,-10] [ 64,56, 20,19, -14, -5] [ 96,56, 28,15, -14, -8] [144,56, 20,19, -6, -7] [176,56, 8,18, -3,-10] [192,56, 20,19, -14, -9] [224,56, 28,15, -14, -8] [272,56, 20,19, -6, -7] } alternative_sprites(foster_express_set, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "opengfx_generic_trams1.png") { [ 48,56, 8,18, -3,-10] [ 64,56, 20,19, -14, -5] [ 96,56, 28,15, -14, -8] [144,56, 20,19, -6, -7] [176,56, 8,18, -3,-10] [192,56, 20,19, -14, -9] [224,56, 28,15, -14, -8] [272,56, 20,19, -6, -7] }
Advanced example with templates
Sprites for various zoom-levels and color-depths scale the number of offsets and positions you need to put into the code. This can be simplified using templates. Assume you have 3 spritesheets containing vehicle sprites for multiple vehicle and cargos, organised in rows.
- 3 spritesheets for 8bpp 1x-zoom, 32bpp 1x-zoom, 32bpp 4x-zoom
- Spritesheets organised in rows, one vehicle (with 8 orientations) per row
- Rows have height 32 in 1x-spritesheet, and 128 in 4x-spritesheet.
// Template for sprites with multiple zoom levels // x,y Position in 1x spritesheet // w,h Size in 1x spritesheet // ox,oy Offset for 1x sprite // zoom Zoomlevel template template_zoom(x, y, w, h, ox, oy, zoom) { [ x*zoom, y*zoom, w*zoom, h*zoom, ox*zoom, oy*zoom - (zoom/2) ] } // Template for a vehicle. // line Line in spritesheet // zoom Zoomlevel template template_vehicle(line, zoom) { template_zoom( 0, line*32, 8, 18, -3, -10, zoom) // N template_zoom( 16, line*32, 20, 19, -14, -5, zoom) // NE template_zoom( 48, line*32, 28, 15, -14, -8, zoom) // E template_zoom( 96, line*32, 20, 19, -6, -7, zoom) // SE template_zoom(128, line*32, 8, 18, -3, -10, zoom) // S template_zoom(144, line*32, 20, 19, -14, -9, zoom) // SW template_zoom(176, line*32, 28, 15, -14, -8, zoom) // W template_zoom(224, line*32, 20, 19, -6, -7, zoom) // NW } /// Line 0 contains "coal" sprites spriteset(vehicle_coal, "vehicles_1x_8bpp.png") { template_vehicle(0, 1) } alternative_sprites(vehicle_coal, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "vehicles_1x_32bpp.png") { template_vehicle(0, 1) } alternative_sprites(vehicle_coal, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "vehicles_4x_32bpp.png") { template_vehicle(0, 4) } /// Line 1 contains "mail" sprites spriteset(vehicle_mail, "vehicles_1x_8bpp.png") { template_vehicle(1, 1) } alternative_sprites(vehicle_mail, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "vehicles_1x_32bpp.png") { template_vehicle(1, 1) } alternative_sprites(vehicle_mail, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "vehicles_4x_32bpp.png") { template_vehicle(1, 4) }