// Heavy Freight Station
// =====================

	1 * 1	00 04 09 01 HEAVY_FREIGHT_STAT
		08 "ISRA"

		// Sprite layout
		1A 0A
			// 00 (x) - crane on rails
			44
			\dx000003F4 \wx0000 // ground sprite - track
			\dx8000042D \wx0000 // back platform
			00 00 00 // x/y/z offset
			10 05 03 // x/y/z extent
			\dx8000042E \wx0000 // front platform
			00 0B 00 // x/y/z offset
			10 05 03 // x/y/z extent
			\dx80000431 \wx0013 // crane back
			00 00 03 // x/y/z offset
			0C 05 28 // x/y/z extent
			01 0A 11 12 // registers - show, sprite offset, x, y
			\dx8000043C \wx0013 // crane front
			00 0B 03 // x/y/z offset
			0C 05 28 // x/y/z extent
			01 0A 11 12 // registers - show, sprite offset, x, y

			// 01 (y) - crane on rails
			44
			\dx000003F3 \wx0000 // ground sprite - track
			\dx8000042F \wx0000 // back platform
			00 00 00 // x/y/z offset
			05 10 03 // x/y/z extent
			\dx80000430 \wx0000 // front platform
			0B 00 00 // x/y/z offset
			05 10 03 // x/y/z extent
			\dx80000447 \wx0013 // crane back
			00 00 03 // x/y/z offset
			05 0C 28 // x/y/z extent
			01 0A 12 11 // registers - show, sprite offset, x, y
			\dx80000452 \wx0013 // crane front
			0B 00 03 // x/y/z offset
			05 0C 28 // x/y/z extent
			01 0A 12 11 // registers - show, sprite offset, x, y

			// 02 (x) - platform
			43
			\dx000003F4 \wx0002 // ground sprite
			10 // register
			\dx8000042D \wx0040 // ground overlay sprite (child)
			00 00 80 // x/y/z offset
			04 // value for variable 10
			\dx8000042D \wx0001 // back platform
			00 00 00 // x/y/z offset
			10 05 03 // x/y/z extent
			06 // register
			\dx8000042E \wx0001 // front platform
			00 0B 00 // x/y/z offset
			10 05 03 // x/y/z extent
			07 // register

			// 03 (y) - platform
			43
			\dx000003F3 \wx0002 // ground sprite
			10 // register
			\dx8000042E \wx0040 // ground overlay sprite (child)
			00 00 80 // x/y/z offset
			04 // value for variable 10
			\dx8000042F \wx0001 // back platform
			00 00 00 // x/y/z offset
			05 10 03 // x/y/z extent
			06 // register
			\dx80000430 \wx0001 // front platform
			0B 00 00 // x/y/z offset
			05 10 03 // x/y/z extent
			07 // register

			// 04 (x) - ramp
			45
			\dx000003F4 \wx0002 // ground sprite
			10 // register
			\dx8000042D \wx0040 // ground overlay sprite (child)
			00 00 80 // x/y/z offset
			04 // value for variable 10
			\dx8000042E \wx0001 // back ramp N
			00 00 00 // x/y/z offset
			10 05 03 // x/y/z extent
			02 // register
			\dx8000042E \wx0001 // front ramp N
			00 0B 00 // x/y/z offset
			10 05 03 // x/y/z extent
			03 // register
			\dx8000042D \wx0001 // back ramp S
			00 00 00 // x/y/z offset
			10 05 03 // x/y/z extent
			04 // register
			\dx8000042D \wx0001 // front ramp S
			00 0B 00 // x/y/z offset
			10 05 03 // x/y/z extent
			05 // register

			// 05 (y) - ramp
			45
			\dx000003F3 \wx0002 // ground sprite
			10 // register
			\dx8000042E \wx0040 // ground overlay sprite (child)
			00 00 80 // x/y/z offset
			04 // value for variable 10
			\dx80000430 \wx0001 // back ramp N
			00 00 00 // x/y/z offset
			05 10 03 // x/y/z extent
			02 // register
			\dx80000430 \wx0001 // front ramp N
			0B 00 00 // x/y/z offset
			05 10 03 // x/y/z extent
			03 // register
			\dx8000042F \wx0001 // back ramp S
			00 00 00 // x/y/z offset
			05 10 03 // x/y/z extent
			04 // register
			\dx8000042F \wx0001 // front ramp S
			0B 00 00 // x/y/z offset
			05 10 03 // x/y/z extent
			05 // register


			// 06 (x) - office
			44
			\dx000003F4 \wx0002 // ground sprite - track
			10 // register
			\dx8000042D \wx0040 // ground overlay (child) - platforms
			00 00 80 // x/y/z offset
			04 // value for variable 10
			\dx8000843D \wx0002 // office
			00 00 00 // x/y/z offset
			10 05 0E // x/y/z extent
			09 // register
			\dx8000044F \wx0003 // snow
			00 00 80 // x/y/z offset
			08 09 // registers
			\dx8000842F \wx0000 // front platform fence
			03 0D 00 // x/y/z offset
			0A 01 05 // x/y/z extent

			// 07 (y) - office
			44
			\dx000003F3 \wx0002 // ground sprite - track
			10 // register
			\dx8000042E \wx0040 // ground overlay (child) - platforms
			00 00 80 // x/y/z offset
			04 // value for variable 10
			\dx8000843E \wx0002 // office
			00 00 00 // x/y/z offset
			05 10 0E // x/y/z extent
			09 // register
			\dx80000450 \wx0003 // snow
			00 00 80 // x/y/z offset
			08 09 // registers
			\dx80008430 \wx0000 // front platform fence
			0D 03 00 // x/y/z offset
			01 0A 05 // x/y/z extent

			// 08 (x) - purchase
			41
			\dx000003F4 \wx0000 // ground sprite
			\dx8000842D \wx0000 // purchase list sprite
			00 00 00 // x/y/z offset
			10 10 20 // x/y/z extent

			// 09 (y) - purchase
			41
			\dx000003F3 \wx0000 // ground sprite
			\dx8000842E \wx0000 // purchase list sprite
			00 00 00 // x/y/z offset
			10 10 20 // x/y/z extent


		0B 06 // use callback to determine layout and animation frame

		0D 01 // disallow platform length 1
		14 03 // wires (not on crane tiles)
		11 FC // pylon placement (not on crane tiles)

		16 \wx01E1 // animation info 226 frames looping
		17 04      // animation speed 2^4 ticks per frame (~400ms)
		18 \wx0018 // animation triggers - train enters (0x08), train leaves (0x10)


	1 * 1 	01 04 01 02
	// Purchase list
	1 images/purchaseicons.pcx  19  800  9  62  64 -31 -31 // 042D x
	1 images/purchaseicons.pcx  91  800  9  62  64 -31 -31 // 042E y

	1 * 1	02 04 00 // ID
		00 01
		\w0


