mirror of
https://github.com/extremscorner/not64.git
synced 2024-05-28 16:58:03 -04:00
Ported tehpola's gc_input code to googlecode/.
Removed unnecessary usleep now that PAD_Init is fixed. Changed N64_B button to map to wiimote MINUS or PLUS buttons for wiimote+nunchuck config. Changed wiimote+nunchuck to get use buttons _held_ rather than buttons _down_. Updated wii makefiles. Added fade message for autosave to all devices when return to menu.
This commit is contained in:
parent
0f8a4838ba
commit
1feadbc937
|
@ -77,7 +77,8 @@ OBJ_PPC =r4300/ppc/MIPS-to-PPC.o \
|
|||
|
||||
OBJ_INPUT =gc_input/main.o \
|
||||
gc_input/controller-GC.o \
|
||||
gc_input/controller-Classic.o
|
||||
gc_input/controller-Classic.o \
|
||||
gc_input/controller-WiimoteNunchuk.o
|
||||
|
||||
OBJ_RSPHLE =rsp_hle-ppc/main.o \
|
||||
rsp_hle-ppc/jpeg.o \
|
||||
|
|
|
@ -98,7 +98,8 @@ OBJ_PPC =r4300/ppc/MIPS-to-PPC.o \
|
|||
|
||||
OBJ_INPUT =gc_input/main.o \
|
||||
gc_input/controller-GC.o \
|
||||
gc_input/controller-Classic.o
|
||||
gc_input/controller-Classic.o \
|
||||
gc_input/controller-WiimoteNunchuk.o
|
||||
|
||||
OBJ_RSPHLE =rsp_hle-ppc/main.o \
|
||||
rsp_hle-ppc/jpeg.o \
|
||||
|
|
|
@ -39,7 +39,6 @@ static int _GetKeys(int Control, BUTTONS * Keys )
|
|||
c->A_BUTTON = (b & CLASSIC_CTRL_BUTTON_A) ? 1 : 0;
|
||||
|
||||
c->Z_TRIG = (b & CLASSIC_CTRL_BUTTON_ZR) ? 1 : 0;
|
||||
c->Z_TRIG |= (b & CLASSIC_CTRL_BUTTON_ZL) ? 1 : 0;
|
||||
c->R_TRIG = (b & CLASSIC_CTRL_BUTTON_FULL_R) ? 1 : 0;
|
||||
c->L_TRIG = (b & CLASSIC_CTRL_BUTTON_FULL_L) ? 1 : 0;
|
||||
|
||||
|
@ -85,13 +84,13 @@ controller_t controller_Classic =
|
|||
};
|
||||
|
||||
static void init(void){
|
||||
int i, ret;
|
||||
int i;
|
||||
WPAD_ScanPads();
|
||||
for(i=0; i<4; ++i){
|
||||
WPADData wpad;
|
||||
ret = WPAD_ReadEvent(i, &wpad);
|
||||
WPADData* wpad = WPAD_Data(i);
|
||||
// Only use a connected classic controller
|
||||
if(!ret && wpad.err == WPAD_ERR_NONE &&
|
||||
wpad.exp.type == WPAD_EXP_CLASSIC){
|
||||
if(wpad->err == WPAD_ERR_NONE &&
|
||||
wpad->exp.type == WPAD_EXP_CLASSIC){
|
||||
controller_Classic.available[i] = 1;
|
||||
WPAD_SetDataFormat(i, WPAD_DATA_EXPANSION);
|
||||
} else
|
||||
|
|
|
@ -74,7 +74,15 @@ static void init(void){
|
|||
PAD_Init();
|
||||
|
||||
PADStatus status[4];
|
||||
PAD_Read(status);
|
||||
do PAD_Read(status);
|
||||
while((status[0].err != PAD_ERR_NO_CONTROLLER &&
|
||||
status[0].err != PAD_ERR_NONE) ||
|
||||
(status[1].err != PAD_ERR_NO_CONTROLLER &&
|
||||
status[1].err != PAD_ERR_NONE) ||
|
||||
(status[2].err != PAD_ERR_NO_CONTROLLER &&
|
||||
status[2].err != PAD_ERR_NONE) ||
|
||||
(status[3].err != PAD_ERR_NO_CONTROLLER &&
|
||||
status[3].err != PAD_ERR_NONE));
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
controller_GC.available[i] = status[i].err != PAD_ERR_NO_CONTROLLER;
|
||||
|
|
98
gc_input/controller-WiimoteNunchuk.c
Normal file
98
gc_input/controller-WiimoteNunchuk.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* controller-WiimoteNunchuk.c - Wiimote + Nunchuk input module
|
||||
by Mike Slegeir for Mupen64-GC
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
#include "controller.h"
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159f
|
||||
#endif
|
||||
|
||||
enum { STICK_X, STICK_Y };
|
||||
static int getStickValue(joystick_t* j, int axis, int maxAbsValue){
|
||||
double angle = PI * j->ang/180.0f;
|
||||
double magnitude = (j->mag > 1.0f) ? 1.0f :
|
||||
(j->mag < -1.0f) ? -1.0f : j->mag;
|
||||
double value;
|
||||
if(axis == STICK_X)
|
||||
value = magnitude * sin( angle );
|
||||
else
|
||||
value = magnitude * cos( angle );
|
||||
return (int)(value * maxAbsValue);
|
||||
}
|
||||
|
||||
static int _GetKeys(int Control, BUTTONS * Keys )
|
||||
{
|
||||
if(wpadNeedScan){ WPAD_ScanPads(); wpadNeedScan = 0; }
|
||||
WPADData* wpad = WPAD_Data(Control);
|
||||
BUTTONS* c = Keys;
|
||||
|
||||
int b = wpad->btns_h;
|
||||
int d2 = b & WPAD_BUTTON_2;
|
||||
c->R_DPAD = (b & WPAD_BUTTON_RIGHT && d2) ? 1 : 0;
|
||||
c->L_DPAD = (b & WPAD_BUTTON_LEFT && d2) ? 1 : 0;
|
||||
c->D_DPAD = (b & WPAD_BUTTON_DOWN && d2) ? 1 : 0;
|
||||
c->U_DPAD = (b & WPAD_BUTTON_UP && d2) ? 1 : 0;
|
||||
c->START_BUTTON = (b & WPAD_BUTTON_HOME) ? 1 : 0;
|
||||
c->B_BUTTON = (b & (WPAD_BUTTON_MINUS | WPAD_BUTTON_PLUS)) ? 1 : 0;
|
||||
c->A_BUTTON = (b & WPAD_BUTTON_A) ? 1 : 0;
|
||||
|
||||
c->Z_TRIG = (b & WPAD_NUNCHUK_BUTTON_Z) ? 1 : 0;
|
||||
c->R_TRIG = (b & WPAD_BUTTON_B) ? 1 : 0;
|
||||
c->L_TRIG = (b & WPAD_NUNCHUK_BUTTON_C) ? 1 : 0;
|
||||
|
||||
c->R_CBUTTON = (b & WPAD_BUTTON_RIGHT) ? 1 : 0;
|
||||
c->L_CBUTTON = (b & WPAD_BUTTON_LEFT) ? 1 : 0;
|
||||
c->D_CBUTTON = (b & WPAD_BUTTON_DOWN) ? 1 : 0;
|
||||
c->U_CBUTTON = (b & WPAD_BUTTON_UP) ? 1 : 0;
|
||||
|
||||
c->X_AXIS = getStickValue(&wpad->exp.nunchuk.js, STICK_X, 127);
|
||||
c->Y_AXIS = getStickValue(&wpad->exp.nunchuk.js, STICK_Y, 127);
|
||||
|
||||
// 1+2 quits to menu
|
||||
return (b & WPAD_BUTTON_1) && (b & WPAD_BUTTON_2);
|
||||
}
|
||||
|
||||
static void pause(int Control){ }
|
||||
|
||||
static void resume(int Control){ }
|
||||
|
||||
static void rumble(int Control, int rumble){ }
|
||||
|
||||
static void configure(int Control){
|
||||
// Don't know how this should be integrated
|
||||
}
|
||||
|
||||
static void assign(int p, int v){
|
||||
// TODO: Light up the LEDs appropriately
|
||||
}
|
||||
|
||||
static void init(void);
|
||||
|
||||
controller_t controller_WiimoteNunchuk =
|
||||
{ _GetKeys,
|
||||
configure,
|
||||
init,
|
||||
assign,
|
||||
pause,
|
||||
resume,
|
||||
rumble,
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void init(void){
|
||||
int i;
|
||||
WPAD_ScanPads();
|
||||
for(i=0; i<4; ++i){
|
||||
WPADData* wpad = WPAD_Data(i);
|
||||
// Only use a connected nunchuk
|
||||
if(wpad->err == WPAD_ERR_NONE &&
|
||||
wpad->exp.type == WPAD_EXP_NUNCHUK){
|
||||
controller_WiimoteNunchuk.available[i] = 1;
|
||||
WPAD_SetDataFormat(i, WPAD_DATA_EXPANSION);
|
||||
} else
|
||||
controller_WiimoteNunchuk.available[i] = 0;
|
||||
}
|
||||
}
|
|
@ -31,4 +31,33 @@ typedef struct {
|
|||
char available[4];
|
||||
} controller_t;
|
||||
|
||||
typedef struct _virtualControllers_t {
|
||||
BOOL inUse; // This virtual controller is being controlled
|
||||
controller_t* control; // The type of controller being used
|
||||
int number; // The physical controller number
|
||||
} virtualControllers_t;
|
||||
|
||||
extern virtualControllers_t virtualControllers[4];
|
||||
|
||||
// List of all the defined controller_t's
|
||||
#if defined(WII) && !defined(NO_BT)
|
||||
|
||||
#define num_controller_t 3
|
||||
extern controller_t controller_GC;
|
||||
extern controller_t controller_Classic;
|
||||
extern controller_t controller_WiimoteNunchuk;
|
||||
extern controller_t* controller_ts[num_controller_t];
|
||||
|
||||
#else // WII && !NO_BT
|
||||
|
||||
#define num_controller_t 1
|
||||
extern controller_t controller_GC;
|
||||
controller_t* controller_ts[num_controller_t];
|
||||
|
||||
#endif // WII && !NO_BT
|
||||
|
||||
void init_controller_ts(void);
|
||||
void assign_controller(int whichVirtual, controller_t*, int whichPhysical);
|
||||
void unassign_controller(int whichVirtual);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,15 +19,22 @@
|
|||
static CONTROL_INFO control_info;
|
||||
static BOOL lastData[4];
|
||||
|
||||
static struct {
|
||||
BOOL inUse;
|
||||
controller_t* control;
|
||||
int number;
|
||||
} controllers[4];
|
||||
virtualControllers_t virtualControllers[4];
|
||||
|
||||
controller_t* controller_ts[num_controller_t] =
|
||||
#if defined(WII) && !defined(NO_BT)
|
||||
{ &controller_GC, &controller_Classic,
|
||||
&controller_WiimoteNunchuk,
|
||||
};
|
||||
#else
|
||||
{ &controller_GC,
|
||||
};
|
||||
#endif
|
||||
|
||||
// Use to invoke func on the mapped controller with args
|
||||
#define DO_CONTROL(Control,func,args...) \
|
||||
controllers[Control].control->func(controllers[Control].number, ## args)
|
||||
virtualControllers[Control].control->func( \
|
||||
virtualControllers[Control].number, ## args)
|
||||
|
||||
unsigned char mempack_crc(unsigned char *data);
|
||||
|
||||
|
@ -177,27 +184,10 @@ EXPORT void CALL InitiateControllers (CONTROL_INFO ControlInfo)
|
|||
int i,t,w;
|
||||
control_info = ControlInfo;
|
||||
|
||||
// List of all the defined controller_t's
|
||||
#if defined(WII) && !defined(NO_BT)
|
||||
#define num_controller_t 2
|
||||
extern controller_t controller_GC;
|
||||
extern controller_t controller_Classic;
|
||||
controller_t* controller_ts[num_controller_t] =
|
||||
{ &controller_GC, &controller_Classic,
|
||||
};
|
||||
int num_assigned[num_controller_t] = { 0, 0 };
|
||||
#else
|
||||
#define num_controller_t 1
|
||||
extern controller_t controller_GC;
|
||||
controller_t* controller_ts[num_controller_t] =
|
||||
{ &controller_GC,
|
||||
};
|
||||
int num_assigned[num_controller_t] = { 0 };
|
||||
#endif
|
||||
init_controller_ts();
|
||||
|
||||
// Init all our controllers
|
||||
for(i=0; i<num_controller_t; ++i)
|
||||
controller_ts[i]->init();
|
||||
int num_assigned[num_controller_t];
|
||||
memset(num_assigned, 0, sizeof(num_assigned));
|
||||
|
||||
// Map controllers in the priority given
|
||||
// Outer loop: virtual controllers
|
||||
|
@ -210,25 +200,17 @@ EXPORT void CALL InitiateControllers (CONTROL_INFO ControlInfo)
|
|||
// If we've exhausted this type, move on
|
||||
if(w == 4) continue;
|
||||
|
||||
controllers[i].control = type;
|
||||
controllers[i].inUse = 1;
|
||||
controllers[i].number = w;
|
||||
controllers[i].control->assign(w,i);
|
||||
control_info.Controls[i].Present = 1;
|
||||
if (pakMode[i] == PAKMODE_MEMPAK) control_info.Controls[i].Plugin = PLUGIN_MEMPAK;
|
||||
else control_info.Controls[i].Plugin = PLUGIN_RAW;
|
||||
assign_controller(i, type, w);
|
||||
// Don't assign the next type over this one or the same controller
|
||||
++num_assigned[t];
|
||||
break;
|
||||
}
|
||||
if(t == num_controller_t)
|
||||
break;
|
||||
}
|
||||
// 'Initialize' the unmapped virtual controllers
|
||||
for(; i<4; ++i){
|
||||
controllers[i].control = NULL;
|
||||
controllers[i].inUse = 0;
|
||||
controllers[i].number = -1;
|
||||
control_info.Controls[i].Present = 0;
|
||||
control_info.Controls[i].Plugin = PLUGIN_NONE;
|
||||
unassign_controller(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,12 +312,39 @@ EXPORT void CALL WM_KeyUp( WPARAM wParam, LPARAM lParam )
|
|||
void pauseInput(void){
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
if(controllers[i].inUse) DO_CONTROL(i, pause);
|
||||
if(virtualControllers[i].inUse) DO_CONTROL(i, pause);
|
||||
}
|
||||
|
||||
void resumeInput(void){
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
if(controllers[i].inUse) DO_CONTROL(i, resume);
|
||||
if(virtualControllers[i].inUse) DO_CONTROL(i, resume);
|
||||
}
|
||||
|
||||
void init_controller_ts(void){
|
||||
int i;
|
||||
for(i=0; i<num_controller_t; ++i)
|
||||
controller_ts[i]->init();
|
||||
}
|
||||
|
||||
void assign_controller(int wv, controller_t* type, int wp){
|
||||
virtualControllers[wv].control = type;
|
||||
virtualControllers[wv].inUse = 1;
|
||||
virtualControllers[wv].number = wp;
|
||||
|
||||
type->assign(wp,wv);
|
||||
|
||||
control_info.Controls[wv].Present = 1;
|
||||
if (pakMode[wv] == PAKMODE_MEMPAK) control_info.Controls[wv].Plugin = PLUGIN_MEMPAK;
|
||||
else control_info.Controls[wv].Plugin = PLUGIN_RAW;
|
||||
}
|
||||
|
||||
void unassign_controller(int wv){
|
||||
virtualControllers[wv].control = NULL;
|
||||
virtualControllers[wv].inUse = 0;
|
||||
virtualControllers[wv].number = -1;
|
||||
|
||||
control_info.Controls[wv].Present = 0;
|
||||
control_info.Controls[wv].Plugin = PLUGIN_NONE;
|
||||
}
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ void ConfigurePaksFrame::activateSubmenu(int submenu)
|
|||
{
|
||||
Component* defaultFocus = this;
|
||||
|
||||
usleep(1000); //This sleep prevents the PAD_Init() from failing
|
||||
// usleep(1000); //This sleep prevents the PAD_Init() from failing
|
||||
control_info_init(); //TODO: This controller poll might need rethinking when we implement Input Configuration
|
||||
|
||||
//All buttons: hide; unselect
|
||||
|
|
|
@ -196,7 +196,7 @@ void Func_PlayGame()
|
|||
|
||||
menu::Gui::getInstance().gfx->clearEFB((GXColor){0, 0, 0, 0xFF}, 0x000000);
|
||||
|
||||
usleep(1000); //This sleep prevents the PAD_Init() from failing
|
||||
// usleep(1000); //This sleep prevents the PAD_Init() from failing
|
||||
control_info_init(); //TODO: This controller re-poll might need rethinking when we implement reconfigurable input
|
||||
|
||||
//Wait until 'A' button released before play/resume game
|
||||
|
@ -269,13 +269,13 @@ void Func_PlayGame()
|
|||
menu::MessageBox::getInstance().fadeMessage("Automatically saved to SD card");
|
||||
break;
|
||||
case NATIVESAVEDEVICE_USB:
|
||||
menu::MessageBox::getInstance().setMessage("Automatically saved to USB device");
|
||||
menu::MessageBox::getInstance().fadeMessage("Automatically saved to USB device");
|
||||
break;
|
||||
case NATIVESAVEDEVICE_CARDA:
|
||||
menu::MessageBox::getInstance().setMessage("Automatically saved to memcard in Slot A");
|
||||
menu::MessageBox::getInstance().fadeMessage("Automatically saved to memcard in Slot A");
|
||||
break;
|
||||
case NATIVESAVEDEVICE_CARDB:
|
||||
menu::MessageBox::getInstance().setMessage("Automatically saved to memcard in Slot B");
|
||||
menu::MessageBox::getInstance().fadeMessage("Automatically saved to memcard in Slot B");
|
||||
break;
|
||||
}
|
||||
flashramWritten = sramWritten = eepromWritten = mempakWritten = 0; //nothing new written since save
|
||||
|
|
Loading…
Reference in a new issue