⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nes.cpp

📁 著名的任天堂FC游戏机模拟器VirtuaNes 085版的源码!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		case	0x17:
			CPUREG[addr & 0xFF] = data;
			pad->Write( addr, data );
			apu->Write( addr, data );
			break;
		// VirtuaNES屌桳億乕僩
		case	0x18:
			apu->Write( addr, data );
			break;
#if	0
		case	0x1C:
			m_dwProfileTempCycle = cpu->GetTotalCycles();
			break;
		case	0x1D:
			m_dwProfileCycle = cpu->GetTotalCycles()-m_dwProfileTempCycle-4;
			m_dwProfileTotalCycle += m_dwProfileCycle;
			m_dwProfileTotalCount++;
			break;
		case	0x1E:
			m_dwProfileTotalCount = 0;
			m_dwProfileTotalCycle = 0;
			m_dwTotalTempCycle = cpu->GetTotalCycles();
			break;
		case	0x1F:
			m_dwTotalCycle = cpu->GetTotalCycles()-m_dwTotalTempCycle-4;
			break;
#endif
		default:
			mapper->ExWrite( addr, data );
			break;
	}
}

void	NES::LoadSRAM()
{
	if( rom->IsNSF() )
		return;

	ZEROMEMORY( WRAM, sizeof(WRAM) );

	if( !rom->IsSAVERAM() )
		return;

	string	pathstr, tempstr;
	if( Config.path.bSavePath ) {
		pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
	} else {
		pathstr = rom->GetRomPath();
	}
	tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "sav" );
	DEBUGOUT( "Path: %s\n", tempstr.c_str() );

	FILE*	fp = NULL;
	try
	{
		if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) {
			// xxx 僼傽僀儖傪奐偗傑偣傫
			LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
			sprintf( szErrorString, szErrStr, tempstr.c_str() );
			throw	szErrorString;
		}

		DEBUGOUT( "Loading SAVERAM..." );

		LONG	size;
		// 僼傽僀儖僒僀僘庢摼
		::fseek( fp, 0, SEEK_END );
		size = ftell( fp );
		::fseek( fp, 0, SEEK_SET );
		if( size <= 128*1024 ) {
			if( ::fread( WRAM, size, 1, fp ) != 1 )
				throw	"File Read error.";
		}

		DEBUGOUT( "Ok.\n" );
		FCLOSE( fp );
	} catch( CHAR* str ) {
		FCLOSE( fp );
		DEBUGOUT( "Loading SAVERAM Error.\n" );
		DEBUGOUT( "%s\n", str );
//		throw	str;
#ifndef	_DEBUG
	} catch(...) {
		FCLOSE( fp );
		DEBUGOUT( "Loading SAVERAM Error.\n" );
		// 晄柧側僄儔乕偑敪惗偟傑偟偨
		throw	CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
	}
}

void	NES::SaveSRAM()
{
INT	i;

	if( rom->IsNSF() )
		return;

	if( !rom->IsSAVERAM() )
		return;

	for( i = 0; i < SAVERAM_SIZE; i++ ) {
		if( WRAM[i] != 0x00 )
			break;
	}

	if( i < SAVERAM_SIZE ) {
		DEBUGOUT( "Saving SAVERAM...\n" );

		string	pathstr, tempstr;
		if( Config.path.bSavePath ) {
			pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
			::CreateDirectory( pathstr.c_str(), NULL );
		} else {
			pathstr = rom->GetRomPath();
		}
		tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "sav" );
		DEBUGOUT( "Path: %s\n", tempstr.c_str() );

		FILE*	fp = NULL;
		try
		{
			if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) {
				// xxx 僼傽僀儖傪奐偗傑偣傫
				LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
				sprintf( szErrorString, szErrStr, tempstr.c_str() );
				throw	szErrorString;
			}

			if( ::fwrite( WRAM, SAVERAM_SIZE, 1, fp ) != 1 ) {
				// 僼傽僀儖偺彂偒崬傒偵幐攕偟傑偟偨
				throw	CApp::GetErrorString( IDS_ERROR_WRITE );
			}

			DEBUGOUT( "Ok.\n" );
			FCLOSE( fp );
		} catch( CHAR* str ) {
			DEBUGOUT( "Writing SAVERAM Error.\n" );
			FCLOSE( fp );
			throw	str;
	#ifndef	_DEBUG
		} catch(...) {
			DEBUGOUT( "Writing SAVERAM Error.\n" );
			FCLOSE( fp );
			// 晄柧側僄儔乕偑敪惗偟傑偟偨
			throw	CApp::GetErrorString( IDS_ERROR_UNKNOWN );
	#endif
		}
	}
}

