Welcome! Log In Create A New Profile

Advanced

Nunchuk Programming

Posted by Arikado 
Nunchuk Programming
August 28, 2008 08:13PM
Perhaps I missed this, but I've been looking through libogc for a while and I can't find to way to program in input from the Nunchuk's analog stick (or motion control for the nunchuk, but I don't care about that). I would appreciate any help anyone could give me.

-Thanks,
Arikado
Re: Nunchuk Programming
August 28, 2008 08:50PM
Take a look through wiiuse/wpad.h (inside the libogc include directory). The wiiuse guide should help you understand a bit how WPAD works behind the scenes, although you don't use wiiuse directly. WPAD is fairly self-explanatory anyway, just studying the header should help you find out how to read data from extension controllers (and how to check what extension is currently connected).



Edited 1 time(s). Last edit at 08/28/2008 08:51PM by AerialX.
Re: Nunchuk Programming
August 28, 2008 11:39PM
This was all I could find that mught be of use, but unfortunately I lack a proper example to understand its use:

#define WPAD_THRESH_DEFAULT_JOYSTICK			2

void WPAD_Orientation(int chan, struct orient_t *orient);
void WPAD_GForce(int chan, struct gforce_t *gforce);
void WPAD_Accel(int chan, struct vec3b_t *accel);
void WPAD_Expansion(int chan, struct expansion_t *exp);

Would someone please explain this for me?

EDIT: Sorry if I'm missing something "really obvious", but before Wii I only programmed on the pc with the allegro angine and I never worked with the joystick.



Edited 1 time(s). Last edit at 08/29/2008 12:00AM by Arikado.
Re: Nunchuk Programming
August 29, 2008 01:47AM
Just improvising here, but something along these lines:

// Assuming WPAD is all set up...
struct expansion_t data;
WPAD_Expansion(WPAD_CHAN_0, &data); // Get expansion info from the first wiimote

if (data.type == WPAD_EXP_NUNCHUK) { // Ensure there's a nunchuk
do something with data.nunchuk.joystick
}

data.nunchuk.joystick is of type joystick_t defined in wiiuse/wiiuse.h:
typedef struct joystick_t {
        struct vec2b_t max;                             /**< maximum joystick values    */
        struct vec2b_t min;                             /**< minimum joystick values    */
        struct vec2b_t center;                  /**< center joystick values             */
        struct vec2b_t pos;                             /**< raw position values        */

        float ang;                                              /**< angle the joystick is being held           */
        float mag;                                              /**< magnitude of the joystick (range 0-1)      */
} joystick_t;
Re: Nunchuk Programming
August 29, 2008 03:15PM
I just want a line along these lines:

if(WPAD_NUNCHUK_DOWN)
do someting

and also up, left, and right.
Re: Nunchuk Programming
August 29, 2008 05:48PM
Unfortunately you can't do that. If it did exist, what would count as a down event? It's not a button, you'd have to specify a magnitude (maybe half/0.5) that counts as a press (and find out what angle counts for what directions). In any case, libogc isn't all that high-level, and won't make that call for you.

You can make a function for it yourself though. Use the mag and ang fields of joystick to see where the analog stick is pointing and how much it's being pressed. It's more complicated than just checking directional events because it's an analog stick and not a button, but you can write your own code that will check it like a button.
Re: Nunchuk Programming
August 29, 2008 07:41PM
Personally I think that the ang and mag properties are bloat. It's not that fircking hard to do it yourself, but only when needed.
I just want access to normal scaled X and Y values.
Re: Nunchuk Programming
August 29, 2008 08:50PM
Quote
henke37
Personally I think that the ang and mag properties are bloat. It's not that fircking hard to do it yourself, but only when needed.
I just want access to normal scaled X and Y values.
True enough, so just use the pos field instead. Again, there's no instant way to check for a "down" press or not, but just pick a reasonable threshold for the X and Y values.
Re: Nunchuk Programming
August 29, 2008 10:21PM
Is there an example of source I can look at for this (preferably one that uses libwiisprite)?
Re: Nunchuk Programming
August 30, 2008 04:13AM
I doubt there is one that uses libwiisprite, but why would it matter if it was libwiisprite anyway? It would use a graphics library that updated the x and y pos anyways so it would be pretty much the same.
Re: Nunchuk Programming
August 30, 2008 04:52AM
Gah, don't know why I did this >.>

Here's your example, kk? Notice how ugly the Nunchuk's X and Y values are, I'd personally prefer to use mag and ang :P

Instructions:
Copy the Wii template from wii-examples...
Replace template.c with:
#include 

#include 

#include 

#include 



static void *xfb = NULL;

static GXRModeObj *rmode = NULL;



//---------------------------------------------------------------------------------

