Ejemplo n.º 1
0
 void CQTOpenGLLuaMainWindow::OpenFile(const QString& str_path) {
    QFile cFile(str_path);
    if(! cFile.open(QFile::ReadOnly | QFile::Text)) {
       QMessageBox::warning(this, tr("ARGoS v" ARGOS_VERSION "-" ARGOS_RELEASE " - Lua Editor"),
                            tr("Cannot read file %1:\n%2.")
                            .arg(str_path)
                            .arg(cFile.errorString()));
       return;
    }
    QApplication::setOverrideCursor(Qt::WaitCursor);
    m_pcCodeEditor->setPlainText(cFile.readAll());
    QApplication::restoreOverrideCursor();
    SetCurrentFile(str_path);
    statusBar()->showMessage(tr("File loaded"), 2000);
 }
Ejemplo n.º 2
0
bool MainWindow::LoadFile(const QString &FileName)
{


    if(!ReadFile(FileName))
    {
        statusBar()->showMessage(tr("Loading canceled"),2000);
        return false;
    }


    SetCurrentFile(FileName);
    statusBar()->showMessage(tr("File Loaded"),2000);

    return true;
}
Ejemplo n.º 3
0
bool MyMdi::SaveFile(const QString &file_name)
{
    QFile file(file_name);
    //即使是写入文本,也得将文本先打开
    if(!file.open(QFile::WriteOnly | QFile::Text))
    {
        QMessageBox::warning(this, "多文档编辑器", QStringLiteral("无法写入文件 %1:\n%2").arg(file_name).arg(file.errorString()));
        return false;
    }
    QTextStream out(&file);
    QApplication::setOverrideCursor(Qt::WaitCursor);
    out << toPlainText();//以纯文本方式写入,核心函数
    QApplication::restoreOverrideCursor();
    //返回之前,也将该文件的标题,路径名等设置好。
    SetCurrentFile(file_name);
    return true;
}
Ejemplo n.º 4
0
 bool CQTOpenGLLuaMainWindow::SaveFile(const QString& str_path) {
    QFile cFile(str_path);
    if(! cFile.open(QFile::WriteOnly | QFile::Text)) {
       QMessageBox::warning(this, tr("ARGoS v" ARGOS_VERSION "-" ARGOS_RELEASE " - Lua Editor"),
                            tr("Cannot write file %1:\n%2.")
                            .arg(str_path)
                            .arg(cFile.errorString()));
       return false;
    }
    QTextStream cOut(&cFile);
    QApplication::setOverrideCursor(Qt::WaitCursor);
    cOut << m_pcCodeEditor->toPlainText();
    QApplication::restoreOverrideCursor();
    SetCurrentFile(str_path);
    statusBar()->showMessage(tr("File saved"), 2000);
    return true;
 }
