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

How to use the Wiimote (Commented): Difference between revisions

From WiiBrew
Jump to navigation Jump to search
Gcb (talk | contribs)
No edit summary
Hallowizer (talk | contribs)
m Category
 
(8 intermediate revisions by 6 users not shown)
Line 2: Line 2:


PLEASE help us comment this code.
PLEASE help us comment this code.
Only add comments if you really know what it does. Please don't add comments that just repeat the code verbatim:


Only add if you really know what it means, and no obvious comments.<br><br>
Wrong:
Wrong:<br>
  // declares Integer 'dooff' and sets to zero
  <code>//Declares Integer 'dooff' and sets to Zero"
  int dooff=0;
  int doreload=0, dooff=0;</code><br>
<br>
Correct:<br>
<code>//dooff(Do Off) is a flag that tells the program to quit looping and properly shuts down the wii
int dooff=0;</code><br>


<!--Sorry about the many !unsure! things, I am at work and doing this durring lunch. I will have more time tonight to confirm 100% each function and provide a good explaination. -->
Right:
// dooff (do off) is a flag that tells the program to quit looping and properly shuts down the wii
int dooff=0;
 
<!--Sorry about the many !unsure! things, I am at work and doing this during lunch. I will have more time tonight to confirm 100% each function and provide a good explanation. -->


<source lang="c">
<source lang="c">
Line 39: Line 39:
}
}
   
   
//Calling the function will end the while loop and properly shutdown the system.
//Calling the function will end the while loop and then properly shutdown the system  
// QUESTION: why calling the shutdown function direcly here halts the console?
//with SYS_ResetSystem(SYS_SHUTDOWN,0,0) (see the last if statement).
void shutdown(void) {
void shutdown(void) {
dooff=1;
dooff=1;
Line 47: Line 47:
//Draw a square on the screen (May draw rectangles as well, I am uncertain).  
//Draw a square on the screen (May draw rectangles as well, I am uncertain).  
//*xfb - framebuffer
//*xfb - framebuffer
//*rmode - !unsure!
//*rmode - the current video mode (# lines,progressive or interlaced, NTSC or PAL etc.) see libogc/gc/ogc/gx_struct.h
// for the definition
//w - Width of screen (Used as scale factor in converting fx to pixel coordinates)
//w - Width of screen (Used as scale factor in converting fx to pixel coordinates)
//h - Height of screen (Used as scale factor in converting fy to pixel coordinates)
//h - Height of screen (Used as scale factor in converting fy to pixel coordinates)
Line 91: Line 92:
switch(wiimote_connection_status) {
switch(wiimote_connection_status) {
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",wiimote_connection_status);
printf(" Unknown Wimote state %d\n",wiimote_connection_status);
}
}
}
}


