SDL支援一個現在不常見的搖桿裝置:軌跡球(Trackball)
說到那顆球嘛,我就想到以前有些滑鼠的「球」是長在上面的。
下面是SDL中取得軌跡球的函式。
int SDL_JoystickGetBall(SDL_Joystick * joystick, int ball, int *dx, int *dy);這函式長得和其它的傢伙不同,它有兩個「回傳值」,嗯,我是說我們重視是dx和dy這兩個值。
但這下問題來了,我們要怎麼把它們變成一個變數,好讓它們看起來和其它傢伙一樣?
問題:將兩個32-bit的整數合成一個64-bit的整數
簡單的想法就是把第一個數 位移 32個bit,再和第二個數黏起來。
int a, b;
long long fusion = (long long(a) << 32) | b;
int a2 = fusion >> 32;
int b2 = fusion;不過,在碰上了負數時我們有了麻煩,融合解除後第一個數和原來的不同。
雖然,如果我是敵方,用了融合解除後能把一隻怪獸變殘廢會很高興啦...
用一個比較簡單的模型來思考好了,比如把兩個4-bit裝進1個8-bit中。
對a來說:0111 ==轉成8-bit=> 0000 0111 ==位移=> 0111 0000
對b來說:1001 ==轉成8-bit=> 1111 1001
很明顯的,負數在轉成8-bit後會補1而非0,所以造成我們的融合的數值不正確。(所以有問題的是融合)
那麼,我們要用哪一個方法去除多出來的1,但又不影響我們的原本的值呢?
仔細想了一個下午(喂!),最後想到讓b和0000 1111作AND運算就能達成這個目的。
套用在32-bit合成64-bit中,就是前32個bit是0,後32個bit是1。
int a, b;
long long bx = b;
if(b < 0) {
bx &= 0xffffffff;
}
long long fusion = (long long(a) << 32) | bx;
int a2 = fusion >> 32;
int b2 = fusion;但寫完後...突然想到...用struct來處理不是更簡單嗎?