Page 1 of 1

problems compiling wiiuse

Posted: Wed Mar 09, 2011 7:52 pm
by wilco2009
Hi all!

I usually use wpad to manage the wiimotes, but I want to access to the memory of wiimote to read Mii's information.

I'm trying to use wiiuse to read the wiimote memory but I got follow message when I tried to compile:

> "make"
miis.c
linking ... Miis.elf
miis.o: In function `main':
miis.c:(.text.main+0x4c): undefined reference to `wiiuse_find'
miis.c:(.text.main+0x60): undefined reference to `wiiuse_connect'
miis.c:(.text.main+0xb0): undefined reference to `wiiuse_poll'
collect2: ld returned 1 exit status
make[1]: *** [/d/wii/codigo/Miis/Miis.elf] Error 1
"make": *** [build] Error 2

> Process Exit Code: 2
> Time Taken: 00:05

Can somebody help me??

I attach also the code:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <gccore.h>
#include <wiiuse/wiiuse.h>

#include <wiiuse/wpad.h>


static void *xfb = NULL;
static GXRModeObj *rmode = NULL;

#define MII_DATA_ADDR 0x0fca

#define MII_NAME_LENGTH			10
#define MII_CREATOR_NAME_LENGTH		10
 
typedef struct
{
// addr: 0x00 & 0x01
	u16 invalid:1; // doesn't seem to have any effect?
	u16 isGirl:1;
	u16 month:4;
	u16 day:5;
	u16 favColor:4;		 // 0 - 11 (changing to 1111, along with setting the preceeding bit 
              		           // results in a grey shirt, some values over 11 will crash the Wii 
		 // when trying to change the favorite color).
	u16 isFavorite:1;
 
// addr: 0x02 through 0x15
	u16 name[MII_NAME_LENGTH];
 
// addr: 0x16
	u8 height; // 0 - 127
 
// addr: 0x17
	u8 weight; // 0 - 127
 
// addr: 0x18 - 0x1B
 	u8 miiID1; 	           // Unique Mii identifier. Seems to increment with time. Also can
 	u8 miiID2; 	           // be used to change colour of Mii Trousers (see 'See Also' links)
 	u8 miiID3;
 	u8 miiID4;
 
// addr: 0x1C through 0x1F
	u8 systemID0;	 // Checksum8 of first 3 bytes of mac addr
	u8 systemID1;	 // mac addr 3rd-to-last byte
	u8 systemID2;	 // mac addr 2nd-to-last byte
	u8 systemID3;	 // mac addr last byte
 
// addr: 0x20 & 0x21
	u16 faceShape:3; // 0 - 7
	u16 skinColor:3; // 0 - 5
	u16 facialFeature:4; // 0 - 11
	u16 unknown1:3; // Mii appears unaffected by changes to this data 
	u16 mingleOff:1; // 0 = Mingle, 1 = Don't Mingle
	u16 unknown2:1; // Mii appears unaffected by changes to this data
	u16 downloaded:1; // If the Mii has been downloaded from the Check Mii Out Channel
 
// addr: 0x22 & 0x23
	u16 hairType:7; // 0 - 71, Value is non-sequential with regard to page, row and column
	u16 hairColor:3; // 0 - 7
	u16 hairPart:1; // 0 = Normal, 1 = Reversed
	u16 unknown3:5;
 
// addr: 0x24 through 0x27
	u32 eyebrowType:5; // 0 - 23, Value is non-sequential with regard to page, row and column
	u32 unknown4:1;
	u32 eyebrowRotation:4; // 0 - 11, Default value varies based on eyebrow type
	u32 unknown5:6;
	u32 eyebrowColor:3; // 0 - 7
	u32 eyebrowSize:4;	 // 0 - 8, Default = 4
	u32 eyebrowVertPos:5; // 3 - 18, Default = 10
	u32 eyebrowHorizSpacing:4; // 0 - 12, Default = 2
 
// addr: 0x28 through 0x2B
	u32 eyeType:6; // 0 - 47, Value is non-sequential with regard to page, row and column
	u32 unknown6:2;
	u32 eyeRotation:3; // 0 - 7, Default value varies based on eye type
	u32 eyeVertPos:5; // 0 - 18, Default = 12
	u32 eyeColor:3; // 0 - 5
	u32 unknown7:1;
	u32 eyeSize:3; // 0 - 7, Default = 4
	u32 eyeHorizSpacing:4; // 0 - 12, Default = 2
	u32 unknown8:5;
 
// addr: 0x2C & 0x2D
	u16 noseType:4; // 0 - 11, Value is non-sequential with regard to row and column
	u16 noseSize:4; // 0 - 8, Default = 4
	u16 noseVertPos:5; // 0 - 18, Default = 9
	u16 unknown9:3;
 
// addr: 0x2E & 2F
	u16 lipType:5; // 0 - 23, Value is non-sequential with regard to page, row and column
	u16 lipColor:2; // 0 - 2
	u16 lipSize:4; // 0 - 8, Default = 4
	u16 lipVertPos:5; // 0 - 18, Default = 13
 
// addr: 0x30 & 0x31
	u16 glassesType:4; // 0 - 8
	u16 glassesColor:3; // 0 - 5
	u16 unknown:1; // when turned on mii does not appear (use not known)
	u16 glassesSize:3; // 0 - 7, Default = 4
	u16 glassesVertPos:5; // 0 - 20, Default = 10
 
// addr: 0x32 & 33
	u16 mustacheType:2; // 0 - 3
	u16 beardType:2; // 0 - 3
	u16 facialHairColor:3; // 0 - 7
	u16 mustacheSize:4; // 0 - 8, Default = 4
	u16 mustacheVertPos:5; // 0 - 16, Default = 10
 
// addr: 0x34 & 0x35
	u16 moleOn:1; // 0 = No Mole, 1 = Has Mole
	u16 moleSize:4; // 0 - 8, Default = 4
	u16 moleVertPos:5; // 0 - 30, Default = 20
	u16 moleHorizPos:5; // 0 - 16, Default = 2
	u16 unknown10:1; 
 
// addr: 0x36 through 0x49
	u16 creatorName[MII_CREATOR_NAME_LENGTH];
} MII_DATA_STRUCT;

