How QuadStick Config Manager works
A plain-English tour of the code, for contributors and the curious. Everything here matches the source; nothing is simplified into being wrong.
1. The one-paragraph version
The QuadStick is a mouth-operated game controller. It reads one CSV file at a time from its own memory (it shows up on your computer like a USB stick). That file says which sip, puff, or joystick move presses which game button. This app opens those files, shows them as a picture of the QuadStick, lets you change them safely, and copies them back to the device in a way that can never leave it half-written.
2. The big picture
3. What a profile file looks like
A profile is one CSV file (a plain text table). The layout comes from the maker's own tools and is documented fact, not guesswork (see docs/FORMAT.md for sources).
| Line | Content | Meaning |
|---|---|---|
| 1 | QuadStick Configuration,Version 1.5,,gta | Header. Says which tool wrote the file and the profile's name. |
| 2 | Profile Name,,Left joy | A sheet starts. A1 must contain the word "Profile" (or be "Preferences" / "Infrared"). |
| 3 | gta.csv | Only on the FIRST sheet: the file's own name. |
| 4 | PlayStation Outputs,Function,usb | Column labels. The first cell also picks PlayStation or Xbox button names. |
| 5+ | x repeat 5 mp_right_sip … my note | One mapping per row: game button (yellow), how it presses (pink), up to 8 inputs (blue, columns C–J), and free comments after column J (grey) that the device ignores. |
| … | (blank line) | A blank line ends the sheet. The next sheet starts after it. |
4. How editing never corrupts a file
The app never converts your file into its own format and back. It keeps the file's raw table (the "grid") in memory and edits cells in place. What you see on screen is a read-only view built from that grid.
5. The install pipeline (the most careful code in the app)
6. Where the "legal words" come from
Every input name (mp_left_sip), button name (left_trigger), and function (repeat) the app suggests or checks comes from one place: the validation list the QuadStick's maker uses for his own spreadsheets. It is embedded in the app verbatim and compared against his source by script, not by eye: 140 inputs, 388 PlayStation-style outputs, 380 Xbox-style outputs, 14 functions.
7. Finding your way around the app
8. Files, settings, and the community catalog
Three more things this app can do, and all three only work when a QuadStick is mounted: its drive shows up like a USB stick in Finder or File Explorer. There is no serial or HID connection anywhere in this app, only file access, so if the drive is hidden (PS4 boot mode, or controller emulation switched on) the app cannot see the device at all. Turning mass storage back on needs QMP or the device's own prefs, not this app; there is no other way in from here.
Device settings. prefs.csv holds the QuadStick's own settings, not a game profile. On its Preferences sheet, a setting the app recognizes (61 of them are embedded in the app) gets a real control instead of a plain cell: a number box, a checkbox, or a dropdown, each one only offering values the device actually accepts. A setting the app does not recognize, or a value already in the file that a real control could not show without changing it, keeps the plain text box it always had, untouched. Installing prefs.csv back to the device asks first, because it changes every profile at once, not just the one open.
Manage files. This window lists the .csv files on every mounted QuadStick drive, grouped by drive. From there you can copy a file into your library, open the Google Sheet it is linked to, or delete it. Deleting backs the file up to the same QuadStickBackups folder Install uses (see section 5) before removing it from the device. default.csv and prefs.csv cannot be deleted from this window: the app refuses before anything is copied or removed. The window also shows the order the device steps through its files when the profile switch is pressed, and the light colour for each position, because that table only exists in the maker's own documentation, not in any file on the device.
Community profiles. This window searches the QuadStick maker's own catalog of shared game profiles. Nothing is fetched over the network until this window is opened or Refresh is pressed in it; the last successful list is cached on this computer, so the window still opens with no network at all. Importing a profile opens it in the editor the same way pasting a share link does. This app does not flash firmware, load or run a profile on the device directly, or do live calibration. The only thing it ever writes to a QuadStick is a profile file, through the same safe install pipeline in section 5.
9. Accessibility: what is built in
This app is built for the people who use a QuadStick: mouth-mouse users, switch users, screen-reader users, and low-vision users. These are not add-ons; several are enforced by automated tests.
| Feature | What it means | Checked how |
|---|---|---|
| Everything speaks | Every button, field, card, and device part has a spoken name, usually a full sentence ("Left mouthpiece hole. sip presses left_1…"). | Deep review sweep; names live next to each control in code |
| Keyboard everywhere | Tab reaches everything, Enter activates, Escape closes, arrows move through suggestions. No drag-only or right-click-only actions exist. | Review sweep |
| Color contrast gated | Every text/background pair used on screen must meet WCAG 4.5:1 (3:1 for the focus ring) in every theme. | Automated: PaletteContrastTests, 82-test suite |
| Never color-only | State is always words plus color: "Not on model" is written on dimmed parts, problems say the cell and the fix in text. | Fixed in this sweep |
| Tutorial can't trap or leak | The welcome tour blocks the app behind it for pointer AND keyboard, so Tab cannot reach live buttons mid-tour. | Fixed in this sweep |
| Tips are announced | Info popovers take focus and announce politely to screen readers; Escape closes them. | Fixed in this sweep |
| Big targets, scalable UI | 44px minimum hit targets; the whole interface scales from Settings; motion can be reduced. | Review sweep |
| Mistakes are cheap | Undo everywhere (Ctrl/Cmd+Z), unsaved-work warnings on every exit path, and installs that back up first. | Automated tests |
Honest remainders: real screen-reader testing (VoiceOver/NVDA) by actual users hasn't happened yet. That is what the beta ask is for. Sync file reads on the UI thread can briefly freeze the window with a slow USB stick (logged, low risk, on the list).
10. Where things live
| Path | What it is |
|---|---|
| src/QuadStick.Format/ | The careful layer: CSV parser, validator, lossless editor, safe installer, vocabulary. Pure logic, no UI, strictest compiler checks. |
| src/QuadStick.Format/Data/validation.json | The maker's legal-names list, embedded verbatim. |
| src/QuadStick.Format/Data/preferences.json | What the app knows about 61 device settings: type, range, and where each applies. A setting missing here still round-trips as plain text. |
| src/QuadStick.App/ | The window: home, device view, list view, install flow, settings, tutorial, theme and contrast tokens, plus the Manage files and Community profiles windows. |
| tests/ | 1013 automated tests, including real community profiles as fixtures, a transcription of the device's own file reader, and the contrast gate. |
| tools/RenderPreview/ | Takes screenshots of the real window without a display, so UI changes are reviewed by looking, not hoping. |
| docs/FORMAT.md | The file-format ground truth, every statement tied to its source. |
QuadStick Config Manager · free, open source (MIT) · not affiliated with QuadStick · github.com/Bbrizly/Quadstick-Config-Manager