void	NES::LoadDISK()
{
	if( rom->GetMapperNo() != 20 )
		return;

	BOOL	bExit = FALSE;

	INT	i, j, diskno;
	FILE*	fp = NULL;
	DISKIMGFILEHDR	ifh;
	DISKIMGHDR	hdr;
	LPBYTE		disk;

	WORD	Version;

	string	pathstr, tempstr;
	if( Config.path.bSavePath ) {
		pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
	} else {
		pathstr = rom->GetRomPath();
	}
	tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "dsv" );
	DEBUGOUT( "Path: %s\n", tempstr.c_str() );

	try
	{
		if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) {
			// xxx 僼傽僀儖傪奐偗傑偣傫
			LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
			sprintf( szErrorString, szErrStr, tempstr.c_str() );
			throw	szErrorString;
		}

		if( ::fread( &ifh, sizeof(DISKIMGFILEHDR), 1, fp ) != 1 ) {
			// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
			throw	CApp::GetErrorString( IDS_ERROR_READ );
		}

		if( ::memcmp( ifh.ID, "VirtuaNES DI", sizeof(ifh.ID) ) == 0 ) {
			if( ifh.BlockVersion < 0x0100 && ifh.BlockVersion > 0x200 ) {
				// 枹懳墳宍幃偱偡
				throw	CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
			}
			Version = ifh.BlockVersion;
		} else {
			// 枹懳墳宍幃偱偡
			throw	CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
		}

		if( Version == 0x0100 ) {
		// Ver0.24埲慜
			if( ifh.DiskNumber > 4 ) {
				// 枹懳墳宍幃偱偡
				throw	CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
			}

			for( i = 0; i < (INT)ifh.DiskNumber; i++ ) {
				if( ::fread( &hdr, sizeof(DISKIMGHDR), 1, fp ) != 1 ) {
					if( i == 0 ) {
						// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
						throw	CApp::GetErrorString( IDS_ERROR_READ );
					} else {
						break;
					}
				}

				if( ::memcmp( hdr.ID, "SIDE0A", sizeof(hdr.ID) ) == 0 ) {
					diskno = 0;
				} else if( ::memcmp( hdr.ID, "SIDE0B", sizeof(hdr.ID) ) == 0 ) {
					diskno = 1;
				} else if( ::memcmp( hdr.ID, "SIDE1A", sizeof(hdr.ID) ) == 0 ) {
					diskno = 2;
				} else if( ::memcmp( hdr.ID, "SIDE1B", sizeof(hdr.ID) ) == 0 ) {
					diskno = 3;
				} else {
					// 枹懳墳宍幃偱偡
					throw	CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
				}

				for( j = 0; j < 16; j++ ) {
					if( hdr.DiskTouch[j] ) {
						disk = rom->GetPROM()+16+65500*diskno+(4*1024)*j;
						if( j < 15 ) {
							if( ::fread( disk, 4*1024, 1, fp ) != 1 ) {
								bExit = TRUE;
								// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
								throw	CApp::GetErrorString( IDS_ERROR_READ );
							}
						} else {
							if( ::fread( disk, 4*1024-36, 1, fp ) != 1 ) {
								bExit = TRUE;
								// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
								throw	CApp::GetErrorString( IDS_ERROR_READ );
							}
						}
					}
				}
			}
		} else 
		if( Version == 0x0200 || Version == 0x0210 ) {
			// Ver0.30埲崀
			DISKFILEHDR	dfh;
			LPBYTE	lpDisk = rom->GetPROM();
			LPBYTE	lpWrite = rom->GetDISK();
			LONG	DiskSize = 16+65500*rom->GetDiskNo();
			DWORD	pos;
			BYTE	data;

			// 彂偒姺偊FLAG徚嫀
			::ZeroMemory( lpWrite, 16+65500*rom->GetDiskNo() );

			// 僿僢僟撉傒捈偟
			if( ::fseek( fp, 0, SEEK_SET ) ) {
				// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
				throw	CApp::GetErrorString( IDS_ERROR_READ );
			}
			if( ::fread( &dfh, sizeof(DISKFILEHDR), 1, fp ) != 1 ) {
				// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
				throw	CApp::GetErrorString( IDS_ERROR_READ );
			}

			if( Config.emulator.bCrcCheck ) {
				// 尰嵼儘乕僪拞偺僞僀僩儖偲堘偆偐傪僠僃僢僋
				if( dfh.ProgID  !=       rom->GetGameID()
				 || dfh.MakerID != (WORD)rom->GetMakerID()
				 || dfh.DiskNo  != (WORD)rom->GetDiskNo() ) {
					// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
					throw	CApp::GetErrorString( IDS_ERROR_READ );
				}
			}

			for( i = 0; i < dfh.DifferentSize; i++ ) {
				if( ::fread( &pos, sizeof(DWORD), 1, fp ) != 1 ) {
					// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
					bExit = TRUE;
					throw	CApp::GetErrorString( IDS_ERROR_READ );
				}
				data = (BYTE)(pos>>24);
				pos &= 0x00FFFFFF;
				if( pos >= 16 && pos < DiskSize ) {
					lpDisk[pos] = data;
					lpWrite[pos] = 0xFF;
				}
			}
		}
		FCLOSE( fp );
	} catch( CHAR* str ) {
		FCLOSE( fp );
		DEBUGOUT( "%s\n", str );
		if( bExit )
			throw	str;
#ifndef	_DEBUG
	} catch(...) {
		FCLOSE( fp );
		DEBUGOUT( "Loading DISKIMAGE Error.\n" );
		// 晄柧側僄儔乕偑敪惗偟傑偟偨
		throw	CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
	}
}

