Midi Fighter Twister — the 16-knob button layouts
A DJ TechTools Midi Fighter Twister (16 push encoders in a 4×4 grid, 6 side buttons) drives Plugin Player out of the box with one of two button layout files in the installer/presets folder of the player (ask for them if you did not get them with your copy): Midi Fighter Twister.ppcontrols (· Dials) and Midi Fighter Twister - Pad layout.ppcontrols (· Pad layout, below). It is made for the Twister's factory MIDI map, bank 1 (the bank the Twister starts in): no change to the controller is needed. General MIDI set-up and the learn flow: MIDI_OSC.md.
Import the layout (once)
- Plug the Twister in. Open CONTROLS (F3). In the MIDI · OSC card click MIDI: OFF so it says ON — Midi Fighter Twister appears under it (a dot blinks when you turn a knob).
- Click IMPORT (next to SAVE LAYOUT / EXPORT), pick
Midi Fighter Twister.ppcontrols, read the WHAT CHANGES list, click APPLY + KEEP AS LAYOUT. The LAYOUT dropdown now says MIDI FIGHTER TWISTER · DIALS (or · PAD LAYOUT). You can import both and switch in that dropdown.- It is a whole button layout: it also puts every scene's pad buttons back to their defaults and replaces any MIDI / OSC learns you had. If you want to keep yours, EXPORT first; UNDO in the toast puts everything back.
- Turn knob 1: the LIGHT value in the PRESETS monitor moves. Done.
Which layout to use
- · Controller layout — you already play Plugin Player on a game controller (8BitDo, PlayStation, Xbox): the Twister is laid out like the controller, so the same move lives in the same place. Row 1 = □ △ ○ ✕, row 2 = d-pad + shoulders, row 3 = the sticks, row 4 = show tools. Push 1 does exactly what □ does in every scene.
- · Dials — you want as many of each scene's dials as possible under your hands (12 per scene) and preset / scene buttons on the top rows. The grid is under Bank 1 — Dials below.
Both use bank 1 of the factory map and both make the rings follow.
Controller layout (Midi Fighter Twister - Controller layout.ppcontrols)
Each cell: turn · push. Symbols are the PlayStation positions (8BitDo / Xbox map by position: □ = left face button, △ = top, ○ = right, ✕ = bottom).
| column 1 | column 2 | column 3 | column 4 | |
|---|---|---|---|---|
| row 1 — the face buttons | 1 · turn: the param □ drives · push: □ | 2 · turn: △'s param · push: △ | 3 · turn: ○'s param · push: ○ | 4 · turn: ✕'s param · push: ✕ |
| row 2 — d-pad + shoulders | 5 · turn: the ▲▼ param (speed, melt…) · push: L1 (hold = hold) | 6 · turn: the ◀▶ param (glow, sensitivity…) · push: R1 (hold = hold) | 7 · turn: LIGHT · push: L2 = NEXT SCENE | 8 · turn: FX INTENSITY · push: R2 = NEXT PRESET |
| row 3 — the sticks | 9 · turn: left stick ◀▶ · push: L3 / PS = SCENE ↔ FX CHANNEL | 10 · turn: left stick ▲▼ · push: FX LAYER ON / OFF | 11 · turn: right stick ◀▶ · push: BACK TO WHERE YOU WERE | 12 · turn: right stick ▲▼ · push: CAMERA IN / OUT |
| row 4 — show tools | 13 · turn: FADE TIME · push: PREVIOUS SCENE | 14 · turn: AUDIO AMOUNT · push: TAP TEMPO | 15 · turn: featured dial · push: LEARN BACKGROUND | 16 · turn: featured dial · push: PREVIOUS PRESET |
A push is the controller button itself: tap = tap, hold = hold (L1 / R1 surges lock on a tap and boost while held, exactly as on the controller). A scene with no △ (Custom Particles, Pixel Smear): push 2 does nothing. Push 11 (the PlayStation R3 is the scene button = next / previous scene, which pushes 7 and 13 already do) is BACK TO WHERE YOU WERE. Pushes 10 and 12 are one-push toggles (FX layer on with its next preset / off; camera to the scene / off the scene).
What the knobs turn in each scene (* = that button or stick has no dial a knob can set, a trigger / a counter / a named set / no stick, so the knob takes one of the scene's featured dials instead). Stick knobs cover the param's whole range. The layout is made from the scenes' own default controller mappings, so a new scene gets its row 1 from its own buttons.
| Scene | 1 □ | 2 △ | 3 ○ | 4 ✕ | 5 ▲▼ | 6 ◀▶ | 9 L ◀▶ | 10 L ▲▼ | 11 R ◀▶ | 12 R ▲▼ | 15 | 16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Blob Tracking v3 | fillOpacity | blobCount * | motionThreshold * | followSmooth * | trackSpeed | lockStrength * | boxWidth * | boxHeight * | connectDistance * | dataScale * | dataRollSpeed | backgroundDim |
| Corridor Panels | panelZoom * | coreGlow * | exposure | roll | animRate | intensity * | tubeW | tubeH | camYawStick | camPitch | pulseDepth | camFov |
| Cube Bloom | exposure * | haloAmount * | randomAmount | flyCells * | animRate | edgeGlow | blockSpin | gap * | orbitRate | lookPitch | waveSpan | gloss |
| Cube Stack | lineWork * | turnRate * | screenGain * | contrast * | climbSpeed | kickAngle * | sweepGain * | sweepRate * | haze * | mirror * | camSpin | echoMax |
| Custom Particles | trailTrim * | speed * | drive | glow * | densityTrim | intensity * | amount * | spread * | life * | swirl * | sizeTrim | flowTrim |
| Flashpoint | hueShift | splatForce | exposure * | splatRadius * | energy | dyeDissipation * | spinKick | vorticity | colorSpeed * | dyeIntensity | bloom | simRate |
| Goop | bloom * | simRate * | splatForce | dyeDissipation | energy | exposure * | splatRadius * | colorSpeed * | pressure * | shockAmt * | vorticity | dyeIntensity |
| Frame Stack | orbit * | styleChance * | styleSeed | animRate * | orbitSpin | orbGlow * | spreadX | stickStride | orbitRate | elevation | planeCount | planeGap |
| Machine Vision | hudOpacity * | motionTrack * | counterRate * | popOnMotion * | detectDensity | textSize | holdTime * | linkAmount * | innerGlyphs * | markDensity * | masterThresh | detectThresh |
| Pixel Smear | meltDissipation | splatRadius * | forceScale * | flowDamping * | meltAmount | motionSens | flowSmoothing * | pressure * | massWeight * | motionThresh * | simRate | exposure |
| Plane Drift | planeCount * | sizeBase * | planeSpin | travelAngle | loopSecs | glow * | exposure * | waveAmount * | waveLength * | swayAmount * | energy | dyeIntensity |
| Test Stage | holdY | holdX | holdA | burst | energy | holdRight | lsX | lsY | rsX | rsY | fluidGain | panelSmoke |
| Typewriter Terrain | bgLevel * | grid * | churn | invertPop | density | typeRate | aimX | aimY | macroGrid * | wordLock * | macroMix | cursorPop |
Side buttons in the Controller layout (if set to CC Hold): left column AUDIO ON / OFF · SAVE PRESET · RESET PRESET, right column FX PRESET 1 · FX PRESET 2 · SEND SHOCK (one wave through the fluid: the effect layer, or the own fluid of Frame Stack / Plane Drift; it took FX PRESET 3, which is one R2 tap away).
5-minute test (Pad layout): import it; in Cube Bloom push 3 (○) = a random look, push 1 (□) = spin scope, hold push 5 (L1) = faces cycle; turn knob 5 = speed, knob 6 = glow; push 7 = next scene and watch every ring jump.
Bank 1 — Dials: what each knob does (turn) and what its push does (click)
Knob 1 is top-left (the Twister sends CC 0 on channel 1), knob 4 is top-right (CC 3), knob 16 is bottom-right (CC 15). A push sends the same number on channel 2.
| column 1 | column 2 | column 3 | column 4 | |
|---|---|---|---|---|
| row 1 — every scene | 1 · LIGHT (0.5× … 2.5×, the monitor's LIGHT) · push: NEXT PRESET | 2 · FX INTENSITY (Effect Layer) · push: PREVIOUS PRESET | 3 · FADE TIME (0 … 5 s crossfade) · push: SAVE PRESET | 4 · AUDIO AMOUNT (0 … 200 %) · push: RESET PRESET |
| row 2 — the same job in every scene | 5 · SPEED · push: NEXT SCENE | 6 · GLOW · push: PREVIOUS SCENE | 7 · EXPOSURE · push: BACK TO WHERE YOU WERE | 8 · AMOUNT · push: TAP TEMPO |
| row 3 — the scene's dials | 9 · push: the scene's A (○) button | 10 · push: the scene's B (✕) button | 11 · push: the scene's X (△) button | 12 · push: the scene's Y (□) button |
| row 4 — the scene's dials | 13 · push: CAMERA IN (to the scene) | 14 · push: CAMERA OUT (off the scene) | 15 · push: FX LAYER: NEXT PRESET (turns it on) | 16 · push: FX LAYER OFF |
Rows 3 and 4 and the names in row 2 change with the scene (the CONTROLS tab's THIS SCENE · SLIDERS list shows the live names; MONITOR ▾ shows every message and what it did):
| Scene | 5 SPEED | 6 GLOW | 7 EXPOSURE | 8 AMOUNT | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Cube Bloom | animRate | edgeGlow | exposure | haloAmount | flyCells | gap | sizeMax | fogAmount | flyDrift | edgeWidth | camFov | camDist |
| Corridor Panels | animRate | coreGlow | exposure | intensity | litChance | litBoost | bloomAmount | fogAmount | tracerAmount | waveTiles | camFov | swayAmount |
| Frame Stack | animRate | orbGlow | exposure | animAmount | planeCount | planeSize | density | flowRate | orbitSpin | spreadZ | energy (fluid) | camDist |
| Plane Drift | loopSecs (right = slower) | glow | exposure | waveAmount | planeCount | sizeBase | waveLength | swayAmount | bandSpread | clump | energy (fluid) | haze |
| Typewriter Terrain | typeRate | cursorPop (the flash at the writing head) | bgLevel (the picture under the type) | density (how much type, ◀ ▶ on the controller) | grid | churn | macroMix (giant letters) | macroGrid | invertPop (white panels, ✕ on the controller) | wordLock | terrainScale | motionPop |
| Cube Stack | turnRate | screenGain | contrast | echoMax | kickAngle | camSpin | sweepGain | sweepRate | haze | mirror | rimGain | fov |
| Custom Particles | speed | glow | intensity | amount | drive | spread | life | swirl | gravity | trailAmount | sizeTrim | dissipate |
| Goop | simRate | bloom | exposure | splatForce | splatRadius | vorticity | dyeIntensity | dyeDissipation | colorSpeed | pressure | shockAmt | highlight |
| Blob Tracking v3 | dataRollSpeed | fillOpacity | backgroundDim | blobCount | motionThreshold | followSmooth | lockStrength | boxWidth | boxHeight | connectDistance | dataScale | hudScale |
| Pixel Smear | simRate | meltDissipation (no glow in a melt: how long the smear stays) | exposure | meltAmount | motionSens | splatRadius | forceScale | flowDamping | flowSmoothing | pressure | massWeight | motionThresh |
| Flashpoint | simRate | bloom | exposure | energy (the fire level, ▲ ▼ on the controller) | splatForce | splatRadius | vorticity | dyeIntensity | dyeDissipation | colorSpeed | hueShift | motionThresh |
| Machine Vision | counterRate (the ids' count speed) | hudOpacity (HUD glow) | masterThresh (choke, the controller's L1) | detectDensity (detections, ▲ ▼ on the controller) | textSize | detectThresh | motionTrack | popOnMotion | holdTime | linkAmount | innerGlyphs (centre symbols) | markDensity (satellites) |
| Test Stage | energy (fluid energy) | fluidGain (fluid brightness) | panelSmoke (the smoked panel) | shockAmt (wave strength, ✕ on the controller) | ballEnergy | growSpeed (coral) | growGlow | growHue | growOpacity | growFlow (the fluid smears the coral) | growRecede | panelBlur |
Pixel Smear: a preset sets most of its dials, so its knobs are the ones that still move the picture on top of any preset (the melt masters, the motion field, exposure). It has no △ move, so push 11 is its MELT SURGE (the pad's L1: tap = lock, hold = boost).
A knob covers the dial's whole range: fully left = the minimum, fully right = the maximum (your range brackets on the PARAMS shelf narrow it). Custom Particles has no X action, so push 11 does nothing there.
The rings follow Plugin Player
Plugin Player sends each knob's value back to the Twister, so the LED ring of every knob shows where its dial is right now — whatever moved it: the knob, the pad's ▲ ▼, an OSC message, a preset change, a scene change, a glide. Change scene and all 16 rings jump to the new scene's values; change preset and they jump to the preset's values. Because the Twister's encoders take the value they are sent, the next click of a knob continues from the dial's real value — no jump after a scene or preset change.
- It is the SEND VALUES BACK (RINGS / MOTOR FADERS) button next to Midi Fighter Twister in the MIDI · OSC card (CONTROLS tab). It is ON by itself for a Twister (and for any device that turns the layout's knobs); click it to stop sending. Other controllers stay OFF until you turn it on for them.
- Only the knobs are sent (CC 0 … 15 on channel 1, plain MIDI CC, never SysEx); the ring colours stay the Twister's own. While you turn a knob, Plugin Player sends nothing to that knob (the ring already shows your hand).
- If Resolume or another app has the Twister open, Windows may not let two apps use it at once — the same as for MIDI in.
Side buttons (if you set them to CC Hold in the Midi Fighter Utility; from the factory they switch banks and send nothing): left column top → bottom AUDIO ON / OFF · LEARN BACKGROUND · SCENE ↔ FX CHANNEL; right column FX PRESET 1 · FX PRESET 2 · FX PRESET 3.
GUEST MODE does not lock the Twister: every knob and push above keeps working for whoever holds it; only the CONTROLS tab (importing, learning, MIDI ON / OFF) is locked.
Your Twister set to RELATIVE (endless) encoders?
The layout expects the factory absolute encoders (0 … 127, the ring shows the position). If you set the encoders to a relative mode in the Midi Fighter Utility (ENC 3FH/41H), the knobs will jump instead of turn: on the CONTROLS tab click a knob's chip (for example CC 4 · CH1) and under KNOB pick RELATIVE (BIN. OFFSET) (3FH/41H = 63 / 65 = binary offset). Do it once per knob you use; it is saved with the layout. CHANNEL and DEVICE can stay on ANY.
The 5-minute test
- Plug in, MIDI ON, import the layout (above). The MIDI chip in the header says MIDI 1.
- Turn knob 1 → the LIGHT value in the PRESETS monitor follows (1× at about the middle, 2.5× fully right). Turn knob 5 → the scene speeds up / slows down. Knobs 9 … 16 → the scene's dials (watch the PARAMS shelf).
- Push knob 1 → next favorite preset (toast PRESET 2/12 · …). Push 2 → the previous one. Push 5 → next scene; push 7 → back to where you were.
- Push 9 → the scene's ○ button (Cube Bloom: a random look). Hold it: it is held like the controller's button.
- Unplug the USB cable while holding push 9, then plug it back in: nothing stays held, the MIDI chip goes OFF → MIDI 1 again, the knobs work at once.
- GUEST MODE on (Plugin Player ▾ → LOCK AND PASS THE CONTROLLER…): knobs and pushes still work; the CONTROLS tab says locked.
- The rings: press L2 (next scene) or R2 (next preset) on the controller → all 16 rings jump to the new values. Click the LIGHT ▲ in the PRESETS monitor → ring 1 moves up a notch.
- MONITOR ▾ on the CONTROLS tab: each message shows what it did (
CC 4 · CH1 → SLIDER animRate,CC 0 · CH2 → NEXT FAVORITE PRESET). A line that says NOT BOUND is a control the layout does not map (bank 2 … 4, or a side button).
Hand test on your own Twister (5 minutes, both layouts)
What was already proved on a real Twister without touching it (Oct 30, Seat 3): Windows shows Midi Fighter Twister as an input AND an output, Plugin Player opens both, imports either layout with 0 warnings, and sends the 16 ring values on channel 1 (CC 0–15) on import, on every scene change and while a dial moves. What only your hands can prove is the knobs and pushes coming in. Start in Cube Bloom, with the Twister on bank 1 (the factory bank; the LEDs of the side buttons show the bank) and nothing else using it (if Resolume has the Twister ticked in Preferences › MIDI, untick it or quit Resolume first).
A · Dials layout (Midi Fighter Twister.ppcontrols)
- CONTROLS (F3) › MIDI · OSC › MIDI: ON; Midi Fighter Twister is listed and SEND VALUES BACK says ON. IMPORT the file › APPLY + KEEP AS LAYOUT. All 16 rings jump to a position at once (that is Plugin Player talking to the Twister).
- Turn knob 1 (top-left) → LIGHT in the PRESETS monitor follows (≈1× in the middle, 2.5× fully right). Put it back near the middle.
- Turn knob 5 (row 2, left) → Cube Bloom speeds up (right) / slows down (left). Knob 6 → the cube edges glow more / less.
- Push knob 1 → next preset (toast PRESET n/…) and the rings jump to the new preset. Push 2 → the previous preset.
- Push knob 9 (row 3, left) → a random look (Cube Bloom's ○). Push 5 → next scene (Frame Stack): every ring jumps again. Push 7 → back to Cube Bloom.
- Open MONITOR ▾: turning knob 5 shows
CC 4 · CH1 → SLIDER animRate; pushing 1 showsCC 0 · CH2 → NEXT FAVORITE PRESET. A side button shows NOT BOUND unless you set it to CC Hold (expected).
B · Controller layout (Midi Fighter Twister - Controller layout.ppcontrols, import it too and pick it in the LAYOUT dropdown)
- Push knob 3 (top row, ○) → a random look, exactly like ○ on the pad. Push knob 4 (✕) → the cubes spin.
- Push knob 1 (□) → spin: each cube ↔ whole block. Hold push 5 (L1) → the faces cycle as when you hold L1.
- Turn knob 5 → speed (the ▲▼ param); turn knob 6 → glow (the ◀▶ param); knob 7 → LIGHT.
- Push knob 7 (L2) → next scene: all 16 rings jump; push 13 → the previous scene.
- Push knob 10 → the FX layer comes on; push it again → off.
Pass = every step did what it says and no knob did two things. If a knob does nothing: MONITOR ▾ shows the message — a CH1 number other than CC 0 … 15 means the Twister is on another bank (press the side buttons back to bank 1) or was re-programmed in the Midi Fighter Utility (Reset to factory there, or learn that knob); nothing at all in MONITOR means another app has the port. If the knobs jump instead of turning smoothly, see RELATIVE above.
Known gaps
- The rings follow the values (above), but their colours are not set by Plugin Player (no RGB / animation messages yet).
- No 14-bit (high-resolution) encoder mode; banks 2 … 4 (CC 16 … 63) are not mapped — learn them on any row yourself.
- The side buttons are mapped only if they send CC (see above).