Skip to content
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

Add alternative control modes. (RPX branch) #35

Open
wants to merge 2 commits into
base: homebrew_launcher_rpx
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added data/images/player0_point.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/images2/player0_point.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "gui/FreeTypeGX.h"
#include "gui/VPadController.h"
#include "gui/WPadController.h"
#include "gui/DVPadController.h"
#include "gui/DWPadController.h"
#include "resources/Resources.h"
#include "sounds/SoundHandler.hpp"
#include "system/memory.h"
Expand Down Expand Up @@ -245,11 +247,71 @@ void Application::executeThread(void)
//! Read out inputs
for(int i = 0; i < 5; i++)
{
if(controller[i] == NULL) continue;

if(controller[i]->update(video->getTvWidth(), video->getTvHeight()) == false)
continue;

//! update controller states
mainWindow->update(controller[i]);

//If the + button on the GamePad is pressed, switch to DPAD mode and vice versa.
if((i == 0) && (controller[i]->data.buttons_d & GuiTrigger::BUTTON_PLUS))
{
if(controller[i]->isDPadMode)
{
delete controller[i];
controller[i] = new VPadController(GuiTrigger::CHANNEL_1);
}
else
{
delete controller[i];
controller[i] = new DVPadController(GuiTrigger::CHANNEL_1);
}
}

//If the + button on any other controller is pressed, switch to DPAD mode and vice versa.
else if(controller[i]->data.buttons_d & GuiTrigger::BUTTON_PLUS)
{
if(controller[i]->isDPadMode)
{
delete controller[i];
switch(i)
{
case 1:
controller[i] = new WPadController(GuiTrigger::CHANNEL_2);
break;
case 2:
controller[i] = new WPadController(GuiTrigger::CHANNEL_3);
break;
case 3:
controller[i] = new WPadController(GuiTrigger::CHANNEL_4);
break;
case 4:
controller[i] = new WPadController(GuiTrigger::CHANNEL_5);
break;
}
}
else
{
delete controller[i];
switch(i)
{
case 1:
controller[i] = new DWPadController(GuiTrigger::CHANNEL_2);
break;
case 2:
controller[i] = new DWPadController(GuiTrigger::CHANNEL_3);
break;
case 3:
controller[i] = new DWPadController(GuiTrigger::CHANNEL_4);
break;
case 4:
controller[i] = new DWPadController(GuiTrigger::CHANNEL_5);
break;
}
}
}
}

//! start rendering DRC
Expand Down
90 changes: 90 additions & 0 deletions src/gui/DVPadController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* This class implements the DPAD mode for the GamePad, allowing you to use the DPAD to move a virtual
* on screen pointer, rather than using the touch screen. The program will not be able to detect
* any DPAD/A button presses in this mode, as it may interfere with the user who is navigating the pointer.
*
* Created by CreeperMario in July 2017.
*/

#ifndef DPAD_CONTROLLER_H_
#define DPAD_CONTROLLER_H_

#include <vpad/input.h>
#include "GuiController.h"

class DVPadController : public GuiController
{
public:

//!Constructor
DVPadController(int channel) : GuiController(channel)
{
memset(&vpad, 0, sizeof(VPADStatus));
memset(&data, 0, sizeof(PadData));
memset(&lastData, 0, sizeof(PadData));

data.validPointer = true;
isDPadMode = true;
showPointer = true;
}

//!Destructor
virtual ~DVPadController() {}

//Remove the DPAD buttons (by clearing their bits) so that they aren't used by the Gui processes.
u32 fixButtons(u32 buttons)
{
buttons &= ~VPAD_BUTTON_LEFT;
buttons &= ~VPAD_BUTTON_RIGHT;
buttons &= ~VPAD_BUTTON_UP;
buttons &= ~VPAD_BUTTON_DOWN;
buttons &= ~VPAD_BUTTON_A;
return buttons;
}

bool update(int width, int height)
{
lastData = data;

VPADReadError vpadError = VPAD_READ_SUCCESS;
VPADRead(0, &vpad, 1, &vpadError);

if(vpadError == VPAD_READ_SUCCESS)
{
if(vpad.hold & VPAD_BUTTON_LEFT)
{
if(data.x > -(width / 2)) data.x -= 10;
}
if(vpad.hold & VPAD_BUTTON_RIGHT)
{
if(data.x < (width / 2)) data.x += 10;
}
if(vpad.hold & VPAD_BUTTON_UP)
{
if(data.y < (height / 2)) data.y += 10;
}
if(vpad.hold & VPAD_BUTTON_DOWN)
{
if(data.y > -(height / 2)) data.y -= 10;
}

if(vpad.hold & VPAD_BUTTON_A)
data.touched = true;
else
data.touched = false;

data.buttons_r = fixButtons(vpad.release);
data.buttons_h = fixButtons(vpad.hold);
data.buttons_d = fixButtons(vpad.trigger);

return true;
}

return false;
}

private:
VPADStatus vpad;
};

#endif
157 changes: 157 additions & 0 deletions src/gui/DWPadController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* This class implements the DPAD mode for Wii Remote, Classic and Pro controllers, allowing you to use
* the DPAD on your controller to move a virtual on screen pointer, rather than having to point at the
* screen. This means that users who do not have a sensor bar or primarily use Classic/Pro controllers
* can now use this program without trouble. The program will not be able to detect any DPAD button
* presses in this mode, as it may interfere with the user who is navigating the pointer.
*
* Created by CreeperMario in July 2017.
*/

#ifndef DWPAD_CONTROLLER_H_
#define DWPAD_CONTROLLER_H_

#include "GuiController.h"
#include "dynamic_libs/padscore_functions.h"