typedef struct {
	u32 RNCD;
	u16 MiiParadeSlots;
	u32 unknown;
	MII_DATA_STRUCT MiiArray[0x0A];
	u16 crc;
} MIIDATABLOCK; // 752 bytes en total


/**
  * Calculate a modified CRC16-CCITT checksum of a byte array, as used for
  * checking the validity of a Mii data block stored on a Wiimote.
  *
  * @param bytes the byte array to calculate the checksum for
  * @return the checksum (in the lower 16 bits)
  */
 int crc (u8* bytes[]) {
     int crc = 0x0000;
	 int byteIndex, bitIndex,counter;
     for (byteIndex = 0; byteIndex < sizeof(bytes); byteIndex++) {
         for (bitIndex = 7; bitIndex >= 0; bitIndex--) {
             crc = (((crc << 1) | ((*bytes[byteIndex] >> bitIndex) & 0x1)) ^
             (((crc & 0x8000) != 0) ? 0x1021 : 0)); 
         }
     }
     for (counter = 16; counter > 0; counter--) {
         crc = ((crc << 1) ^ (((crc & 0x8000) != 0) ? 0x1021 : 0));
     }
     return (crc & 0xFFFF);
 }
 
#define MAX_WIIMOTES	 4
/**
*	@brief Callback that handles an event.
*
*	@param wm	 Pointer to a wiimote_t structure.
*
*	This function is called automatically by the wiiuse library when an
*	event occurs on the specified wiimote.
*/
void handle_event(struct wiimote_t* wm, int event) {
	printf("\n\n--- EVENT [id %i] ---\n", wm->unid);

	/* if a button is pressed, report it */
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_A))	 printf("A pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_B))	 printf("B pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_UP))	 printf("UP pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN))	printf("DOWN pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT))	printf("LEFT pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT))	printf("RIGHT pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS))	printf("MINUS pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS))	printf("PLUS pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE))	 printf("ONE pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_TWO))	 printf("TWO pressed\n");
	if (IS_PRESSED(wm, WIIMOTE_BUTTON_HOME))	printf("HOME pressed\n");

	/*
	 *	Pressing minus will tell the wiimote we are no longer interested in movement.
	 *	This is useful because it saves battery power.
	 */
	if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_MINUS))
	wiiuse_motion_sensing(wm, 0);

	/*
	 *	Pressing plus will tell the wiimote we are interested in movement.
	 */
	if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_PLUS))
	wiiuse_motion_sensing(wm, 1);

	/*
	 *	Pressing B will toggle the rumble
	 *
	 *	if B is pressed but is not held, toggle the rumble
	 */

	if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_B))
		wiiuse_toggle_rumble(wm);

	if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_UP))
		wiiuse_set_ir(wm, 1);
	if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_DOWN))
		wiiuse_set_ir(wm, 0);

	/* if the accelerometer is turned on then print angles */
	if (WIIUSE_USING_ACC(wm)) {
		printf("wiimote roll = %f [%f]\n", wm->orient.roll, wm->orient.a_roll);
		printf("wiimote pitch = %f [%f]\n", wm->orient.pitch, wm->orient.a_pitch);
		printf("wiimote yaw = %f\n", wm->orient.yaw);
	}

	/*
	 *	If IR tracking is enabled then print the coordinates
	 *	on the virtual screen that the wiimote is pointing to.
	 *
	 *	Also make sure that we see at least 1 dot.
	 */
	if (WIIUSE_USING_IR(wm)) {
		int i = 0;

		/* go through each of the 4 possible IR sources */
		for (; i < 4; ++i) {
			/* check if the source is visible */
			if (wm->ir.dot[i].visible)
			printf("IR source %i: (%u, %u)\n", i, wm->ir.dot[i].rx, wm->ir.dot[i].ry);
		}

		printf("IR cursor: (%f, %f)\n", wm->ir.x, wm->ir.y);
	}

	/* show events specific to supported expansions */
	if (wm->exp.type == EXP_NUNCHUK) {
		/* nunchuk */
		struct nunchuk_t* nc = (nunchuk_t*)&wm->exp.nunchuk;

		if (IS_PRESSED(nc, NUNCHUK_BUTTON_C))	 printf("Nunchuk: C pressed\n");
		if (IS_PRESSED(nc, NUNCHUK_BUTTON_Z))	 printf("Nunchuk: Z pressed\n");

		printf("nunchuk roll = %f\n", nc->orient.roll);
		printf("nunchuk pitch = %f\n", nc->orient.pitch);
		printf("nunchuk yaw = %f\n", nc->orient.yaw);	

		printf("nunchuk joystick angle: %f\n", nc->js.ang);
		printf("nunchuk joystick magnitude: %f\n", nc->js.mag);
	} else if (wm->exp.type == EXP_CLASSIC) {
		/* classic controller */
		struct classic_ctrl_t* cc = (classic_ctrl_t*)&wm->exp.classic;

		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_ZL))	 printf("Classic: ZL pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_B))	 printf("Classic: B pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_Y))	 printf("Classic: Y pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_A))	 printf("Classic: A pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_X))	 printf("Classic: X pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_ZR))	 printf("Classic: ZR pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_LEFT))	 printf("Classic: LEFT pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_UP))	 printf("Classic: UP pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_RIGHT))	 printf("Classic: RIGHT pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_DOWN))	 printf("Classic: DOWN pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_FULL_L))	 printf("Classic: FULL L pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_MINUS))	 printf("Classic: MINUS pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_HOME))	 printf("Classic: HOME pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_PLUS))	 printf("Classic: PLUS pressed\n");
		if (IS_PRESSED(cc, CLASSIC_CTRL_BUTTON_FULL_R))	 printf("Classic: FULL R pressed\n");

		printf("classic L button pressed: %f\n", cc->l_shoulder);
		printf("classic R button pressed: %f\n", cc->r_shoulder);
		printf("classic left joystick angle: %f\n", cc->ljs.ang);
		printf("classic left joystick magnitude: %f\n", cc->ljs.mag);
		printf("classic right joystick angle: %f\n", cc->rjs.ang);
		printf("classic right joystick magnitude: %f\n", cc->rjs.mag);
	} else if (wm->exp.type == EXP_GUITAR_HERO_3) {
	/* guitar hero 3 guitar */
		struct guitar_hero_3_t* gh3 = (guitar_hero_3_t*)&wm->exp.gh3;

		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_STRUM_UP))	 printf("Guitar: Strum Up pressed\n");
		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_STRUM_DOWN))	printf("Guitar: Strum Down pressed\n");
		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_YELLOW))	 printf("Guitar: Yellow pressed\n");
		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_GREEN))	 printf("Guitar: Green pressed\n");
		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_BLUE))	 printf("Guitar: Blue pressed\n");
		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_RED))	 printf("Guitar: Red pressed\n");
		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_ORANGE))	 printf("Guitar: Orange pressed\n");
		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_PLUS))	 printf("Guitar: Plus pressed\n");
		if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_MINUS))	 printf("Guitar: Minus pressed\n");

		printf("Guitar whammy bar: %f\n", gh3->whammy_bar);
		printf("Guitar joystick angle: %f\n", gh3->js.ang);
		printf("Guitar joystick magnitude: %f\n", gh3->js.mag);
	}
}


 
 void handle_ctrl_status(struct wiimote_t* wm) {
	printf("\n\n--- CONTROLLER STATUS [wiimote id %i] ---\n", wm->unid);

	printf("attachment: %i\n", wm->exp.type);
	printf("speaker: %i\n", WIIUSE_USING_SPEAKER(wm));
	printf("ir: %i\n", WIIUSE_USING_IR(wm));
	printf("leds: %i %i %i %i\n", WIIUSE_IS_LED_SET(wm, 1), WIIUSE_IS_LED_SET(wm, 2), WIIUSE_IS_LED_SET(wm, 3), WIIUSE_IS_LED_SET(wm, 4));
	printf("battery: %i %%\n", wm->battery_level);
}