int main(int argc, char **argv) {

//---------------------------------------------------------------------------------



	// Initialise the video system

	VIDEO_Init();

	

	// This function initialises the attached controllers

	WPAD_Init();

	

	// Obtain the preferred video mode from the system

	// This will correspond to the settings in the Wii menu

	rmode = VIDEO_GetPreferredMode(NULL);



	// Allocate memory for the display in the uncached region

	xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));

	

	// Initialise the console, required for printf

	console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);

	

	// Set up the video registers with the chosen mode

	VIDEO_Configure(rmode);

	

	// Tell the video hardware where our display memory is

	VIDEO_SetNextFramebuffer(xfb);

	

	// Make the display visible

	VIDEO_SetBlack(FALSE);



	// Flush the video register changes to the hardware

	VIDEO_Flush();



	// Wait for Video setup to complete

	VIDEO_WaitVSync();

	if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();



	while (1) {

		// The console understands VT terminal escape codes

		// This positions the cursor on row 2, column 0

		// we can use variables for this with format codes too

		// e.g. printf ("\x1b[%d;%dH", row, column );

		printf("\x1b[2;0H");

	



		printf("Hello World!\n");



		// Call WPAD_ScanPads each loop, this reads the latest controller states

		WPAD_ScanPads();



		// WPAD_ButtonsDown tells us which buttons were pressed in this loop

		// this is a "one shot" state which will not fire again until the button has been released

		u32 pressed = WPAD_ButtonsDown(0);



		// We return to the launcher application via exit

		if ( pressed & WPAD_BUTTON_HOME ) exit(0);



		struct expansion_t data;

		WPAD_Expansion(WPAD_CHAN_0, &data); // Get expansion info from the first wiimote



		if (data.type == WPAD_EXP_NUNCHUK) { // Ensure there's a nunchuk

			printf("Nunchuk X: %d\n Nunchuk Y: %d\n", data.nunchuk.js.pos.x, data.nunchuk.js.pos.y);

		}



		// Wait for the next frame

		VIDEO_WaitVSync();

	}



	return 0;

}
Compile and run via wiiload/TP, plug in a nunchuk (before or after running it) and move the joystick around.
Re: Nunchuk Programming
August 30, 2008 04:36PM
Beautiful, thanks AerialX. And then for if's I can just play around with the x and y values, correct?
Re: Nunchuk Programming
August 30, 2008 06:28PM
Well yeah, but one thing I forgot to mention/use... The joystick_t has a "center" field. Change my printf line to:

			vec2b_t center = data.nunchuk.js.center;
			printf("Nunchuk X: %d     \n Nunchuk Y: %d     \n", data.nunchuk.js.pos.x - center.x, data.nunchuk.js.pos.y - center.y);

Then play with those x and y values. I forgot about joystick center/neutral calibration >.>
Re: Nunchuk Programming
August 30, 2008 10:47PM
Good thing I haven't gotten around to it yet :). I'll post the working if's I come up with when I'm done.
Re: Nunchuk Programming
September 01, 2008 11:08PM
Solved! Did a little reading... Found some good source... Did a little modifying... Enjoy! :)

//Nunchuck Up
if((exp.nunchuk.js.ang>=315 || exp.nunchuk.js.ang<=45) && exp.nunchuk.js.mag>=0.9)

//Nunchuck Right
if((exp.nunchuk.js.ang>=90-45 && exp.nunchuk.js.ang<=90+45) && exp.nunchuk.js.mag>=0.9)

//Nunchuck Down
if((exp.nunchuk.js.ang>=180-45 && exp.nunchuk.js.ang<=180+45) && exp.nunchuk.js.mag>=0.9)

//Nunchuck Left
if((exp.nunchuk.js.ang>=270-45 && exp.nunchuk.js.ang<=270+45) && exp.nunchuk.js.mag>=0.9)
Re: Nunchuk Programming
September 02, 2008 07:53AM
I still prefer good old X and Y. It's so much faster to compare those.
Re: Nunchuk Programming
September 02, 2008 02:42PM
It is, but I originally learned angles and orientation so I'm used to that. Anyways, I still want to figure out how to check for a shake of nunchuck.
Re: Nunchuk Programming
September 03, 2008 03:00AM
Either way is good. I may prefer ang + mag simply because 0.9f is easier to read / more obvious than a magic number for X and Y. X and Y are simple though, so go with whatever you're comfortable with.

As for the shake, dunno, I've never used the motion sensors of the Wiimore or Nunchuk. You're on your own for this one :P, just look at the headers and read up on the wiiuse documentation.
Re: Nunchuk Programming
September 03, 2008 07:05AM
Shake detection is easy, just check if the force is anything other than the (normal of the) gravitational acceleration.
Re: Nunchuk Programming
September 03, 2008 02:02PM
Fascinating, hopefully I'll have some time to play around with that soon.
Sorry, only registered users may post in this forum.

Click here to login