void	NES::SaveDISK()
{
	if( rom->GetMapperNo() != 20 )
		return;

	INT	i;
	FILE*	fp = NULL;
	DISKFILEHDR ifh;
	LPBYTE	lpDisk  = rom->GetPROM();
	LPBYTE	lpWrite = rom->GetDISK();
	LONG	DiskSize = 16+65500*rom->GetDiskNo();
	DWORD	data;

	try
	{
		::ZeroMemory( &ifh, sizeof(ifh) );

		::memcpy( ifh.ID, "VirtuaNES DI", sizeof(ifh.ID) );
		ifh.BlockVersion = 0x0210;
		ifh.ProgID  = rom->GetGameID();
		ifh.MakerID = (WORD)rom->GetMakerID();
		ifh.DiskNo  = (WORD)rom->GetDiskNo();

		// 憡堘悢傪僇僂儞僩
		for( i = 16; i < DiskSize; i++ ) {
			if( lpWrite[i] )
				ifh.DifferentSize++;
		}

		if( !ifh.DifferentSize )
			return;

		string	pathstr, tempstr;
		if( Config.path.bSavePath ) {
			pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
			::CreateDirectory( pathstr.c_str(), NULL );
		} else {
			pathstr = rom->GetRomPath();
		}
		tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "dsv" );
		DEBUGOUT( "Path: %s\n", tempstr.c_str() );

		if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) {
			// xxx 僼傽僀儖傪奐偗傑偣傫
			LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
			::wsprintf( szErrorString, szErrStr, tempstr.c_str() );
			throw	szErrorString;
		}

		if( ::fwrite( &ifh, sizeof(DISKFILEHDR), 1, fp ) != 1 ) {
			// 僼傽僀儖偺彂偒崬傒偵幐攕偟傑偟偨
			throw	CApp::GetErrorString( IDS_ERROR_WRITE );
		}

		for( i = 16; i < DiskSize; i++ ) {
			if( lpWrite[i] ) {
				data = i & 0x00FFFFFF;
				data |= ((DWORD)lpDisk[i]&0xFF)<<24;

				// Write File
				if( ::fwrite( &data, sizeof(DWORD), 1, fp ) != 1 ) {
					// 僼傽僀儖偺彂偒崬傒偵幐攕偟傑偟偨
					throw	CApp::GetErrorString( IDS_ERROR_WRITE );
				}
			}
		}
		FCLOSE( fp );
	} catch( CHAR* str ) {
		FCLOSE( fp );
		DEBUGOUT( "%s\n", str );
#ifndef	_DEBUG
	} catch(...) {
		FCLOSE( fp );
		DEBUGOUT( "Saving DISKIMAGE Error.\n" );
		// 晄柧側僄儔乕偑敪惗偟傑偟偨
		throw	CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
	}
}

