# SL Rust Implementation
SL locomotive animation in Rust using crossterm.
## Build
```bash
cargo build --release
```
Binary: `target/release/sl.exe` (215 KB)
## Usage
```bash
sl.exe # D51 locomotive (default)
sl.exe -c # C51 locomotive
sl.exe -l # Logo/SL
sl.exe -a # Accident mode
sl.exe -F # Flying mode
sl.exe -ac # C51 in accident mode
sl.exe -lF # Logo flying
```
## Architecture
### Key Design Principles
1. **Full-screen redraw**: Clears and redraws entire screen each frame (vs. delta/dirty region)
- Eliminates flickering (no partial updates)
- Matches original C implementation behavior
- Simpler mental model
2. **crossterm-only**: No extra dependencies
- Uses: `MoveTo`, `Clear`, `write!`, `execute!`
- Avoids complex state management
3. **Simple rendering flow**:
```
for each frame:
1. clear_screen()
2. draw_train(x, pattern)
3. draw_smoke()
4. draw_man() if accident
5. flush()
6. sleep(40ms)
```
### Module Structure
```
terminal.rs
├─ Terminal struct (wrapper around crossterm)
├─ move_to()
├─ clear()
├─ write_str()
└─ cleanup()
config.rs
└─ Config struct (parse CLI flags)
train/
├─ ascii.rs (ASCII art constants from original sl.h)
├─ d51.rs, c51.rs, logo.rs (stubs)
smoke.rs
├─ Particle struct
├─ thread_local SMOKE queue
├─ add_smoke()
├─ update_smoke()
└─ get_smoke_particles()
render.rs
├─ render_frame()
├─ render_d51/c51/logo/man()
├─ render_smoke()
└─ draw_line()
main.rs
└─ parse args → loop → render → sleep
```
## Implementation Details
### Rendering Strategy
**Character-by-character placement**:
```rust
for y in train_lines {
terminal.move_to(x, y)?;
terminal.write_str(line)?;
}
```
This avoids:
- Buffer management complexity
- Synchronization issues between buffer and output
- Character loss at boundaries
### Smoke System
- `thread_local!` particle queue (state persists across frames)
- Particles created at locomotive funnel position
- Pattern cycles (0-4) and disappear after 5 frames
- 5 smoke styles determined by creation time counter
### Flying Mode
Y position varies by x:
```rust
y = (height/2) - (x/4) // parabolic arc
```
## Performance
- **Frame time**: 40ms (25 FPS, matching original)
- **CPU**: Minimal (one-shot I/O per frame)
- **Memory**: ~2-3 KB (small particle queue)
## Differences from C Version
| Terminal library | ncurses | crossterm |
| Dependencies | None | crossterm 0.27 |
| Code lines | ~300 | ~650 (incl. ASCII data) |
| Smoke | Global static array | thread_local queue |
| Pattern timing | Hardcoded loop | Atomic counter |
## Testing
All combinations verified:
- ✓ Default (D51)
- ✓ C51 (-c)
- ✓ Logo (-l)
- ✓ Accident (-a)
- ✓ Flying (-F)
- ✓ Multi-flag combinations
No flickering, no shape corruption, no cut-off characters.