class DWPadController : public GuiController
{
public:

//!Constructor
DWPadController(int channel) : GuiController(channel)
{
memset(&kpadData, 0, sizeof(KPADData));

data.validPointer = true;
isDPadMode = true;
showPointer = true;
}

//!Destructor
virtual ~DWPadController() {}

//Remove the DPAD buttons (by ignoring their bits) so that they aren't used by the Gui processes.
u32 remapWiiMoteButtons(u32 buttons)
{
u32 temp = 0;

if(buttons & WPAD_BUTTON_MINUS)
temp |= GuiTrigger::BUTTON_MINUS;
if(buttons & WPAD_BUTTON_PLUS)
temp |= GuiTrigger::BUTTON_PLUS;
if(buttons & WPAD_BUTTON_2)
temp |= GuiTrigger::BUTTON_2;
if(buttons & WPAD_BUTTON_1)
temp |= GuiTrigger::BUTTON_1;
if(buttons & WPAD_BUTTON_B)
temp |= GuiTrigger::BUTTON_B;
if(buttons & WPAD_BUTTON_A)
temp |= GuiTrigger::BUTTON_A;
if(buttons & WPAD_BUTTON_Z) //Nunchuk only
temp |= GuiTrigger::BUTTON_Z;
if(buttons & WPAD_BUTTON_C) //Nunchuk only
temp |= GuiTrigger::BUTTON_C;
if(buttons & WPAD_BUTTON_HOME)
temp |= GuiTrigger::BUTTON_HOME;

return temp;
}

//Remove the DPAD buttons (by ignoring their bits) so that they aren't used by the Gui processes.
u32 remapClassicButtons(u32 buttons)
{
u32 temp = 0;

if(buttons & WPAD_CLASSIC_BUTTON_MINUS)
temp |= GuiTrigger::BUTTON_MINUS;
if(buttons & WPAD_CLASSIC_BUTTON_PLUS)
temp |= GuiTrigger::BUTTON_PLUS;
if(buttons & WPAD_CLASSIC_BUTTON_X)
temp |= GuiTrigger::BUTTON_X;
if(buttons & WPAD_CLASSIC_BUTTON_Y)
temp |= GuiTrigger::BUTTON_Y;
if(buttons & WPAD_CLASSIC_BUTTON_B)
temp |= GuiTrigger::BUTTON_B;
if(buttons & WPAD_CLASSIC_BUTTON_A)
temp |= GuiTrigger::BUTTON_A;
if(buttons & WPAD_CLASSIC_BUTTON_HOME)
temp |= GuiTrigger::BUTTON_HOME;
if(buttons & WPAD_CLASSIC_BUTTON_ZR)
temp |= GuiTrigger::BUTTON_ZR;
if(buttons & WPAD_CLASSIC_BUTTON_ZL)
temp |= GuiTrigger::BUTTON_ZL;
if(buttons & WPAD_CLASSIC_BUTTON_R)
temp |= GuiTrigger::BUTTON_R;
if(buttons & WPAD_CLASSIC_BUTTON_L)
temp |= GuiTrigger::BUTTON_L;

return temp;
}

bool update(int width, int height)
{
lastData = data;
u32 controller_type;

//! check if the controller is connected
if(WPADProbe(chanIdx-1, &controller_type) != 0)
return false;

KPADRead(chanIdx-1, &kpadData, 1);

if(kpadData.device_type <= 1)
{
if(kpadData.btns_h & WPAD_BUTTON_LEFT)
{
if(data.x > -(width / 2)) data.x -= 10;
}
if(kpadData.btns_h & WPAD_BUTTON_RIGHT)
{
if(data.x < (width / 2)) data.x += 10;
}
if(kpadData.btns_h & WPAD_BUTTON_UP)
{
if(data.y < (height / 2)) data.y += 10;
}
if(kpadData.btns_h & WPAD_BUTTON_DOWN)
{
if(data.y > -(height / 2)) data.y -= 10;
}

data.buttons_r = remapWiiMoteButtons(kpadData.btns_r);
data.buttons_h = remapWiiMoteButtons(kpadData.btns_h);
data.buttons_d = remapWiiMoteButtons(kpadData.btns_d);
}
else
{
if(kpadData.classic.btns_h & WPAD_CLASSIC_BUTTON_LEFT)
{
if(data.x > -(width / 2)) data.x -= 10;
}
if(kpadData.classic.btns_h & WPAD_CLASSIC_BUTTON_RIGHT)
{
if(data.x < (width / 2)) data.x += 10;
}
if(kpadData.classic.btns_h & WPAD_CLASSIC_BUTTON_UP)
{
if(data.y < (height / 2)) data.y += 10;
}
if(kpadData.classic.btns_h & WPAD_CLASSIC_BUTTON_DOWN)
{
if(data.y > -(height / 2)) data.y -= 10;
}

data.buttons_r = remapClassicButtons(kpadData.classic.btns_r);
data.buttons_h = remapClassicButtons(kpadData.classic.btns_h);
data.buttons_d = remapClassicButtons(kpadData.classic.btns_d);
}

return true;
}

private:
KPADData kpadData;
};

#endif
4 changes: 4 additions & 0 deletions src/gui/GuiController.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class GuiController
chanIdx = 4;
break;
}
isDPadMode = false;
showPointer = false;
}

//!Destructor
Expand All @@ -72,6 +74,8 @@ class GuiController
int chanIdx;
PadData data;
PadData lastData;
bool isDPadMode;
bool showPointer;

};

Expand Down
1 change: 1 addition & 0 deletions src/gui/WPadController.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class WPadController : public GuiController
: GuiController(channel)
{
memset(&kpadData, 0, sizeof(kpadData));
showPointer = true;
}

//!Destructor
Expand Down
Loading