rumble

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2026 License: GPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package rumble parses and validates rumble files, which drive gamepad vibration from emulated game memory. FORMAT.md specifies the file format and its semantics.

Index

Constants

View Source
const (
	MinPriority = -99
	MaxPriority = 99
)

The range a rule's Priority may take; values outside it are reserved.

Variables

This section is empty.

Functions

This section is empty.

Types

type BinaryExpr

type BinaryExpr struct {
	Op    BoolOp
	Left  Expr
	Right Expr
}

BinaryExpr combines two subexpressions with and/or.

type BoolOp

type BoolOp int

BoolOp is a boolean connective.

const (
	OpAnd BoolOp = iota
	OpOr
)

type CompareCond

type CompareCond struct {
	Watch   string
	Op      CompareOp
	Operand uint32
	Line    int
}

CompareCond compares a value against a constant.

type CompareOp

type CompareOp int

CompareOp is a constant comparison operator.

const (
	OpEq CompareOp = iota
	OpNe
	OpLt
	OpGt
	OpLe
	OpGe
)

type CompareWatchCond

type CompareWatchCond struct {
	Left  string
	Op    CompareOp
	Right string
	Line  int
}

CompareWatchCond compares two watches' current values each frame. Both sides must declare the same interpretation so the values compare in one domain. Either side unresolved makes the condition false.

type Const

type Const struct {
	Name  string
	Value uint32
	Line  int
}

Const names a fixed integer usable wherever a numeric literal appears as a condition operand.

type Def

type Def struct {
	Name string
	Expr Expr
	Line int
}

Def names a reusable constant-comparison expression.

type DefRef

type DefRef struct {
	Name   string
	Negate bool
	Line   int
}

DefRef references a def or an event by name. Negate inverts the reference. A negated def evaluates as its body with the negation pushed to the leaves, so an unresolved watch makes the negated conditions false too, and a negated event is true while its window is closed.

type Effect

type Effect struct {
	Kind       EffectKind
	Strong     float64
	Weak       float64
	DurationMs int
	Steps      []Step
	Percent    int
}

Effect is a rule's effect. Strong, Weak, and DurationMs describe a pulse or hold (DurationMs unused for hold). Steps describes a pattern. A dampen or amplify effect uses only Percent.

type EffectKind

type EffectKind int

EffectKind identifies which effect a rule carries.

const (
	EffectPulse EffectKind = iota
	EffectPattern
	EffectHold
	EffectDampen
	EffectAmplify
)

type Endian

type Endian int

Endian selects the byte order used to decode a multi-byte value.

const (
	// EndianDefault decodes with the system's native byte order.
	EndianDefault Endian = iota
	EndianLittle
	EndianBig
)

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine evaluates a ruleset once per emulated frame.

func NewEngine

func NewEngine(rs *Ruleset, sys System, players int) (*Engine, error)

NewEngine validates a ruleset and binds it to a system's memory layout. Parsed and programmatically built rulesets pass through the same validation. players is the number of emulated players a "player all" rule fans out to; a count below 1 is treated as 1.

The engine keeps references into rs - a pattern's steps and a rule's scale - so rs must not be mutated after it is bound. Build a fresh ruleset and a fresh engine to change a rule.

func (*Engine) Evaluate

func (en *Engine) Evaluate(mem Reader, now time.Time) []MotorState

Evaluate runs one frame and returns the per-player motor output.

func (*Engine) Metadata

func (en *Engine) Metadata() Metadata

Metadata returns the ruleset's metadata block.

func (*Engine) Reset

func (en *Engine) Reset()

Reset clears all runtime state and re-arms the settle window. Called on save state load, rewind, and resume (see INTEGRATION.md).

type Event

type Event struct {
	Name       string
	Trigger    PrevCond
	DurationMs int
	Held       bool
	Cond       Expr
	HeldFrames int
	Line       int
}

Event names a timed condition, in one of two forms: a trigger event opens a window of DurationMs when Trigger fires, and a held event (Held set) is true once Cond has held for HeldFrames consecutive frames. Each form uses only its own fields.

type Expr

type Expr interface {
	// contains filtered or unexported methods
}

Expr is a node of a condition expression.

type Metadata

type Metadata struct {
	Game     string
	GameID   string
	System   string
	Revision int
}

Metadata is a rumble file's documentation block, the statements above the "---" terminator. Every field is optional and the engine reads none of them: they describe the file for a host or a tool. Revision is 1 when omitted.

type MotorState

type MotorState struct {
	Player int
	Strong float64
	Weak   float64
}

MotorState is the final motor output for one player on one frame, after arbitration and hold mixing. A player absent from a frame's output has both motors off. The converse does not hold: a silent pattern step, a pulse authored off, and an effect or hold muted by a full dampen all leave a player present at zero.