/**
*	@brief Callback that handles a read event.
*
*	@param wm	 Pointer to a wiimote_t structure.
*	@param data	 Pointer to the filled data block.
*	@param len	 Length in bytes of the data block.
*
*	This function is called automatically by the wiiuse library when
*	the wiimote has returned the full data requested by a previous
*	call to wiiuse_read_data().
*
*	You can read data on the wiimote, such as Mii data, if
*	you know the offset address and the length.
*
*	The \a data pointer was specified on the call to wiiuse_read_data().
*	At the time of this function being called, it is not safe to deallocate
*	this buffer.
*/

void handle_read(struct wiimote_t* wm, u8* data, unsigned short len) {
int i = 0;

	printf("\n\n--- DATA READ [wiimote id %i] ---\n", wm->unid);
	printf("finished read of size %i\n", len);
	for (; i < len; ++i) {
		if (!(i%16))
		printf("\n");
		printf("%x ", data[i]);
	}
	printf("\n\n");
}



void Init_Video(void);

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

	wiimote** wiimotes;
	int found, connected;

	Init_Video();

	/*
	 *	Initialize an array of wiimote objects.
	 *
	 *	The parameter is the number of wiimotes I want to create.
	 */
	
	wiimotes = wiiuse_init(MAX_WIIMOTES, handle_event);
	found = wiiuse_find(wiimotes, MAX_WIIMOTES, 5);
	if (!found) {
		printf ("No wiimotes found.");
		return 0;
	}


	connected = wiiuse_connect(wiimotes, MAX_WIIMOTES);
	if (connected)
		printf("Connected to %i wiimotes (of %i found).\n", connected, found);
	else {
		printf("Failed to connect to any wiimote.\n");
		return 0;
	}


	while(1) {
		if (wiiuse_poll(wiimotes, MAX_WIIMOTES)) {
			int i = 0;
			for (; i < MAX_WIIMOTES; ++i) {
				switch (wiimotes[i]->event) {
				case WIIUSE_EVENT:
					/* a generic event occured */
//					handle_event(wiimotes[i]);
					break;

				case WIIUSE_STATUS:
					/* a status event occured */
					handle_ctrl_status(wiimotes[i]);
					break;

				case WIIUSE_DISCONNECT:
				case WIIUSE_UNEXPECTED_DISCONNECT:
					/* the wiimote disconnected */
//					handle_disconnect(wiimotes[i]);
					break;

				case WIIUSE_READ_DATA:
					/*
					 *	Data we requested to read was returned.
					 *	Take a look at wiimotes[i]->read_req
					 *	for the data.
					 */
					break;

				case WIIUSE_NUNCHUK_INSERTED:
					/*
					 *	a nunchuk was inserted
					 *	This is a good place to set any nunchuk specific
					 *	threshold values. By default they are the same
					 *	as the wiimote.
					 */
					printf("Nunchuk inserted.\n");
					break;

				case WIIUSE_CLASSIC_CTRL_INSERTED:
					printf("Classic controller inserted.\n");
					break;

				case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED:
					/* some expansion was inserted */
					handle_ctrl_status(wiimotes[i]);
					printf("Guitar Hero 3 controller inserted.\n");
					break;

				case WIIUSE_NUNCHUK_REMOVED:
				case WIIUSE_CLASSIC_CTRL_REMOVED:
				case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED:
					/* some expansion was removed */
					handle_ctrl_status(wiimotes[i]);
					printf("An expansion was removed.\n");
					break;

				default:
					break;
				}
			}
		}

		// Esperamos al siguiente frame
		VIDEO_WaitVSync();
	}

	/*
	 *	Disconnect the wiimotes
	 */
	wiiuse_cleanup(wiimotes, MAX_WIIMOTES);

	return 0;
}


void Init_Video(void) {
	// Initialise the video system
	VIDEO_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();
}

Re: problems compiling wiiuse

Posted: Tue May 01, 2012 11:22 pm
by Anakclusmos
Can anyone please respond to this? I'm attempting the same thing and am getting the same problem. It looks like a linking problem, but I'm already linking with libwiiuse.

Re: problems compiling wiiuse

Posted: Wed May 02, 2012 12:21 am
by WinterMute
These functions were leftovers of the port of wiiuse from windows to wii, they don't exist, sorry.

Re: problems compiling wiiuse

Posted: Thu May 10, 2012 1:18 am
by Anakclusmos
WinterMute wrote:These functions were leftovers of the port of wiiuse from windows to wii, they don't exist, sorry.
Is there another method for reading from a classic controller? I've spend hours searching and haven't found anything, and there's no examples for this like there were in the pspsdk >_>