出发点: 传统的游戏模拟器(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 { public static native void loadGame(byte[] data) throws IllegalStateException; public static native void destroyGame() throws IllegalStateException; public static native void sendEvent(int keyState,int event) throws IllegalStateException; public static native void setVideoSurface(Surface surface) throws IllegalStateException; public static native void setSkipFrame(int skip); }
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) { jclass exceptionClass = env->FindClass(className); if (exceptionClass == NULL) { __android_log_print(ANDROID_LOG_ERROR, TAG, "Unable to find exception class %s", className); return -1; } if (env->ThrowNew(exceptionClass, msg) != JNI_OK) { __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed throwing '%s' '%s'", className, msg); } return 0; }
6. 最好是把native方法一次性注册。
运行结果:
下载:魂斗罗