type PrevCond

type PrevCond struct {
	Watch   string
	Op      PrevOp
	Qual    PrevQual
	Operand uint32
	Line    int
}

PrevCond compares a value against its previous-frame value. Operand is the qualifier's operand and is meaningful only when Qual is not QualNone.

type PrevOp

type PrevOp int

PrevOp is a previous-frame condition operator.

const (
	OpChanged PrevOp = iota
	OpUnchanged
	OpIncreased
	OpDecreased
)

type PrevQual

type PrevQual int

PrevQual qualifies a previous-frame condition with an operand. A condition takes at most one qualifier, and unchanged takes none.

const (
	QualNone PrevQual = iota
	QualBy
	QualAtLeast
	QualAtMost
	QualFrom
	QualTo
)

type Reader

type Reader interface {
	ReadMemory(addr uint32, buf []byte) uint32
}

Reader is the memory interface the engine reads through, matching the shape of the core memory interface. Addresses are native bus addresses.

type Region

type Region struct {
	Name  string
	Start uint32 // native bus address of the region's first byte
	Size  uint32 // region size in bytes
}

Region describes one memory region of a system's bus in canonical addresses.

type Rule

type Rule struct {
	On         Expr
	While      Expr // nil when the rule has no gate
	Effect     Effect
	Level      bool
	Priority   int
	Clip       bool
	ClipMs     int
	CooldownMs int
	Player     int // 1-based; ignored when PlayerAll is set
	PlayerAll  bool
	Scale      *Scale
	Line       int
}

Rule binds a condition to an effect with its modifiers. Clip bounds the effect's life by On. Once On has been false for ClipMs the installed effect is cancelled. Priority ranks the rule inside its pool, strictly greater winning.

type Ruleset

type Ruleset struct {
	Metadata Metadata
	Watches  []Watch
	Consts   []Const
	Events   []Event
	Defs     []Def
	Rules    []Rule
}

Ruleset is the structured form of a rumble file: the metadata block, the declared watches, consts, events, and defs, and the rules in file order.

func Parse

func Parse(src []byte) (*Ruleset, error)

Parse parses and validates rumble file source. Address validation against a system's memory regions happens in NewEngine, when the ruleset is bound to a running system.

type Scale

type Scale struct {
	Watch     string
	MagMin    uint32
	MagMax    uint32
	MagMinNeg bool
	MagMaxNeg bool
	MulMin    float64
	MulMax    float64
}

Scale maps a magnitude clamped to [MagMin, MagMax] linearly onto an intensity multiplier in [MulMin, MulMax]. Watch selects where the magnitude comes from. Empty is the frame's change in the rule's one previous-frame condition, and a name is that watch's current value.

MagMinNeg and MagMaxNeg record an endpoint written with a minus sign, which folding otherwise erases; validation allows one only on a signed magnitude watch.

type SetCond

type SetCond struct {
	Watch  string
	Negate bool
	Set    []uint32
	Line   int
}

SetCond tests a value for membership in a constant set.

type Step

type Step struct {
	Strong     float64
	Weak       float64
	DurationMs int
}

Step is one step of a pattern effect.

type System

type System struct {
	BigEndian bool
	Regions   []Region
}

System describes the memory layout that addresses validate against and the native byte order values decode with.

type Watch

type Watch struct {
	Name    string
	Width   int // 8, 16, or 32 bits
	Address uint32
	Pointer bool   // Address holds a pointer to the value
	Offset  uint32 // added to a pointer's target; needs Pointer or FieldPtr
	Stride  uint32 // bytes between slots; 0 on a single-value watch
	Count   int    // number of slots; 0 on a single-value watch

	HasKey      bool   // keyed slot watch; needs Stride and Count
	KeyOffset   uint32 // slot offset of the key long
	KeyValue    uint32 // value selecting the slot
	FieldOffset uint32 // slot offset of the watched field
	FieldPtr    bool   // the field holds a pointer to the value

	// Signed, Abs, and BCD interpret the masked value as two's
	// complement, its absolute value, or packed BCD (see FORMAT.md).
	// At most one may be set, and like Mask and Endian they apply to
	// the watched value only, never to a pointer or a key. Condition
	// operands stay uint32 bit patterns.
	Signed bool
	Abs    bool
	BCD    bool

	Mask    uint32
	HasMask bool
	Endian  Endian
	Line    int
}

Watch declares a named memory watch. Address is the canonical native bus address. A Count of 0 declares a single value. A Count of 2 or more declares an array watch reading Count slots spaced Stride bytes apart, whose conditions test whether any slot matches. Pointer declares a pointer watch and HasKey a keyed slot watch; both have a single value and can be unresolved (see FORMAT.md).

Directories

Path Synopsis
cmd
validate command
Command validate checks rumble files
Command validate checks rumble files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL