出發點: 傳統的遊戲模擬器(FC,neo,fba,gba,mame,n64,nds,psp)都陸陸續續移植到Android手機裡了,然後把遊戲ROM儲存到SD卡裡通過模擬器運行,但是考慮到手機遊戲要遵循快進快出的原則,所以我在此基礎上實現了如下幾點微創新
1. 直接把遊戲ROM放在Android的APK裡,點擊應用就開始遊戲,省去了通過檔案瀏覽器尋找遊戲的過程。
2. 通過插值演算法把遊戲畫面放大到支援Android平板解析度
3. 充分利用手機重力感應器的專屬特性(相對於其它兩塊屏,PC顯示器和電視),通過手機sensor作為方向鍵
移植步驟:
1. 選擇開源的基於Linux的FC遊戲模擬器
2. 實現java訪問C層的JNI介面
public class Game {</p><p>public static native void loadGame(byte[] data) throws IllegalStateException;<br />public static native void destroyGame() throws IllegalStateException;<br />public static native void sendEvent(int keyState,int event) throws IllegalStateException;<br />public static native void setVideoSurface(Surface surface) throws IllegalStateException;<br />public static native void setSkipFrame(int skip);<br />}
3. Android的Acitvity Layout布局時用RalativieLayout,將五項鍵和按鍵分別浮動在遊戲介面的兩端。
常用的JNI實戰經驗可以通過jni spec擷取,這裡要注意以下幾點:
1. 如果定義的是static native方法,在C/C++代碼裡不能用GetObjectClass擷取對象的類
2. 如果是Java和C/C++層需要共用記憶體,可以用GetDirectBufferAdress() API
3. jchar佔兩個位元組(typedef unsigned short jchar;)
4. 全域引用記得釋放(NewGlobalRef,DeleteGlobalRef)
5 可以在jni裡(也就是在C/C++層)拋出Java需要捕獲的異常,如:
int jniThrowException(JNIEnv* env, const char* className, const char* msg) {<br /> jclass exceptionClass = env->FindClass(className);<br /> if (exceptionClass == NULL) {<br /> __android_log_print(ANDROID_LOG_ERROR,<br /> TAG,<br /> "Unable to find exception class %s",<br /> className);<br /> return -1;<br /> }<br /> if (env->ThrowNew(exceptionClass, msg) != JNI_OK) {<br /> __android_log_print(ANDROID_LOG_ERROR,<br /> TAG,<br /> "Failed throwing '%s' '%s'",<br /> className, msg);<br /> }<br /> return 0;<br />}
6. 最好是把native方法一次性註冊。
運行結果:
下載:魂鬥羅