EvilEngine/DSCO

A Disco Floor is an arrangement of tiles that light up and damage the player when fully lit.

Each tile has 3 states, "off", "transition", and "on", and has a unique SIMP assigned to each state. When a tile is "on", the player will be damaged if they touch the SIMP. In BFBB and TSSM, there are 3 models that SIMPs use to show each tile state:


 * disco_floor_A_3m - White square, "off" state
 * disco_floor_A_yellow_3m - Yellow square, "transition" state
 * disco_floor_A_red_3m - Red square, "on" state



A Disco Floor can have multiple tiles. For each tile state (off, transition, on), there is a specific prefix that all SIMPs must have in their name to be found by the Disco Floor. The prefix must end with a number (usually 0), and the SIMPs must have this number at the end of their name, counting up by 1 for each tile in the Disco Floor.
 * For example, the prefixes for the Disco Floor in bc01.HIP are "DISCO_NORM_000", "DISCO_YELLOW_000", and "DISCO_RED_000", and there are multiple SIMPs in the level named "DISCO_NORM_000", "DISCO_NORM_001", "DISCO_NORM_002", "DISCO_YELLOW_000", "DISCO_YELLOW_001", etc.

In-game, a Disco Floor runs through a user-defined pattern that specifies which tiles should turn on (red) and off (white) at each step in the pattern. In between steps, there is a transition period in which any tiles about to turn on will be in the "transition" (yellow) state. The user can set how long each step and transition period will take. They can also choose to have the Disco Floor loop automatically when it reaches the end, or simply pause when it reaches the last step.

Format
Internally, a Disco Floor doesn't have a "pattern" or "steps", it just has a list of "states", and each "step" is just one "state" in that list.

Each state is made up of a bitmask, where each tile in the Disco Floor gets 2 bits. Therefore if you have 10 tiles, the bitmask will be 20 bits long. The bitmask is rounded up to the nearest number of bytes, so 20 bits would round up to 24 bits == 3 bytes.

The Disco Floor asset data is represented by the  struct which inherits from  :

After the  is where the SIMP prefixes would be in the data. Each prefix string is padded to an alignment of 4 bytes.

After this is an array of offsets to each state bitmask, relative to offset 0x8. This is somewhat redundant, since each state bitmask will be the same length (3 bytes for 20 tiles, etc.). Each offset is a.

After this is the state bitmask array. As explained earlier, each tile gets 2 bits. Note however, they are ordered from LSB to MSB within each byte, so in binary, tile 0 would take up bits 6-7, tile 1 would take up bits 4-5, tile 2 would take up bits 2-3, and tile 3 would take up bits 0-1. Then tile 4 would take up bits 6-7 in the next byte, and so on.

Tile #       3   2   1   0         7   6   5   4          11  10  9   8 Binary       0 1 1 0 1 0 0 1       1 0 1 1 1 0 1 0        0 1 1 0 1 0 1 0

Each tile having 2 bits means they can have up to 4 values (0-3). The first 3 are used:
 * 0x0 - Off - The tile is off
 * 0x1 - On - The tile is on
 * 0x2 - Random - The tile is either on or off, it is random each time

The state bitmask array is padded to an alignment of 4 bytes at the end.

Overall Format
Here is the overall format of the Disco Floor asset:

Enable
Enable the Disco Floor. Same as setting the Enabled flag.

Disable
Disable the Disco Floor (and hide its SIMPs). Same as setting the Disabled flag.

Reset
Reset the Disco Floor to its initial state (pattern step) and transition and state intervals.

Set State
Change the Disco Floor's current state (pattern step) to the first argument.


 * float32 - State Index

Set State Range
Change the Disco Floor's minimum and maximum state to the first and second argument respectively. The Disco Floor will only run states within this range.


 * float32 - Minimum State Index
 * float32 - Maximum State Index

Set State Delay
Change the Disco Floor's state delay to the first argument. Same as setting.


 * float32 - State Delay

Set Transition Delay
Change the Disco Floor's transition delay to the first argument. Same as setting.


 * float32 - Transition Delay