EvilEngine/DSCO

From Heavy Iron Modding
(Redirected from DSCO)

DSCO
Disco Floor
TypeBase
Base Type0x00
Games usedBattle for Bikini Bottom
The SpongeBob SquarePants Movie
Source codezDiscoFloor.h

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 z_disco_floor_asset struct which inherits from BaseAsset:

struct z_disco_floor_asset : xBaseAsset
{
    uint32 flags;
    struct
    {
        float32 transition;
        float32 state;
    } interval;
    struct
    {
        uint32 off;
        uint32 transition;
        uint32 on;
    } prefix_offset;
    uint32 state_mask_size;
    uint32 states_offset;
    uint32 states_size;
};
Offset Type Name Description
0x08 uint32 flags
  • 0x1 - Loop - If disabled, the Disco Floor will pause when it reaches the end state.
  • 0x2 - Enabled - If disabled, the Disco Floor will not function and its SIMPs will not render.
0x0C float32 interval.transition Duration of transition between states in seconds (yellow tile)
0x10 float32 interval.state Duration of each state in seconds (red tile)
0x14 uint32 prefix_offset.off Offset of the "off" SIMP name prefix (relative to offset 0x8)
0x18 uint32 prefix_offset.transition Offset of the "transition" SIMP name prefix (relative to offset 0x8)
0x1C uint32 prefix_offset.on Offset of the "on" SIMP name prefix (relative to offset 0x8)
0x20 uint32 state_mask_size Amount of tiles (total amount of SIMPs / 3)/how many tiles are in each state's bitmask
0x24 uint32 states_offset Offset of an array of state bitmask offsets (relative to offset 0x8)
0x28 uint32 states_size Amount of state bitmasks

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

string prefix_off; // align to 4 bytes
string prefix_transition; // align to 4 bytes
string prefix_on; // align to 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 uint32.

uint32 state_offsets[states_size];

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:

z_disco_floor_asset asset;
string prefix_off; // align to 4 bytes
string prefix_transition; // align to 4 bytes
string prefix_on; // align to 4 bytes
uint32 state_offsets[asset.states_size];
state states[asset.states_size]; // state bitmasks, variable length, aligned to 4 bytes at the end

Events

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 interval.state.

  • float32 - State Delay

Set Transition Delay

Change the Disco Floor's transition delay to the first argument. Same as setting interval.transition.

  • float32 - Transition Delay