How to use the Wiimote (Commented): Difference between revisions
Jump to navigation
Jump to search
CloneDeath (talk | contribs) mNo edit summary |
little refactoring: make each function to fit on screen. |
||
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 properly shutdown the system. | ||
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 - !unsure! | ||
Line 53: | Line 53: | ||
//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! | |||
//px - !unsure! | |||
//py - !unsure! | |||
//x - !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 79: | ||
} | } | ||
} | } | ||
} | } | ||
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) { | ||
void *xfb[2]; | void *xfb[2]; | ||
u32 type; | u32 type; | ||
int fbi = 0; | int fbi = 0; | ||
VIDEO_Init(); | VIDEO_Init(); | ||
PAD_Init(); | PAD_Init(); | ||
WPAD_Init(); | WPAD_Init(); | ||
rmode = VIDEO_GetPreferredMode(NULL); | rmode = VIDEO_GetPreferredMode(NULL); | ||
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 198: | ||
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 210: | ||
printf("\n\n\n"); | printf("\n\n\n"); | ||
WPAD_ReadPending(WPAD_CHAN_ALL, countevs); | 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); | printf(" Event count: %d\n",evctr); | ||
if( | if(wiimote_connection_status == WPAD_ERR_NONE) { | ||
print_and_draw_wiimote_data(xfb[fbi]); | |||
} | } | ||
VIDEO_SetNextFramebuffer(xfb[fbi]); | VIDEO_SetNextFramebuffer(xfb[fbi]); | ||
Line 220: | Line 224: | ||
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> |
Revision as of 15:21, 28 July 2008
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 if you really know what it means, and no obvious comments.
Wrong:
//Declares Integer 'dooff' and sets to Zero" int doreload=0, dooff=0;
Correct:
//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 properly shutdown the system.
void shutdown(void) {
dooff=1;
}
//Draw a square on the screen (May draw rectangles as well, I am uncertain).
//*xfb - !unsure!
//*rmode - !unsure!
//w - !unsure!
//h -!unsure!
//fx - X coordinate to draw on the screen
//fy - Y coordinate to draw on the screen
//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);
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