int GameLauncher::loadGameToMemory(const discHeader *header) { if(!header) return INVALID_INPUT; //! initialize the RPL/RPX table first entry to zero + 1 byte for name zero termination //! just in case no RPL/RPX are found, though it wont boot then anyway memset(RPX_RPL_ARRAY, 0, sizeof(s_rpx_rpl) + 1); DirList rpxList(header->gamepath + RPX_RPL_PATH, ".rpx", DirList::Files); if(rpxList.GetFilecount() == 0) { log_printf("RPX file not found!\n"); return RPX_NOT_FOUND; } if(rpxList.GetFilecount() != 1) { log_printf("Warning: Too many RPX files in the folder! Found %i files! Using first one.\n", rpxList.GetFilecount()); //return TOO_MANY_RPX_NOT_FOUND; } u32 entryIndex = 0; std::string rpxName; std::vector<std::string> rplImportList; DirList rplList(header->gamepath + RPX_RPL_PATH, ".rpl", DirList::Files); int result = LoadRpxRplToMem(rpxList.GetFilepath(0), rpxList.GetFilename(0), true, entryIndex++, rplImportList); if(result < 0) { log_printf("Failed loading RPX file %s, error %i\n", rpxList.GetFilepath(0), result); return result; } rpxName = rpxList.GetFilename(0); //! get all imports from the RPX GetRpxImports((s_rpx_rpl *)(RPX_RPL_ARRAY), rplImportList); for(int i = 0; i < rplList.GetFilecount(); i++) { result = LoadRpxRplToMem(rplList.GetFilepath(i), rplList.GetFilename(i), false, entryIndex++, rplImportList); if(result < 0) { log_printf("Failed loading RPL file %s, error %i\n", rplList.GetFilepath(0), result); return result; } } //! TODO: clean this path creation up std::string game_dir = header->gamepath; size_t pos = game_dir.rfind('/'); if(pos != std::string::npos) game_dir = game_dir.substr(pos + 1); //! set the save game path from the gamenames path std::string saveGamePath = CSettings::getValueAsString(CSettings::GameSavePath) + "/" + game_dir; std::string saveGamePathCommon; std::string saveGamePathUser; if(CSettings::getValueAsU8(CSettings::GameSaveMode) == GAME_SAVES_SHARED) { saveGamePathUser = "******"; saveGamePathCommon = "c"; } else { /* get persistent ID - thanks to Maschell */ unsigned int nn_act_handle; unsigned long (*GetPersistentIdEx)(unsigned char); int (*GetSlotNo)(void); void (*nn_Initialize)(void); void (*nn_Finalize)(void); OSDynLoad_Acquire("nn_act.rpl", &nn_act_handle); OSDynLoad_FindExport(nn_act_handle, 0, "GetPersistentIdEx__Q2_2nn3actFUc", &GetPersistentIdEx); OSDynLoad_FindExport(nn_act_handle, 0, "GetSlotNo__Q2_2nn3actFv", &GetSlotNo); OSDynLoad_FindExport(nn_act_handle, 0, "Initialize__Q2_2nn3actFv", &nn_Initialize); OSDynLoad_FindExport(nn_act_handle, 0, "Finalize__Q2_2nn3actFv", &nn_Finalize); nn_Initialize(); // To be sure that it is really Initialized unsigned char slotno = GetSlotNo(); unsigned int persistentID = GetPersistentIdEx(slotno); nn_Finalize(); //must be called an equal number of times to nn_Initialize char persistentIdString[10]; snprintf(persistentIdString, sizeof(persistentIdString), "%08X", persistentID); saveGamePathUser = persistentIdString; saveGamePathCommon = "common"; } CreateSubfolder((saveGamePath + "/" + saveGamePathUser).c_str()); CreateSubfolder((saveGamePath + "/" + saveGamePathCommon).c_str()); std::string tempPath = CSettings::getValueAsString(CSettings::GamePath); //! remove "sd:" and replace with "/vol/external01" pos = tempPath.find('/'); if(pos != std::string::npos) tempPath = std::string(CAFE_OS_SD_PATH) + tempPath.substr(pos); game_paths_t *game_paths = (game_paths_t *)GAME_PATH_STRUCT; //! set pointer to firth path and copy it game_paths->os_game_path_base = (char*)(game_paths + 1); strcpy(game_paths->os_game_path_base, tempPath.c_str()); //! set pointer to next path and copy it game_paths->os_save_path_base = game_paths->os_game_path_base + tempPath.size() + 1; tempPath = CSettings::getValueAsString(CSettings::GameSavePath); //! remove "sd:" and replace with "/vol/external01" pos = tempPath.find('/'); if(pos != std::string::npos) tempPath = std::string(CAFE_OS_SD_PATH) + tempPath.substr(pos); strcpy(game_paths->os_save_path_base, tempPath.c_str()); //! set pointer to next path and copy it game_paths->game_dir = game_paths->os_save_path_base + tempPath.size() + 1; strcpy(game_paths->game_dir, game_dir.c_str()); //! set pointer to next path and copy it game_paths->save_dir_common = game_paths->game_dir + game_dir.size() + 1; strcpy(game_paths->save_dir_common, saveGamePathCommon.c_str()); //! set pointer to next path and copy it game_paths->save_dir_user = game_paths->save_dir_common + saveGamePathCommon.size() + 1; strcpy(game_paths->save_dir_user, saveGamePathUser.c_str()); log_printf("game_paths->os_game_path_base: %s\n", game_paths->os_game_path_base); log_printf("game_paths->os_save_path_base: %s\n", game_paths->os_save_path_base); log_printf("game_paths->game_dir: %s\n", game_paths->game_dir); log_printf("game_paths->save_dir_common: %s\n", game_paths->save_dir_common); log_printf("game_paths->save_dir_user: %s\n", game_paths->save_dir_user); LoadXmlParameters(&cosAppXmlInfoStruct, rpxName.c_str(), (header->gamepath + RPX_RPL_PATH).c_str()); DCFlushRange((void*)&cosAppXmlInfoStruct, sizeof(ReducedCosAppXmlInfo)); log_printf("XML Launching Parameters\n"); log_printf("rpx_name: %s\n", cosAppXmlInfoStruct.rpx_name); log_printf("version_cos_xml: %i\n", cosAppXmlInfoStruct.version_cos_xml); log_printf("os_version: %08X%08X\n", (unsigned int)(cosAppXmlInfoStruct.os_version >> 32), (unsigned int)(cosAppXmlInfoStruct.os_version & 0xFFFFFFFF)); log_printf("title_id: %08X%08X\n", (unsigned int)(cosAppXmlInfoStruct.title_id >> 32), (unsigned int)(cosAppXmlInfoStruct.title_id & 0xFFFFFFFF)); log_printf("app_type: %08X\n", cosAppXmlInfoStruct.app_type); log_printf("cmdFlags: %08X\n", cosAppXmlInfoStruct.cmdFlags); log_printf("max_size: %08X\n", cosAppXmlInfoStruct.max_size); log_printf("avail_size: %08X\n", cosAppXmlInfoStruct.avail_size); log_printf("codegen_size: %08X\n", cosAppXmlInfoStruct.codegen_size); log_printf("codegen_core: %08X\n", cosAppXmlInfoStruct.codegen_core); log_printf("max_codesize: %08X\n", cosAppXmlInfoStruct.max_codesize); log_printf("overlay_arena: %08X\n", cosAppXmlInfoStruct.overlay_arena); log_printf("sdk_version: %i\n", cosAppXmlInfoStruct.sdk_version); log_printf("title_version: %08X\n", cosAppXmlInfoStruct.title_version); return 0; }
int GameLauncher::loadGameToMemory(const discHeader *header) { if(!header) return INVALID_INPUT; //! initialize our tables required for the games memoryInitAreaTable(); rpxRplTableInit(); DirList rpxList(header->gamepath + RPX_RPL_PATH, ".rpx", DirList::Files); if(rpxList.GetFilecount() == 0) { log_printf("RPX file not found!\n"); return RPX_NOT_FOUND; } if(rpxList.GetFilecount() != 1) { log_printf("Warning: Too many RPX files in the folder! Found %i files! Using first one.\n", rpxList.GetFilecount()); //return TOO_MANY_RPX_NOT_FOUND; } u32 entryIndex = 0; std::string rpxName; std::vector<std::string> rplImportList; std::set<int> rplImportFileIdx; DirList rplList(header->gamepath + RPX_RPL_PATH, ".rpl", DirList::Files); int result = LoadRpxRplToMem(rpxList.GetFilepath(0), rpxList.GetFilename(0), true, entryIndex++, rplImportList); if(result < 0) { log_printf("Failed loading RPX file %s, error %i\n", rpxList.GetFilepath(0), result); return result; } rpxName = rpxList.GetFilename(0); //! get all imports from the RPX GetRpxImports(rpxRplTableGet(), rplImportList); for(int i = 0; i < rplList.GetFilecount(); i++) { rplImportFileIdx.insert(i); } //! check for static rpls and load them bool importsAdded; do { importsAdded = false; for(std::set<int>::iterator it = rplImportFileIdx.begin(); it != rplImportFileIdx.end();) { int num = *it; if(std::find(rplImportList.begin(), rplImportList.end(), rplList.GetFilename(num)) != rplImportList.end()) { result = LoadRpxRplToMem(rplList.GetFilepath(num), rplList.GetFilename(num), false, entryIndex++, rplImportList); if(result < 0) { log_printf("Failed loading RPL file %s, error %i\n", rplList.GetFilepath(num), result); return result; } importsAdded = true; it = rplImportFileIdx.erase(it); } else { it++; } } } while (importsAdded); //! load dynamic rpls for(std::set<int>::iterator it = rplImportFileIdx.begin(); it != rplImportFileIdx.end(); it++) { int num = *it; result = LoadRpxRplToMem(rplList.GetFilepath(num), rplList.GetFilename(num), false, entryIndex++, rplImportList); if(result < 0) { log_printf("Failed loading RPL file %s, error %i\n", rplList.GetFilepath(num), result); return result; } } //! TODO: clean this path creation up std::string game_dir = header->gamepath; size_t pos = game_dir.rfind('/'); if(pos != std::string::npos) game_dir = game_dir.substr(pos + 1); //! set the save game path from the gamenames path std::string saveGamePath = CSettings::getValueAsString(CSettings::GameSavePath) + "/" + game_dir; std::string saveGamePathCommon; std::string saveGamePathUser; if(CSettings::getValueAsU8(CSettings::GameSaveMode) == GAME_SAVES_SHARED) { saveGamePathUser = "******"; saveGamePathCommon = "c"; } else { /* get persistent ID - thanks to Maschell */ unsigned int nn_act_handle; unsigned long (*GetPersistentIdEx)(unsigned char); int (*GetSlotNo)(void); void (*nn_Initialize)(void); void (*nn_Finalize)(void); OSDynLoad_Acquire("nn_act.rpl", &nn_act_handle); OSDynLoad_FindExport(nn_act_handle, 0, "GetPersistentIdEx__Q2_2nn3actFUc", &GetPersistentIdEx); OSDynLoad_FindExport(nn_act_handle, 0, "GetSlotNo__Q2_2nn3actFv", &GetSlotNo); OSDynLoad_FindExport(nn_act_handle, 0, "Initialize__Q2_2nn3actFv", &nn_Initialize); OSDynLoad_FindExport(nn_act_handle, 0, "Finalize__Q2_2nn3actFv", &nn_Finalize); nn_Initialize(); // To be sure that it is really Initialized unsigned char slotno = GetSlotNo(); unsigned int persistentID = GetPersistentIdEx(slotno); nn_Finalize(); //must be called an equal number of times to nn_Initialize char persistentIdString[10]; snprintf(persistentIdString, sizeof(persistentIdString), "%08X", persistentID); saveGamePathUser = persistentIdString; saveGamePathCommon = "common"; } CreateSubfolder((saveGamePath + "/" + saveGamePathUser).c_str()); CreateSubfolder((saveGamePath + "/" + saveGamePathCommon).c_str()); std::string tempPath = CSettings::getValueAsString(CSettings::GamePath); //! remove "sd:" and replace with "/vol/external01" pos = tempPath.find('/'); if(pos != std::string::npos) tempPath = std::string(CAFE_OS_SD_PATH) + tempPath.substr(pos); strlcpy(gamePathStruct.os_game_path_base, tempPath.c_str(), sizeof(gamePathStruct.os_game_path_base)); tempPath = CSettings::getValueAsString(CSettings::GameSavePath); //! remove "sd:" and replace with "/vol/external01" pos = tempPath.find('/'); if(pos != std::string::npos) tempPath = std::string(CAFE_OS_SD_PATH) + tempPath.substr(pos); strlcpy(gamePathStruct.os_save_path_base, tempPath.c_str(), sizeof(gamePathStruct.os_save_path_base)); strlcpy(gamePathStruct.game_dir, game_dir.c_str(), sizeof(gamePathStruct.game_dir)); strlcpy(gamePathStruct.save_dir_common, saveGamePathCommon.c_str(), sizeof(gamePathStruct.save_dir_common)); strlcpy(gamePathStruct.save_dir_user, saveGamePathUser.c_str(), sizeof(gamePathStruct.save_dir_user)); log_printf("gamePathStruct.os_game_path_base: %s\n", gamePathStruct.os_game_path_base); log_printf("gamePathStruct.os_save_path_base: %s\n", gamePathStruct.os_save_path_base); log_printf("gamePathStruct.game_dir: %s\n", gamePathStruct.game_dir); log_printf("gamePathStruct.save_dir_common: %s\n", gamePathStruct.save_dir_common); log_printf("gamePathStruct.save_dir_user: %s\n", gamePathStruct.save_dir_user); LoadXmlParameters(&cosAppXmlInfoStruct, rpxName.c_str(), (header->gamepath + RPX_RPL_PATH).c_str()); DCFlushRange((void*)&cosAppXmlInfoStruct, sizeof(ReducedCosAppXmlInfo)); log_printf("XML Launching Parameters\n"); log_printf("rpx_name: %s\n", cosAppXmlInfoStruct.rpx_name); log_printf("version_cos_xml: %i\n", cosAppXmlInfoStruct.version_cos_xml); log_printf("os_version: %08X%08X\n", (unsigned int)(cosAppXmlInfoStruct.os_version >> 32), (unsigned int)(cosAppXmlInfoStruct.os_version & 0xFFFFFFFF)); log_printf("title_id: %08X%08X\n", (unsigned int)(cosAppXmlInfoStruct.title_id >> 32), (unsigned int)(cosAppXmlInfoStruct.title_id & 0xFFFFFFFF)); log_printf("app_type: %08X\n", cosAppXmlInfoStruct.app_type); log_printf("cmdFlags: %08X\n", cosAppXmlInfoStruct.cmdFlags); log_printf("max_size: %08X\n", cosAppXmlInfoStruct.max_size); log_printf("avail_size: %08X\n", cosAppXmlInfoStruct.avail_size); log_printf("codegen_size: %08X\n", cosAppXmlInfoStruct.codegen_size); log_printf("codegen_core: %08X\n", cosAppXmlInfoStruct.codegen_core); log_printf("max_codesize: %08X\n", cosAppXmlInfoStruct.max_codesize); log_printf("overlay_arena: %08X\n", cosAppXmlInfoStruct.overlay_arena); log_printf("sdk_version: %i\n", cosAppXmlInfoStruct.sdk_version); log_printf("title_version: %08X\n", cosAppXmlInfoStruct.title_version); return 0; }