Callbacks Tutorial

From TTWiki
Revision as of 10:31, 3 June 2008 by peter1138 (talk)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Tutorial on using callbacks

Callbacks in Graphics Files

Since TTDPatch 2.0.1 alpha 11, it is possible to use callbacks, in which the graphics files can influence how TTDPatch features work. This is a lot more sophisticated than simply using action 0 to choose various settings, in that callbacks can use the full capabilities of variational and random action 2 entries.

-=How it works=-

When the patch wants to use the value of certain properties, it can ask the graphics file what value to use, instead of simply looking it up in the table set by action 0. It does this if the corresponding callback bit has been set in the vehicle's action 0 properties. Then, the following happens:

  • The patch sets the current callback ID, variable 0C, according to what callback it is
  • Then, the patch starts at the vehicle's action 3 entry and finds the initial action 2 number to use
  • The patch then follows the chain of variational/random action 2 entries
  • The set-id of the final action 2 is used as result for the callback

Because callbacks are different from regular vehicle graphics, the last action 2 in the chain must have a set-id with bit 15 set (e.g. XX 80 to return XX), which is invalid for regular graphics.  Therefore, at least one action 2 in the chain must check the variable 0C, to decide whether this is a callback or the determination of graphics.

-=How to define callbacks=-

There are several things you have to do to get callbacks to work.

  1. If necessary, enable the callback. For vehicles, set the callback bit in the action 0 property for the vehicle which should use callbacks (props 1E, 17, 12 or 14 depending on vehicle type)
  2. Set a default for the value that the callback modifies, e.g. set prop 07 when using the load amount callback
  3. Define an action 3 for the vehicle if it doesn't have one already
  4. Add a variational action 2 that checks the callback variable 0C for the value of the callback. See the description of a variational action 2 to find what values those are.
  5. This variational action 2 has to return a callback result (set-id with bit 15 set) when in a callback, or a regular set-id when not in a callback
  6. Make sure that the "default" of the var. 0C check (corresponding to unknown callbacks) points to a regular action 2 instead of one that returns callback results, ideally using the same action 2 as in the non-callback case. This way, unknown callbacks will fail instead of returning valid, but wrong, results.

As explained above, a callback result is something like -+06 80+- (with 06 being used as value of the callback), instead of a regular set-id that would be for example -+04 00+-.

-=Example=-

Suppose you have three different graphics for a wagon:

  • unpowered with no pantograph
  • powered with active pantograph
  • powered with inactive pantograph

Now you want only every other wagon to be powered and have a pantograph, and only the third wagon should have an active pantograph.

Then, your .NFO file might look like this:

~pp~0 * 4 1C 00 00 00

1 * 8 08 02 xx xx xx xx 00 00

// Set wagon to use new sprites, to use callback, and set default visual effect to none

2 * 11 00 00 03 01 1B 12 FD 1E 01 22 40

// Set engine to use callback and default, set wagon

// power&weight;, but *don't* set to use new sprites

// (no new sprites so we can put a pure callback

// action 2 in its action 3)

3 * 14 00 00 04 01 00 1E 01 22 14 1B 40 00 23 14

4 * 4 01 00 03 04

[...]

// Cargo-ids 0..2: use above sets

17 * 9 02 00 00 01 01 00 00 00 00

18 * 9 02 00 01 01 01 01 00 01 00

19 * 9 02 00 02 01 01 02 00 02 00

// Cargo-id 3: Show active pantographs only for first powered

// wagon, i.e. the third vehicle in the consist

20 * 14 02 00 03 81 40 00 FF 01 01 00 02 02 02 00

// Cargo-id 4: Show pantographs only on every other wagon

21 * 14 02 00 04 81 40 00 01 01 00 00 01 01 03 00

// Repeat the above for a callback, return the following:

// 8080 for unpowered wagons (i.e. has cargo-id 00)

// 8000 for powered wagons without effects (i.e. cargo-id 01)

// 8034 for powered wagons with sparks (i.e. cargo-id 02)

22 * 14 02 00 05 81 40 00 FF 01 34 80 02 02 00 80

23 * 14 02 00 06 81 40 00 01 01 80 80 01 01 05 00

// Finally switch between callback (06) and cargo-ids (04)

24 * 14 02 00 07 81 0C 00 FF 01 06 00 10 10 04 00

// Define callback for the engine: show sparks only if less

// than two wagons (otherwise third wagon has them)

25 * 14 02 00 08 81 40 10 FF 01 40 80 02 FF 14 80

// And use this in the action 3 for the engine and the

// passenger wagon override

26 * 7 03 00 01 00 00 08 00

27 * 7 03 00 81 1B 00 07 00~/pp~

The decision tree of the wagon cargo ID definitions (shown in bold below), read from left to right would look like this:

||

| | |Y, 8034|Powered with sparks

| |Y, 05: Is third wagon?|

| | |N, 8000|Powered without sparks

|Y, 06: Is odd wagon?|

| |N, 8080|

|Unpowered

07: Callback?|

| | |Y, 01|Active pantograph

| |Y, 03: Is third wagon?|

| | |N, 02|Inactive pantograph

|N, 04: Is odd wagon?|

| |N, 00|

|No pantograph

||

Notice how all callbacks return something with "80" in the high byte, and all non-callbacks return regular cargo-IDs for the wagons.  It's important that this is true, or otherwise the vehicle either gets no new graphics or the callback is unsuccessful.  For the engine, we didn't set it to use new graphics, so the action 2 entries can all return callback results.

Note that you still have to set the wagon power using action 0, as well as the callback flags.