void	NES::LoadTurboFile()
{
	ZEROMEMORY( ERAM, sizeof(ERAM) );

	if( pad->GetExController() != PAD::EXCONTROLLER_TURBOFILE )
		return;

	string	pathstr, tempstr;
	if( Config.path.bSavePath ) {
		pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
	} else {
		pathstr = rom->GetRomPath();
	}
	tempstr = CPathlib::MakePathExt( pathstr.c_str(), "TurboFile", "vtf" );
	DEBUGOUT( "Path: %s\n", tempstr.c_str() );

	FILE*	fp = NULL;
	try
	{
		if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) {
			// xxx 僼傽僀儖傪奐偗傑偣傫
			LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
			sprintf( szErrorString, szErrStr, tempstr.c_str() );
			throw	szErrorString;
		}

		DEBUGOUT( "Loading TURBOFILE..." );

		LONG	size;
		// 僼傽僀儖僒僀僘庢摼
		::fseek( fp, 0, SEEK_END );
		size = ftell( fp );
		::fseek( fp, 0, SEEK_SET );
		if( size > 32*1024 ) {
			size = 32*1024;
		}
		if( ::fread( ERAM, size, 1, fp ) != 1 )
			throw	"File Read error.";

		DEBUGOUT( "Ok.\n" );
		FCLOSE( fp );
	} catch( CHAR* str ) {
		FCLOSE( fp );
		DEBUGOUT( "Loading TurboFile Error.\n" );
		DEBUGOUT( "%s\n", str );
//		throw	str;
#ifndef	_DEBUG
	} catch(...) {
		FCLOSE( fp );
		DEBUGOUT( "Loading TurboFile Error.\n" );
		// 晄柧側僄儔乕偑敪惗偟傑偟偨
		throw	CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif
	}
}

void	NES::SaveTurboFile()
{
INT	i;

	if( pad->GetExController() != PAD::EXCONTROLLER_TURBOFILE )
		return;

	for( i = 0; i < sizeof(ERAM); i++ ) {
		if( ERAM[i] != 0x00 )
			break;
	}

	if( i < sizeof(ERAM) ) {
		DEBUGOUT( "Saving TURBOFILE...\n" );

		string	pathstr, tempstr;
		if( Config.path.bSavePath ) {
			pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath );
			::CreateDirectory( pathstr.c_str(), NULL );
		} else {
			pathstr = rom->GetRomPath();
		}
		tempstr = CPathlib::MakePathExt( pathstr.c_str(), "TurboFile", "vtf" );
		DEBUGOUT( "Path: %s\n", tempstr.c_str() );

		FILE*	fp = NULL;
		try
		{
			if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) {
				// xxx 僼傽僀儖傪奐偗傑偣傫
				LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
				sprintf( szErrorString, szErrStr, tempstr.c_str() );
				throw	szErrorString;
			}

			if( ::fwrite( ERAM, sizeof(ERAM), 1, fp ) != 1 ) {
				// 僼傽僀儖偺彂偒崬傒偵幐攕偟傑偟偨
				throw	CApp::GetErrorString( IDS_ERROR_WRITE );
			}

			DEBUGOUT( "Ok.\n" );
			FCLOSE( fp );
		} catch( CHAR* str ) {
			DEBUGOUT( "Writing TurboFile Error.\n" );
			FCLOSE( fp );
			throw	str;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -