-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
custom OSContPad
?
#344
Comments
I'm not fundamentally against the idea of an action oriented system instead of mapping to N64 buttons. I have some issues with it that would need to be worked out to make a change like this. The first is that I'm not totally sure I see the conceptual value for the kinds of projects LUS is meant to support, outside of one. What I mean by that is everyone knows these are N64 games and are used to an emulator-like approach to bind controls. In other words, people are already used to mapping physical to virtual N64 buttons. There is one project which this assumption is a lot weaker on. Plus we are not an emulator. Really looking to discuss this point more than anything. The actual problem is that an action system is a fundamental change to how the game interacts with LUS. It no longer calls a libultra function and gets back libultra data. You now need to query the state of an action instead of a ContPad. I think this needs more baking time before it's ready. If you're not suggesting to remove the old system, but instead treat an action as a bit flag for which virtual buttons are pressed, we are getting closer, but it still needs thought on how it would interact where the buttons are the bits. I'm other words, how would a port out of the box that doesn't want to deal with this complexity query data? The systems need to support both. How does that new port transition? This would also mean we no longer need to change the controller headers, which would be a good thing. I don't think there's very many other places, maybe 2 or 3, where we modify headers. I'd be nice to take a look and see if we could theoretically reset them and allow games to provide their own headers. |
however, we already rely heavily on workarounds in SoH to provide context specific control customization. a specific example from SoH is playing the ocarina. from a player perspective: a player must map their physical controller in one menu, then edit settings in another menu to add custom ocarina playback controls (which, due to the nature of n64 controller based mapping, is based on n64 buttons) from an implementation perspective: 10 cvars are needed to provide dpad, right stick, and custom ocarina controls bool customControls = CVarGetInteger("gCustomOcarinaControls", 0);
bool dpad = CVarGetInteger("gDpadOcarina", 0);
bool rStick = CVarGetInteger("gRStickOcarina", 0); and then this: Audio_OcaUpdateBtnMap(customControls, dpad, rStick); which calls into this: // Function originally not called, so repurposing for control mapping
void Audio_OcaUpdateBtnMap(bool customControls, bool dpad, bool rStick) {
if (customControls) {
sOcarinaD5BtnMap = CVarGetInteger("gOcarinaD5BtnMap", BTN_CUP);
sOcarinaB4BtnMap = CVarGetInteger("gOcarinaB4BtnMap", BTN_CLEFT);
sOcarinaA4BtnMap = CVarGetInteger("gOcarinaA4BtnMap", BTN_CRIGHT);
sOcarinaF4BtnMap = CVarGetInteger("gOcarinaF4BtnMap", BTN_CDOWN);
sOcarinaD4BtnMap = CVarGetInteger("gOcarinaD4BtnMap", BTN_A);
} else {
sOcarinaD5BtnMap = BTN_CUP;
sOcarinaB4BtnMap = BTN_CLEFT;
sOcarinaA4BtnMap = BTN_CRIGHT;
sOcarinaF4BtnMap = BTN_CDOWN;
sOcarinaD4BtnMap = BTN_A;
}
if (dpad) {
sOcarinaD5BtnMap |= BTN_DUP;
sOcarinaB4BtnMap |= BTN_DLEFT;
sOcarinaA4BtnMap |= BTN_DRIGHT;
sOcarinaF4BtnMap |= BTN_DDOWN;
}
if (rStick) {
sOcarinaD5BtnMap |= RSTICK_UP;
sOcarinaB4BtnMap |= RSTICK_LEFT;
sOcarinaA4BtnMap |= RSTICK_RIGHT;
sOcarinaF4BtnMap |= RSTICK_DOWN;
}
sOcarinaAllowedBtnMask = (
sOcarinaD5BtnMap |
sOcarinaB4BtnMap |
sOcarinaA4BtnMap |
sOcarinaF4BtnMap |
sOcarinaD4BtnMap
);
} as well as extra logic to handle the right stick here: s8 rstick_x = input->cur.right_stick_x;
s8 rstick_y = input->cur.right_stick_y;
const s8 sensitivity = 64;
if (rstick_x > sensitivity) {
sCurOcarinaBtnPress |= RSTICK_RIGHT;
}
if (rstick_x < -sensitivity) {
sCurOcarinaBtnPress |= RSTICK_LEFT;
}
if (rstick_y > sensitivity) {
sCurOcarinaBtnPress |= RSTICK_UP;
}
if (rstick_y < -sensitivity) {
sCurOcarinaBtnPress |= RSTICK_DOWN;
} and then more modification is done here: u32 noteSharpBtnMap;
if (customControls) {
noteSharpBtnMap = CVarGetInteger("gOcarinaSharpBtnMap", BTN_R);
} else {
noteSharpBtnMap = BTN_R;
} and here: u32 noteFlatBtnMap;
if (customControls) {
noteFlatBtnMap = CVarGetInteger("gOcarinaFlatBtnMap", BTN_Z);
} else {
noteFlatBtnMap = BTN_Z;
} with an action-based system this could be simplified immensely and done with 0 cvars. s32 sOcarinaD5BtnMap = BTN_CUP;
s32 sOcarinaB4BtnMap = BTN_CLEFT;
s32 sOcarinaA4BtnMap = BTN_CRIGHT;
s32 sOcarinaF4BtnMap = BTN_CDOWN;
s32 sOcarinaD4BtnMap = BTN_A; to be the actions instead, for example s32 sOcarinaD5BtnMap = ACTION_OCARINA_D5;
s32 sOcarinaB4BtnMap = ACTION_OCARINA_B4;
s32 sOcarinaA4BtnMap = ACTION_OCARINA_A4;
s32 sOcarinaF4BtnMap = ACTION_OCARINA_F4;
s32 sOcarinaD4BtnMap = ACTION_OCARINA_D4;
i'd argue it already doesn't (we get back extended libultra data), but i understand your point. if we want to continue to support
then providing the default
This is where a port would need to do some heavy reworking. I wouldn't expect young ports to go this direction as it requires finding all the places where the authentic bit structure of button in the Input struct in the port would be modified to use the action pad typedef struct {
/* 0x00 */ OSActionPad cur;
/* 0x?? */ OSActionPad prev;
/* 0x?? */ OSActionPad press; // X/Y store delta from last frame
/* 0x?? */ OSActionPad rel; // X/Y store adjusted
} Input; // size = 0x?? and the port-specific
I agree, and I think it probably makes sense to build as much of this as possible out within a port instead of LUS to start, and then see what can be done to move away from an implementation that I assume will basically be "we aren't using LUS for control stuff right now" tentative plan would be to:
|
The initial suggestion will no longer be an issue once libultra headers are gone. #406 |
the current LUS implementation of
OSContPad
includes things beyond what exists on the n64 (multiple analog sticks, gyro), but is still very opinionated as to what can exist on the pad.i think in order to satisfy the two port dev user stories from #342 it could be helpful to add some flexibility here.
To satisfy
it could be helpful to provide controller functionality that utilizes an
OSContPad
that matches the authentic data structure. Only including n64 buttons/one analog stick. The existing LUS controller functionality could then be provided viaOSContPadExtended
, which would provide the default "modern controller" version ofOSContPad
that exists in LUS today (n64 controller + a few extra things)To satisfy
we would want to provide the ability for any given port could provide their own
OSContPad
structure that can deviate as far from the authentic n64 controllerOSContPad
as the port would like. This would allow for a port to create anOSContPad
structure based on in-game actions, for example, instead of havinglibultraship/include/libultraship/libultra/controller.h
Lines 85 to 88 in 883fb45
a port could have
this would be very port specific, as each port would know which actions they would want to be able to map (as opposed to relying on original n64 controller mapping to game actions), so LUS wouldn't need to provide any examples or UI for this, just the framework to do so
The text was updated successfully, but these errors were encountered: