2008年1月14日 星期一

宅男遇上 Wii remote

前幾天看到同事分享 Johnny Lee的影片。心中有蠻大的震憾。一直認為 Wii Remote 已經很神奇了…沒想到還有那麼多的玩法…果然厲害。就開始想在自己的機器上玩玩 Wii Remote.

沒想到一切都是如此的美好: Ubuntu 已經有了 CWiid 的 package.
直接安裝後,把 bluetooth 打開,就可以玩了

身為一名陽光宅男…當然好好的研究一下這個好玩的東西…
也就寫了一支小小的程式…可以依 Wii remote 的水平改變小 Icon 的位置。

Filename: wii_toy.c

#include <wiimote.h>
#include <wiimote_api.h>
#include <Ecore_Evas.h>
#include <Ecore.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define WIDTH 800
#define HEIGHT 600

Ecore_Evas * ee;
Evas * evas;

struct remoter {
Evas_Object * o;
wiimote_t *wii;
double x,y,size;
};

inline void set_wiiremote(wiimote_t *wii) {
wii->led.one = 1;
wii->mode.ir = 1;
wii->mode.acc =1;
}

inline void change_position(struct remoter *handle) {
if ( abs(handle->wii->tilt.x) <= 90 &&
abs (handle->wii->tilt.y) <= 90) {

handle->x += (double)handle->wii->tilt.x/10.0f;
handle->y += (double)handle->wii->tilt.y/10.0f;
}
handle->x = handle->x <= 0 ? 0 : handle->x >= WIDTH - handle->size? WIDTH-handle->size : handle->x;
handle->y = handle->y <= 0 ? 0 : handle->y >= HEIGHT - handle->size? HEIGHT-handle->size : handle->y;


// fprintf(stderr, "remote: x=%3.3f y=%3.3f\n",handle->x,handle->y);
evas_object_move(handle->o, handle->x,handle->y);
}

inline void show_status(wiimote_t *wii) {
fprintf(stderr, "AXIS x=%03d y=%03d z=%03d\n",
wii->axis.x,
wii->axis.y,
wii->axis.z);
fprintf(stderr, "TILT x=%.3f y=%.3f z=%.3f\n",
wii->tilt.x,
wii->tilt.y,
wii->tilt.z);
fprintf(stderr, "FORCE x=%.3f y=%.3f z=%.3f\n",
wii->force.x,
wii->force.y,
wii->force.z);
fprintf(stderr,"\n");
}

int scan_wii_event(void *data) {
struct remoter *handle=(struct remoter *)data;
if (wiimote_is_open(handle->wii)) {
if (wiimote_update(handle->wii) < 0) {
printf("Update Failed!! Exit!!\n");
wiimote_disconnect(handle->wii);
exit(1);
}
if (handle->wii->keys.home) {
printf("Home pressed!! Exit!!\n");
wiimote_disconnect(handle->wii);
exit(1);
}
change_position(handle);
//show_status(handle->wii);
}
return 1;
}

int main(int argc,char **argv) {
struct remoter handle;
if (argc < 2) {
fprintf(stderr, "Usage: test1 BDADDR\n");
exit(1);
}
Evas_Object * background;
ecore_evas_init();

ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, WIDTH, HEIGHT);
ecore_evas_title_set(ee, "Tick's Wii Toy");
// ecore_evas_borderless_set(ee, 1); // borderless
ecore_evas_borderless_set(ee, 0); // border
ecore_evas_show(ee);


evas = ecore_evas_get(ee);
evas_font_path_append(evas, "fonts/");


background = evas_object_rectangle_add(evas);
evas_object_color_set(background,30,30,30,255);
evas_object_resize(background, WIDTH, HEIGHT);
evas_object_move( background,0 ,0 );
evas_object_focus_set(background, 1);
evas_object_show( background);

handle.size = 64;
handle.x=(WIDTH-handle.size)/2;
handle.y=(HEIGHT-handle.size)/2;
handle.o = evas_object_image_add(evas);
evas_object_image_file_set (handle.o, "/home/tick/work/e17/icon.png" ,NULL);
if (evas_object_image_load_error_get(handle.o)) {
printf("Evas can't load PNG files. Check Evas has PNG\n");
return 1;
}
evas_object_color_set(handle.o,255,255,255,128);
evas_object_move(handle.o, handle.x,handle.y);
evas_object_resize(handle.o,handle.size,handle.size);
evas_object_image_fill_set(handle.o, 0, 0, handle.size, handle.size);
evas_object_show(handle.o);

printf("Please press 1+2 to connect Wii remote!!\n");
handle.wii = wiimote_open(argv[1]);
if (!handle.wii) {
fprintf(stderr, "unable to open wiimote:\n");
exit(1);
}
printf("Connecting.......\n");
set_wiiremote(handle.wii);
ecore_timer_add(.01,scan_wii_event, &handle);
ecore_main_loop_begin();

return 0;
}




使用:
1.先下 /etc/init.d/bluetooth start 打開bluetooth
2.按下 Wii remote 的 1+2 鍵
3.當 Wii remote 的Led 還在閃時,做 hcitool scan 找出你的 remote bdaddr
4. compile 完程式後,打 ./wii_toy 00:1A:E9:3B:CA:49 <--- 每個人的 wii remote 不一樣 就可以玩了

tick@tock:~/work/e17>hcitool scan
Scanning ...
00:1A:E9:3B:CA:49 Nintendo RVL-CNT-01
tick@tock:~/work/e17>gcc `pkg-config --libs ecore-evas evas` -I/usr/local/include/libcwiimote-0.4.0/libcwiimote/ -lcwiimote -lbluetooth -Wall -pipe -D_ENABLE_TILT -D_ENABLE_FORCE -g2 -o wii_toy wii_toy.c
tick@tock:~/work/e17>./wii_toy 00:1A:E9:3B:CA:49
Please press 1+2 to connect Wii remote!!
Connecting.......


有圖有真象

2008年1月13日 星期日

學習 Evas

這陣子開始需要用 Evas 寫一些東西…
個人覺得學一個 library 最快的方法就是去真的拿它去寫程式。
如我的一個好友常說的:學中作,作中學 ^^
所以就寫了支小小的玩具… 和大家分享…


亂畫一個方塊,設定一個重力場,和一個 boundary反彈機制. ( 和一些阻泥 (mark 掉了)) 加上一個色彩空間的旋轉。就玩起來了 ^^

程式:

Filename: toy.c

#include <Ecore_Evas.h>
#include <Ecore.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define WIDTH 400
#define HEIGHT 400

Ecore_Evas * ee;
Evas * evas;
Evas_Object * base_rect;

double rotation[3][3] = { {0 , 0 , 1},
{1, 0, 0},
{0 , 1, 0}
};

struct bouncer {
Evas_Object *o;
int w,h;
double xs,ys;
double x,y;
double color[3];
};

inline void change_color(struct bouncer *bounce) {
double X[3];
int i,j;
int R,G,B;
for (i=0;i<3;i++) {
X[i]=bounce->color[i];
bounce->color[i]=0;
}
for (i=0;i<3;i++) {
for (j=0;j<3;j++) {
bounce->color[i] += rotation[i][j]*X[j];
}
}
R=bounce->color[0] < 0 ? bounce->color[0] + 255: bounce->color[0];
G=bounce->color[1] < 0 ? bounce->color[1] + 255: bounce->color[1];
B=bounce->color[2] < 0 ? bounce->color[2] + 255: bounce->color[2];
evas_object_color_set( bounce->o , R, G, B, 255);
}

inline void center(struct bouncer *bounce,double *x,double *y) {
*x = bounce->x + bounce->w/2;
*y = bounce->y + bounce->h/2;
}

inline void grav(struct bouncer *bounce) {
const double G=300;
double Gx,Gy,Gs;
double x,y;
double dist;
center(bounce,&x,&y);

dist = pow(pow(WIDTH/2-x,2) + pow(HEIGHT/2-y,2),0.5);
Gs = G/pow(dist,2);
Gx = (WIDTH/2 - x)/dist;
Gy = (HEIGHT/2 -y)/dist;
Gx = Gx * Gs;
Gy = Gy * Gs;

bounce->xs += Gx;
bounce->ys += Gy;

// Slow down~~
//bounce->xs = abs(bounce->xs) > 13 ? bounce->xs *(1/ pow(bounce->xs-10,2)): bounce->xs;
//bounce->ys = abs(bounce->ys) > 13 ? bounce->ys *(1/ pow(bounce->ys-10,2)): bounce->ys;
printf ("x=%2.2f y=%2.2f dist=%4.2f Gs=%2.2f Gx=%2.2f Gy=%2.2f xs=%2.2f ys=%2.2f\n",x,y,dist,Gs,Gx,Gy,bounce->xs,bounce->ys);
}
inline void calculate_pos(struct bouncer *bounce) {
grav(bounce);
bounce->x += bounce->xs;
bounce->y += bounce->ys;

// bounce
bounce->xs = bounce->x >=0 ? bounce->x + bounce->w <= WIDTH ? bounce->xs : -bounce->xs : -bounce->xs;
bounce->ys = bounce->y >=0 ? bounce->y + bounce->h <= HEIGHT? bounce->ys : - bounce->ys : - bounce->ys;
}

int move(void *data) {
struct bouncer *bounce =(struct bouncer *)data;
calculate_pos(bounce);
evas_object_move(bounce->o,bounce->x,bounce->y);
change_color(bounce);
return 1;
}

int main() {
struct bouncer bounce;
ecore_evas_init();

ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, WIDTH, HEIGHT);
ecore_evas_title_set(ee, "Tick's Evas Study");
// ecore_evas_borderless_set(ee, 1); // borderless
ecore_evas_borderless_set(ee, 0); // border
ecore_evas_show(ee);


evas = ecore_evas_get(ee);
evas_font_path_append(evas, "fonts/");


bounce.o = evas_object_rectangle_add(evas);
bounce.w=bounce.h= (double)WIDTH/4;
bounce.x=(double)(WIDTH - bounce.w)/3;
bounce.y=(double)(HEIGHT- bounce.h)/6;
bounce.xs=-1.1; bounce.ys=1.1;
bounce.color[0]=128;
bounce.color[1]=64;
bounce.color[2]=255;
change_color(&bounce);
evas_object_resize( bounce.o, bounce.w, bounce.h);
evas_object_move( bounce.o,bounce.x,bounce.y);
evas_object_show( bounce.o);

ecore_timer_add((double)0.01,move,&bounce);

ecore_main_loop_begin();

return 0;
}


2008年1月9日 星期三

codecovert

Covert C code to Google prettyprint format

Filename: /usr/local/bin/codecovert

#!/bin/bash
for FF in $@;
do
if [ -e $FF ];then
echo Filename: $FF
echo "<pre class=\"prettyprint\">"
sed -e 's/&/\&amp;/g' -e 's/</\&lt;/g' -e 's/>/\&gt;/g' $FF
echo "</pre>"
fi
echo
done

Hello world


BITS 32

;section .text
;global _start
;_start:
jmp short two

one:
pop ecx ; using the db
; write
xor eax,eax
mov al, 4
xor ebx,ebx
mov bl, 1
xor edx, edx
mov dl, 13
int 0x80

;exit
xor eax,eax
mov al, 1
xor ebx, ebx
int 0x80

two:
call one
db "Hello_World!!"

Warning of "system" and "pipe"

I chatted with my friend about some security issues days before. I had mentioned about the function call "system" and "pipe" shall be avoid in many cases. It's very simple idea, but as I know many programmers even do not know it's very dangerous.
Please NEVER NEVER NEVER use this function to important programs.
NEVER allow user to touch the args, or PATH.
Please~~~



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void fake_ls(int args,char **argv) {
char buf[50];
char *ptr=buf;
int i;
sprintf(buf,"ls");
for (i=1;i<args;i++) {
ptr = buf + strlen(buf);
sprintf(ptr," %s",argv[i]);
}
printf("The command you send is: '%s'\n",buf);
system(buf);
}
int main (int args,char **argv) {
printf("argv=%p\n",argv);
fake_ls(args,argv);
}


you can use the following argument to execute
extra command: "-al\;cat /etc/passwd"
It's very easy to see how terrible it is. :-)