ppsspp双人对打实现原理
Posted 程序员入门进阶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ppsspp双人对打实现原理相关的知识,希望对你有一定的参考价值。
可以是多进程,也可以多线程。当前实现使用多线程。
Java_org_ppsspp_ppsspp_NativeApp_init
extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
(JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jstring jlangRegion, jstring japkpath,
jstring jdataDir, jstring jexternalStorageDir, jstring jexternalFilesDir, jstring jadditionalStorageDirs, jstring jlibraryDir, jstring jcacheDir, jstring jshortcutParam,
jint jandroidVersion, jstring jboard)
SetCurrentThreadName("androidInit");
// Makes sure we get early permission grants.
ProcessFrameCommands(env);
apkPath = GetJavaString(env, japkpath);
systemName = GetJavaString(env, jmodel);
langRegion = GetJavaString(env, jlangRegion);
externalStorageDir = GetJavaString(env, jexternalStorageDir);
additionalStorageDirsString = GetJavaString(env, jadditionalStorageDirs);
externalFilesDir = GetJavaString(env, jexternalFilesDir);
user_data_path = GetJavaString(env, jdataDir);
if (user_data_path.size() > 0)
user_data_path += "/";
library_path = GetJavaString(env, jlibraryDir) + "/";
shortcut_param = GetJavaString(env, jshortcutParam);
cacheDir = GetJavaString(env, jcacheDir);
buildBoard = GetJavaString(env, jboard);
androidVersion = jAndroidVersion;
deviceType = jdeviceType;
INFO_LOG(AUDIO, "lxm NativeApp.Init() library_path --%s", library_path.c_str());
pthread_t pt[5];
int i;
// for (i = 0; i < 5; i++)
pthread_create(&pt[0], NULL, &thread_fun1, (void *)i);
//
NativeInit_Ex(systemName,deviceType,langRegion,apkPath,user_data_path,externalStorageDir,externalFilesDir,additionalStorageDirsString,library_path,cacheDir,shortcut_param,androidVersion,buildBoard,false);
利用多线程,共享全局变量,完成通信。
extern "C" void NativeInit_Ex(std::string systemName,jint jdeviceType,std::string langRegion,std::string apkPath,std::string user_data_path,std::string externalStorageDir,
std::string externalFilesDir,std::string additionalStorageDirsString,
std::string library_path,std::string cacheDir,std::string shortcut_param,jint jAndroidVersion,
std::string buildBoard,bool isSecond)
// INFO_LOG(AUDIO, "lxm setisSecondLib111.%x", &isSecondLib);
isSecondLib=isSecond;
boardName = buildBoard;
EARLY_LOG("NativeApp.init(): isSecondLib lxm: %d-------%x", isSecondLib,&isSecondLib);
EARLY_LOG("NativeApp.init(): isSecondLib lxm: %s-------%x", boardName.c_str(),&boardName);
EARLY_LOG("NativeApp.init() -- begin");
PROFILE_INIT();
std::lock_guard<std::mutex> guard(renderLock);
renderer_inited = false;
androidVersion = jAndroidVersion;
deviceType = jdeviceType;
left_joystick_x_async = 0;
left_joystick_y_async = 0;
right_joystick_x_async = 0;
right_joystick_y_async = 0;
hat_joystick_x_async = 0;
hat_joystick_y_async = 0;
VFSRegister("", new ZipAssetReader(apkPath.c_str(), "assets/"));
EARLY_LOG("NativeApp.init(): device name: '%s'", systemName.c_str());
g_externalDir = externalStorageDir;
g_extFilesDir = externalFilesDir;
if (!additionalStorageDirsString.empty())
SplitString(additionalStorageDirsString, ':', g_additionalStorageDirs);
for (auto &str : g_additionalStorageDirs)
EARLY_LOG("Additional storage: %s", str.c_str());
EARLY_LOG("NativeApp.init(): External storage path: %s", externalStorageDir.c_str());
EARLY_LOG("NativeApp.init(): Launch shortcut parameter: %s", shortcut_param.c_str());
std::string app_name;
std::string app_nice_name;
std::string version;
bool landscape;
// Unfortunately, on the Samsung Galaxy S7, this isn't in /proc/cpuinfo.
// We also can't read it from __system_property_get.
if (buildBoard == "universal8890")
cpu_info.sQuirks.bExynos8890DifferingCachelineSizes = true;
NativeGetAppInfo(&app_name, &app_nice_name, &landscape, &version);
// If shortcut_param is not empty, pass it as additional arguments to the NativeInit() method.
// NativeInit() is expected to treat extra argument as boot_filename, which in turn will start game immediately.
// NOTE: Will only work if ppsspp started from Activity.onCreate(). Won't work if ppsspp app start from onResume().
std::vector<const char *> args;
std::vector<std::string> temp;
args.push_back(app_name.c_str());
if (!shortcut_param.empty())
parse_args(temp, shortcut_param);
for (const auto &arg : temp)
args.push_back(arg.c_str());
NativeInit((int)args.size(), &args[0], user_data_path.c_str(), externalStorageDir.c_str(), cacheDir.c_str());
// No need to use EARLY_LOG anymore.
retry:
// Now that we've loaded config, set javaGL.
javaGL = NativeQueryConfig("androidJavaGL") == "true";
switch (g_Config.iGPUBackend)
case (int)GPUBackend::OPENGL:
useCPUThread = true;
if (javaGL)
INFO_LOG(SYSTEM, "NativeApp.init() -- creating OpenGL context (JavaGL)");
graphicsContext = new AndroidJavaEGLGraphicsContext();
else
graphicsContext = new AndroidEGLGraphicsContext();
break;
case (int)GPUBackend::VULKAN:
INFO_LOG(SYSTEM, "NativeApp.init() -- creating Vulkan context");
useCPUThread = false; // The Vulkan render manager manages its own thread.
// We create and destroy the Vulkan graphics context in the "EGL" thread.
AndroidVulkanContext *ctx = new AndroidVulkanContext();
if (!ctx->InitAPI())
INFO_LOG(SYSTEM, "Failed to initialize Vulkan, switching to OpenGL");
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
SetGPUBackend(GPUBackend::OPENGL);
goto retry;
else
graphicsContext = ctx;
break;
case GPUCORE_NULL:
INFO_LOG(SYSTEM, "NativeApp.init() -- creating null context");
graphicsContext = new AndroidNullGraphicsContext();
break;
default:
ERROR_LOG(SYSTEM, "NativeApp.init(): iGPUBackend %d not supported. Switching to OpenGL.", (int)g_Config.iGPUBackend);
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
goto retry;
if (useCPUThread)
INFO_LOG(SYSTEM, "NativeApp.init() - launching emu thread");
EmuThreadStart();
if (IsVRBuild())
Version gitVer(PPSSPP_GIT_VERSION);
InitVROnAndroid(gJvm, nativeActivity, gitVer.ToInteger(), "PPSSPP");
extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
(JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jstring jlangRegion, jstring japkpath,
jstring jdataDir, jstring jexternalStorageDir, jstring jexternalFilesDir, jstring jadditionalStorageDirs, jstring jlibraryDir, jstring jcacheDir, jstring jshortcutParam,
jint jAndroidVersion, jstring jboard)
SetCurrentThreadName("androidInit");
// Makes sure we get early permission grants.
ProcessFrameCommands(env);
apkPath = GetJavaString(env, japkpath);
systemName = GetJavaString(env, jmodel);
langRegion = GetJavaString(env, jlangRegion);
externalStorageDir = GetJavaString(env, jexternalStorageDir);
additionalStorageDirsString = GetJavaString(env, jadditionalStorageDirs);
externalFilesDir = GetJavaString(env, jexternalFilesDir);
user_data_path = GetJavaString(env, jdataDir);
if (user_data_path.size() > 0)
user_data_path += "/";
library_path = GetJavaString(env, jlibraryDir) + "/";
shortcut_param = GetJavaString(env, jshortcutParam);
cacheDir = GetJavaString(env, jcacheDir);
buildBoard = GetJavaString(env, jboard);
androidVersion = jAndroidVersion;
deviceType = jdeviceType;
INFO_LOG(AUDIO, "lxm NativeApp.Init() library_path --%s", library_path.c_str());
pthread_t pt[5];
int i;
// for (i = 0; i < 5; i++)
pthread_create(&pt[0], NULL, &thread_fun1, (void *)i);
//
NativeInit_Ex(systemName,deviceType,langRegion,apkPath,user_data_path,externalStorageDir,externalFilesDir,additionalStorageDirsString,library_path,cacheDir,shortcut_param,androidVersion,buildBoard,false);
最终都是使用:void NativeInit
不过在过程里面,依赖一个全局变量,来判断是哪个线程。
if (isSecondLib)
coreParam.enableSound = false;
else
coreParam.enableSound = g_Config.bEnableSound;
利用这个来做区分,可以直接区分出来是在哪个线程,从而进行多线程,设计对打:
if (!isSecondLib)
gJvm->AttachCurrentThread(&env, nullptr);
对打,使用开源项目:ggpo 项目,大家可以关注它的官网,了解具体实现。
以上是关于ppsspp双人对打实现原理的主要内容,如果未能解决你的问题,请参考以下文章
FBA 街机游戏安卓盒子,游戏盒子实现双人对打,四人对打方案