void print_wiimote_buttons(WPADData *wd) {
void print_wiimote_buttons(WPADData *wd) {
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 113: Line 114:
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 124: Line 125:
//Makes the var wd point to the data on the wiimote
//Makes the var wd point to the data on the wiimote
WPADData *wd = WPAD_Data(0);
WPADData *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");
int i;
int i;
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);
drawdot(screen_buffer, rmode, 1024, 768, wd->ir.dot[i].rx, wd->ir.dot[i].ry, COLOR_YELLOW);
drawdot(screen_buffer, rmode, 1024, 768, wd->ir.dot[i].rx, wd->ir.dot[i].ry, COLOR_YELLOW);
} else {
} else {
printf("   None\n");
printf(" None\n");
}
}
}
}
Line 141: Line 142:
//ir.x/ir.y - The x/y coordinates that the wiimote is pointing to, relative to the screen.
//ir.x/ir.y - The x/y coordinates that the wiimote is pointing to, relative to the screen.
//ir.angle - how far (in degrees) the wiimote is twisted (based on ir)
//ir.angle - how far (in degrees) the wiimote is twisted (based on ir)
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);
drawdot(screen_buffer, rmode, rmode->fbWidth, rmode->xfbHeight, wd->ir.x, wd->ir.y, COLOR_RED);
drawdot(screen_buffer, rmode, rmode->fbWidth, rmode->xfbHeight, wd->ir.x, wd->ir.y, COLOR_RED);
drawdot(screen_buffer, rmode, rmode->fbWidth, rmode->xfbHeight, wd->ir.x + 10*sinf(theta), wd->ir.y - 10*cosf(theta), COLOR_BLUE);      
drawdot(screen_buffer, rmode, rmode->fbWidth, rmode->xfbHeight, wd->ir.x + 10*sinf(theta), wd->ir.y - 10*cosf(theta), COLOR_BLUE);  
} else {
} else {
printf(" No Cursor\n\n");
printf(" No Cursor\n\n");
}
}
if(wd->ir.raw_valid) {
if(wd->ir.raw_valid) {
//ir.z - How far away the wiimote is from the screen in meters
//ir.z - How far away the wiimote is from the screen in meters
printf(" Distance: %.02fm\n", wd->ir.z);
printf(" Distance: %.02fm\n", wd->ir.z);
//orient.yaw - The left/right angle of the wiimote to the screen  
//orient.yaw - The left/right angle of the wiimote to the screen  
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");
//accel.x/accel.y/accel.z - analog values for the accelleration of the wiimote
//accel.x/accel.y/accel.z - analog values for the accelleration of the wiimote
//(Note: Gravity pulls downwards, so even if the wiimote is not moving,  
//(Note: Gravity pulls downwards, so even if the wiimote is not moving,  
//one(or more) axis will have a reading as if it is moving "upwards")
//one(or more) axis will have a reading as if it is moving "upwards")
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);
//orient.pitch - how far the wiimote is "tilted" in degrees
//orient.pitch - how far the wiimote is "tilted" in degrees
printf("   Pitch: %.02f\n",wd->orient.pitch);
printf(" Pitch: %.02f\n",wd->orient.pitch);
//orient.roll - how far the wiimote is "twisted" in degrees (uses accelerometer)
//orient.roll - how far the wiimote is "twisted" in degrees (uses accelerometer)
printf("   Roll: %.02f\n",wd->orient.roll);
printf(" Roll: %.02f\n",wd->orient.roll);


print_wiimote_buttons(wd);
print_wiimote_buttons(wd);
Line 214: Line 215:
print_wiimote_connection_status(wiimote_connection_status);
print_wiimote_connection_status(wiimote_connection_status);


printf(" Event count: %d\n",evctr);
printf(" Event count: %d\n",evctr);
if(wiimote_connection_status == WPAD_ERR_NONE) {
if(wiimote_connection_status == WPAD_ERR_NONE) {
print_and_draw_wiimote_data(xfb[fbi]);
print_and_draw_wiimote_data(xfb[fbi]);
Line 231: Line 232:
</source>
</source>


To make this example work, extra libraries must be linked in. Modify the standard Makefile LIBS line as follows:<br>
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>
<code>LIBS := -lwiiuse -lbte -logc</code>
[[Category:How To]]

Latest revision as of 05:38, 17 March 2021

Please add comments to the code on this page. If enough higher-ups/WinterMute feel that the uncommented version is not needed, then feel free to have them/him do whatever.

PLEASE help us comment this code. Only add comments if you really know what it does. Please don't add comments that just repeat the code verbatim:

Wrong:

// declares Integer 'dooff' and sets to zero
int dooff=0;

Right:

// dooff (do off) is a flag that tells the program to quit looping and properly shuts down the wii
int dooff=0;


//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;
 
//-----------------------------------------------------------------------------------
//doreload - a flag that tells the program to quit looping and exit the program to the HBChannel.
//dooff - a flag that tells the program to quit looping and properly shutdown the system.
int doreload=0, dooff=0;
 
//Calling the function will end the while loop and properly exit the program to the HBChannel. 
void reload(void) {
	doreload=1;
}
 
//Calling the function will end the while loop and then properly shutdown the system 
//with SYS_ResetSystem(SYS_SHUTDOWN,0,0) (see the last if statement).
void shutdown(void) {
	dooff=1;
}
 
//Draw a square on the screen (May draw rectangles as well, I am uncertain). 
//*xfb - framebuffer
//*rmode - the current video mode (# lines,progressive or interlaced, NTSC or PAL etc.) see libogc/gc/ogc/gx_struct.h
// for the definition
//w - Width of screen (Used as scale factor in converting fx to pixel coordinates)
//h - Height of screen (Used as scale factor in converting fy to pixel coordinates)
//fx - X coordinate to draw on the screen (0-w)
//fy - Y coordinate to draw on the screen (!unsure!-h)
//color - the color of the rectangle (Examples: COLOR_YELLOW, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_BLACK, COLOR_WHITE)
void drawdot(void *xfb, GXRModeObj *rmode, float w, float h, float fx, float fy, u32 color) {
 
	//*fb - !unsure!
	//px - !unsure!
	//py - !unsure!
	//x - !unsure!
	//y - !unsure!
 
	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++;
}

void print_wiimote_connection_status(int wiimote_connection_status) {
	switch(wiimote_connection_status) {
		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",wiimote_connection_status);
	}
}

void print_wiimote_buttons(WPADData *wd) {
	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");
}

void print_and_draw_wiimote_data(void *screen_buffer) {
	//Makes the var wd point to the data on the wiimote
	WPADData *wd = WPAD_Data(0);
	printf(" Data->Err: %d\n",wd->err);
	printf(" IR Dots:\n");
	int i;
	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);
			drawdot(screen_buffer, rmode, 1024, 768, wd->ir.dot[i].rx, wd->ir.dot[i].ry, COLOR_YELLOW);
		} else {
			printf(" None\n");
		}
	}
	//ir.valid - TRUE is the wiimote is pointing at the screen, else it is false
	if(wd->ir.valid) {
		float theta = wd->ir.angle / 180.0 * M_PI;
	
		//ir.x/ir.y - The x/y coordinates that the wiimote is pointing to, relative to the screen.
		//ir.angle - how far (in degrees) the wiimote is twisted (based on ir)
		printf(" Cursor: %.02f,%.02f\n",wd->ir.x, wd->ir.y);
		printf(" @ %.02f deg\n",wd->ir.angle);
		
		drawdot(screen_buffer, rmode, rmode->fbWidth, rmode->xfbHeight, wd->ir.x, wd->ir.y, COLOR_RED);
		drawdot(screen_buffer, rmode, rmode->fbWidth, rmode->xfbHeight, wd->ir.x + 10*sinf(theta), wd->ir.y - 10*cosf(theta), COLOR_BLUE); 
	} else {
		printf(" No Cursor\n\n");
	}
	if(wd->ir.raw_valid) {
		//ir.z - How far away the wiimote is from the screen in meters
		printf(" Distance: %.02fm\n", wd->ir.z);
		//orient.yaw - The left/right angle of the wiimote to the screen 
		printf(" Yaw: %.02f deg\n", wd->orient.yaw);
	} else {
		printf("\n\n");
	}
	printf(" Accel:\n");
	//accel.x/accel.y/accel.z - analog values for the accelleration of the wiimote
	//(Note: Gravity pulls downwards, so even if the wiimote is not moving, 
	//one(or more) axis will have a reading as if it is moving "upwards")
	printf(" XYZ: %3d,%3d,%3d\n",wd->accel.x,wd->accel.y,wd->accel.z);
	//orient.pitch - how far the wiimote is "tilted" in degrees
	printf(" Pitch: %.02f\n",wd->orient.pitch);
	//orient.roll - how far the wiimote is "twisted" in degrees (uses accelerometer)
	printf(" Roll: %.02f\n",wd->orient.roll);

	print_wiimote_buttons(wd);

	if(wd->ir.raw_valid) {
		for(i=0; i<2; i++) {
			drawdot(screen_buffer, rmode, 4, 4, wd->ir.sensorbar.rot_dots[i].x+2, wd->ir.sensorbar.rot_dots[i].y+2, COLOR_GREEN);
		}
	}

	if(wd->btns_h & WPAD_BUTTON_1) doreload=1;
}
 
int main(int argc, char **argv) {
	void *xfb[2];
	u32 type;
	int fbi = 0;
 
	VIDEO_Init();
	PAD_Init();
	WPAD_Init();
 
	rmode = VIDEO_GetPreferredMode(NULL);
 
	// double buffering, prevents flickering (is it needed for LCD TV? i don't have one to test)
	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);
		int wiimote_connection_status = WPAD_Probe(0, &type);
		print_wiimote_connection_status(wiimote_connection_status);

		printf(" Event count: %d\n",evctr);
		if(wiimote_connection_status == WPAD_ERR_NONE) {
			print_and_draw_wiimote_data(xfb[fbi]);
		}
		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