Page 1 of 1

Wrong calibration data for Wii U Pro controller

Posted: Sat Jan 14, 2017 12:32 pm
by Oibaf
The Wii U Pro controller does not provide calibration data therefore these data have been written in the code (classic.c)

Code: Select all

/* is this a wiiu pro? */
	if (len > 223 && data[223] == 0x20) {
		cc->ljs.max.x = cc->ljs.max.y = 0xFF;
		cc->ljs.min.x = cc->ljs.min.y = 0;
		cc->ljs.center.x = cc->ljs.center.y = 0x80;

		cc->rjs = cc->ljs;

		cc->type = 2;
	}
However the min and max values (0 and 0xFF) are not correct and far from the real values.
More convenient values should be min=55 and max=197.
Wrong calibration data lead to wrong polar coordinates values (in particular exp.classic.ljs.mag).

I don't have a Wii U Pro controller but I wrote a test and received the results from this thread:

https://gbatemp.net/threads/fbzx-wii-wi ... 944/page-2

It would be necessary to use this test on several Wii U Pro controllers to have more precise results on min, center and max calibration data:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiiuse/wpad.h>


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();

	WPADData *data;
	
	while(1) {
	
	printf("\x1b[2J"); //clear the screen
	printf("\x1b[1;0H");

	// Call WPAD_ScanPads each loop, this reads the latest controller states
	WPAD_ScanPads();
		
	data = WPAD_Data(0);
		
		
	switch (data->exp.type)
	{
		case WPAD_EXP_NUNCHUK:

		printf("nck pos x = %d \n",data->exp.nunchuk.js.pos.x);
		printf("nck min x = %d \n",data->exp.nunchuk.js.min.x);
		printf("nck max x = %d \n",data->exp.nunchuk.js.max.x);
		printf("\n");
		
		printf("nck pos y = %d \n",data->exp.nunchuk.js.pos.y);
		printf("nck min y = %d \n", data->exp.nunchuk.js.min.y);
		printf("nck max y = %d \n", data->exp.nunchuk.js.max.y);
		printf("\n");
		
		printf("mag left= %f \n", data->exp.nunchuk.js.mag);
		printf("ang left= %f \n", data->exp.nunchuk.js.ang);
		printf("\n");
		
		break;

		case WPAD_EXP_CLASSIC:
		
		printf("ccl pos x = %d \n",data->exp.classic.ljs.pos.x);
		printf("ccl min x = %d \n",data->exp.classic.ljs.min.x);
		printf("ccl max x = %d \n",data->exp.classic.ljs.max.x);
		printf("\n");
		
		printf("ccl pos y = %d \n",data->exp.classic.ljs.pos.y);
		printf("ccl min y = %d \n",data->exp.classic.ljs.min.y);
		printf("ccl max y = %d \n",data->exp.classic.ljs.max.y);
		printf("\n");
		
		printf("ccl mag = %f \n", data->exp.classic.ljs.mag);
		printf("ccl ang = %f \n", data->exp.classic.ljs.ang);
		printf("\n");
		
		printf("ccr pos x = %d \n",data->exp.classic.rjs.pos.x);
		printf("ccr min x = %d \n",data->exp.classic.rjs.min.x);
		printf("ccr max x = %d \n",data->exp.classic.rjs.max.x);
		printf("\n");
		
		printf("ccr pos y = %d \n",data->exp.classic.rjs.pos.y);
		printf("ccr min y = %d \n",data->exp.classic.rjs.min.y);
		printf("ccr max y = %d \n",data->exp.classic.rjs.max.y);
		printf("\n");
		
		printf("ccr mag = %f \n", data->exp.classic.rjs.mag);
		printf("ccr ang = %f \n", data->exp.classic.rjs.ang);
		printf("\n");
		
		break;

		default:
			break;
	}	
		sleep(1);
		
		// 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);

		// Wait for the next frame
		VIDEO_WaitVSync();
	}

	return 0;
}