Compare commits
22 Commits
Author | SHA1 | Date |
---|---|---|
Neale Pickett | ed8d884054 | |
Neale Pickett | 8ccbaaa4b7 | |
Neale Pickett | 195c02748b | |
Neale Pickett | 13825855d3 | |
Neale Pickett | e54595e630 | |
Neale Pickett | 63bd067250 | |
Neale Pickett | 9f0c0711a8 | |
Neale Pickett | efc67e9fe5 | |
Neale Pickett | ce7d6107cf | |
Neale Pickett | 48d2450514 | |
Neale Pickett | 5f44832151 | |
Neale Pickett | da45584955 | |
Neale Pickett | 50ce7c245a | |
Neale Pickett | f767eb6e23 | |
Neale Pickett | 7495bfd20f | |
Neale Pickett | 5fa607d6b0 | |
Neale Pickett | 855ad3ba60 | |
Neale Pickett | 25a917dc81 | |
Neale Pickett | a8d4918e05 | |
Neale Pickett | 544ffa8ced | |
Neale Pickett | a3d8262e01 | |
Neale Pickett | 0ba9c0957a |
|
@ -7,23 +7,21 @@ VERSION=$GITHUB_REF_NAME
|
||||||
|
|
||||||
BASE=$GITHUB_SERVER_URL/api/packages/$GITHUB_ACTOR/generic/$PACKAGE/$VERSION
|
BASE=$GITHUB_SERVER_URL/api/packages/$GITHUB_ACTOR/generic/$PACKAGE/$VERSION
|
||||||
|
|
||||||
|
echo "=== Delete $VERSION"
|
||||||
curl \
|
curl \
|
||||||
--user "$GITHUB_ACTOR:$PACKAGE_API_TOKEN" \
|
--user "$GITHUB_ACTOR:$PACKAGE_API_TOKEN" \
|
||||||
--request DELETE \
|
--request DELETE \
|
||||||
$BASE
|
$BASE
|
||||||
|
echo
|
||||||
|
|
||||||
for path in "$@"; do
|
for path in "$@"; do
|
||||||
fn=$(basename "$path")
|
fn=$(basename "$path")
|
||||||
echo "=== Upload $VERSION/$fn"
|
echo "=== Upload $VERSION/$fn"
|
||||||
|
|
||||||
curl \
|
|
||||||
--user "$GITHUB_ACTOR:$PACKAGE_API_TOKEN" \
|
|
||||||
--request DELETE \
|
|
||||||
$BASE/$fn
|
|
||||||
|
|
||||||
curl \
|
curl \
|
||||||
--fail \
|
--fail \
|
||||||
--user "$GITHUB_ACTOR:$PACKAGE_API_TOKEN" \
|
--user "$GITHUB_ACTOR:$PACKAGE_API_TOKEN" \
|
||||||
--upload-file "$path" \
|
--upload-file "$path" \
|
||||||
$BASE/$fn
|
$BASE/$fn
|
||||||
|
echo
|
||||||
done
|
done
|
||||||
|
|
|
@ -16,4 +16,4 @@ jobs:
|
||||||
- name: publish
|
- name: publish
|
||||||
env:
|
env:
|
||||||
PACKAGE_API_TOKEN: ${{ secrets.PACKAGE_API_TOKEN }}
|
PACKAGE_API_TOKEN: ${{ secrets.PACKAGE_API_TOKEN }}
|
||||||
run: .gitea/publish.sh *.hex *.zip
|
run: .gitea/publish.sh build/*.zip build/*.hex
|
||||||
|
|
42
Makefile
42
Makefile
|
@ -2,29 +2,27 @@ DEVICE=/dev/ttyACM0
|
||||||
|
|
||||||
all: firmwares
|
all: firmwares
|
||||||
|
|
||||||
firmwares: MockBand.guitar-wammy.hex
|
firmwares: build/MockBand.guitar-wammy.hex
|
||||||
MockBand.guitar-wammy.hex: VID=0x1bad
|
build/MockBand.guitar-wammy.hex: VID=0x1bad
|
||||||
MockBand.guitar-wammy.hex: PID=0x0004
|
build/MockBand.guitar-wammy.hex: PID=0x0004
|
||||||
MockBand.guitar-wammy.hex: FLAGS=-DWAMMY
|
build/MockBand.guitar-wammy.hex: FLAGS=-DWAMMY
|
||||||
|
|
||||||
firmwares: MockBand.guitar.hex
|
firmwares: build/MockBand.guitar.hex
|
||||||
MockBand.guitar.hex: VID=0x1bad
|
build/MockBand.guitar.hex: VID=0x1bad
|
||||||
MockBand.guitar.hex: PID=0x0004
|
build/MockBand.guitar.hex: PID=0x0004
|
||||||
|
|
||||||
firmwares: MockBand.drums.hex
|
firmwares: build/MockBand.drums.hex
|
||||||
MockBand.drums.hex: VID=0x1bad
|
build/MockBand.drums.hex: VID=0x1bad
|
||||||
MockBand.drums.hex: PID=0x3110
|
build/MockBand.drums.hex: PID=0x3110
|
||||||
|
|
||||||
MockBand.drums-xbox.hex: VID=0x1bad
|
firmwares: build/MockBand.drums1.hex
|
||||||
MockBand.drums-xbox.hex: PID=0x0003
|
build/MockBand.drums1.hex: VID=0x1bad
|
||||||
|
build/MockBand.drums1.hex: PID=00005
|
||||||
MockBand.drums-rb1.hex: VID=0x1bad
|
|
||||||
MockBand.drums-rb1.hex: PID=00005
|
|
||||||
|
|
||||||
|
|
||||||
MockBand.%.hex: MockBand.ino
|
build/MockBand.%.hex: MockBand.ino
|
||||||
rm -rf build
|
|
||||||
mkdir -p build/cache
|
mkdir -p build/cache
|
||||||
|
rm -f build/build.options.json
|
||||||
arduino-builder \
|
arduino-builder \
|
||||||
-build-path $(abspath build/) \
|
-build-path $(abspath build/) \
|
||||||
-build-cache $(abspath build/cache/) \
|
-build-cache $(abspath build/cache/) \
|
||||||
|
@ -36,16 +34,16 @@ MockBand.%.hex: MockBand.ino
|
||||||
mv build/MockBand.ino.hex $@
|
mv build/MockBand.ino.hex $@
|
||||||
|
|
||||||
|
|
||||||
flash-%: MockBand.%.hex
|
flash-%: build/MockBand.%.hex
|
||||||
echo -n "Waiting for $(DEVICE)..."; while [ ! -e $(DEVICE) ]; do echo -n .; sleep 1; done
|
echo -n "Waiting for $(DEVICE)..."; while [ ! -e $(DEVICE) ]; do echo -n .; sleep 1; done
|
||||||
avrdude -v -patmega32u4 -cavr109 -P$(DEVICE) -b57600 -D -Uflash:w:$<:i
|
avrdude -v -patmega32u4 -cavr109 -P$(DEVICE) -b57600 -D -Uflash:w:$<:i
|
||||||
|
|
||||||
dist: MockBand.zip
|
dist: build/MockBand.zip
|
||||||
|
|
||||||
MockBand.zip: firmwares
|
build/MockBand.zip: firmwares
|
||||||
rm -f $@
|
rm -f $@
|
||||||
zip -r $@ README.md *.hex docs/
|
zip -r $@ README.md build/*.hex docs/
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build MockBand.*.hex MockBand.zip
|
rm -rf build
|
||||||
|
|
||||||
|
|
98
MockBand.ino
98
MockBand.ino
|
@ -2,9 +2,11 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <PluggableUSB.h>
|
#include <PluggableUSB.h>
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
#include "hid.hh" // Modified HID library: doesn't prefix each packet with ID
|
#include "hid.hh" // Modified HID library: doesn't prefix each packet with ID
|
||||||
#include "instrument.hh"
|
#include "instrument.hh"
|
||||||
#include "standard.hh" // Standard pins
|
#include "piezos.hh"
|
||||||
|
|
||||||
// If defined, we will check the wammy bar input
|
// If defined, we will check the wammy bar input
|
||||||
//#define WAMMY
|
//#define WAMMY
|
||||||
|
@ -26,9 +28,7 @@
|
||||||
#error USB_VID must be set to 0x1bad: see INSTALL.md
|
#error USB_VID must be set to 0x1bad: see INSTALL.md
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USB_PID == 0x0003
|
#if USB_PID == 0x0004
|
||||||
#define DRUM // XBox
|
|
||||||
#elif USB_PID == 0x0004
|
|
||||||
#define GUITAR
|
#define GUITAR
|
||||||
#elif USB_PID == 0x0005
|
#elif USB_PID == 0x0005
|
||||||
#define DRUM // Wii RB1
|
#define DRUM // Wii RB1
|
||||||
|
@ -41,23 +41,17 @@
|
||||||
InstrumentButtonState buttonState = {0};
|
InstrumentButtonState buttonState = {0};
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
pinMode(STRUM_DOWN, INPUT_PULLUP);
|
pinMode(BUTTON_GREEN, INPUT);
|
||||||
pinMode(STRUM_UP, INPUT_PULLUP);
|
pinMode(BUTTON_RED, INPUT);
|
||||||
pinMode(TILT_SWITCH, INPUT_PULLUP);
|
pinMode(BUTTON_YELLOW, INPUT);
|
||||||
pinMode(BUTTON_GREEN, INPUT_PULLUP);
|
pinMode(BUTTON_BLUE, INPUT);
|
||||||
pinMode(BUTTON_RED, INPUT_PULLUP);
|
|
||||||
pinMode(BUTTON_YELLOW, INPUT_PULLUP);
|
|
||||||
pinMode(BUTTON_BLUE, INPUT_PULLUP);
|
|
||||||
pinMode(BUTTON_ORANGE, INPUT_PULLUP);
|
pinMode(BUTTON_ORANGE, INPUT_PULLUP);
|
||||||
pinMode(SOLO_GREEN, INPUT_PULLUP);
|
pinMode(SOLO_GREEN, INPUT);
|
||||||
pinMode(SOLO_RED, INPUT_PULLUP);
|
pinMode(SOLO_RED, INPUT);
|
||||||
pinMode(SOLO_YELLOW, INPUT_PULLUP);
|
pinMode(SOLO_YELLOW, INPUT);
|
||||||
pinMode(SOLO_BLUE, INPUT_PULLUP);
|
pinMode(SOLO_BLUE, INPUT);
|
||||||
pinMode(SOLO_ORANGE, INPUT_PULLUP);
|
|
||||||
pinMode(BUTTON_PLUS, INPUT_PULLUP);
|
pinMode(BUTTON_PLUS, INPUT_PULLUP);
|
||||||
pinMode(BUTTON_MINUS, INPUT_PULLUP);
|
pinMode(BUTTON_MINUS, INPUT_PULLUP);
|
||||||
pinMode(ANALOG_WAMMY, INPUT);
|
|
||||||
pinMode(ANALOG_DPAD, INPUT);
|
|
||||||
|
|
||||||
// Initialize HID
|
// Initialize HID
|
||||||
static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
|
static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
|
||||||
|
@ -86,10 +80,13 @@ uint8_t pins[] = {
|
||||||
};
|
};
|
||||||
#define npins (sizeof(pins) / sizeof(*pins))
|
#define npins (sizeof(pins) / sizeof(*pins))
|
||||||
|
|
||||||
|
#define NOISE_THRESHOLD 40 // Minimum analog value to treat as a hit
|
||||||
|
|
||||||
// The 3.3v Pro Micro is on the slow side.
|
// The 3.3v Pro Micro is on the slow side.
|
||||||
// Our strategy is to poll button state as quickly as possible,
|
// Our strategy is to poll button state as quickly as possible,
|
||||||
// and hope we don't miss anything while we're doing USB stuff.
|
// and hope we don't miss anything while we're doing USB stuff.
|
||||||
void loop() {
|
void loop() {
|
||||||
|
uint16_t inputs[16] = {0};
|
||||||
uint16_t buttons = 0;
|
uint16_t buttons = 0;
|
||||||
uint16_t samples = 0;
|
uint16_t samples = 0;
|
||||||
unsigned long next = 0;
|
unsigned long next = 0;
|
||||||
|
@ -99,15 +96,22 @@ void loop() {
|
||||||
uint16_t edge = 0;
|
uint16_t edge = 0;
|
||||||
|
|
||||||
samples++;
|
samples++;
|
||||||
|
inputs[0] = analogRead(INPUT_BLUE);
|
||||||
|
inputs[1] = analogRead(INPUT_GREEN);
|
||||||
|
inputs[2] = analogRead(INPUT_RED);
|
||||||
|
inputs[3] = analogRead(INPUT_YELLOW);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < npins; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
if (silence[i]) {
|
if (silence[i]) {
|
||||||
silence[i]--;
|
silence[i]--;
|
||||||
} else if (bitRead(buttons, i) != !digitalRead(pins[i])) {
|
} else {
|
||||||
|
bool trigger = inputs[i] > NOISE_THRESHOLD;
|
||||||
|
if (trigger != bitRead(buttons, i)) {
|
||||||
edge |= bit(i);
|
edge |= bit(i);
|
||||||
silence[i] = SILENCE_SAMPLES;
|
silence[i] = SILENCE_SAMPLES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
buttons ^= edge;
|
buttons ^= edge;
|
||||||
|
|
||||||
// We've sampled everything. Is it time to do calculations and USB?
|
// We've sampled everything. Is it time to do calculations and USB?
|
||||||
|
@ -127,58 +131,42 @@ void loop() {
|
||||||
//
|
//
|
||||||
// Calculate and send an HID update
|
// Calculate and send an HID update
|
||||||
//
|
//
|
||||||
uint16_t vbuttons = buttons; // We're going to mess with the button state
|
|
||||||
|
|
||||||
buttonState.buttons = (vbuttons & 0b1100111111); // +-..!OYRGB
|
buttonState.buttons = (buttons & 0b1100111111); // +-..!OYRGB
|
||||||
#ifdef GUITAR
|
#ifdef GUITAR
|
||||||
buttonState.buttons |= (vbuttons >> 10) & 0b11111; // Solo keys
|
buttonState.buttons |= (buttons >> 10) & 0b11111; // Solo keys
|
||||||
bitWrite(buttonState.buttons, 6, (vbuttons >> 10) & 0b11111); // Solo modifier
|
bitWrite(buttonState.buttons, 6, buttons & (0b11111 << 10)); // Solo modifier
|
||||||
|
|
||||||
if (bitRead(vbuttons, 6)) {
|
if (bitRead(buttons, 6)) {
|
||||||
buttonState.hatAndConstant = 0; // up
|
buttonState.hatAndConstant = 0; // up
|
||||||
} else if bitRead(vbuttons, 7) {
|
} else if bitRead(buttons, 7) { //
|
||||||
buttonState.hatAndConstant = 4; // down
|
buttonState.hatAndConstant = 4; // down
|
||||||
} else {
|
} else {
|
||||||
buttonState.hatAndConstant = 8; // nothing
|
buttonState.hatAndConstant = 8; // nothing
|
||||||
}
|
}
|
||||||
#else // DRUMS
|
#else // DRUMS
|
||||||
|
buttonState.buttons |= (buttons >> 10) & 0b01011; // Cymbals
|
||||||
|
bitWrite(buttonState.buttons, 10, (buttons >> 0) & 0b01111); // Drum pad modifier
|
||||||
|
bitWrite(buttonState.buttons, 11, (buttons >> 10) & 0b01011); // Cymbals modifier
|
||||||
|
buttonState.axis[3] = bitRead(buttons, 12)?255:0; // High hat
|
||||||
|
|
||||||
// Hi hat pedal (SOLO_RED) makes yellow cymbal strike a blue cymbal strike
|
// rbdrum2midi wants these set
|
||||||
if (bitRead(vbuttons, 12) && bitRead(vbuttons, 13)) {
|
buttonState.velocity[0] = inputs[3]/4; // Y
|
||||||
bitClear(vbuttons, 13);
|
buttonState.velocity[1] = inputs[2]/4; // R
|
||||||
bitSet(vbuttons, 10);
|
buttonState.velocity[2] = inputs[1]/2; // G
|
||||||
}
|
buttonState.velocity[3] = inputs[0]/4; // B
|
||||||
|
|
||||||
buttonState.buttons |= (vbuttons >> 10) & 0b01011; // Cymbals
|
// Say the D-pad is centered
|
||||||
bitWrite(buttonState.buttons, 10, (vbuttons >> 0) & 0b01111); // Drum pad modifier
|
buttonState.hatAndConstant = 8;
|
||||||
bitWrite(buttonState.buttons, 11, (vbuttons >> 10) & 0b01011); // Cymbals modifier
|
|
||||||
|
|
||||||
|
|
||||||
// rbdrum2midi wants these set: it ignores the button states.
|
|
||||||
buttonState.velocity[0] = bitRead(buttonState.buttons, 3)?127:0; // Y
|
|
||||||
buttonState.velocity[1] = bitRead(buttonState.buttons, 2)?127:0; // R
|
|
||||||
buttonState.velocity[2] = bitRead(buttonState.buttons, 1)?127:0; // G
|
|
||||||
buttonState.velocity[3] = bitRead(buttonState.buttons, 0)?127:0; // B
|
|
||||||
|
|
||||||
// Clone Hero 1.0.0.4080-final needs blue and yellow cymbals to send up and down on d-pad.
|
|
||||||
// This is what the mysterous CymExt1 and CymExt2 mappings mean.
|
|
||||||
// If these aren't set, all pads (except red) register as simultaneous drum and cymbal hits.
|
|
||||||
if (bitRead(vbuttons, 13)) {
|
|
||||||
buttonState.hatAndConstant = 0; // up
|
|
||||||
} else if (bitRead(vbuttons, 10)) {
|
|
||||||
buttonState.hatAndConstant = 4; // down
|
|
||||||
} else {
|
|
||||||
buttonState.hatAndConstant = 8; // nothing
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DPAD
|
#ifdef DPAD
|
||||||
#error DPAD isn't implemented yet
|
#error DPAD isn't implemented yet
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUGY0
|
#ifdef DEBUG
|
||||||
// Log sample rate to the first Y axis
|
// Log sample rate to the first X axis
|
||||||
buttonState.axis[1] = samples & 0xff;
|
buttonState.axis[0] = samples & 0xff;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Send an update
|
// Send an update
|
||||||
|
|
76
README.md
76
README.md
|
@ -1,9 +1,4 @@
|
||||||
---
|
# Mock Band
|
||||||
gitea: none
|
|
||||||
include_toc: true
|
|
||||||
---
|
|
||||||
|
|
||||||
# Introduction
|
|
||||||
|
|
||||||
Microcontroller Firmware to emulate guitar and drum kit controllers from the
|
Microcontroller Firmware to emulate guitar and drum kit controllers from the
|
||||||
Wii version of the Rock Band games.
|
Wii version of the Rock Band games.
|
||||||
|
@ -23,23 +18,6 @@ Thanks, Nicholas!
|
||||||
* A physical controller
|
* A physical controller
|
||||||
|
|
||||||
|
|
||||||
# Skills Needed
|
|
||||||
|
|
||||||
This is a research project:
|
|
||||||
it's assumed you already have a skillset that includes:
|
|
||||||
|
|
||||||
* Disassembling consumer electronics
|
|
||||||
* Using a multimeter to perform continuity checks
|
|
||||||
* Building electronics projects using a microcontroller
|
|
||||||
* Soldering
|
|
||||||
* Running the Arduino IDE *or* using `avrdude` to flash a firmware
|
|
||||||
|
|
||||||
If you're not comfortable with the above list,
|
|
||||||
your best option right now (Jan 2024) is to either buy a used kit,
|
|
||||||
or wait for the Polybar project to finish their work
|
|
||||||
producing a beginner-friendly kit with assembly manual.
|
|
||||||
|
|
||||||
|
|
||||||
# Controllers
|
# Controllers
|
||||||
|
|
||||||
## Guitar
|
## Guitar
|
||||||
|
@ -71,30 +49,10 @@ I'm sorry I didn't photograph or record any of this,
|
||||||
but it was pretty straightforward.
|
but it was pretty straightforward.
|
||||||
|
|
||||||
|
|
||||||
# Building
|
# Compiling
|
||||||
|
|
||||||
This will compile in the Arduino IDE,
|
This compiles in the Arduino IDE.
|
||||||
or on the commandline using `make`.
|
It doesn't have any library dependencies.
|
||||||
|
|
||||||
## Command Line
|
|
||||||
|
|
||||||
Just run `make` on a Unix system.
|
|
||||||
I set up paths for my Debian install of Arduino 1.8;
|
|
||||||
you may need to adjust them if your setup has different paths.
|
|
||||||
|
|
||||||
There is a `flash-%` target that will upload the built firmware to a Pro Micro.
|
|
||||||
The following targets exist:
|
|
||||||
|
|
||||||
make flash-guitar # Guitar firmware
|
|
||||||
make flash-guitar-wammy # Guitar firmware with wammy bar
|
|
||||||
make flash-drums # Drums firmware
|
|
||||||
|
|
||||||
## Arduino
|
|
||||||
|
|
||||||
Mockband has no library dependencies,
|
|
||||||
and as far as I can tell,
|
|
||||||
will work with the built-in Leonardo profile,
|
|
||||||
even though you're uploading to a Pro Micro.
|
|
||||||
|
|
||||||
You need to make two edits to `boards.txt`.
|
You need to make two edits to `boards.txt`.
|
||||||
Instructions for this are all over the place.
|
Instructions for this are all over the place.
|
||||||
|
@ -105,7 +63,7 @@ Don't edit anything that doesn't say `build` on the line! I can't help you if yo
|
||||||
In my examples, I'm editing the lines for the leonardo build. Yours might be different:
|
In my examples, I'm editing the lines for the leonardo build. Yours might be different:
|
||||||
it should match the board you're using.
|
it should match the board you're using.
|
||||||
|
|
||||||
### Build flags
|
## Build flags
|
||||||
|
|
||||||
This disables serial communications on the board.
|
This disables serial communications on the board.
|
||||||
|
|
||||||
|
@ -114,7 +72,7 @@ This disables serial communications on the board.
|
||||||
Hat tip to Nicholas Angle for figuring this out
|
Hat tip to Nicholas Angle for figuring this out
|
||||||
so I didn't have to.
|
so I didn't have to.
|
||||||
|
|
||||||
### VID and PID
|
## VID and PID
|
||||||
|
|
||||||
These set the USB identifiers.
|
These set the USB identifiers.
|
||||||
VID is the Vendor ID,
|
VID is the Vendor ID,
|
||||||
|
@ -123,7 +81,7 @@ and PID is the Product ID.
|
||||||
`0x1bad` means "Harmonix Music",
|
`0x1bad` means "Harmonix Music",
|
||||||
at least, it does to the Linux kernel.
|
at least, it does to the Linux kernel.
|
||||||
|
|
||||||
#### For guitar
|
### For guitar
|
||||||
|
|
||||||
PID `0x004` means "Guitar controller".
|
PID `0x004` means "Guitar controller".
|
||||||
|
|
||||||
|
@ -132,7 +90,7 @@ PID `0x004` means "Guitar controller".
|
||||||
leonardo.build.usb_product="Mockband Guitar"
|
leonardo.build.usb_product="Mockband Guitar"
|
||||||
|
|
||||||
|
|
||||||
#### For drums
|
### For drums
|
||||||
|
|
||||||
PID `0x3110` means "Rock Band 2 drums".
|
PID `0x3110` means "Rock Band 2 drums".
|
||||||
This works better with all versions of Rock Band on my wii,
|
This works better with all versions of Rock Band on my wii,
|
||||||
|
@ -228,19 +186,6 @@ will use both the 2x kick and the hi hat.
|
||||||
Maybe there is some other game that uses this too.
|
Maybe there is some other game that uses this too.
|
||||||
|
|
||||||
|
|
||||||
# Related Projects
|
|
||||||
|
|
||||||
Mockband is a research project.
|
|
||||||
You can use it to build a fully working controller,
|
|
||||||
but the main goal of this project is to inform other developers.
|
|
||||||
|
|
||||||
If you're looking for a user-friendly way to get a Rock Band drum controller,
|
|
||||||
consider the following alternatives:
|
|
||||||
|
|
||||||
* Buying a used Harmonix (official Rock Band) drum kit
|
|
||||||
* Mad Catz Rock Band 3 MIDI PRO-Adapter and a MIDI e-drum kit
|
|
||||||
* [Santroller](https://santroller.tangentmc.net/wiring_guides/drum.html)
|
|
||||||
wired to a used Harmonix drum kit
|
|
||||||
|
|
||||||
|
|
||||||
# Bugs / Not Yet Implemented
|
# Bugs / Not Yet Implemented
|
||||||
|
@ -255,11 +200,6 @@ just
|
||||||
and I'll open an issue.
|
and I'll open an issue.
|
||||||
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
You may use this under the terms of the [MIT License](docs/COPYING.md).
|
|
||||||
|
|
||||||
|
|
||||||
# Need help?
|
# Need help?
|
||||||
|
|
||||||
[Email me](mailto:neale@woozle.org),
|
[Email me](mailto:neale@woozle.org),
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Changelog
|
|
||||||
|
|
||||||
## [1.0-beta2] - 2024-01-07
|
|
||||||
### Added
|
|
||||||
- CI/CD build
|
|
||||||
- Make-based build, but it still works with the Arduino IDE!
|
|
||||||
- XBox controller
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Blue and Yellow cymbal strikes send up and down on the D-pad.
|
|
||||||
- This fixes a bug with Clone Hero where Blue, Yellow, and Green pads,
|
|
||||||
both cymbal and drum pads,
|
|
||||||
triggered a drum and cymbal hit at the same time.
|
|
||||||
- Clone Hero's mysterious CymExt1 and CymExt2 are read on Yellow and Blue
|
|
||||||
cymbal hits, and must map to dpad up and down. In Windows this might be called "POV Hat";
|
|
||||||
in Linux it's called "Hat 0"
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
- The "high hat" pin now causes the yellow cymbal to send a blue cymbal hit,
|
|
||||||
similar to devices sold in the past for this express purpose.
|
|
||||||
Previously it changed a hat axis,
|
|
||||||
because I thought "hat" meant "high hat". Heh.
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
- No more DEBUG option
|
|
||||||
|
|
||||||
## [1.0-beta1] - 2024-01-04
|
|
|
@ -1,22 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright © 2023 Nicholas Angle
|
|
||||||
Copyright © 2023-2024 Neale Pickett <neale@woozle.org>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
**The software is provided "as is", without warranty of any kind, express or
|
|
||||||
implied, including but not limited to the warranties of merchantability,
|
|
||||||
fitness for a particular purpose and noninfringement. In no event shall the
|
|
||||||
authors or copyright holders be liable for any claim, damages or other
|
|
||||||
liability, whether in an action of contract, tort or otherwise, arising from,
|
|
||||||
out of or in connection with the software or the use or other dealings in the
|
|
||||||
software.**
|
|
|
@ -7,44 +7,16 @@ so that when original sources fall off the net,
|
||||||
hopefully at least my notes will still be around.
|
hopefully at least my notes will still be around.
|
||||||
|
|
||||||
|
|
||||||
USB data rate
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Unlike the Santroller
|
|
||||||
(which is much easier to install for beginners),
|
|
||||||
this firmware does not send continuous updates over USB,
|
|
||||||
unless it has to.
|
|
||||||
|
|
||||||
Because the only analog input is the wammy bar,
|
|
||||||
if you don't include that input,
|
|
||||||
the controller can stay silent until a button is pressed or released.
|
|
||||||
This allows 4 controllers to connect to a USB hub,
|
|
||||||
with no concern for overwhelming the hub.
|
|
||||||
Since the amount of data is about the same as a keyboard,
|
|
||||||
and a little less than a mouse,
|
|
||||||
I would expect that a 7-port USB 2 hub would also handle 7 instruments,
|
|
||||||
no problem.
|
|
||||||
I just don't know of any games that can use mor than 4 instruments.
|
|
||||||
|
|
||||||
If you do use the wammy bar,
|
|
||||||
an update is sent every 20 milliseconds.
|
|
||||||
The firmware still attempts to reduce lag
|
|
||||||
by sending button change events as soon as possible.
|
|
||||||
I haven't played with this much,
|
|
||||||
so if you have a wammy bar set up,
|
|
||||||
please reach out to me and let me know how it works.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Sample Rate
|
Sample Rate
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
If `DEBUGY0' is defined,
|
The number of samples taken since the last HID report
|
||||||
the number of samples taken since the last HID report
|
is sent as the second Y axis.
|
||||||
is sent as Y axis on hat 0.
|
If you `#define DEBUG`,
|
||||||
You can use the
|
you can use the
|
||||||
[included gamepad tester](gamepad.html),
|
[included gamepad tester](gamepad.html),
|
||||||
to see the approximate number of samples as an integer.
|
to see the approximate number of samples as an integer,
|
||||||
|
on the first X axis.
|
||||||
|
|
||||||
This is approximate,
|
This is approximate,
|
||||||
because the browser encodes the value as a real number between -1 and 1.
|
because the browser encodes the value as a real number between -1 and 1.
|
||||||
|
@ -52,11 +24,6 @@ We convert it back, but may lose a little precision.
|
||||||
It's close enough for me,
|
It's close enough for me,
|
||||||
hopefully it's close enough for you.
|
hopefully it's close enough for you.
|
||||||
|
|
||||||
This number will not be very useful
|
|
||||||
unless you are polling the wammy bar,
|
|
||||||
since without that input,
|
|
||||||
updates are only sent when a button state changes.
|
|
||||||
|
|
||||||
|
|
||||||
Debouncing
|
Debouncing
|
||||||
----------
|
----------
|
||||||
|
@ -99,33 +66,11 @@ Here's what each bit means:
|
||||||
* 0o13: Cymbal modifier
|
* 0o13: Cymbal modifier
|
||||||
* 0o14: Select
|
* 0o14: Select
|
||||||
|
|
||||||
Hats
|
|
||||||
----
|
|
||||||
|
|
||||||
I guess "hats" are what I would have called "joysticks and dpads".
|
hatAndConstant
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The HAT switch reports its position like a clock.
|
||||||
### Hat 0: unknown
|
|
||||||
|
|
||||||
This doesn't appear to be sent or used.
|
|
||||||
|
|
||||||
### Hat 1: guitar analog controls
|
|
||||||
|
|
||||||
The X axis is the position of the wammy bar.
|
|
||||||
|
|
||||||
The Y axis is the pickup selector.
|
|
||||||
I believe this was a 5-position switch on some guitars.
|
|
||||||
Only Rock Band 1 seems to use this.
|
|
||||||
|
|
||||||
### Hat 2: navigation
|
|
||||||
|
|
||||||
Sent by the dpad on the controller,
|
|
||||||
as `hatAndConstant`.
|
|
||||||
|
|
||||||
Guitars send up/down for the up/down strum buttons.
|
|
||||||
Drums send up/down on the blue/yellow cymbal pads.
|
|
||||||
|
|
||||||
The position of this digital input is reported in only 3 bits:
|
|
||||||
|
|
||||||
7 0 1
|
7 0 1
|
||||||
|
|
||||||
|
@ -153,19 +98,20 @@ Sending these values does not seem to cause problems with my Wii games.
|
||||||
Product ID (PID)
|
Product ID (PID)
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
The following USB PIDs are recognized by various things:
|
Nicholas,
|
||||||
|
who did the initial work on the guitar,
|
||||||
|
suggested that PID 0x0005 would get the sketch working as drums.
|
||||||
|
And that was correct:
|
||||||
|
this works great on
|
||||||
|
Wii Rock Band 1 and
|
||||||
|
Wii LEGO Rock Band.
|
||||||
|
|
||||||
* 0x0003: XBox Drum
|
But it fails in frustrating ways on
|
||||||
* 0x0004: Wii Guitar
|
Wii Rock Band 3:
|
||||||
* 0x0005: Wii Drums - Rock Band 1
|
the yellow and blue pads don't navigate menus,
|
||||||
* 0x3110: Wii Drums - Rock Band 2
|
and cymbals aren't detected.
|
||||||
|
|
||||||
There are some quirks to note:
|
The fix was setting the USB PID to 0x3110.
|
||||||
|
|
||||||
* Rock Band 3 won't recognize cymbal hits on PID=0x0005,
|
|
||||||
but the same program with PID=0x3110 works fine.
|
|
||||||
* Wii games don't appear to recognized PID=0x0003.
|
|
||||||
Maybe Rock Band 3 does: I didn't test that one.
|
|
||||||
|
|
||||||
|
|
||||||
Drum Velocity
|
Drum Velocity
|
||||||
|
@ -173,8 +119,7 @@ Drum Velocity
|
||||||
|
|
||||||
I split the 12 "reserved" bytes from Nicholas's
|
I split the 12 "reserved" bytes from Nicholas's
|
||||||
`struct InstrumentButtonState`
|
`struct InstrumentButtonState`
|
||||||
into 4 bytes of I-Don't-Know,
|
into 4 bytes of I-Don't-Know, 4 bytes of velocity,
|
||||||
4 bytes of velocity,
|
|
||||||
and 4 more bytes of I-Don't-Know.
|
and 4 more bytes of I-Don't-Know.
|
||||||
Whenever a pad is hit,
|
Whenever a pad is hit,
|
||||||
I send 127 on the corresponding velocity.
|
I send 127 on the corresponding velocity.
|
||||||
|
@ -185,21 +130,10 @@ and looks only at the velocity values.
|
||||||
|
|
||||||
None of the Wii games I have
|
None of the Wii games I have
|
||||||
seem to care what these values are set to.
|
seem to care what these values are set to.
|
||||||
Clone Hero also does not care.
|
|
||||||
|
|
||||||
|
|
||||||
Clone Hero
|
|
||||||
==========
|
|
||||||
|
|
||||||
Clone Hero wants Hat 2 up on yellow cymbal hit,
|
|
||||||
and Hat 2 down on blue cymbal hit.
|
|
||||||
|
|
||||||
If it doesn't see these while mapping drum pads,
|
|
||||||
then hitting any color bad will trigger both drum and cymbal for that color.
|
|
||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
==========
|
=========
|
||||||
|
|
||||||
The most valuable sources of information I found were:
|
The most valuable sources of information I found were:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Standard setup for a Pro Micro
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't forget to do this (guitar pid=0x0004, drum pid=0x0005):
|
||||||
|
|
||||||
|
< micro.build.vid=0x2341
|
||||||
|
< micro.build.pid=0x8037
|
||||||
|
--
|
||||||
|
> micro.build.vid=0x1bad
|
||||||
|
> micro.build.pid=0x0004
|
||||||
|
|
||||||
|
< micro.build.extra_flags={build.usb_flags}
|
||||||
|
---
|
||||||
|
> micro.build.extra_flags={build.usb_flags} -DCDC_DISABLED
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int BUTTON_GREEN = 18; // A0
|
||||||
|
const int BUTTON_RED = 19; // A1
|
||||||
|
const int BUTTON_YELLOW = 20; // A2
|
||||||
|
const int BUTTON_BLUE = 21; // A3
|
||||||
|
const int BUTTON_ORANGE = 15;
|
||||||
|
|
||||||
|
const int SOLO_GREEN = 9;
|
||||||
|
const int SOLO_RED = 8;
|
||||||
|
const int SOLO_YELLOW = 6;
|
||||||
|
const int SOLO_BLUE = 4;
|
||||||
|
const int SOLO_ORANGE = 14;
|
||||||
|
|
||||||
|
const int BUTTON_PLUS = 1;
|
||||||
|
const int BUTTON_MINUS = 0;
|
Loading…
Reference in New Issue