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 街机游戏安卓盒子,游戏盒子实现双人对打,四人对打方案

FBA 街机游戏安卓盒子,游戏盒子实现双人对打,四人对打方案

ppsspp的游戏到哪里下载呀!

31.用 CSS 的动画原理,创作一个乒乓球对打动画

如何利用 CSS 的动画原理,创作一个乒乓球对打动画

linux怎么安装软件包?我在ppsspp官网下了几个软件,然后怎么在linux下安装(使用)?