Ejemplo n.º 5
0
bool MyMdi::LoadFile(const QString &file_name)
{
    QFile file(file_name);//建立需打开的文件对象
    if(!file.open(QFile::ReadOnly | QFile::Text))
    {
        //打开失败时,输出错误信息
        QMessageBox::warning(this, "多文档编辑器", QStringLiteral("无法读取文件 %1:\n%2").arg(file_name).arg(file.errorString()));
        return false;
    }
    QTextStream in(&file);//文本流
    QApplication::setOverrideCursor(Qt::WaitCursor);//设置整个应用程序的光标形状为等待形状,因为如果文件的内容非常多时可以提醒用户
    setPlainText(in.readAll());//读取文本流中的所有内容,并显示在其窗体中
    QApplication::restoreOverrideCursor();//恢复开始时的光标状态
    SetCurrentFile(file_name);//设置标题什么的
    //注意这里发射信号用的是contentsChanged(),而不是contentsChange().
    connect(document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified()));

    return true;
}
Ejemplo n.º 6
0
void ParticleEditor::SaveAs()
{
	char path[___OUTPUT_LENGTH], file[___OUTPUT_LENGTH];
	if (SaveSystem(path, file))
	{
		strcpy(path, ETHGlobal::AppendExtensionIfNeeded(path, ".par").c_str());

		TiXmlDocument doc;
		TiXmlDeclaration *pDecl = new TiXmlDeclaration(GS_L("1.0"), GS_L(""), GS_L(""));
		doc.LinkEndChild(pDecl);

		TiXmlElement *pElement = new TiXmlElement(GS_L("Ethanon"));
		doc.LinkEndChild(pElement);

		m_system.WriteToXMLFile(doc.RootElement());
		const str_type::string filePath = path;
		doc.SaveFile(filePath);

		SetCurrentFile(path);
		m_untitled = false;
	}
}
Ejemplo n.º 7
0
bool ProjectManager::SaveAs()
{
	FILE_FORM_FILTER filter(GS_L("Ethanon Project files (*.ethproj)"), GS_L("ethproj"));
	char path[___OUTPUT_LENGTH], file[___OUTPUT_LENGTH];
	std::string sLastDir = ReadLastDir();
	if (SaveForm(filter, sLastDir.c_str(), path, file))
	{
		std::string sOut;
		AddExtension(path, ".ethproj", sOut);
		std::ofstream ofs(sOut.c_str());
		if (ofs.is_open())
		{
			ofs << "Ethanon Engine project file";
			ofs.close();
		}
		SetCurrentFile(sOut.c_str());
		SetCurrentProject(sOut.c_str());
		SaveLastDir(Platform::GetFileDirectory(sOut.c_str()).c_str());
		PrepareProjectDir();
	}
	return true;
}
Ejemplo n.º 8
0
bool ProjectManager::SaveAs()
{
	char filter[] = "Ethanon Project files (*.ethproj)\0*.ethproj\0\0";
	char path[___OUTPUT_LENGTH], file[___OUTPUT_LENGTH];
	string sLastDir = ReadLastDir();
	if (SaveForm(filter, "", path, file, sLastDir.c_str()))
	{
		string sOut;
		AddExtension(path, ".ethproj", sOut);
		std::ofstream ofs(sOut.c_str());
		if (ofs.is_open())
		{
			ofs << "Ethanon Engine project file";
			ofs.close();
		}
		SetCurrentFile(sOut.c_str());
		SetCurrentProject(sOut.c_str());
		SaveLastDir(ETHGlobal::GetPathName(sOut.c_str(), true).c_str());
		PrepareProjectDir();
	}
	return true;
}
Ejemplo n.º 9
0
void ParticleEditor::ParticlePanel()
{
	std::string programPath = GetCurrentProjectPath(false);
	const VideoPtr& video = m_provider->GetVideo();
	const InputPtr& input = m_provider->GetInput();

	GSGUI_BUTTON file_r = m_fileMenu.PlaceMenu(Vector2(0,m_menuSize*2));
	if (file_r.text == LOAD_BMP)
	{
		char path[___OUTPUT_LENGTH], file[___OUTPUT_LENGTH];
		if (OpenParticleBMP(path, file))
		{
			ETHGlobal::CopyFileToProject(programPath, path, ETHDirectories::GetParticlesDirectory(), m_provider->GetFileManager());
			m_system.bitmapFile = file;
			m_provider->GetGraphicResourceManager()->ReleaseResource(m_system.bitmapFile);
			m_manager = ETHParticleManagerPtr(
				new ETHParticleManager(m_provider, m_system, m_v2Pos, Vector3(m_v2Pos, 0), m_systemAngle, 1.0f));
		}
	}

	if (file_r.text == SAVE_SYSTEM)
	{
		if (m_untitled)
			SaveAs();
		else
			Save();
	}

	if (file_r.text == SAVE_SYSTEM_AS)
	{
		SaveAs();
	}

	if (file_r.text == LOAD_BG)
	{
		char path[___OUTPUT_LENGTH], file[___OUTPUT_LENGTH];
		if (OpenParticleBMP(path, file))
		{
			m_backgroundSprite = video->CreateSprite(path);
		}	
	}

	if (file_r.text == OPEN_SYSTEM)
	{
		m_systemAngle = 0.0f;
		char path[___OUTPUT_LENGTH], file[___OUTPUT_LENGTH];
		if (OpenSystem(path, file))
		{
			m_manager = ETHParticleManagerPtr(
				new ETHParticleManager(m_provider, path, m_v2Pos, Vector3(m_v2Pos, 0), m_systemAngle));
			m_manager->SetZPosition(0.0f);
			m_manager->Kill(false);
			m_system = *m_manager->GetSystem();
			SetMenuConstants();

			SetCurrentFile(path);
			m_untitled = false;
		}
	}

	if (file_r.text == _S_GOTO_PROJ)
	{
		m_projManagerRequested = true;
	}

	if (input->GetKeyState(GSK_K) == GSKS_HIT)
		m_manager->Kill(!m_manager->Killed());
	
	if (!m_fileMenu.IsActive())
	{
		Vector2 v2ScreenDim = video->GetScreenSizeF();
		float menu = m_menuSize*m_menuScale+(m_menuSize*2);

		// places the alpha mode menu
		ShadowPrint(Vector2(v2ScreenDim.x-m_alphaModes.GetWidth(), menu), GS_L("Alpha mode:"), GS_L("Verdana14_shadow.fnt"), gs2d::constant::WHITE);
		menu += m_menuSize;
		m_alphaModes.PlaceMenu(Vector2(v2ScreenDim.x-m_alphaModes.GetWidth(), menu)); menu += m_alphaModes.GetNumButtons()*m_menuSize;

		// sets the alpha mode according to the selected item
		if (m_alphaModes.GetButtonStatus(ALPHA_MODE_PIXEL))
			m_system.alphaMode = Video::AM_PIXEL;
		if (m_alphaModes.GetButtonStatus(ALPHA_MODE_ADD))
			m_system.alphaMode = Video::AM_ADD;
		if (m_alphaModes.GetButtonStatus(ALPHA_MODE_MODULATE))
			m_system.alphaMode = Video::AM_MODULATE;

		// places the sprite cut fields to the right
		menu += m_menuSize/2;
		ShadowPrint(Vector2(v2ScreenDim.x-m_alphaModes.GetWidth(), menu), GS_L("Sprite cut:"), GS_L("Verdana14_shadow.fnt"), gs2d::constant::WHITE);
		menu += m_menuSize;
		m_system.spriteCut.x = Max(1, static_cast<int>(m_spriteCut[0].PlaceInput(Vector2(v2ScreenDim.x-m_alphaModes.GetWidth(),menu)))); menu += m_menuSize;
		m_system.spriteCut.y = Max(1, static_cast<int>(m_spriteCut[1].PlaceInput(Vector2(v2ScreenDim.x-m_alphaModes.GetWidth(),menu)))); menu += m_menuSize;

		// if there is sprite animation in the particle system, places the animation mode selector
		if (m_system.spriteCut.x > 1 || m_system.spriteCut.y > 1)
		{
			menu += m_menuSize/2;
			m_animationModes.PlaceMenu(Vector2(v2ScreenDim.x-m_animationModes.GetWidth(), menu)); menu += m_animationModes.GetNumButtons()*m_menuSize;

			if (m_animationModes.GetButtonStatus(ANIMATION_MODE_ANIMATE))
				m_system.animationMode = ETHParticleSystem::PLAY_ANIMATION;
			if (m_animationModes.GetButtonStatus(ANIMATION_MODE_PICK))
				m_system.animationMode = ETHParticleSystem::PICK_RANDOM_FRAME;
		}

		// inputs all data
		menu = m_menuSize*m_menuScale+(m_menuSize*2);
		menu += m_menuSize/2;
		ShadowPrint(Vector2(0.0f,menu), GS_L("Particles:"), GS_L("Verdana14_shadow.fnt"), gs2d::constant::WHITE);
		int nParticles = m_particles.PlaceInput(Vector2(m_menuWidth,menu)); menu += m_menuSize;

		ShadowPrint(Vector2(0.0f,menu), GS_L("Repeats:"), GS_L("Verdana14_shadow.fnt"), gs2d::constant::WHITE);
		m_system.repeat = m_repeats.PlaceInput(Vector2(m_menuWidth,menu)); menu += m_menuSize;
		menu += m_menuSize/2;

		if (nParticles != m_system.nParticles && nParticles > 0)
		{
			m_system.nParticles = nParticles;
			m_manager = ETHParticleManagerPtr(
				new ETHParticleManager(m_provider, m_system, m_v2Pos, Vector3(m_v2Pos, 0), m_systemAngle, 1.0f));
			m_manager->Kill(false);
		}

		m_system.gravityVector.x = m_gravity[0].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.gravityVector.y = m_gravity[1].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;

		m_system.directionVector.x = m_direction[0].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.directionVector.y = m_direction[1].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;

		m_system.randomizeDir.x = m_randDir[0].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.randomizeDir.y = m_randDir[1].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.boundingSphere = m_boundingSphere.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.allAtOnce = (bool)(m_allAtOnce.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize) != 0); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.startPoint.x = m_startPoint[0].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.startPoint.y = m_startPoint[1].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.randStartPoint.x = m_randStart[0].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.randStartPoint.y = m_randStart[1].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.color0.w = m_color0[0].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.color0.x = m_color0[1].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.color0.y = m_color0[2].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.color0.z = m_color0[3].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.color1.w = m_color1[0].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.color1.x = m_color1[1].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.color1.y = m_color1[2].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.color1.z = m_color1[3].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.size = m_size.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.growth = m_growth.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.randomizeSize = m_randSize.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.lifeTime = m_lifeTime.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.randomizeLifeTime = m_randLifeTime.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.angleStart = m_angleStart.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.angleDir = m_angle.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.randAngle = m_randAngle.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.randAngleStart = m_randAngleStart.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.minSize = m_minSize.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.maxSize = m_maxSize.PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_system.emissive.x = m_luminance[0].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.emissive.y = m_luminance[1].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		m_system.emissive.z = m_luminance[2].PlaceInput(Vector2(0.0f,menu), Vector2(0.0f, v2ScreenDim.y-m_menuSize), m_menuSize); menu += m_menuSize;
		menu += m_menuSize/2;

		m_manager->SetSystem(m_system);
	}
}
Ejemplo n.º 10
0
//-----------------------------------------------------------------------------
// Name: StreamCurrentBundle()
// Desc: updates the streaming state, returning S_OK when finished
//-----------------------------------------------------------------------------
HRESULT CLevelLoader::StreamCurrentLevel()
{
    HRESULT hr;

    switch(m_IOState)
    {
    case Begin:
    {
        // reset IO
        ResetStreaming();

        // if we are reading from the cache, get the signature
        if( IsCurrentCacheGood())
        {
            SetCurrentFile( m_pCurrentLevel->hSigFile );
            if( FAILED( hr = DoIO( Read, m_pFileSig, HD_SECTOR_SIZE )))
                return EndStreamLevel( BadRead );
        }
        m_IOState = LoadSig;
    }

    case LoadSig:
    {
        // wait for previous IO to complete
        if( FAILED( hr = HasIOCompleted()))
            return EndStreamLevel( hr == E_PENDING ? Pending : BadRead );

        // Reading cached file, so a signature exists
        if( IsCurrentCacheGood())
        {
            // Look for sig magic number.
            DWORD dwSig;
            dwSig = *(DWORD*)( m_pFileSig );
            if( dwSig != SIG_MAGIC )
            {
                if( dwSig == ~SIG_MAGIC )
                    return EndStreamLevel( NoSigMagic );
                else
                    return EndStreamLevel( BadSig );
            }

            // Check date and time.
            dwSig = *(((DWORD*)m_pFileSig ) + 1 );
            if( dwSig != Crc::GenerateCRCFromString( p_date_string ))
            {
                return EndStreamLevel( BadSig );
            }
            dwSig = *(((DWORD*)m_pFileSig ) + 2 );
            if( dwSig != Crc::GenerateCRCFromString( p_time_string ))
            {
                return EndStreamLevel( BadSig );
            }
        }
        else
        {
            // Set sig magic number so it is written out.
            *(((DWORD*)m_pFileSig )	+ 0 )	= SIG_MAGIC;
            *(((DWORD*)m_pFileSig ) + 1 )	= Crc::GenerateCRCFromString( p_date_string );
            *(((DWORD*)m_pFileSig ) + 2 )	= Crc::GenerateCRCFromString( p_time_string );
        }

        m_IOState = LoadSysMem;
    }

    case LoadSysMem:
    {
        // Wait for previous IO to complete.
        if( FAILED( hr = HasIOCompleted()))
            return EndStreamLevel( hr == E_PENDING ? Pending : BadRead );

        // Read initial system memory buffer.
        if( IsCurrentCacheGood())
        {
            // At this point we have decided the sig file is fine, which indicates that the cached file is fine also.
            // As such, no further work required for this file.
//				SetCurrentFile( m_pCurrentLevel->hHDFile );
            m_pCurrentLevel->bIsPreCached = TRUE;
            m_pCurrentLevel->bIsCacheCorrupted = FALSE;
            return EndStreamLevel( Finished );
        }
        else
        {
            // Set file pointer to start of HD file.
            SetCurrentFile( m_pCurrentLevel->hHDFile );

            // Set file pointer to start of DVD file.
            SetCurrentFile( m_pCurrentLevel->hDVDFile );
        }

        // At this point we want to loop through reading the buffer and writing it until teh file is fully written.
        DWORD	total_bytes_read		= 0;
        DWORD	total_bytes_written		= 0;
        int		bytes_remaining			= m_pCurrentLevel->dwDVDFileSize;
        for( ;; )
        {
            // Set the DVD file, but don't reset the file pointer.
            SetCurrentFile( m_pCurrentLevel->hDVDFile, FALSE );

//				DWORD bytes_to_transfer = ( bytes_remaining >= m_dwSysMemSize ) ? m_dwSysMemSize : bytes_remaining;
            DWORD bytes_to_transfer = ( bytes_remaining >= (int)m_dwSysMemSize ) ? m_dwSysMemSize : m_dwSysMemSize;

            if( FAILED( DoIO( Read, m_pSysMemData, bytes_to_transfer )))
                return EndStreamLevel( BadRead );

            total_bytes_read += bytes_to_transfer;

            // Set the HD file, but don't reset the file pointer.
            SetCurrentFile( m_pCurrentLevel->hHDFile, FALSE );

            if( FAILED( DoIO( Write, m_pSysMemData, bytes_to_transfer )))
                return EndStreamLevel( BadWrite );

            total_bytes_written += bytes_to_transfer;
            bytes_remaining -= bytes_to_transfer;

            if( bytes_remaining <= 0 )
            {
                DWORD rv = SetFilePointer( m_pCurrentLevel->hHDFile, m_pCurrentLevel->dwDVDFileSize, NULL, FILE_BEGIN );
                if( rv == INVALID_SET_FILE_POINTER )
                {
                    DWORD last_error = GetLastError();
                    printf( "Last error: %x\n", last_error );
                }

                SetEndOfFile( m_pCurrentLevel->hHDFile );

                m_IOState = WriteSig;
                break;
            }
        }
    }

    case WriteSig:
    {
        // Wait for previous IO to complete.
        if( FAILED( hr = HasIOCompleted() ) )
            return EndStreamLevel( hr == E_PENDING ? Pending : BadRead );

        // We are now loaded.
        m_dLoadTime = Tmr::GetTime() - m_dStartTime;

        // We write the sig file last. If the box is turned off during a cache operation, the sig file will be missing.
        // If the box is turned off during the write of the sig file, it won't have a header or will not match the level
        // data. In either case, the level will be re-cached.
        SetCurrentFile( m_pCurrentLevel->hSigFile );
        if( FAILED( hr = DoIO( Write, m_pFileSig, HD_SECTOR_SIZE) ) )
            return EndStreamLevel( BadWrite );

        m_IOState = End;
    }

    case End:
    {
        // Wait for previous IO to complete.
        if( FAILED( hr = HasIOCompleted() ) )
            return EndStreamLevel( hr == E_PENDING ? Pending : BadRead );

        // Record cache time.
        m_dCacheTime = Tmr::GetTime() - m_dStartTime;

        // We are now cached.
        m_pCurrentLevel->bIsPreCached		= TRUE;
        m_pCurrentLevel->bIsCacheCorrupted	= FALSE;

        return EndStreamLevel( Finished );
    }
    }

    // should never reach here
    Dbg_Assert( FALSE );
    return E_FAIL;
}
Ejemplo n.º 11
0
HRESULT CLevelLoader::OpenLevel( SLevelState* pLevel, DWORD dwFlags )
{
    // If the level has never been opened before, open in.
    if( !pLevel->bIsOpen )
    {
        // Check that the level file handles are not open.
        Dbg_Assert( pLevel->hDVDFile == INVALID_HANDLE_VALUE );
        Dbg_Assert( pLevel->hHDFile == INVALID_HANDLE_VALUE );
        Dbg_Assert( pLevel->hSigFile == INVALID_HANDLE_VALUE );

        char szBuffer[MAX_PATH];

        // DVD File.
        sprintf( szBuffer, "D:\\data\\%s", pLevel->Desc.szName );

        // Open DVD file for reading.
        pLevel->hDVDFile = CreateFile( szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dwFlags, NULL );

        if( pLevel->hDVDFile == INVALID_HANDLE_VALUE )
            return EndOpenLevel( pLevel, BadOpen );

        // Get size of file on DVD. NOTE: This size is used to help detect corrupt cached levels. If a cached level
        // is not the same size as its DVD counterpart, the cached level is considered corrupt.
        pLevel->dwDVDFileSize = ::GetFileSize( pLevel->hDVDFile, NULL );

        // NOTE: Both files stored on the utility drive (signature file and level) are pre-sized. This prevents the files from
        // becoming fragmented in the FATX.  Also, Overlapped reads/writes to the hard disk are synchronous if the file system
        // has to hit the FATX to determine local->physical cluster mapping.

        // SIG File.
        sprintf( szBuffer, "Z:\\data\\%s.sig", pLevel->Desc.szName );

        // See if we have a cached sig.
        pLevel->bIsPreCached = ( GetFileAttributes( szBuffer ) != DWORD( -1 ));

        // Open sig file for reading and writing.
        pLevel->hSigFile = CreateFile( szBuffer,
                                       GENERIC_READ | GENERIC_WRITE,
                                       FILE_SHARE_READ |
                                       FILE_SHARE_WRITE |
                                       FILE_SHARE_DELETE,
                                       NULL,
                                       OPEN_ALWAYS,
                                       dwFlags,
                                       NULL );
        if( pLevel->hSigFile == INVALID_HANDLE_VALUE )
            return EndOpenLevel( pLevel, BadOpen );

        // Cache is corrupted if sig file is not the right size. NOTE: The sig file is HD_SECTOR_SIZE in size. The actual
        // signature calculated by XCalculateSignature* is much smaller that HD_SECTOR_SIZE, but we must write at least
        // HD_SECTOR_SIZE to use DMA on the hard disk.
        pLevel->bIsCacheCorrupted = pLevel->bIsPreCached && ::GetFileSize( pLevel->hSigFile, NULL ) != HD_SECTOR_SIZE;

        // If the sig file is corrupted or not saved, resize it.
        if( !pLevel->bIsPreCached || pLevel->bIsCacheCorrupted )
        {
            // Set file size for faster write.
            SetFilePointer( pLevel->hSigFile, HD_SECTOR_SIZE, NULL, FILE_BEGIN );
            SetEndOfFile( pLevel->hSigFile );

            // Clear Sig magic number.
            BYTE apyBuffer[HD_SECTOR_SIZE];
            *(DWORD*)(apyBuffer) = ~SIG_MAGIC;
            SetCurrentFile( pLevel->hSigFile );
            if( FAILED( DoIO( Write, apyBuffer, HD_SECTOR_SIZE )))
                return EndOpenLevel( pLevel, BadSigMagicWrite );

            // Wait for IO completion for sig magic writes.
            while( HasIOCompleted() != S_OK );
        }


        // CACHED file.
        sprintf( szBuffer, "Z:\\data\\%s", pLevel->Desc.szName );

        // See if we have a cached file.
        pLevel->bIsPreCached = pLevel->bIsPreCached && ( GetFileAttributes( szBuffer ) != DWORD( -1 ));

        // Open cached file for reading and writing.
        pLevel->hHDFile = CreateFile( szBuffer,
                                      GENERIC_WRITE | GENERIC_READ,
                                      FILE_SHARE_READ |
                                      FILE_SHARE_WRITE |
                                      FILE_SHARE_DELETE,
                                      NULL,
                                      OPEN_ALWAYS,
                                      dwFlags,
                                      NULL );

        if( pLevel->hHDFile == INVALID_HANDLE_VALUE )
            return EndOpenLevel( pLevel, BadOpen );

        // Cache is corrupted if cache file is not the right size
        pLevel->bIsCacheCorrupted = pLevel->bIsPreCached && (( ::GetFileSize( pLevel->hHDFile, NULL ) != pLevel->dwDVDFileSize ) || pLevel->bIsCacheCorrupted );

        // If the cache file is corrupted or not saved, resize it.
        if( !pLevel->bIsPreCached || pLevel->bIsCacheCorrupted )
        {
            // Set file size for faster write.
            DWORD rv = SetFilePointer( pLevel->hHDFile, pLevel->dwDVDFileSize, NULL, FILE_BEGIN );
            if( rv == INVALID_SET_FILE_POINTER )
            {
                DWORD last_error = GetLastError();
                printf( "Last error: %x\n", last_error );
            }
            SetEndOfFile( pLevel->hHDFile );
        }
        return EndOpenLevel( pLevel, FilesOpened );
    }

    return S_OK;
}