peter-griffin-prank / README.md

raw file 3690 bytes
# Peter Griffin prank (Rust remake)

A tiny prank desktop app: a borderless 397x319 window shows a Peter Griffin
image and a **Close** button. The button does not close anything — it opens
50 windows (800x450, same image stretched) at random positions on screen, one
every 100 ms, until the desktop is buried.

This is a Rust port (eframe/egui) of an original .NET WinForms executable
(`Peter.exe`). Window sizes, image placement, the "Close" button and the
50-popup volley match the original; popup placement is now randomised instead
of stacking.

## Run it

The manifest holds the whole story:

```toml
install = "cargo build --release"
run     = "bin\\peter.exe || bin/peter || cargo run --release"
```

`nd run <slug>` shells that out (`sh -c` on Unix, `cmd /C` on Windows), so:

```bash
nd run peter-griffin-prank      # prebuilt binary for this OS
cargo run --release             # force a source build
```

How the chain resolves:

| Shell | First branch | Result |
|---|---|---|
| cmd (Windows) | `bin\peter.exe` | runs the Windows build — **backslashes are required**: cmd splits `bin/peter` into command `bin` plus switch `/peter` |
| sh (Linux/macOS) | `bin\peter.exe` → `binpeter.exe` | not found (one harmless line), falls through to `bin/peter`, the native ELF |
| either, no prebuilt | `cargo run --release` | builds and runs from source (needs rustc 1.95+) |

Windows without Rust still works — the first branch never needs cargo.

### Prebuilt binaries

| Platform | File | Notes |
|---|---|---|
| Linux x86-64 | `bin/peter` | needs GL/Vulkan, X11 or Wayland |
| Windows x86-64 | `bin/peter.exe` | Windows 10+ (UCRT), DirectX 12 or Vulkan |

They can also be run directly. Both were verified locally: the Linux one
natively, the Windows one under Wine (window appears at 397x319 as expected).

## Build from source

Requires **rustc 1.95+** (the eframe/egui 0.37 family declares that MSRV):

```bash
rustup update stable
cargo build --release          # -> target/release/peter
cargo run --release
```

### Cross-compiling the Windows build on Linux

Needs a Linux-hosted MinGW-w64 toolchain (Debian/Ubuntu:
`gcc-mingw-w64-x86-64`; Arch: `mingw-w64-gcc` + `mingw-w64-binutils`, which also
provides the `x86_64-w64-mingw32-dlltool` that `rustc` needs for the `windows`
crates' raw-dylib imports). Zig's bundled MinGW is *not* enough — its sysroot
lacks `libpthread.a`/`msvcrt` that Rust's `windows-gnu` link line expects.

```bash
rustup target add x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnu
cp target/x86_64-pc-windows-gnu/release/peter.exe bin/peter.exe
cp target/release/peter bin/peter                   # refresh the Linux build too
```

Release builds use the Windows GUI subsystem (`#![cfg_attr(not(debug_assertions),
windows_subsystem = "windows")]`), so no console window appears.

## Notes

- The main window is borderless and centred on the monitor at startup.
- Popups get explicit random positions. Wayland compositors ignore
  client-requested window positions, so the app hides
  `WAYLAND_DISPLAY`/`WAYLAND_SOCKET` at startup to make winit use
  X11/XWayland. Set `PETER_KEEP_WAYLAND=1` to keep native Wayland — popups will
  then be placed by the compositor (usually all in the same spot).
- There is no network, filesystem or persistence code; the app only creates
  windows.

## Layout (taken from the original WinForms forms)

| Element | Geometry |
|---|---|
| main window | 397x319, undecorated, centred |
| face image | (12,43) 373x171, stretched |
| "Close" button | (149,273) 75x23 |
| popup window | 800x450, title "Form2", image stretched |
| popup timing | 50 windows, 100 ms apart, random positions |