Work out what bit position changed don't know how to do this
Use an XOR
byte changedBits = oldBits ^ newBits;
For each bit that has changed, changedBits will contain a 1; non-changed bits will be 0.
Further, if you change
output_t outputs[5]; //can have max 5 outputs for each button; this holds an array of output_t objects
in your button_t struct to
output_t *outputs; // outputs
byte numOutputs; // number of outputs
You do not have the limitation of 5 outputs; due to the use of a byte variable it's now limited to 256 (and if you use an unsigned int, it will be 65536.