In memory of Ben “bushing” Byer, who passed away on Monday, February 8th, 2016.

Difference between revisions of "How to use the Wiimote"

From WiiBrew
Jump to navigation Jump to search
(New page: <source lang="c"> //code by WinterMute #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> #include <ogcsys.h> #include <gccore.h> #include <stdarg.h> #include <...)
 
m (How to)
 
(15 intermediate revisions by 9 users not shown)
Line 1: Line 1:
 +
{{Seealso|How to use the Wiimote (Commented)}}
 +
 +
Code by {{User|Wintermute}}
 
<source lang="c">
 
<source lang="c">
//code by WinterMute
 
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <stdlib.h>
Line 93: Line 95:
 
switch(res) {
 
switch(res) {
 
case WPAD_ERR_NO_CONTROLLER:
 
case WPAD_ERR_NO_CONTROLLER:
printf(" Wiimote not connected\n");
+
printf(" Wiimote not connected\n");
 
break;
 
break;
 
case WPAD_ERR_NOT_READY:
 
case WPAD_ERR_NOT_READY:
printf(" Wiimote not ready\n");
+
printf(" Wiimote not ready\n");
 
break;
 
break;
 
case WPAD_ERR_NONE:
 
case WPAD_ERR_NONE:
printf(" Wiimote ready\n");
+
printf(" Wiimote ready\n");
 
break;
 
break;
 
default:
 
default:
printf(" Unknown Wimote state %d\n",res);
+
printf(" Unknown Wimote state %d\n",res);
 
 
 
}
 
}
printf(" Event count: %d\n",evctr);
+
printf(" Event count: %d\n",evctr);
 
if(res == WPAD_ERR_NONE) {
 
if(res == WPAD_ERR_NONE) {
 
wd = WPAD_Data(0);
 
wd = WPAD_Data(0);
printf(" Data->Err: %d\n",wd->err);
+
printf(" Data->Err: %d\n",wd->err);
printf(" IR Dots:\n");
+
printf(" IR Dots:\n");
 
for(i=0; i<4; i++) {
 
for(i=0; i<4; i++) {
 
if(wd->ir.dot[i].visible) {
 
if(wd->ir.dot[i].visible) {
printf("   %4d, %3d\n", wd->ir.dot[i].rx, wd->ir.dot[i].ry);
+
printf(" %4d, %3d\n", wd->ir.dot[i].rx, wd->ir.dot[i].ry);
 
} else {
 
} else {
printf("   None\n");
+
printf(" None\n");
 
}
 
}
 
}
 
}
 
if(wd->ir.valid) {
 
if(wd->ir.valid) {
printf(" Cursor: %.02f,%.02f\n",wd->ir.x, wd->ir.y);
+
printf(" Cursor: %.02f,%.02f\n",wd->ir.x, wd->ir.y);
printf("   @ %.02f deg\n",wd->ir.angle);
+
printf(" @ %.02f deg\n",wd->ir.angle);
 
} else {
 
} else {
printf(" No Cursor\n\n");
+
printf(" No Cursor\n\n");
 
}
 
}
 
if(wd->ir.raw_valid) {
 
if(wd->ir.raw_valid) {
printf(" Distance: %.02fm\n", wd->ir.z);
+
printf(" Distance: %.02fm\n", wd->ir.z);
printf(" Yaw: %.02f deg\n", wd->orient.yaw);
+
printf(" Yaw: %.02f deg\n", wd->orient.yaw);
 
} else {
 
} else {
 
printf("\n\n");
 
printf("\n\n");
 
}
 
}
printf(" Accel:\n");
+
printf(" Accel:\n");
printf("   XYZ: %3d,%3d,%3d\n",wd->accel.x,wd->accel.y,wd->accel.z);
+
printf(" XYZ: %3d,%3d,%3d\n",wd->accel.x,wd->accel.y,wd->accel.z);
printf("   Pitch: %.02f\n",wd->orient.pitch);
+
printf(" Pitch: %.02f\n",wd->orient.pitch);
printf("   Roll: %.02f\n",wd->orient.roll);
+
printf(" Roll: %.02f\n",wd->orient.roll);
printf(" Buttons down:\n   ");
+
printf(" Buttons down:\n ");
 
if(wd->btns_h & WPAD_BUTTON_A) printf("A ");
 
if(wd->btns_h & WPAD_BUTTON_A) printf("A ");
 
if(wd->btns_h & WPAD_BUTTON_B) printf("B ");
 
if(wd->btns_h & WPAD_BUTTON_B) printf("B ");
Line 141: Line 143:
 
if(wd->btns_h & WPAD_BUTTON_HOME) printf("HOME ");
 
if(wd->btns_h & WPAD_BUTTON_HOME) printf("HOME ");
 
if(wd->btns_h & WPAD_BUTTON_PLUS) printf("PLUS ");
 
if(wd->btns_h & WPAD_BUTTON_PLUS) printf("PLUS ");
printf("\n   ");
+
printf("\n ");
 
if(wd->btns_h & WPAD_BUTTON_LEFT) printf("LEFT ");
 
if(wd->btns_h & WPAD_BUTTON_LEFT) printf("LEFT ");
 
if(wd->btns_h & WPAD_BUTTON_RIGHT) printf("RIGHT ");
 
if(wd->btns_h & WPAD_BUTTON_RIGHT) printf("RIGHT ");
Line 173: Line 175:
  
 
return 0;
 
return 0;
}</source>
+
}
 +
</source>
 +
 
 +
To make this example work, extra libraries must be linked in. Modify the standard Makefile LIBS line as follows:<br />
 +
<code>LIBS := -lwiiuse -lbte -logc</code>
 +
 
 +
On Mac OS X you will need to add <code>-lm</code> for libmath. On Mac OS X and Vista the order of the library flags is important, don't deviate from the above order otherwise you will get [http://www.tehskeen.com/forums/showthread.php?t=3012&page=3 strange errors] like:<br />
 +
<pre>C:/devkitpro/libogc/lib/wii/libbte.a(physbusif.o): In function 'physbusif_output':
 +
physbusig.c: (.text.physbusif_output*0x148): undefined reference to 'USB_WriteBlkMsgAsync'</pre><br />
 +
 
 +
== See Also: ==
 +
* [[WiiMotionDemo]] ''accelerometer, GRRLIB''
 +
* [[WiiMenu]]
 +
 
 +
[[Category:References]]
 +
[[Category:How To]]

Latest revision as of 05:39, 17 March 2021

See also: How to use the Wiimote (Commented)


Code by Wintermute

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ogcsys.h>
#include <gccore.h>
#include <stdarg.h>
#include <ctype.h>
#include <math.h>
#include <wiiuse/wpad.h>

static GXRModeObj *rmode = NULL;

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

int doreload=0, dooff=0;

void reload(void) {
	doreload=1;
}

void shutdown(void) {
	dooff=1;
}

void drawdot(void *xfb, GXRModeObj *rmode, float w, float h, float fx, float fy, u32 color) {
	u32 *fb;
	int px,py;
	int x,y;
	fb = (u32*)xfb;

	y = fy * rmode->xfbHeight / h;
	x = fx * rmode->fbWidth / w / 2;
	
	for(py=y-4; py<=(y+4); py++) {
		if(py < 0 || py >= rmode->xfbHeight)
				continue;
		for(px=x-2; px<=(x+2); px++) {
			if(px < 0 || px >= rmode->fbWidth/2)
				continue;
			fb[rmode->fbWidth/VI_DISPLAY_PIX_SZ*py + px] = color;
		}
	}

}

int evctr = 0;

void countevs(int chan, const WPADData *data) {
	evctr++;
}

int main(int argc, char **argv) {
	int res;
	
	void *xfb[2];
	u32 type;
	int i;
	int fbi = 0;
	float theta;
	WPADData *wd;
	
	VIDEO_Init();
	PAD_Init();
	WPAD_Init();

	rmode = VIDEO_GetPreferredMode(NULL);

	xfb[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
	xfb[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
	
	VIDEO_Configure(rmode);
	VIDEO_SetNextFramebuffer(xfb);
	VIDEO_SetBlack(FALSE);
	VIDEO_Flush();
	VIDEO_WaitVSync();
	if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();

	SYS_SetResetCallback(reload);
	SYS_SetPowerCallback(shutdown);
	
	WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR);
	WPAD_SetVRes(0, rmode->fbWidth, rmode->xfbHeight);
	
	while(!doreload && !dooff) {
		CON_Init(xfb[fbi],0,0,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
		//VIDEO_ClearFrameBuffer(rmode,xfb[fbi],COLOR_BLACK);
		printf("\n\n\n");
		WPAD_ReadPending(WPAD_CHAN_ALL, countevs);
		res = WPAD_Probe(0, &type);
		switch(res) {
			case WPAD_ERR_NO_CONTROLLER:
				printf(" Wiimote not connected\n");
				break;
			case WPAD_ERR_NOT_READY:
				printf(" Wiimote not ready\n");
				break;
			case WPAD_ERR_NONE:
				printf(" Wiimote ready\n");
				break;
			default:
				printf(" Unknown Wimote state %d\n",res);
			
		}
		printf(" Event count: %d\n",evctr);
		if(res == WPAD_ERR_NONE) {
			wd = WPAD_Data(0);
			printf(" Data->Err: %d\n",wd->err);
			printf(" IR Dots:\n");
			for(i=0; i<4; i++) {
				if(wd->ir.dot[i].visible) {
					printf(" %4d, %3d\n", wd->ir.dot[i].rx, wd->ir.dot[i].ry);
				} else {
					printf(" None\n");
				}
			}
			if(wd->ir.valid) {
				printf(" Cursor: %.02f,%.02f\n",wd->ir.x, wd->ir.y);
				printf(" @ %.02f deg\n",wd->ir.angle);
			} else {
				printf(" No Cursor\n\n");
			}
			if(wd->ir.raw_valid) {
				printf(" Distance: %.02fm\n", wd->ir.z);
				printf(" Yaw: %.02f deg\n", wd->orient.yaw);
			} else {
				printf("\n\n");
			}
			printf(" Accel:\n");
			printf(" XYZ: %3d,%3d,%3d\n",wd->accel.x,wd->accel.y,wd->accel.z);
			printf(" Pitch: %.02f\n",wd->orient.pitch);
			printf(" Roll: %.02f\n",wd->orient.roll);
			printf(" Buttons down:\n ");
			if(wd->btns_h & WPAD_BUTTON_A) printf("A ");
			if(wd->btns_h & WPAD_BUTTON_B) printf("B ");
			if(wd->btns_h & WPAD_BUTTON_1) printf("1 ");
			if(wd->btns_h & WPAD_BUTTON_2) printf("2 ");
			if(wd->btns_h & WPAD_BUTTON_MINUS) printf("MINUS ");
			if(wd->btns_h & WPAD_BUTTON_HOME) printf("HOME ");
			if(wd->btns_h & WPAD_BUTTON_PLUS) printf("PLUS ");
			printf("\n ");
			if(wd->btns_h & WPAD_BUTTON_LEFT) printf("LEFT ");
			if(wd->btns_h & WPAD_BUTTON_RIGHT) printf("RIGHT ");
			if(wd->btns_h & WPAD_BUTTON_UP) printf("UP ");
			if(wd->btns_h & WPAD_BUTTON_DOWN) printf("DOWN ");
			printf("\n");
			for(i=0; i<4; i++) {
				if(wd->ir.dot[i].visible) {
					drawdot(xfb[fbi], rmode, 1024, 768, wd->ir.dot[i].rx, wd->ir.dot[i].ry, COLOR_YELLOW);
				}
			}
			if(wd->ir.raw_valid) {
				for(i=0; i<2; i++) {
					drawdot(xfb[fbi], rmode, 4, 4, wd->ir.sensorbar.rot_dots[i].x+2, wd->ir.sensorbar.rot_dots[i].y+2, COLOR_GREEN);
				}
			}
			if(wd->ir.valid) {
				theta = wd->ir.angle / 180.0 * 3.1415;
				drawdot(xfb[fbi], rmode, rmode->fbWidth, rmode->xfbHeight, wd->ir.x, wd->ir.y, COLOR_RED);
				drawdot(xfb[fbi], rmode, rmode->fbWidth, rmode->xfbHeight, wd->ir.x + 10*sinf(theta), wd->ir.y - 10*cosf(theta), COLOR_BLUE);
			}
			if(wd->btns_h & WPAD_BUTTON_1) doreload=1;
		}
		VIDEO_SetNextFramebuffer(xfb[fbi]);
		VIDEO_Flush();
		VIDEO_WaitVSync();
		fbi ^= 1;
	}
	if(doreload) return 0;
	if(dooff) SYS_ResetSystem(SYS_SHUTDOWN,0,0);

	return 0;
}

To make this example work, extra libraries must be linked in. Modify the standard Makefile LIBS line as follows:
LIBS := -lwiiuse -lbte -logc

On Mac OS X you will need to add -lm for libmath. On Mac OS X and Vista the order of the library flags is important, don't deviate from the above order otherwise you will get strange errors like:

C:/devkitpro/libogc/lib/wii/libbte.a(physbusif.o): In function 'physbusif_output':
physbusig.c: (.text.physbusif_output*0x148): undefined reference to 'USB_WriteBlkMsgAsync'


See Also: