Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mino.js

GameCube controller library for JavaScript. Plug in any GameCube adapter and get normalized, event-driven input in the browser zero dependencies, ~5 KB minified.

Features

  • Adapter auto-detection — Nintendo WUP-028, Mayflash, Raphnet, 8BitDo GBros, Brook, and generic USB adapters
  • Normalized state — every adapter maps to the same GCButton / GCAxis constants
  • Edge-detected eventspress, release, connect, disconnect
  • Full analog support — main stick, C-stick, L/R trigger analog values with configurable deadzone
  • 8-way stick directionmainStickDirection() / cStickDirection() helpers
  • Vibration — rumble support (where the browser/adapter allows)
  • Zero dependencies — pure W3C Gamepad API

Install

npm install mino.js

Or use a CDN:

<script src="https://unpkg.com/mino.js/dist/mino.min.js"></script>

Quick Start

import { Mino, GCButton } from 'mino.js';

const gc = new Mino();

// Listen for button presses
gc.on('press', ({ port, button }) => {
  console.log(`Port ${port}: ${button} pressed`);
});

gc.on('release', ({ port, button }) => {
  console.log(`Port ${port}: ${button} released`);
});

// Connection events
gc.on('connect', ({ port, adapter }) => {
  console.log(`Controller connected on port ${port} (${adapter})`);
});

// Poll loop — read state every frame
gc.on('poll', ({ port, state }) => {
  const { x, y } = state.mainStick;
  // Move character by (x, y)

  if (state.isPressed(GCButton.A)) {
    // A is held
  }
});

API

new Mino(options?)

Create a new GameCube controller manager.

Option Type Default Description
deadzone number 0.15 Stick deadzone (0–1)
triggerThreshold number 0.5 Analog trigger → digital press threshold
smoothing boolean false Enable low-pass filter on stick axes
smoothFactor number 0.5 Smoothing strength (lower = smoother)
autoStart boolean true Auto-start polling on construction
debug boolean false Log adapter connections to console

Reading State

// Get state for first connected controller
const state = gc.getState();

// Get state for a specific port
const state = gc.getState(0);

// All states
const all = gc.getAllStates();
// → [{ port: 0, adapter: 'Nintendo WUP-028', state: GCState }]

GCState Properties

Property Type Description
buttons Record<GCButton, boolean> All 12 button states
axes Record<GCAxis, number> All 6 axis values
mainStick { x, y } Main stick (−1 to +1)
cStick { x, y } C-stick (−1 to +1)
leftTrigger number L trigger analog (0–1)
rightTrigger number R trigger analog (0–1)
mainStickAngle number Main stick angle (radians)
mainStickMagnitude number Main stick distance (0–1)
connected boolean Connection status

Methods

Method Description
isPressed(button) Check if button is held
mainStickDirection(deadzone?) 8-way direction string or null
cStickDirection(deadzone?) 8-way direction string or null
clone() Deep copy state
toJSON() Serialize to plain object

Frame-Perfect Queries

// Did the button JUST go down this frame?
if (gc.justPressed(GCButton.A)) { /* jump */ }

// Did it JUST go up?
if (gc.justReleased(GCButton.B)) { /* release charge */ }

// Is it currently held?
if (gc.isHeld(GCButton.Z)) { /* shield */ }

Events

Event Payload Description
connect { port, adapter, gamepad } Controller plugged in
disconnect { port, adapter } Controller unplugged
press { port, button } Button just pressed
release { port, button } Button just released
poll { port, state } Every frame (RAF)
const unsub = gc.on('press', handler);
unsub(); // remove listener

gc.once('connect', handler); // fire once
gc.off('press', handler);    // manual remove

Configuration

gc.setDeadzone(0.2);
gc.setTriggerThreshold(0.4);
gc.setSmoothing(true, 0.3);

Vibration

gc.vibrate(0, {
  duration: 300,       // ms
  weakMagnitude: 0.5,  // 0–1
  strongMagnitude: 1.0 // 0–1
});

Lifecycle

gc.startPolling();  // begin RAF loop
gc.stopPolling();   // pause
gc.destroy();       // full cleanup

Button Constants

import { GCButton, GCAxis } from 'mino.js';

GCButton.A            GCButton.DPAD_UP
GCButton.B            GCButton.DPAD_DOWN
GCButton.X            GCButton.DPAD_LEFT
GCButton.Y            GCButton.DPAD_RIGHT
GCButton.Z            GCButton.L
GCButton.START        GCButton.R

GCAxis.MAIN_X         GCAxis.C_X
GCAxis.MAIN_Y         GCAxis.C_Y
GCAxis.L_ANALOG       GCAxis.R_ANALOG

Supported Adapters

Adapter Detection Status
Nintendo WUP-028 (Official) VID 057e PID 0337 ✅ Full support
Mayflash 4-Port (PC Mode) VID 0079 PID 1844 ✅ Full support
Mayflash 4-Port (Wii U Mode) VID 0079 PID 1800 ✅ Full support
Raphnet Technologies VID 289b ✅ Full support
8BitDo GBros Wireless VID 2dc8 ✅ Standard mapping
Brook Super Converter Name match ✅ Standard mapping
Generic USB GC Adapter Fallback ⚠️ Best-effort

Browser Support

Any browser implementing the W3C Gamepad API:

  • Chrome 21+
  • Firefox 29+
  • Edge 12+
  • Safari 10.1+
  • Opera 15+

About

GameCube controller library for the browser. Supports Nintendo, Mayflash, and Raphnet adapters via the W3C Gamepad API.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages