# TrickyTracker for ProTracker Users

---

## Core Concepts

| ProTracker | TrickyTracker | 
|------------|---------------|
| Pattern (64 rows) | Segment (16 rows) |
| Sample slots (1-31) | Instruments (1-8) |
| Pattern order list | Arrangement grid | 
| .MOD file | .TT file (JSON) |

---

## The Big Differences

### Segments, Not Patterns

In ProTracker, a **pattern** is 4 channels locked together for 64 rows — you sequence entire patterns as a unit.

In TrickyTracker, a **segment** is a block of 16-rows. You assign segments *per channel* in the arrangement grid, so you can assign which segment each channel plays independently — channel 1 might play segment 3 while channel 2 plays segment 7 at the same time position.

This means you compose horizontally (across channels) and vertically (across time) independently — no more giant 4-channel blocks moving in lockstep.

### Per-Channel Arrangement

The **Arrangement View** (top) is a grid: rows = time positions, columns = channels. Each cell holds a segment ID.

- Click a cell to assign which segment that channel plays at that position.
- Channels are fully independent — reuse segments freely across channels and positions.

## Instrument Editing

Each instrument is two waveforms blended together:
- **Primary** waveform at base pitch
- **Secondary** waveform at an optional different octave (set by PER)
- Blended by MIX ratio, then shaped by volume/pitch slides over time

### Waveform Selection
- **Left-click** waveform: cycle forward (Sine → Square → Saw → Noise)
- **Right-click** waveform: cycle backward

### Sliders
| Slider | Range | Function |
|--------|-------|----------|
| PER | 0-4 | Secondary period multiplier (×1, ×4, ×8, ×16, ×32) — higher = lower pitch |
| MIX | 1-4 | Blend ratio (see table below) |
| VOL | 0-64 | Base volume |
| VSL | -32 to +31 | Volume slide per tick (negative = fade out) |
| PSL | -32 to +31 | Pitch slide per tick (negative = pitch down) |

**MIX values:**

| MIX | Primary | Secondary |
|-----|---------|-----------|
| 1 | 50% | 50% |
| 2 | 75% | 25% |
| 3 | 87% | 13% |
| 4 | 94% | 6% |

- **Double-click** a slider to reset to default.
- **R** to rename selected instrument.
- **C/P buttons** (top-right of slot): Copy/Paste instrument.

---

## Tracker Panel

### Segment Badges
- Each channel column shows a **circled number** = which segment plays there.
- **Left-click** badge: increment segment.
- **Right-click** badge: decrement segment.

### Navigation
- **Arrow keys**: move edit cursor.
- **Tab / Shift+Tab**: move right/left.
- **Page Up/Down**: jump 16 rows (full segment).
- **Click** in grid: set edit cursor position.

### Editing
- **Piano keys** (see below): enter note (requires Record mode).
- **Delete/Backspace**: clear note.
- **T**: insert note-off (kill).
- **Ctrl+C / Ctrl+V**: copy/paste segment.
- **Ctrl+X**: clear entire segment.
- **Ctrl+1-8**: change instrument of current note.
- **F8 / Shift+F8**: transpose semitone/octave down.
- **F9 / Shift+F9**: transpose semitone/octave up.

---

## Arrangement View

- **Click** to focus. Arrow keys navigate.
- **Shift+Arrow**: extend selection.
- **Page Up/Down**: increment/decrement segment ID.
- **Ctrl+C / Ctrl+V**: copy/paste block.
- **Delete**: clear selected cells.
- **Ctrl+Insert**: insert row.
- **Ctrl+Delete**: delete row.
- **Escape**: clear selection.

---

## Keyboard Reference

### Playback
| Key | Action |
|-----|--------|
| F5 / Right Shift | Play/Stop |
| Ctrl+F5 / Ctrl+Shift | Play from cursor |
| F6 | Rewind (stop + reset) |
| F7 / Space | Toggle record mode |
| Escape | Stop playback |
| Enter | Preview current row |

### Global
| Key | Action |
|-----|--------|
| 1-8 | Select instrument |
| Shift+1-4 | Mute/unmute channel |
| F1 / F2 | Octave down/up |
| F4 | Help |
| Ctrl+Z / Ctrl+Y | Undo / Redo |
| Ctrl+N / Ctrl+O / Ctrl+S | New / Open / Save |
| Ctrl+E | Export to assembly |
| Ctrl+I | Project info |

### Note Entry
White keys: `Z X C V B N M , .` (C to D+1)
Black keys: `S D G H J L` (C# D# F# G# A# C#+1)

---

## What's Missing (By Design)

- No sample import 
- No effects column — volume/pitch slides are per-instrument.
- No pattern break/jump — arrangement handles song structure.

---

## Project Info (Ctrl+I)

Shows export statistics to help optimize size:
- **Notes**: which notes are used and how often
- **Instruments**: usage count per instrument
- **Segments**: usage count per segment

Single-use items are highlighted — candidates for inlining/removal to save bytes when compressing the module.

---

## Export Formats

### Assembly Export (68000 for Amiga)

Exports to **68000 assembly** for Amiga:
- `Tricky_Init` — call once to set up audio
- `Tricky_Play` — call every VBlank for playback

### Binary Detached Format

For embedding directly in runtime players without assembly compilation. The binary format is structured for fast PC-relative loading on the Amiga.

**Header (26 bytes):**
```

Offset 0x00:  Longword   Note table offset (PC-relative)
Offset 0x04:  Longword   Segments offset (PC-relative)
Offset 0x08:  Longword   Channel arrangements offset (PC-relative)
Offset 0x0C:  Longword   Instruments offset (PC-relative)
Offset 0x10:  Longword   Generation data offset (PC-relative)
Offset 0x14:  Word       Instrument count - 1
Offset 0x16:  Word       Song length
Offset 0x18:  Word       Channel stride (always 8)
```

**Data sections (big-endian Motorola order):**

| Section | Format | Content |
|---------|--------|---------|
| Note Table | Word array | Note periods (one word per used note) |
| Segments | Word pairs | 16 rows × 4 channels per segment: `[instrument_id, note_index]` |
| Arrangements | Word array | 4 channels × song_length entries: segment indices |
| Instruments | 4 words each | `[unused, volume, pitch_slide, volume_slide]` per instrument |
| Generation | 4 words each | `[primary_waveform, secondary_waveform, mix_shift, secondary_shift]` per instrument |

**Key features:**
- PC-relative offsets enable position-independent loading
- Only used notes are included
- All values in big-endian order (native for 68000)

**Usage in player code:**
```m68k
; a4 = base address of binary header
move.l  0(a4),d0      ; Note table offset
lea     (a4,d0.l),a1  ; Resolve to absolute address
move.l  4(a4),d0      ; Segments offset
lea     (a4,d0.l),a2  ; Resolve to absolute address
; ... etc for other sections
```
