void retro_unload_game()
{
   if (!game)
      return;

   MDFNI_CloseGame();
}
Beispiel #2
0
/* Closes a game and frees memory. */
int CloseGame(void)
{
	if(!CurGame) return(0);

	GameThreadRun = 0;

	SDL_WaitThread(GameThread, NULL);

	if(MDFN_GetSettingB("autosave"))
	 MDFNI_SaveState(NULL, "ncq", NULL, NULL);

	MDFNI_CloseGame();

        KillGameInput();
	KillSound();

	CurGame = NULL;

	if(soundrecfn)
         MDFNI_EndWaveRecord();

	return(1);
}
void retro_unload_game()
{
    MDFNI_CloseGame();
}
MDFNGI *MDFNI_LoadGame(const char *force_module, const char *name)
{
    MDFNFILE GameFile;
    struct stat stat_buf;
    std::vector<FileExtensionSpecStruct> valid_iae;

    if(strlen(name) > 4 && (!strcasecmp(name + strlen(name) - 4, ".cue") || !strcasecmp(name + strlen(name) - 4, ".toc") || !strcasecmp(name + strlen(name) - 4, ".m3u")))
    {
        return(MDFNI_LoadCD(force_module, name));
    }

    if(!stat(name, &stat_buf) && !S_ISREG(stat_buf.st_mode))
    {
        return(MDFNI_LoadCD(force_module, name));
    }

    MDFNI_CloseGame();

    LastSoundMultiplier = 1;

    MDFNGameInfo = NULL;

    MDFN_printf(_("Loading %s...\n"),name);

    MDFN_indent(1);

    GetFileBase(name);

    // Construct a NULL-delimited list of known file extensions for MDFN_fopen()
    for(unsigned int i = 0; i < MDFNSystems.size(); i++)
    {
        const FileExtensionSpecStruct *curexts = MDFNSystems[i]->FileExtensions;

        // If we're forcing a module, only look for extensions corresponding to that module
        if(force_module && strcmp(MDFNSystems[i]->shortname, force_module))
            continue;

        if(curexts)
            while(curexts->extension && curexts->description)
            {
                valid_iae.push_back(*curexts);
                curexts++;
            }
    }
    {
        FileExtensionSpecStruct tmpext = { NULL, NULL };
        valid_iae.push_back(tmpext);
    }

    if(!GameFile.Open(name, &valid_iae[0], _("game")))
    {
        MDFNGameInfo = NULL;
        return 0;
    }

    if(!LoadIPS(GameFile, MDFN_MakeFName(MDFNMKF_IPS, 0, 0).c_str()))
    {
        MDFNGameInfo = NULL;
        GameFile.Close();
        return(0);
    }

    MDFNGameInfo = NULL;

    for(std::list<MDFNGI *>::iterator it = MDFNSystemsPrio.begin(); it != MDFNSystemsPrio.end(); it++)  //_unsigned int x = 0; x < MDFNSystems.size(); x++)
    {
        char tmpstr[256];
        trio_snprintf(tmpstr, 256, "%s.enable", (*it)->shortname);

        if(force_module)
        {
            if(!strcmp(force_module, (*it)->shortname))
            {
                if(!(*it)->Load)
                {
                    GameFile.Close();

                    if((*it)->LoadCD)
                        MDFN_PrintError(_("Specified system only supports CD(physical, or image files, such as *.cue and *.toc) loading."));
                    else
                        MDFN_PrintError(_("Specified system does not support normal file loading."));
                    MDFN_indent(-1);
                    MDFNGameInfo = NULL;
                    return 0;
                }
                MDFNGameInfo = *it;
                break;
            }
        }
        else
        {
            // Is module enabled?
            if(!MDFN_GetSettingB(tmpstr))
                continue;

            if(!(*it)->Load || !(*it)->TestMagic)
                continue;

            if((*it)->TestMagic(name, &GameFile))
            {
                MDFNGameInfo = *it;
                break;
            }
        }
    }

    if(!MDFNGameInfo)
    {
        GameFile.Close();

        if(force_module)
            MDFN_PrintError(_("Unrecognized system \"%s\"!"), force_module);
        else
            MDFN_PrintError(_("Unrecognized file format.  Sorry."));

        MDFN_indent(-1);
        MDFNGameInfo = NULL;
        return 0;
    }

    MDFN_printf(_("Using module: %s(%s)\n\n"), MDFNGameInfo->shortname, MDFNGameInfo->fullname);
    MDFN_indent(1);

    assert(MDFNGameInfo->soundchan != 0);

    MDFNGameInfo->soundrate = 0;
    MDFNGameInfo->name = NULL;
    MDFNGameInfo->rotated = 0;

    if(MDFNGameInfo->Load(name, &GameFile) <= 0)
    {
        GameFile.Close();
        MDFN_indent(-2);
        MDFNGameInfo = NULL;
        return(0);
    }

    if(MDFNGameInfo->GameType != GMT_PLAYER)
    {
        MDFN_LoadGameCheats(NULL);
        MDFNMP_InstallReadPatches();
    }

    MDFNI_SetLayerEnableMask(~0ULL);

#ifdef WANT_DEBUGGER
    MDFNDBG_PostGameLoad();
#endif

    MDFNSS_CheckStates();
    MDFNMOV_CheckMovies();

    MDFN_ResetMessages();	// Save state, status messages, etc.

    MDFN_indent(-2);

    if(!MDFNGameInfo->name)
    {
        unsigned int x;
        char *tmp;

        MDFNGameInfo->name = (UTF8 *)strdup(GetFNComponent(name));

        for(x=0; x<strlen((char *)MDFNGameInfo->name); x++)
        {
            if(MDFNGameInfo->name[x] == '_')
                MDFNGameInfo->name[x] = ' ';
        }
        if((tmp = strrchr((char *)MDFNGameInfo->name, '.')))
            *tmp = 0;
    }

    PrevInterlaced = false;
    deint.ClearState();

    TBlur_Init();

    MDFN_StateEvilBegin();


    last_sound_rate = -1;
    memset(&last_pixel_format, 0, sizeof(MDFN_PixelFormat));

    return(MDFNGameInfo);
}
MDFNGI *MDFNI_LoadCD(const char *force_module, const char *devicename)
{
    uint8 LayoutMD5[16];

    MDFNI_CloseGame();

    LastSoundMultiplier = 1;

    MDFN_printf(_("Loading %s...\n\n"), devicename ? devicename : _("PHYSICAL CD"));

    try
    {
        if(devicename && strlen(devicename) > 4 && !strcasecmp(devicename + strlen(devicename) - 4, ".m3u"))
        {
            std::vector<std::string> file_list;

            ReadM3U(file_list, devicename);

            for(unsigned i = 0; i < file_list.size(); i++)
            {
                CDInterfaces.push_back(new CDIF(file_list[i].c_str()));
            }

            GetFileBase(devicename);
        }
        else
        {
            CDInterfaces.push_back(new CDIF(devicename));
            if(CDInterfaces[0]->IsPhysical())
            {
                GetFileBase("cdrom");
            }
            else
                GetFileBase(devicename);
        }
    }
    catch(std::exception &e)
    {
        MDFND_PrintError(e.what());
        MDFN_PrintError(_("Error opening CD."));
        return(0);
    }

//
// Print out a track list for all discs.
//
    MDFN_indent(1);
    for(unsigned i = 0; i < CDInterfaces.size(); i++)
    {
        CDUtility::TOC toc;

        CDInterfaces[i]->ReadTOC(&toc);

        MDFN_printf(_("CD %d Layout:\n"), i + 1);
        MDFN_indent(1);

        for(int32 track = toc.first_track; track <= toc.last_track; track++)
        {
            MDFN_printf(_("Track %2d, LBA: %6d  %s\n"), track, toc.tracks[track].lba, (toc.tracks[track].control & 0x4) ? "DATA" : "AUDIO");
        }

        MDFN_printf("Leadout: %6d\n", toc.tracks[100].lba);
        MDFN_indent(-1);
        MDFN_printf("\n");
    }
    MDFN_indent(-1);
//
//



// Calculate layout MD5.  The system emulation LoadCD() code is free to ignore this value and calculate
// its own, or to use it to look up a game in its database.
    {
        md5_context layout_md5;

        layout_md5.starts();

        for(unsigned i = 0; i < CDInterfaces.size(); i++)
        {
            CD_TOC toc;

            CDInterfaces[i]->ReadTOC(&toc);

            layout_md5.update_u32_as_lsb(toc.first_track);
            layout_md5.update_u32_as_lsb(toc.last_track);
            layout_md5.update_u32_as_lsb(toc.tracks[100].lba);

            for(uint32 track = toc.first_track; track <= toc.last_track; track++)
            {
                layout_md5.update_u32_as_lsb(toc.tracks[track].lba);
                layout_md5.update_u32_as_lsb(toc.tracks[track].control & 0x4);
            }
        }

        layout_md5.finish(LayoutMD5);
    }

    MDFNGameInfo = NULL;

    for(std::list<MDFNGI *>::iterator it = MDFNSystemsPrio.begin(); it != MDFNSystemsPrio.end(); it++)  //_unsigned int x = 0; x < MDFNSystems.size(); x++)
    {
        char tmpstr[256];
        trio_snprintf(tmpstr, 256, "%s.enable", (*it)->shortname);

        if(force_module)
        {
            if(!strcmp(force_module, (*it)->shortname))
            {
                MDFNGameInfo = *it;
                break;
            }
        }
        else
        {
            // Is module enabled?
            if(!MDFN_GetSettingB(tmpstr))
                continue;

            if(!(*it)->LoadCD || !(*it)->TestMagicCD)
                continue;

            if((*it)->TestMagicCD(&CDInterfaces))
            {
                MDFNGameInfo = *it;
                break;
            }
        }
    }

    if(!MDFNGameInfo)
    {
        if(force_module)
        {
            MDFN_PrintError(_("Unrecognized system \"%s\"!"), force_module);
            return(0);
        }

        // This code path should never be taken, thanks to "cdplay"
        MDFN_PrintError(_("Could not find a system that supports this CD."));
        return(0);
    }

    // This if statement will be true if force_module references a system without CDROM support.
    if(!MDFNGameInfo->LoadCD)
    {
        MDFN_PrintError(_("Specified system \"%s\" doesn't support CDs!"), force_module);
        return(0);
    }

    MDFN_printf(_("Using module: %s(%s)\n\n"), MDFNGameInfo->shortname, MDFNGameInfo->fullname);


// TODO: include module name in hash
    memcpy(MDFNGameInfo->MD5, LayoutMD5, 16);

    if(!(MDFNGameInfo->LoadCD(&CDInterfaces)))
    {
        for(unsigned i = 0; i < CDInterfaces.size(); i++)
            delete CDInterfaces[i];
        CDInterfaces.clear();

        MDFNGameInfo = NULL;
        return(0);
    }

    MDFNI_SetLayerEnableMask(~0ULL);

#ifdef WANT_DEBUGGER
    MDFNDBG_PostGameLoad();
#endif

    MDFNSS_CheckStates();
    MDFNMOV_CheckMovies();

    MDFN_ResetMessages();   // Save state, status messages, etc.

    TBlur_Init();

    MDFN_StateEvilBegin();


    if(MDFNGameInfo->GameType != GMT_PLAYER)
    {
        MDFN_LoadGameCheats(NULL);
        MDFNMP_InstallReadPatches();
    }

    last_sound_rate = -1;
    memset(&last_pixel_format, 0, sizeof(MDFN_PixelFormat));

    return(MDFNGameInfo);
}