// Get number of non-animated tiles to north (non_anim_N)
	1 * 1	02 04 35 // ID
		81
		1A
		20 10
		\2- // subtract position from N from 0x10 to negate the low nibble
		41 // platform info and relative position
		20 0F // position along platform from north
		\2&
		1A
		20 0F // mask for low nibble
		\2rst
		7B 68 // station info of nearby tile using position as parameter
		0A 0F
		01
		\wx8001 09 09 // ramp
		\wx8000

// Get number of non-animated tiles to south (non_anim_S)
	1 * 1	02 04 33 // ID
		81
		41 // platform info and relative position
		24 0F // position along platform from south
		\2rst
		7B 68 // station info of nearby tile using position as parameter
		0A 0F
		01
		\wx8001 09 09 // ramp
		\wx8000


// Callback 141 - Next animation frame
// --------------------------------
	// Calculate new frame for reverse movement - south tile of animation
	1 * 1	02 04 42 // ID
		81 1A // all bits on
		20 \b225 // max_frame
		\2-
		4A // animation frame
		00 FF
		00 // return new_frame = max_frame - frame
		\wx8000

	// Animation frame control - determine point to reverse direction
	// {max_frame = (plat_length - non_anim_N - non_anim_S - 1) * 16}
	1 * 1	02 04 43 // ID
		81 41 // platform info and position
		30 0F // platform length
		\2-
		7E 35 // subtract number of non-animated tiles to N
		20 0F
		\2-
		7D 26 // subtract number of non-animated tiles to S (using register)
		20 0F
		\2< // result = min(val1, val2)
		1A // all bits on
		20 \b7 // result is capped at max 7
		\2-
		1A
		20 \b1 // val - 1
		\2<<
		1A // all bits on
		20 \b4 // val * 16 - gives max frame for this platform length
		\2-
		4A // animation frame
		00 FF // subtract animation frame from max frame
		01
		\wx0042 00 00 // if animation frame = max frame, set new frame
		\wx80FE // continue animation

	// Next animation frame
	1 * 1	02 04 41 // ID
		81
		7E 33 // get number of non-animated tiles to south
		20 0F
		\2sto 1A
		20 26 // store in register to prevent calculating non_anim_S multiple times
		\2rst
		41 // platform info and position
		24 0F // position along platform from south
		\2-
		7D 26 // subtract number of non-animated tiles to S (using register)
		00 0F
		01
		\wx0043 00 00 // if south tile of animation
		\wx80FE // continue animation


