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
mNo edit summary
Hallowizer (talk | contribs)
m Category
 
(11 intermediate revisions by 9 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 26: Line 26:
#include <math.h>
#include <math.h>
#include <wiiuse/wpad.h>
#include <wiiuse/wpad.h>
 
static GXRModeObj *rmode = NULL;
static GXRModeObj *rmode = NULL;
 
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
//doreload - a flag that tells the program to quit looping and exit the program to the HBChannel.
//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.
//dooff - a flag that tells the program to quit looping and properly shutdown the system.
int doreload=0, dooff=0;
int doreload=0, dooff=0;
 
//Calling the function will end the while loop and properly exit the program to the HBChannel.  
//Calling the function will end the while loop and properly exit the program to the HBChannel.  
void reload(void) {
void reload(void) {
doreload=1;
doreload=1;
}
}
 
//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  
//with SYS_ResetSystem(SYS_SHUTDOWN,0,0) (see the last if statement).
void shutdown(void) {
void shutdown(void) {
dooff=1;
dooff=1;
}
}
 
//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 - !unsure!
//*xfb - framebuffer
//*rmode - !unsure!
//*rmode - the current video mode (# lines,progressive or interlaced, NTSC or PAL etc.) see libogc/gc/ogc/gx_struct.h
//w - !unsure!
// for the definition
//h -!unsure!
//w - Width of screen (Used as scale factor in converting fx to pixel coordinates)
//fx - X coordinate to draw on the screen
//h - Height of screen (Used as scale factor in converting fy to pixel coordinates)
//fy - Y coordinate to draw on the screen
//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)
//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) {
void drawdot(void *xfb, GXRModeObj *rmode, float w, float h, float fx, float fy, u32 color) {
       
        //*fb - !unsure!
//*fb - !unsure!
        //px - !unsure!
//px - !unsure!
        //py - !unsure!
//py - !unsure!
        //x - !unsure!
//x - !unsure!
        //y - !unsure!
//y - !unsure!
 
u32 *fb;
u32 *fb;
int px,py;
int px,py;
int x,y;
int x,y;
       
 
fb = (u32*)xfb;
fb = (u32*)xfb;
 
y = fy * rmode->xfbHeight / h;
y = fy * rmode->xfbHeight / h;
x = fx * rmode->fbWidth / w / 2;
x = fx * rmode->fbWidth / w / 2;
for(py=y-4; py<=(y+4); py++) {
for(py=y-4; py<=(y+4); py++) {
if(py < 0 || py >= rmode->xfbHeight)
if(py < 0 || py >= rmode->xfbHeight)
Line 79: Line 81:
}
}
}
}
 
}
}


int evctr = 0;
int evctr = 0;
void countevs(int chan, const WPADData *data) {
void countevs(int chan, const WPADData *data) {
evctr++;
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) {
int main(int argc, char **argv) {
int res;
void *xfb[2];
void *xfb[2];
u32 type;
u32 type;
int i;
int fbi = 0;
int fbi = 0;
float theta;
WPADData *wd;
VIDEO_Init();
VIDEO_Init();
PAD_Init();
PAD_Init();
WPAD_Init();
WPAD_Init();
 
rmode = VIDEO_GetPreferredMode(NULL);
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[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
xfb[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
xfb[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
VIDEO_Configure(rmode);
VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(xfb);
VIDEO_SetNextFramebuffer(xfb);
Line 113: Line 200:
VIDEO_WaitVSync();
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
 
SYS_SetResetCallback(reload);
SYS_SetResetCallback(reload);
SYS_SetPowerCallback(shutdown);
SYS_SetPowerCallback(shutdown);
WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR);
WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(0, rmode->fbWidth, rmode->xfbHeight);
WPAD_SetVRes(0, rmode->fbWidth, rmode->xfbHeight);
while(!doreload && !dooff) {
while(!doreload && !dooff) {
CON_Init(xfb[fbi],0,0,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
CON_Init(xfb[fbi],0,0,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
Line 125: Line 212:
printf("\n\n\n");
printf("\n\n\n");
WPAD_ReadPending(WPAD_CHAN_ALL, countevs);
WPAD_ReadPending(WPAD_CHAN_ALL, countevs);
res = WPAD_Probe(0, &type);
int wiimote_connection_status = WPAD_Probe(0, &type);
switch(res) {
print_wiimote_connection_status(wiimote_connection_status);
case WPAD_ERR_NO_CONTROLLER:
 
printf("  Wiimote not connected\n");
printf(" Event count: %d\n",evctr);
break;
if(wiimote_connection_status == WPAD_ERR_NONE) {
case WPAD_ERR_NOT_READY:
print_and_draw_wiimote_data(xfb[fbi]);
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) {
                        //Makes the var wd point to the data on the wiimote
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");
}
}
                        //ir.valid - TRUE is the wiimote is pointing at the screen, else it is false
if(wd->ir.valid) {
                                //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);
} 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);
printf("  Buttons down:\n  ");
                        //btns_h - returns (in a binary sequence) which buttons are being held down
                        //Notice the single "&", compares the two binary numbers, if the "a" slot is 1, then it returns true.
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);
}
                        //sets flag for you to exit back to the homebrew channel
if(wd->btns_h & WPAD_BUTTON_1) doreload=1;
}
}
VIDEO_SetNextFramebuffer(xfb[fbi]);
VIDEO_SetNextFramebuffer(xfb[fbi]);
Line 220: Line 226:
if(doreload) return 0;
if(doreload) return 0;
if(dooff) SYS_ResetSystem(SYS_SHUTDOWN,0,0);
if(dooff) SYS_ResetSystem(SYS_SHUTDOWN,0,0);
 
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>
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