The following assumes you are seeing OnGamePadChanged being called.
One way you could get the values you want (GamePadEventData *evt) into the loop() would be to add a member variable to the JoystickEvents class, so that class would become something like
class JoystickEvents
{
public:
virtual void OnGamePadChanged(const GamePadEventData *evt);
static GamePadEventData mostRecentEvent;
};
In OnGamePadChanged, make a copy of evt:
GamePadEventData JoystickEvents::mostRecentEvent;
void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
mostReventEvent = *evt;
}
Now you can read it from loop() using something like
Serial.print("X: ");
Serial.print(JoystickEvents::mostReventEvent->x.x);
A significant limitation of this method is that it will only keep the most recent event. Maybe that's OK for your purpose.
It's probably not quite what the author of that code had in mind: he probably expected you to do the work in OnGamePadChanged: his implementation of that method looks like an example so you can see how it works.