// Callback 140 - Animation control
// --------------------------------
	// Animation start/stop control
	1 * 1	02 04 20 // ID
		81 18 // extra callback info - reason for call
		00 FF
		02
		\wx80FE 03 03 // vehicle enters station - start
		\wx80FF 04 04 // vehicle leaves station - stop
		\wx80FD // do nothing

	1 * 1	02 04 21 // ID
		81 68 00 // station info: check this tile
		0C 03 // shift and mask 2 bits for station part type
		01
		\wx0020 00 00 // crane
		\wx80FD // do nothing


// Real sprites
//-------------
	// Platforms
	// Test variable 10 for real sprites
	1 * 1	02 04 3B // ID
		81 10 // additional information for sprite selection
		00 0F
		01
		\wx00FD 04 04 // ground overlay sprites
		\wx00FC // platform sprites

	// Ramps
	// Test variable 10 for real sprites
	1 * 1	02 04 3C // ID
		81 10 // additional information for sprite selection
		00 0F
		01
		\wx00FD 04 04 // ground overlay sprites
		\wx00F7 // ramp sprites

	// Office
	// Test variable 10 for real sprites
	1 * 1	02 04 3D // ID
		81 10 // additional information for sprite selection
		00 0F
		01
		\wx00FD 04 04 // ground overlay sprites
		\wx00EE // office sprites


// Determine register values
// -------------------------
// Crane

// frame     : current frame of animation (0 to 225)
// a_frame   : adjusted frame number for direction change (0 to 112, 112 to 0)
// t_frame   : frame number for tile (0 to 27), crane is hidden in first and last positions

// Frames
// frame:       0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30...
// t_frame t0: 14 15 16 17 18 19 20 21 22 23 24 25 26 27
//         t1:        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
//         t2:                                                        0  1  2  3  4  5  6  7  8  9 10 11 12...

