Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}