// t1 sprite offset:     0  0  1  1  2  2  3  3  4  4  5  5  5  5  5  5  6  6  7  7  8  8  9  9 10 10
// t1 visible:        0  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  0
// t1 x offset:          5  4  5  4  5  4  5  4  5  4  5  4  3  2  1  0  1  0  1  0  1  0  1  0  1  0

	// Get animation frame for south tile of animation
	1 * 1	02 04 47 // ID
		81 41 // platform info and position
		24 0F // position along platform from south
		\2-
		7D 26 // subtract number of non-animated tiles to S (using register)
		20 FF
		\2rst
		7B 66 // animation frame of nearby tile using position from south as parameter
		00 FF
		00 // return frame
		\wx8000

	// Calculate a_frame for reverse movement
	1 * 1	02 04 46 // ID
		81 1A // all bits on
		20 \b225 // max_frame
		\2-
		7D 25 // read register for frame from position
		00 FF
		00 // return a_frame = max_frame - frame
		\wx8000

	// Return a_frame for forward movement
	1 * 1	02 04 48 // ID
		81
		7D 25 // read register for frame from position
		00 FF
		00 // return a_frame = frame
		\wx8000

	// Select movement direction
	1 * 1	02 04 40 // ID
		81 7E 47 // animation frame
		20 FF
		\2sto 1A
		00 25 // store in register to prevent multiple calls to frame of nearby tile
		01
		\wx0048 \b0 \b112 // frames 0 to 112
		\wx0046 // frames 113 to max

	// Calculate t_frame {t_frame = a_frame + 14 - ((p_pos - non_anim_S) * 16)}
	1 * 1	02 04 4A // ID
		81
		41 // platform info, get position along platform (from S)
		24 0F
		\2-
		7D 26 // subtract number of non-animated tiles to S (using register)
		20 0F
		\2<<
		1A
		20 \b4 // val * 16
		\2sto
		1A
		20 23 // store in register
		\2rst
		7E 40 // get a_frame
		20 FF
		\2+
		1A // all bits on
		20 \b14 // val + 14
		\2-
		7D 23 // read register
		20 FF // subtract 16 * (p_pos - non_anim_S)
		\2> // result = max(val1, val2)
		1A // all bits on
		20 \b0 // result is capped at min 0
		\2< // result = min(val1, val2)
		1A // all bits on
		00 \b27 // result is capped at max 27
		00 // return t_frame
		\wx8000

	// Select sprite offset
	1 * 1	02 04 61 // ID
		81 7E 4A // t_frame (0 to 14)
		20 FF
		\2sto 1A
		00 21 // store in register to prevent calculating t_frame multiple times
		0A
		\wx8000 \b1 \b2
		\wx8001 \b3 \b4
		\wx8002 \b5 \b6
		\wx8003 \b7 \b8
		\wx8004 \b9 \b10
		\wx8006 \b17 \b18
		\wx8007 \b19 \b20
		\wx8008 \b21 \b22
		\wx8009 \b23 \b24
		\wx800A \b25 \b26
		\wx8005

	// Check for animated tile
	1 * 1	02 04 60 // ID
		81
		7E 33 // get number of non-animated tiles to south
		20 0F
		\2sto 1A
		20 26 // store in register to prevent calculating non_anim_S multiple times
		\2rst
		41 // platform info and position
		24 0F // position along platform from south
		\2-
		7D 26 // subtract number of non-animated tiles to S (using register)
		00 0F
		01
		\wx0061 00 06 // if valid animation tile
		\wx8000 // else

	// Hide sprite
	1 * 1	02 04 63 // ID
		81 7D 21 // read register for t_frame
		00 FF
		01
		\wx8001 \b1 \b26 // t_frame 1 to 26 - show
		\wx8000 // hide

	// Check for animated tile
	1 * 1	02 04 62 // ID
		81 41 // platform info and position
		24 0F // position along platform from south
		\2-
		7D 26 // subtract number of non-animated tiles to S (using register)
		00 0F
		01
		\wx0063 00 06 // if valid animation tile
		\wx8000 // hide

	// Select sprite position x offset
	1 * 1	02 04 65 // ID
		81 7D 21 // read register for t_frame
		00 FF
		\b20
		\wx8005 \b1 \b1
		\wx8004 \b2 \b2
		\wx8005 \b3 \b3
		\wx8004 \b4 \b4
		\wx8005 \b5 \b5
		\wx8004 \b6 \b6
		\wx8005 \b7 \b7
		\wx8004 \b8 \b8
		\wx8005 \b9 \b9
		\wx8004 \b10 \b10
		\wx8005 \b11 \b11
		\wx8004 \b12 \b12
		\wx8003 \b13 \b13
		\wx8002 \b14 \b14
		\wx8001 \b15 \b15
		\wx8001 \b17 \b17
		\wx8001 \b19 \b19
		\wx8001 \b21 \b21
		\wx8001 \b23 \b23
		\wx8001 \b25 \b25
		\wx8000

	// Check for animated tile
	1 * 1	02 04 64 // ID
		81 41 // platform info and position
		24 0F // position along platform from south
		\2-
		7D 26 // subtract number of non-animated tiles to S (using register)
		00 0F
		01
		\wx0065 00 06 // if valid animation tile
		\wx8000 // else


// Platforms
	1 * 1	02 04 29 // ID
		81 41 // platform info and position
		08 03 // platform number from N mod 4
		01
		\wx8001 01 01 // platform 1 - single sided back platform
		\wx8000 // single sided front platform


// Ramps
 // North or south
	1 * 1	02 04 2D // ID
		81 41 // platform info and position
		04 0F // position along platform from S
		01
		\wx8002 00 00 // south
		\wx8000 // north

	// Ramp back
	1 * 1	02 04 2B // ID
		81 41 // platform info and position
		00 0F // position along platform from N
		01
		\wx8000 00 00 // no back ramp on north most tile
		\wx8001 // show back ramp

	1 * 1	02 04 2A // ID
		81 41 // platform info and position
		08 03 // platform number from N mod 4
		02
		\wx002B 01 01 // platform 1 - maybe back ramp
		\wx8000 02 02 // platform 2 - no back ramp
		\wx8001 // show back ramp

	// Ramp front
	1 * 1	02 04 2C // ID
		81 41 // platform info and position
		08 03 // platform number from N mod 4
		01
		\wx8000 01 01 // platform 1 - no front ramp
		\wx8002 // show front ramp


// Offices
	// Office variety
	1 * 1	02 04 27 // ID
		80
		00 // don't re-randomise
		10 // use bit 16
		02
		\wx8000
		\wx8006


//@@WARNING DISABLE 100
//@@WARNING DISABLE 170

	// Crane on rails
	1 * 1	02 04 15 // ID
		85 7E 60 // get crane sprite offset
		20 \wx7FFF
		\2sto 1A
		20 \wx000A // store in register - sprite offset
		\2rst
		7E 62 // get crane show/hide
		20 \wx7FFF
		\2sto 1A
		20 \wx0001 // store in register - show crane flag
		\2rst
		7E 64 // get crane position offset
		20 \wx7FFF
		\2sto 1A
		20 \wx0011 // store in register - move x offset
		\2rst
		1A // all bits on
		20 \w0 // val = 0
		\2sto 1A
		00 \wx0012 // store in register - move y offset
		01
		\wx00CC \w0 \w0
		\wx00CC

	// Platform
	1 * 1	02 04 16 // ID
		85 7E 29 // get N/S bit
		20 \wx0001
		\2sto 1A
		20 \wx0006 // store in register
		\2^ 1A // use XOR to invert
		20 \wx0001 // invert bit 0
		\2sto 1A
		20 \wx0007 // store in register
		\2rst
		7E BE // get normal/snow/desert offset
		20 \wx7FFF
		\2+
		7E BD // add monorail/maglev offset
		20 \wx00FF
		\2sto 1A
		00 \wx0010 // store in register - ground sprite offset
		01
		\wx003B \w0 \w0
		\wx003B

	// Ramp
	1 * 1	02 04 17 // ID
		85 7E 2C // get front ramp
		20 \wx000F
		\2+
		7E 2A // add back ramp
		20 \wx000F
		\2<<
		7E 2D // shift left 2 bits if S ramp
		20 \wx000F
		\2sto 1A
		20 \wx0020 // store in register
		\2rst
		7D 20 // read register for show/hide bits
		20 \wx0001 // shift and mask for bit 0
		\2sto 1A
		20 \wx0002 // store in register - back ramp S show/hide
		\2rst
		7D 20 // read register for show/hide bits
		21 \wx0001 // shift and mask for bit 1
		\2sto 1A
		20 \wx0003 // store in register - back ramp S show/hide
		\2rst
		7D 20 // read register for show/hide bits
		22 \wx0001 // shift and mask for bit 2
		\2sto 1A
		20 \wx0004 // store in register - back ramp S show/hide
		\2rst
		7D 20 // read register for show/hide bits
		23 \wx0001 // shift and mask for bit 3
		\2sto 1A
		20 \wx0005 // store in register - front ramp S show/hide
		\2rst
		7E BE // get normal/snow/desert offset
		20 \wx7FFF
		\2+
		7E BD // add monorail/maglev offset
		20 \wx00FF
		\2sto 1A
		00 \wx0010 // store in register - ground sprite offset
		01
		\wx003C \w0 \w0
		\wx003C

	// Office
	1 * 1	02 04 18 // ID
		85 7E 27 // get random office variety offset
		20 \wx00FF
		\2sto 1A
		20 \wx0009 // store in register
		\2rst
		7E BB // get snow overlay flag
		20 \wx00FF
		\2sto 1A
		20 \wx0008 // store in register
		\2rst
		7E BE // get normal/snow/desert offset
		20 \wx7FFF
		\2+
		7E BD // add monorail/maglev offset
		20 \wx00FF
		\2sto 1A
		00 \wx0010 // store in register
		01
		\wx003D \w0 \w0
		\wx003D

//@@WARNING ENABLE 100
//@@WARNING ENABLE 170

	1 * 1	02 04 1A // ID
		81 68 00 // station info: check this tile
		0C 03 // shift and mask 2 bits for station part type
		03
		\wx0015 00 00 // crane
		\wx0016 01 01 // platform
		\wx0017 02 02 // ramp
		\wx0018 // office


// Callback 14 - Sprite layout
// ---------------------------
	1 * 1	02 04 30 // ID
		81 68 00 // station info: check this tile
		0C 03 // shift and mask 2 bits for station part type
		03
		\wx8000 00 00 // crane
		\wx8002 01 01 // platform
		\wx8004 02 02 // ramp
		\wx8006 // office


// Callback 24 - Station layout
// ----------------------------
	// Crane on rails
	1 * 1	02 04 0C // ID
		81 10 // platform info and position
		00 0F // position along platform from N
		01
		\wx8004 00 00 // ramp
		\wx8000 // crane on rails

	// Single sided front platform
	1 * 1	02 04 0D // ID
		81 10 // platform info and position
		00 0F // position along platform from N
		01
		\wx8004 00 00 // ramp
		\wx8002 // front platform

	// Single sided back platform with office
	1 * 1	02 04 0A // ID
		81 10 // platform info and position
		00 0F // position along platform from N
		03
		\wx8004 00 00 // ramp
		\wx8006 01 01 // office
		\wx8004 02 02 // ramp
		\wx8002 // back platform

	1 * 1	02 04 0E // ID
		81 10 // platform info and position
		08 03 // platform number from N mod 4
		02
		\wx000A 01 01 // platform 1 - single sided back platform with office
		\wx000D 02 02 // platform 2 - single sided front platform
		\wx000C // crane on rails

	1 * 1	02 04 08 // ID
		81 10 // platform info and position
		04 0F // position along platform from S
		01
		\wx8004 00 00 // ramp
		\wx000E

// -------------------------

	1 * 1	02 04 02 // ID
		85 0C // callback
		00 \wxFFFF
		03
		\wx0030 \wx0014 \wx0014 // sprite layout
		\wx0021 \wx0140 \wx0140 // animation control
		\wx0041 \wx0141 \wx0141 // animation frame
		\wx001A // real sprites

	// Purchase list
	1 * 1	02 04 03 // ID
		81 0C // callback
		00 FF
		02
		\wx8008 14 14 // sprite layout
		\wx0008 24 24 // station layout
		\wx0000 // real sprites

	1 * 1	03 04
		01 HEAVY_FREIGHT_STAT
		01
		FF \wx0003 // purchase list
		\wx0002
