mirror of https://github.com/PCSX2/pcsx2.git
Fixed inconsistent newlines / added as many svn:eol-style=native properties as I could without killing myself.
Please set up auto-props in your svn client. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4488 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e198d5032e
commit
22c1b30ed6
|
@ -1,240 +1,240 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FixedPointTypes.h"
|
||||
#include <cmath> // for pow!
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>::FixedInt()
|
||||
{
|
||||
Raw = 0;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>::FixedInt( int signedval )
|
||||
{
|
||||
Raw = signedval * Precision;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>::FixedInt( double doubval )
|
||||
{
|
||||
Raw = (int)(doubval * (double)Precision);
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>::FixedInt( float floval )
|
||||
{
|
||||
Raw = (int)(floval * (float)Precision);
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::operator+( const FixedInt<Precision>& right ) const
|
||||
{
|
||||
return FixedInt<Precision>().SetRaw( Raw + right.Raw );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::operator-( const FixedInt<Precision>& right ) const
|
||||
{
|
||||
return FixedInt<Precision>().SetRaw( Raw + right.Raw );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::operator+=( const FixedInt<Precision>& right )
|
||||
{
|
||||
return SetRaw( Raw + right.Raw );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::operator-=( const FixedInt<Precision>& right )
|
||||
{
|
||||
return SetRaw( Raw + right.Raw );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::ConfineTo( const FixedInt<Precision>& low, const FixedInt<Precision>& high )
|
||||
{
|
||||
return SetRaw( std::min( std::max( Raw, low.Raw ), high.Raw ) );
|
||||
}
|
||||
|
||||
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
|
||||
// you'll need to use the Raw values directly.
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::operator*( const FixedInt<Precision>& right ) const
|
||||
{
|
||||
s64 mulres = (s64)Raw * right.Raw;
|
||||
return FixedInt<Precision>().SetRaw( (s32)(mulres / Precision) );
|
||||
}
|
||||
|
||||
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
|
||||
// you'll need to use the Raw values directly.
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::operator/( const FixedInt<Precision>& right ) const
|
||||
{
|
||||
s64 divres = Raw * Precision;
|
||||
return FixedInt<Precision>().SetRaw( (s32)(divres / right.Raw) );
|
||||
}
|
||||
|
||||
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
|
||||
// you'll need to use the Raw values directly.
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::operator*=( const FixedInt<Precision>& right )
|
||||
{
|
||||
s64 mulres = (s64)Raw * right.Raw;
|
||||
return SetRaw( (s32)(mulres / Precision) );
|
||||
}
|
||||
|
||||
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
|
||||
// you'll need to use the Raw values directly.
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::operator/=( const FixedInt<Precision>& right )
|
||||
{
|
||||
s64 divres = Raw * Precision;
|
||||
return SetRaw( (s32)(divres / right.Raw) );
|
||||
}
|
||||
|
||||
// returns TRUE if the value overflows the legal integer range of this container.
|
||||
template< int Precision >
|
||||
bool FixedInt<Precision>::OverflowCheck( int signedval )
|
||||
{
|
||||
return ( signedval >= (INT_MAX / Precision) );
|
||||
}
|
||||
|
||||
// returns TRUE if the value overflows the legal integer range of this container.
|
||||
template< int Precision >
|
||||
bool FixedInt<Precision>::OverflowCheck( double signedval )
|
||||
{
|
||||
return ( signedval >= (INT_MAX / Precision) );
|
||||
}
|
||||
|
||||
template< int Precision > int FixedInt<Precision>::GetWhole() const { return Raw / Precision; }
|
||||
template< int Precision > int FixedInt<Precision>::GetFraction() const { return Raw % Precision; }
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::SetRaw( s32 rawsrc )
|
||||
{
|
||||
Raw = rawsrc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::Round()
|
||||
{
|
||||
Raw = ToIntRounded();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::SetWhole( s32 wholepart )
|
||||
{
|
||||
pxAssert( wholepart < (INT_MAX / Precision) );
|
||||
Raw = GetFraction() + (wholepart * Precision);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::SetFraction( u32 fracpart )
|
||||
{
|
||||
Raw = (GetWhole() * Precision) + fracpart;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
wxString FixedInt<Precision>::ToString() const
|
||||
{
|
||||
return wxsFormat( L"%d.%d", GetWhole(), (GetFraction() * 100) / Precision );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
wxString FixedInt<Precision>::ToString( int fracDigits ) const
|
||||
{
|
||||
if( fracDigits == 0 ) return wxsFormat( L"%d", GetWhole() );
|
||||
|
||||
pxAssert( fracDigits <= 7 ); // higher numbers would just cause overflows and bad mojo.
|
||||
int mulby = (int)pow( 10.0, fracDigits );
|
||||
return wxsFormat( L"%d.%d", GetWhole(), (GetFraction() * mulby) / Precision );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
double FixedInt<Precision>::ToDouble() const
|
||||
{
|
||||
return ((double)Raw / (double)Precision);
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
float FixedInt<Precision>::ToFloat() const
|
||||
{
|
||||
return ((float)Raw / (float)Precision);
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
int FixedInt<Precision>::ToIntTruncated() const
|
||||
{
|
||||
return Raw / Precision;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
int FixedInt<Precision>::ToIntRounded() const
|
||||
{
|
||||
return (Raw + (Precision/2)) / Precision;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
bool FixedInt<Precision>::TryFromString( FixedInt<Precision>& dest, const wxString& parseFrom )
|
||||
{
|
||||
long whole=0, frac=0;
|
||||
const wxString beforeFirst( parseFrom.BeforeFirst( L'.' ) );
|
||||
const wxString afterFirst( parseFrom.AfterFirst( L'.' ).Mid(0, 5) );
|
||||
bool success = true;
|
||||
|
||||
if( !beforeFirst.IsEmpty() )
|
||||
success = success && beforeFirst.ToLong( &whole );
|
||||
|
||||
if( !afterFirst.IsEmpty() )
|
||||
success = success && afterFirst.ToLong( &frac );
|
||||
|
||||
if( !success ) return false;
|
||||
|
||||
dest.SetWhole( whole );
|
||||
|
||||
if( afterFirst.Length() != 0 && frac != 0 )
|
||||
{
|
||||
int fracPower = (int)pow( 10.0, (int)afterFirst.Length() );
|
||||
dest.SetFraction( (frac * Precision) / fracPower );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::FromString( const wxString& parseFrom, const FixedInt<Precision>& defval )
|
||||
{
|
||||
FixedInt<Precision> dest;
|
||||
if( !TryFromString( dest, parseFrom ) ) return defval;
|
||||
return dest;
|
||||
}
|
||||
|
||||
// This version of FromString throws a ParseError exception if the conversion fails.
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::FromString( const wxString parseFrom )
|
||||
{
|
||||
FixedInt<Precision> dest;
|
||||
if( !TryFromString( dest, parseFrom ) ) throw Exception::ParseError()
|
||||
.SetDiagMsg(wxsFormat(L"Parse error on FixedInt<%d>::FromString", Precision));
|
||||
|
||||
return dest;
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FixedPointTypes.h"
|
||||
#include <cmath> // for pow!
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>::FixedInt()
|
||||
{
|
||||
Raw = 0;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>::FixedInt( int signedval )
|
||||
{
|
||||
Raw = signedval * Precision;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>::FixedInt( double doubval )
|
||||
{
|
||||
Raw = (int)(doubval * (double)Precision);
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>::FixedInt( float floval )
|
||||
{
|
||||
Raw = (int)(floval * (float)Precision);
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::operator+( const FixedInt<Precision>& right ) const
|
||||
{
|
||||
return FixedInt<Precision>().SetRaw( Raw + right.Raw );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::operator-( const FixedInt<Precision>& right ) const
|
||||
{
|
||||
return FixedInt<Precision>().SetRaw( Raw + right.Raw );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::operator+=( const FixedInt<Precision>& right )
|
||||
{
|
||||
return SetRaw( Raw + right.Raw );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::operator-=( const FixedInt<Precision>& right )
|
||||
{
|
||||
return SetRaw( Raw + right.Raw );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::ConfineTo( const FixedInt<Precision>& low, const FixedInt<Precision>& high )
|
||||
{
|
||||
return SetRaw( std::min( std::max( Raw, low.Raw ), high.Raw ) );
|
||||
}
|
||||
|
||||
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
|
||||
// you'll need to use the Raw values directly.
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::operator*( const FixedInt<Precision>& right ) const
|
||||
{
|
||||
s64 mulres = (s64)Raw * right.Raw;
|
||||
return FixedInt<Precision>().SetRaw( (s32)(mulres / Precision) );
|
||||
}
|
||||
|
||||
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
|
||||
// you'll need to use the Raw values directly.
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::operator/( const FixedInt<Precision>& right ) const
|
||||
{
|
||||
s64 divres = Raw * Precision;
|
||||
return FixedInt<Precision>().SetRaw( (s32)(divres / right.Raw) );
|
||||
}
|
||||
|
||||
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
|
||||
// you'll need to use the Raw values directly.
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::operator*=( const FixedInt<Precision>& right )
|
||||
{
|
||||
s64 mulres = (s64)Raw * right.Raw;
|
||||
return SetRaw( (s32)(mulres / Precision) );
|
||||
}
|
||||
|
||||
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
|
||||
// you'll need to use the Raw values directly.
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::operator/=( const FixedInt<Precision>& right )
|
||||
{
|
||||
s64 divres = Raw * Precision;
|
||||
return SetRaw( (s32)(divres / right.Raw) );
|
||||
}
|
||||
|
||||
// returns TRUE if the value overflows the legal integer range of this container.
|
||||
template< int Precision >
|
||||
bool FixedInt<Precision>::OverflowCheck( int signedval )
|
||||
{
|
||||
return ( signedval >= (INT_MAX / Precision) );
|
||||
}
|
||||
|
||||
// returns TRUE if the value overflows the legal integer range of this container.
|
||||
template< int Precision >
|
||||
bool FixedInt<Precision>::OverflowCheck( double signedval )
|
||||
{
|
||||
return ( signedval >= (INT_MAX / Precision) );
|
||||
}
|
||||
|
||||
template< int Precision > int FixedInt<Precision>::GetWhole() const { return Raw / Precision; }
|
||||
template< int Precision > int FixedInt<Precision>::GetFraction() const { return Raw % Precision; }
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::SetRaw( s32 rawsrc )
|
||||
{
|
||||
Raw = rawsrc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::Round()
|
||||
{
|
||||
Raw = ToIntRounded();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::SetWhole( s32 wholepart )
|
||||
{
|
||||
pxAssert( wholepart < (INT_MAX / Precision) );
|
||||
Raw = GetFraction() + (wholepart * Precision);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision>& FixedInt<Precision>::SetFraction( u32 fracpart )
|
||||
{
|
||||
Raw = (GetWhole() * Precision) + fracpart;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
wxString FixedInt<Precision>::ToString() const
|
||||
{
|
||||
return wxsFormat( L"%d.%d", GetWhole(), (GetFraction() * 100) / Precision );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
wxString FixedInt<Precision>::ToString( int fracDigits ) const
|
||||
{
|
||||
if( fracDigits == 0 ) return wxsFormat( L"%d", GetWhole() );
|
||||
|
||||
pxAssert( fracDigits <= 7 ); // higher numbers would just cause overflows and bad mojo.
|
||||
int mulby = (int)pow( 10.0, fracDigits );
|
||||
return wxsFormat( L"%d.%d", GetWhole(), (GetFraction() * mulby) / Precision );
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
double FixedInt<Precision>::ToDouble() const
|
||||
{
|
||||
return ((double)Raw / (double)Precision);
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
float FixedInt<Precision>::ToFloat() const
|
||||
{
|
||||
return ((float)Raw / (float)Precision);
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
int FixedInt<Precision>::ToIntTruncated() const
|
||||
{
|
||||
return Raw / Precision;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
int FixedInt<Precision>::ToIntRounded() const
|
||||
{
|
||||
return (Raw + (Precision/2)) / Precision;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
bool FixedInt<Precision>::TryFromString( FixedInt<Precision>& dest, const wxString& parseFrom )
|
||||
{
|
||||
long whole=0, frac=0;
|
||||
const wxString beforeFirst( parseFrom.BeforeFirst( L'.' ) );
|
||||
const wxString afterFirst( parseFrom.AfterFirst( L'.' ).Mid(0, 5) );
|
||||
bool success = true;
|
||||
|
||||
if( !beforeFirst.IsEmpty() )
|
||||
success = success && beforeFirst.ToLong( &whole );
|
||||
|
||||
if( !afterFirst.IsEmpty() )
|
||||
success = success && afterFirst.ToLong( &frac );
|
||||
|
||||
if( !success ) return false;
|
||||
|
||||
dest.SetWhole( whole );
|
||||
|
||||
if( afterFirst.Length() != 0 && frac != 0 )
|
||||
{
|
||||
int fracPower = (int)pow( 10.0, (int)afterFirst.Length() );
|
||||
dest.SetFraction( (frac * Precision) / fracPower );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::FromString( const wxString& parseFrom, const FixedInt<Precision>& defval )
|
||||
{
|
||||
FixedInt<Precision> dest;
|
||||
if( !TryFromString( dest, parseFrom ) ) return defval;
|
||||
return dest;
|
||||
}
|
||||
|
||||
// This version of FromString throws a ParseError exception if the conversion fails.
|
||||
template< int Precision >
|
||||
FixedInt<Precision> FixedInt<Precision>::FromString( const wxString parseFrom )
|
||||
{
|
||||
FixedInt<Precision> dest;
|
||||
if( !TryFromString( dest, parseFrom ) ) throw Exception::ParseError()
|
||||
.SetDiagMsg(wxsFormat(L"Parse error on FixedInt<%d>::FromString", Precision));
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
|
|
@ -1,90 +1,90 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Threading.h"
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
// --------------------------------------------------------------------------------------
|
||||
// RwMutex
|
||||
// --------------------------------------------------------------------------------------
|
||||
class RwMutex
|
||||
{
|
||||
DeclareNoncopyableObject(RwMutex);
|
||||
|
||||
protected:
|
||||
pthread_rwlock_t m_rwlock;
|
||||
|
||||
public:
|
||||
RwMutex();
|
||||
virtual ~RwMutex() throw();
|
||||
|
||||
virtual void AcquireRead();
|
||||
virtual void AcquireWrite();
|
||||
virtual bool TryAcquireRead();
|
||||
virtual bool TryAcquireWrite();
|
||||
|
||||
virtual void Release();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseScopedReadWriteLock
|
||||
// --------------------------------------------------------------------------------------
|
||||
class BaseScopedReadWriteLock
|
||||
{
|
||||
DeclareNoncopyableObject(BaseScopedReadWriteLock);
|
||||
|
||||
protected:
|
||||
RwMutex& m_lock;
|
||||
bool m_IsLocked;
|
||||
|
||||
public:
|
||||
BaseScopedReadWriteLock( RwMutex& locker )
|
||||
: m_lock( locker )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~BaseScopedReadWriteLock() throw();
|
||||
|
||||
void Release();
|
||||
bool IsLocked() const { return m_IsLocked; }
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedReadLock / ScopedWriteLock
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ScopedReadLock : public BaseScopedReadWriteLock
|
||||
{
|
||||
public:
|
||||
ScopedReadLock( RwMutex& locker );
|
||||
virtual ~ScopedReadLock() throw() {}
|
||||
|
||||
void Acquire();
|
||||
};
|
||||
|
||||
class ScopedWriteLock : public BaseScopedReadWriteLock
|
||||
{
|
||||
public:
|
||||
ScopedWriteLock( RwMutex& locker );
|
||||
virtual ~ScopedWriteLock() throw() {}
|
||||
|
||||
void Acquire();
|
||||
|
||||
protected:
|
||||
ScopedWriteLock( RwMutex& locker, bool isTryLock );
|
||||
};
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Threading.h"
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
// --------------------------------------------------------------------------------------
|
||||
// RwMutex
|
||||
// --------------------------------------------------------------------------------------
|
||||
class RwMutex
|
||||
{
|
||||
DeclareNoncopyableObject(RwMutex);
|
||||
|
||||
protected:
|
||||
pthread_rwlock_t m_rwlock;
|
||||
|
||||
public:
|
||||
RwMutex();
|
||||
virtual ~RwMutex() throw();
|
||||
|
||||
virtual void AcquireRead();
|
||||
virtual void AcquireWrite();
|
||||
virtual bool TryAcquireRead();
|
||||
virtual bool TryAcquireWrite();
|
||||
|
||||
virtual void Release();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseScopedReadWriteLock
|
||||
// --------------------------------------------------------------------------------------
|
||||
class BaseScopedReadWriteLock
|
||||
{
|
||||
DeclareNoncopyableObject(BaseScopedReadWriteLock);
|
||||
|
||||
protected:
|
||||
RwMutex& m_lock;
|
||||
bool m_IsLocked;
|
||||
|
||||
public:
|
||||
BaseScopedReadWriteLock( RwMutex& locker )
|
||||
: m_lock( locker )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~BaseScopedReadWriteLock() throw();
|
||||
|
||||
void Release();
|
||||
bool IsLocked() const { return m_IsLocked; }
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedReadLock / ScopedWriteLock
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ScopedReadLock : public BaseScopedReadWriteLock
|
||||
{
|
||||
public:
|
||||
ScopedReadLock( RwMutex& locker );
|
||||
virtual ~ScopedReadLock() throw() {}
|
||||
|
||||
void Acquire();
|
||||
};
|
||||
|
||||
class ScopedWriteLock : public BaseScopedReadWriteLock
|
||||
{
|
||||
public:
|
||||
ScopedWriteLock( RwMutex& locker );
|
||||
virtual ~ScopedWriteLock() throw() {}
|
||||
|
||||
void Acquire();
|
||||
|
||||
protected:
|
||||
ScopedWriteLock( RwMutex& locker, bool isTryLock );
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Threading.h"
|
||||
#include "wxAppWithHelpers.h"
|
||||
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
DECLARE_EVENT_TYPE(pxEvt_ThreadedTaskComplete, -1)
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
// --------------------------------------------------------------------------------------
|
||||
// WaitForTaskDialog
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This dialog is displayed whenever the main thread is recursively waiting on multiple
|
||||
// mutexes or semaphores. wxwidgets does not support recursive yielding to pending events
|
||||
// but it *does* support opening a modal dialog, which disables the interface (preventing
|
||||
// the user from starting additional actions), and processes messages (allowing the system
|
||||
// to continue to manage threads and process logging).
|
||||
//
|
||||
class WaitForTaskDialog : public wxDialogWithHelpers
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS_NO_COPY(WaitForTaskDialog)
|
||||
|
||||
typedef wxDialogWithHelpers _parent;
|
||||
|
||||
protected:
|
||||
SynchronousActionState m_sync;
|
||||
|
||||
public:
|
||||
WaitForTaskDialog( const wxString& title=wxEmptyString, const wxString& heading=wxEmptyString );
|
||||
virtual ~WaitForTaskDialog() throw() {}
|
||||
virtual int ShowModal();
|
||||
|
||||
protected:
|
||||
void OnTaskComplete( wxCommandEvent& evt );
|
||||
//void OnTimer( wxTimerEvent& evt );
|
||||
};
|
||||
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Threading.h"
|
||||
#include "wxAppWithHelpers.h"
|
||||
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
DECLARE_EVENT_TYPE(pxEvt_ThreadedTaskComplete, -1)
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
// --------------------------------------------------------------------------------------
|
||||
// WaitForTaskDialog
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This dialog is displayed whenever the main thread is recursively waiting on multiple
|
||||
// mutexes or semaphores. wxwidgets does not support recursive yielding to pending events
|
||||
// but it *does* support opening a modal dialog, which disables the interface (preventing
|
||||
// the user from starting additional actions), and processes messages (allowing the system
|
||||
// to continue to manage threads and process logging).
|
||||
//
|
||||
class WaitForTaskDialog : public wxDialogWithHelpers
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS_NO_COPY(WaitForTaskDialog)
|
||||
|
||||
typedef wxDialogWithHelpers _parent;
|
||||
|
||||
protected:
|
||||
SynchronousActionState m_sync;
|
||||
|
||||
public:
|
||||
WaitForTaskDialog( const wxString& title=wxEmptyString, const wxString& heading=wxEmptyString );
|
||||
virtual ~WaitForTaskDialog() throw() {}
|
||||
virtual int ShowModal();
|
||||
|
||||
protected:
|
||||
void OnTaskComplete( wxCommandEvent& evt );
|
||||
//void OnTimer( wxTimerEvent& evt );
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,368 +1,368 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
DECLARE_EVENT_TYPE( pxEvt_StartIdleEventTimer, -1 )
|
||||
DECLARE_EVENT_TYPE( pxEvt_DeleteObject, -1 )
|
||||
DECLARE_EVENT_TYPE( pxEvt_DeleteThread, -1 )
|
||||
DECLARE_EVENT_TYPE( pxEvt_InvokeAction, -1 )
|
||||
DECLARE_EVENT_TYPE( pxEvt_SynchronousCommand, -1 )
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
|
||||
typedef void FnType_Void();
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SynchronousActionState
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SynchronousActionState
|
||||
{
|
||||
DeclareNoncopyableObject( SynchronousActionState );
|
||||
|
||||
protected:
|
||||
bool m_posted;
|
||||
Threading::Semaphore m_sema;
|
||||
ScopedExcept m_exception;
|
||||
|
||||
public:
|
||||
sptr return_value;
|
||||
|
||||
SynchronousActionState()
|
||||
{
|
||||
m_posted = false;
|
||||
return_value = 0;
|
||||
}
|
||||
|
||||
virtual ~SynchronousActionState() throw() {}
|
||||
|
||||
void SetException( const BaseException& ex );
|
||||
void SetException( BaseException* ex );
|
||||
|
||||
Threading::Semaphore& GetSemaphore() { return m_sema; }
|
||||
const Threading::Semaphore& GetSemaphore() const { return m_sema; }
|
||||
|
||||
void RethrowException() const;
|
||||
int WaitForResult();
|
||||
int WaitForResult_NoExceptions();
|
||||
void PostResult( int res );
|
||||
void ClearResult();
|
||||
void PostResult();
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxSimpleEvent - non-abstract implementation of wxEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Why? I mean, why is wxEvent abstract? Over-designed OO is such a bad habit. And while
|
||||
// I'm on my high horse (and it's so very high!), why use 'private'? Ever? Seriously, it
|
||||
// sucks. Stop using it, people.
|
||||
//
|
||||
class pxSimpleEvent : public wxEvent
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSimpleEvent)
|
||||
|
||||
public:
|
||||
explicit pxSimpleEvent( int evtid=0 )
|
||||
: wxEvent(0, evtid)
|
||||
{ }
|
||||
|
||||
pxSimpleEvent( wxWindowID winId, int evtid )
|
||||
: wxEvent(winId, evtid)
|
||||
{ }
|
||||
|
||||
virtual wxEvent *Clone() const { return new pxSimpleEvent(*this); }
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxActionEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxActionEvent : public wxEvent
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent)
|
||||
|
||||
protected:
|
||||
SynchronousActionState* m_state;
|
||||
|
||||
public:
|
||||
virtual ~pxActionEvent() throw() { }
|
||||
virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); }
|
||||
|
||||
explicit pxActionEvent( SynchronousActionState* sema=NULL, int msgtype=pxEvt_InvokeAction );
|
||||
explicit pxActionEvent( SynchronousActionState& sema, int msgtype=pxEvt_InvokeAction );
|
||||
pxActionEvent( const pxActionEvent& src );
|
||||
|
||||
Threading::Semaphore* GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; }
|
||||
|
||||
const SynchronousActionState* GetSyncState() const { return m_state; }
|
||||
SynchronousActionState* GetSyncState() { return m_state; }
|
||||
|
||||
void SetSyncState( SynchronousActionState* obj ) { m_state = obj; }
|
||||
void SetSyncState( SynchronousActionState& obj ) { m_state = &obj; }
|
||||
|
||||
virtual void SetException( BaseException* ex );
|
||||
void SetException( const BaseException& ex );
|
||||
|
||||
virtual void _DoInvokeEvent();
|
||||
|
||||
protected:
|
||||
// Extending classes should implement this method to perfoem whatever action it is
|
||||
// the event is supposed to do. :) Thread affinity is garaunteed to be the Main/UI
|
||||
// thread, and exceptions will be handled automatically.
|
||||
//
|
||||
// Exception note: exceptions are passed back to the thread that posted the event
|
||||
// to the queue, when possible. If the calling thread is not blocking for a result
|
||||
// from this event, then the exception will be posted to the Main/UI thread instead.
|
||||
virtual void InvokeEvent() {}
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxExceptionEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxExceptionEvent : public pxActionEvent
|
||||
{
|
||||
typedef pxActionEvent _parent;
|
||||
|
||||
protected:
|
||||
BaseException* m_except;
|
||||
|
||||
public:
|
||||
pxExceptionEvent( BaseException* ex=NULL )
|
||||
{
|
||||
m_except = ex;
|
||||
}
|
||||
|
||||
pxExceptionEvent( const BaseException& ex );
|
||||
|
||||
virtual ~pxExceptionEvent() throw()
|
||||
{
|
||||
}
|
||||
|
||||
virtual pxExceptionEvent *Clone() const { return new pxExceptionEvent(*this); }
|
||||
|
||||
protected:
|
||||
void InvokeEvent();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxSynchronousCommandEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
class pxSynchronousCommandEvent : public wxCommandEvent
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent)
|
||||
|
||||
protected:
|
||||
SynchronousActionState* m_sync;
|
||||
wxEventType m_realEvent;
|
||||
|
||||
public:
|
||||
virtual ~pxSynchronousCommandEvent() throw() { }
|
||||
virtual pxSynchronousCommandEvent *Clone() const { return new pxSynchronousCommandEvent(*this); }
|
||||
|
||||
pxSynchronousCommandEvent(SynchronousActionState* sema=NULL, wxEventType commandType = wxEVT_NULL, int winid = 0);
|
||||
pxSynchronousCommandEvent(SynchronousActionState& sema, wxEventType commandType = wxEVT_NULL, int winid = 0);
|
||||
|
||||
pxSynchronousCommandEvent(SynchronousActionState* sema, const wxCommandEvent& evt);
|
||||
pxSynchronousCommandEvent(SynchronousActionState& sema, const wxCommandEvent& evt);
|
||||
|
||||
pxSynchronousCommandEvent(const pxSynchronousCommandEvent& src);
|
||||
|
||||
Threading::Semaphore* GetSemaphore() { return m_sync ? &m_sync->GetSemaphore() : NULL; }
|
||||
wxEventType GetRealEventType() const { return m_realEvent; }
|
||||
|
||||
void SetException( BaseException* ex );
|
||||
void SetException( const BaseException& ex );
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseMessageBoxEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
class BaseMessageBoxEvent : public pxActionEvent
|
||||
{
|
||||
typedef pxActionEvent _parent;
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent)
|
||||
|
||||
protected:
|
||||
wxString m_Content;
|
||||
|
||||
public:
|
||||
virtual ~BaseMessageBoxEvent() throw() { }
|
||||
virtual BaseMessageBoxEvent *Clone() const { return new BaseMessageBoxEvent(*this); }
|
||||
|
||||
explicit BaseMessageBoxEvent( const wxString& content=wxEmptyString, SynchronousActionState* instdata=NULL );
|
||||
BaseMessageBoxEvent( const wxString& content, SynchronousActionState& instdata );
|
||||
BaseMessageBoxEvent( const BaseMessageBoxEvent& event );
|
||||
|
||||
protected:
|
||||
virtual void InvokeEvent();
|
||||
virtual int _DoDialog() const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// MsgButtons
|
||||
// --------------------------------------------------------------------------------------
|
||||
class MsgButtons
|
||||
{
|
||||
protected:
|
||||
BITFIELD32()
|
||||
bool
|
||||
m_OK :1,
|
||||
m_Cancel :1,
|
||||
m_Yes :1,
|
||||
m_No :1,
|
||||
m_AllowToAll:1,
|
||||
m_Apply :1,
|
||||
m_Abort :1,
|
||||
m_Retry :1,
|
||||
m_Ignore :1,
|
||||
m_Reset :1,
|
||||
m_Close :1;
|
||||
BITFIELD_END
|
||||
|
||||
wxString m_CustomLabel;
|
||||
wxString m_CustomLabelId;
|
||||
|
||||
public:
|
||||
MsgButtons() { bitset = 0; }
|
||||
|
||||
MsgButtons& OK() { m_OK = true; return *this; }
|
||||
MsgButtons& Cancel() { m_Cancel = true; return *this; }
|
||||
MsgButtons& Apply() { m_Apply = true; return *this; }
|
||||
MsgButtons& Yes() { m_Yes = true; return *this; }
|
||||
MsgButtons& No() { m_No = true; return *this; }
|
||||
MsgButtons& ToAll() { m_AllowToAll = true; return *this; }
|
||||
|
||||
MsgButtons& Abort() { m_Abort = true; return *this; }
|
||||
MsgButtons& Retry() { m_Retry = true; return *this; }
|
||||
MsgButtons& Ignore() { m_Ignore = true; return *this; }
|
||||
MsgButtons& Reset() { m_Reset = true; return *this; }
|
||||
MsgButtons& Close() { m_Close = true; return *this; }
|
||||
|
||||
// label - native language label displayed to user
|
||||
// id - raw ASCII identifier used in the config file (do not translate, hence char*)
|
||||
MsgButtons& Custom( const wxString& label, const char* id )
|
||||
{
|
||||
m_CustomLabel = label;
|
||||
m_CustomLabelId = fromUTF8(id);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MsgButtons& OKCancel() { m_OK = m_Cancel = true; return *this; }
|
||||
MsgButtons& YesNo() { m_Yes = m_No = true; return *this; }
|
||||
|
||||
bool HasOK() const { return m_OK; }
|
||||
bool HasCancel() const { return m_Cancel; }
|
||||
bool HasApply() const { return m_Apply; }
|
||||
bool HasYes() const { return m_Yes; }
|
||||
bool HasNo() const { return m_No; }
|
||||
bool AllowsToAll() const{ return m_AllowToAll; }
|
||||
|
||||
bool HasAbort() const { return m_Abort; }
|
||||
bool HasRetry() const { return m_Retry; }
|
||||
bool HasIgnore() const { return m_Ignore; }
|
||||
bool HasReset() const { return m_Reset; }
|
||||
bool HasClose() const { return m_Close; }
|
||||
|
||||
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
|
||||
const wxString& GetCustomLabel() const { return m_CustomLabel; }
|
||||
const wxString& GetCustomLabelId() const { return m_CustomLabelId; }
|
||||
|
||||
bool Allows( wxWindowID id ) const;
|
||||
void SetBestFocus( wxWindow* dialog ) const;
|
||||
void SetBestFocus( wxWindow& dialog ) const;
|
||||
|
||||
bool operator ==( const MsgButtons& right ) const
|
||||
{
|
||||
return OpEqu( bitset );
|
||||
}
|
||||
|
||||
bool operator !=( const MsgButtons& right ) const
|
||||
{
|
||||
return !OpEqu( bitset );
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxMessageBoxEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This event type is used to transfer message boxes to the main UI thread, and return the
|
||||
// result of the box. It's the only way a message box can be issued from non-main threads
|
||||
// with complete safety in wx2.8.
|
||||
//
|
||||
// For simplicity sake this message box only supports two basic designs. The main design
|
||||
// is a generic message box with confirmation buttons of your choosing. Additionally you
|
||||
// can specify a "scrollableContent" text string, which is added into a read-only richtext
|
||||
// control similar to the console logs and such.
|
||||
//
|
||||
// Future consideration: If wxWidgets 3.0 has improved thread safety, then it should probably
|
||||
// be reasonable for it to work with a more flexable model where the dialog can be created
|
||||
// on a child thread, passed to the main thread, where ShowModal() is run (keeping the nested
|
||||
// message pumps on the main thread where they belong). But so far this is not possible,
|
||||
// because of various subtle issues in wx2.8 design.
|
||||
//
|
||||
class pxMessageBoxEvent : public BaseMessageBoxEvent
|
||||
{
|
||||
typedef BaseMessageBoxEvent _parent;
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent)
|
||||
|
||||
protected:
|
||||
wxString m_Title;
|
||||
MsgButtons m_Buttons;
|
||||
|
||||
public:
|
||||
virtual ~pxMessageBoxEvent() throw() { }
|
||||
virtual pxMessageBoxEvent *Clone() const { return new pxMessageBoxEvent(*this); }
|
||||
|
||||
pxMessageBoxEvent() {}
|
||||
pxMessageBoxEvent( const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState& instdata );
|
||||
pxMessageBoxEvent( const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState* instdata=NULL );
|
||||
pxMessageBoxEvent( const pxMessageBoxEvent& event );
|
||||
|
||||
protected:
|
||||
int _DoDialog() const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxAssertionEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxAssertionEvent : public BaseMessageBoxEvent
|
||||
{
|
||||
typedef BaseMessageBoxEvent _parent;
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN( pxAssertionEvent )
|
||||
|
||||
protected:
|
||||
wxString m_Stacktrace;
|
||||
|
||||
public:
|
||||
virtual ~pxAssertionEvent() throw() { }
|
||||
virtual pxAssertionEvent *Clone() const { return new pxAssertionEvent(*this); }
|
||||
|
||||
pxAssertionEvent( const wxString& content=wxEmptyString, const wxString& trace=wxEmptyString, SynchronousActionState* instdata=NULL );
|
||||
pxAssertionEvent( const wxString& content, const wxString& trace, SynchronousActionState& instdata );
|
||||
pxAssertionEvent( const pxAssertionEvent& event );
|
||||
|
||||
pxAssertionEvent& SetStacktrace( const wxString& trace );
|
||||
|
||||
protected:
|
||||
int _DoDialog() const;
|
||||
};
|
||||
|
||||
|
||||
typedef void (wxEvtHandler::*pxSyncronousEventFunction)(pxSynchronousCommandEvent&);
|
||||
|
||||
#define pxSynchronousEventHandler(func) \
|
||||
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(pxSyncronousEventFunction, &func )
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
DECLARE_EVENT_TYPE( pxEvt_StartIdleEventTimer, -1 )
|
||||
DECLARE_EVENT_TYPE( pxEvt_DeleteObject, -1 )
|
||||
DECLARE_EVENT_TYPE( pxEvt_DeleteThread, -1 )
|
||||
DECLARE_EVENT_TYPE( pxEvt_InvokeAction, -1 )
|
||||
DECLARE_EVENT_TYPE( pxEvt_SynchronousCommand, -1 )
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
|
||||
typedef void FnType_Void();
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SynchronousActionState
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SynchronousActionState
|
||||
{
|
||||
DeclareNoncopyableObject( SynchronousActionState );
|
||||
|
||||
protected:
|
||||
bool m_posted;
|
||||
Threading::Semaphore m_sema;
|
||||
ScopedExcept m_exception;
|
||||
|
||||
public:
|
||||
sptr return_value;
|
||||
|
||||
SynchronousActionState()
|
||||
{
|
||||
m_posted = false;
|
||||
return_value = 0;
|
||||
}
|
||||
|
||||
virtual ~SynchronousActionState() throw() {}
|
||||
|
||||
void SetException( const BaseException& ex );
|
||||
void SetException( BaseException* ex );
|
||||
|
||||
Threading::Semaphore& GetSemaphore() { return m_sema; }
|
||||
const Threading::Semaphore& GetSemaphore() const { return m_sema; }
|
||||
|
||||
void RethrowException() const;
|
||||
int WaitForResult();
|
||||
int WaitForResult_NoExceptions();
|
||||
void PostResult( int res );
|
||||
void ClearResult();
|
||||
void PostResult();
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxSimpleEvent - non-abstract implementation of wxEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Why? I mean, why is wxEvent abstract? Over-designed OO is such a bad habit. And while
|
||||
// I'm on my high horse (and it's so very high!), why use 'private'? Ever? Seriously, it
|
||||
// sucks. Stop using it, people.
|
||||
//
|
||||
class pxSimpleEvent : public wxEvent
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSimpleEvent)
|
||||
|
||||
public:
|
||||
explicit pxSimpleEvent( int evtid=0 )
|
||||
: wxEvent(0, evtid)
|
||||
{ }
|
||||
|
||||
pxSimpleEvent( wxWindowID winId, int evtid )
|
||||
: wxEvent(winId, evtid)
|
||||
{ }
|
||||
|
||||
virtual wxEvent *Clone() const { return new pxSimpleEvent(*this); }
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxActionEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxActionEvent : public wxEvent
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent)
|
||||
|
||||
protected:
|
||||
SynchronousActionState* m_state;
|
||||
|
||||
public:
|
||||
virtual ~pxActionEvent() throw() { }
|
||||
virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); }
|
||||
|
||||
explicit pxActionEvent( SynchronousActionState* sema=NULL, int msgtype=pxEvt_InvokeAction );
|
||||
explicit pxActionEvent( SynchronousActionState& sema, int msgtype=pxEvt_InvokeAction );
|
||||
pxActionEvent( const pxActionEvent& src );
|
||||
|
||||
Threading::Semaphore* GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; }
|
||||
|
||||
const SynchronousActionState* GetSyncState() const { return m_state; }
|
||||
SynchronousActionState* GetSyncState() { return m_state; }
|
||||
|
||||
void SetSyncState( SynchronousActionState* obj ) { m_state = obj; }
|
||||
void SetSyncState( SynchronousActionState& obj ) { m_state = &obj; }
|
||||
|
||||
virtual void SetException( BaseException* ex );
|
||||
void SetException( const BaseException& ex );
|
||||
|
||||
virtual void _DoInvokeEvent();
|
||||
|
||||
protected:
|
||||
// Extending classes should implement this method to perfoem whatever action it is
|
||||
// the event is supposed to do. :) Thread affinity is garaunteed to be the Main/UI
|
||||
// thread, and exceptions will be handled automatically.
|
||||
//
|
||||
// Exception note: exceptions are passed back to the thread that posted the event
|
||||
// to the queue, when possible. If the calling thread is not blocking for a result
|
||||
// from this event, then the exception will be posted to the Main/UI thread instead.
|
||||
virtual void InvokeEvent() {}
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxExceptionEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxExceptionEvent : public pxActionEvent
|
||||
{
|
||||
typedef pxActionEvent _parent;
|
||||
|
||||
protected:
|
||||
BaseException* m_except;
|
||||
|
||||
public:
|
||||
pxExceptionEvent( BaseException* ex=NULL )
|
||||
{
|
||||
m_except = ex;
|
||||
}
|
||||
|
||||
pxExceptionEvent( const BaseException& ex );
|
||||
|
||||
virtual ~pxExceptionEvent() throw()
|
||||
{
|
||||
}
|
||||
|
||||
virtual pxExceptionEvent *Clone() const { return new pxExceptionEvent(*this); }
|
||||
|
||||
protected:
|
||||
void InvokeEvent();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxSynchronousCommandEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
class pxSynchronousCommandEvent : public wxCommandEvent
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent)
|
||||
|
||||
protected:
|
||||
SynchronousActionState* m_sync;
|
||||
wxEventType m_realEvent;
|
||||
|
||||
public:
|
||||
virtual ~pxSynchronousCommandEvent() throw() { }
|
||||
virtual pxSynchronousCommandEvent *Clone() const { return new pxSynchronousCommandEvent(*this); }
|
||||
|
||||
pxSynchronousCommandEvent(SynchronousActionState* sema=NULL, wxEventType commandType = wxEVT_NULL, int winid = 0);
|
||||
pxSynchronousCommandEvent(SynchronousActionState& sema, wxEventType commandType = wxEVT_NULL, int winid = 0);
|
||||
|
||||
pxSynchronousCommandEvent(SynchronousActionState* sema, const wxCommandEvent& evt);
|
||||
pxSynchronousCommandEvent(SynchronousActionState& sema, const wxCommandEvent& evt);
|
||||
|
||||
pxSynchronousCommandEvent(const pxSynchronousCommandEvent& src);
|
||||
|
||||
Threading::Semaphore* GetSemaphore() { return m_sync ? &m_sync->GetSemaphore() : NULL; }
|
||||
wxEventType GetRealEventType() const { return m_realEvent; }
|
||||
|
||||
void SetException( BaseException* ex );
|
||||
void SetException( const BaseException& ex );
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseMessageBoxEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
class BaseMessageBoxEvent : public pxActionEvent
|
||||
{
|
||||
typedef pxActionEvent _parent;
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent)
|
||||
|
||||
protected:
|
||||
wxString m_Content;
|
||||
|
||||
public:
|
||||
virtual ~BaseMessageBoxEvent() throw() { }
|
||||
virtual BaseMessageBoxEvent *Clone() const { return new BaseMessageBoxEvent(*this); }
|
||||
|
||||
explicit BaseMessageBoxEvent( const wxString& content=wxEmptyString, SynchronousActionState* instdata=NULL );
|
||||
BaseMessageBoxEvent( const wxString& content, SynchronousActionState& instdata );
|
||||
BaseMessageBoxEvent( const BaseMessageBoxEvent& event );
|
||||
|
||||
protected:
|
||||
virtual void InvokeEvent();
|
||||
virtual int _DoDialog() const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// MsgButtons
|
||||
// --------------------------------------------------------------------------------------
|
||||
class MsgButtons
|
||||
{
|
||||
protected:
|
||||
BITFIELD32()
|
||||
bool
|
||||
m_OK :1,
|
||||
m_Cancel :1,
|
||||
m_Yes :1,
|
||||
m_No :1,
|
||||
m_AllowToAll:1,
|
||||
m_Apply :1,
|
||||
m_Abort :1,
|
||||
m_Retry :1,
|
||||
m_Ignore :1,
|
||||
m_Reset :1,
|
||||
m_Close :1;
|
||||
BITFIELD_END
|
||||
|
||||
wxString m_CustomLabel;
|
||||
wxString m_CustomLabelId;
|
||||
|
||||
public:
|
||||
MsgButtons() { bitset = 0; }
|
||||
|
||||
MsgButtons& OK() { m_OK = true; return *this; }
|
||||
MsgButtons& Cancel() { m_Cancel = true; return *this; }
|
||||
MsgButtons& Apply() { m_Apply = true; return *this; }
|
||||
MsgButtons& Yes() { m_Yes = true; return *this; }
|
||||
MsgButtons& No() { m_No = true; return *this; }
|
||||
MsgButtons& ToAll() { m_AllowToAll = true; return *this; }
|
||||
|
||||
MsgButtons& Abort() { m_Abort = true; return *this; }
|
||||
MsgButtons& Retry() { m_Retry = true; return *this; }
|
||||
MsgButtons& Ignore() { m_Ignore = true; return *this; }
|
||||
MsgButtons& Reset() { m_Reset = true; return *this; }
|
||||
MsgButtons& Close() { m_Close = true; return *this; }
|
||||
|
||||
// label - native language label displayed to user
|
||||
// id - raw ASCII identifier used in the config file (do not translate, hence char*)
|
||||
MsgButtons& Custom( const wxString& label, const char* id )
|
||||
{
|
||||
m_CustomLabel = label;
|
||||
m_CustomLabelId = fromUTF8(id);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MsgButtons& OKCancel() { m_OK = m_Cancel = true; return *this; }
|
||||
MsgButtons& YesNo() { m_Yes = m_No = true; return *this; }
|
||||
|
||||
bool HasOK() const { return m_OK; }
|
||||
bool HasCancel() const { return m_Cancel; }
|
||||
bool HasApply() const { return m_Apply; }
|
||||
bool HasYes() const { return m_Yes; }
|
||||
bool HasNo() const { return m_No; }
|
||||
bool AllowsToAll() const{ return m_AllowToAll; }
|
||||
|
||||
bool HasAbort() const { return m_Abort; }
|
||||
bool HasRetry() const { return m_Retry; }
|
||||
bool HasIgnore() const { return m_Ignore; }
|
||||
bool HasReset() const { return m_Reset; }
|
||||
bool HasClose() const { return m_Close; }
|
||||
|
||||
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
|
||||
const wxString& GetCustomLabel() const { return m_CustomLabel; }
|
||||
const wxString& GetCustomLabelId() const { return m_CustomLabelId; }
|
||||
|
||||
bool Allows( wxWindowID id ) const;
|
||||
void SetBestFocus( wxWindow* dialog ) const;
|
||||
void SetBestFocus( wxWindow& dialog ) const;
|
||||
|
||||
bool operator ==( const MsgButtons& right ) const
|
||||
{
|
||||
return OpEqu( bitset );
|
||||
}
|
||||
|
||||
bool operator !=( const MsgButtons& right ) const
|
||||
{
|
||||
return !OpEqu( bitset );
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxMessageBoxEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This event type is used to transfer message boxes to the main UI thread, and return the
|
||||
// result of the box. It's the only way a message box can be issued from non-main threads
|
||||
// with complete safety in wx2.8.
|
||||
//
|
||||
// For simplicity sake this message box only supports two basic designs. The main design
|
||||
// is a generic message box with confirmation buttons of your choosing. Additionally you
|
||||
// can specify a "scrollableContent" text string, which is added into a read-only richtext
|
||||
// control similar to the console logs and such.
|
||||
//
|
||||
// Future consideration: If wxWidgets 3.0 has improved thread safety, then it should probably
|
||||
// be reasonable for it to work with a more flexable model where the dialog can be created
|
||||
// on a child thread, passed to the main thread, where ShowModal() is run (keeping the nested
|
||||
// message pumps on the main thread where they belong). But so far this is not possible,
|
||||
// because of various subtle issues in wx2.8 design.
|
||||
//
|
||||
class pxMessageBoxEvent : public BaseMessageBoxEvent
|
||||
{
|
||||
typedef BaseMessageBoxEvent _parent;
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent)
|
||||
|
||||
protected:
|
||||
wxString m_Title;
|
||||
MsgButtons m_Buttons;
|
||||
|
||||
public:
|
||||
virtual ~pxMessageBoxEvent() throw() { }
|
||||
virtual pxMessageBoxEvent *Clone() const { return new pxMessageBoxEvent(*this); }
|
||||
|
||||
pxMessageBoxEvent() {}
|
||||
pxMessageBoxEvent( const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState& instdata );
|
||||
pxMessageBoxEvent( const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState* instdata=NULL );
|
||||
pxMessageBoxEvent( const pxMessageBoxEvent& event );
|
||||
|
||||
protected:
|
||||
int _DoDialog() const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxAssertionEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxAssertionEvent : public BaseMessageBoxEvent
|
||||
{
|
||||
typedef BaseMessageBoxEvent _parent;
|
||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN( pxAssertionEvent )
|
||||
|
||||
protected:
|
||||
wxString m_Stacktrace;
|
||||
|
||||
public:
|
||||
virtual ~pxAssertionEvent() throw() { }
|
||||
virtual pxAssertionEvent *Clone() const { return new pxAssertionEvent(*this); }
|
||||
|
||||
pxAssertionEvent( const wxString& content=wxEmptyString, const wxString& trace=wxEmptyString, SynchronousActionState* instdata=NULL );
|
||||
pxAssertionEvent( const wxString& content, const wxString& trace, SynchronousActionState& instdata );
|
||||
pxAssertionEvent( const pxAssertionEvent& event );
|
||||
|
||||
pxAssertionEvent& SetStacktrace( const wxString& trace );
|
||||
|
||||
protected:
|
||||
int _DoDialog() const;
|
||||
};
|
||||
|
||||
|
||||
typedef void (wxEvtHandler::*pxSyncronousEventFunction)(pxSynchronousCommandEvent&);
|
||||
|
||||
#define pxSynchronousEventHandler(func) \
|
||||
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(pxSyncronousEventFunction, &func )
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Forward Declarations Section
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
class wxOutputStream;
|
||||
class wxFileOutputStream;
|
||||
class wxFFileOutputStream;
|
||||
|
||||
class wxStreamBase;
|
||||
class wxInputStream;
|
||||
class wxFileInputStream;
|
||||
class wxFFileInputStream;
|
||||
|
||||
class wxPoint;
|
||||
class wxRect;
|
||||
class wxSize;
|
||||
|
||||
class pxInputStream;
|
||||
class pxOutputStream;
|
||||
|
||||
extern const wxSize wxDefaultSize;
|
||||
extern const wxPoint wxDefaultPosition;
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
class Mutex;
|
||||
class Semaphore;
|
||||
class pxThread;
|
||||
}
|
||||
|
||||
namespace Exception
|
||||
{
|
||||
class BaseException;
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Forward Declarations Section
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
class wxOutputStream;
|
||||
class wxFileOutputStream;
|
||||
class wxFFileOutputStream;
|
||||
|
||||
class wxStreamBase;
|
||||
class wxInputStream;
|
||||
class wxFileInputStream;
|
||||
class wxFFileInputStream;
|
||||
|
||||
class wxPoint;
|
||||
class wxRect;
|
||||
class wxSize;
|
||||
|
||||
class pxInputStream;
|
||||
class pxOutputStream;
|
||||
|
||||
extern const wxSize wxDefaultSize;
|
||||
extern const wxPoint wxDefaultPosition;
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
class Mutex;
|
||||
class Semaphore;
|
||||
class pxThread;
|
||||
}
|
||||
|
||||
namespace Exception
|
||||
{
|
||||
class BaseException;
|
||||
}
|
||||
|
|
|
@ -1,116 +1,116 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wx/filefn.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxStreamBase
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxStreamBase
|
||||
{
|
||||
DeclareNoncopyableObject(pxStreamBase);
|
||||
|
||||
protected:
|
||||
// Filename of the stream, provided by the creator/caller. This is typically used *only*
|
||||
// for generating comprehensive error messages when an error occurs (the stream name is
|
||||
// passed to the exception handlers).
|
||||
wxString m_filename;
|
||||
|
||||
public:
|
||||
pxStreamBase(const wxString& filename);
|
||||
virtual ~pxStreamBase() throw() {}
|
||||
|
||||
// Implementing classes should return the base wxStream object (usually either a wxInputStream
|
||||
// or wxOputStream derivative).
|
||||
virtual wxStreamBase* GetWxStreamBase() const=0;
|
||||
virtual void Close()=0;
|
||||
virtual wxFileOffset Tell() const=0;
|
||||
virtual wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart )=0;
|
||||
|
||||
virtual wxFileOffset Length() const;
|
||||
bool IsOk() const;
|
||||
wxString GetStreamName() const { return m_filename; }
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxOutputStream
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxOutputStream : public pxStreamBase
|
||||
{
|
||||
DeclareNoncopyableObject(pxOutputStream);
|
||||
|
||||
protected:
|
||||
ScopedPtr<wxOutputStream> m_stream_out;
|
||||
|
||||
public:
|
||||
pxOutputStream(const wxString& filename, ScopedPtr<wxOutputStream>& output);
|
||||
pxOutputStream(const wxString& filename, wxOutputStream* output);
|
||||
|
||||
virtual ~pxOutputStream() throw() {}
|
||||
virtual void Write( const void* data, size_t size );
|
||||
|
||||
void SetStream( const wxString& filename, ScopedPtr<wxOutputStream>& stream );
|
||||
void SetStream( const wxString& filename, wxOutputStream* stream );
|
||||
|
||||
void Close() { m_stream_out.Delete(); }
|
||||
|
||||
virtual wxStreamBase* GetWxStreamBase() const;
|
||||
|
||||
template< typename T >
|
||||
void Write( const T& data )
|
||||
{
|
||||
Write( &data, sizeof(data) );
|
||||
}
|
||||
|
||||
wxFileOffset Tell() const;
|
||||
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxInputStream
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxInputStream : public pxStreamBase
|
||||
{
|
||||
DeclareNoncopyableObject(pxInputStream);
|
||||
|
||||
protected:
|
||||
ScopedPtr<wxInputStream> m_stream_in;
|
||||
|
||||
public:
|
||||
pxInputStream(const wxString& filename, ScopedPtr<wxInputStream>& input);
|
||||
pxInputStream(const wxString& filename, wxInputStream* input);
|
||||
|
||||
virtual ~pxInputStream() throw() {}
|
||||
virtual void Read( void* dest, size_t size );
|
||||
|
||||
void SetStream( const wxString& filename, ScopedPtr<wxInputStream>& stream );
|
||||
void SetStream( const wxString& filename, wxInputStream* stream );
|
||||
|
||||
void Close() { m_stream_in.Delete(); }
|
||||
|
||||
virtual wxStreamBase* GetWxStreamBase() const;
|
||||
|
||||
template< typename T >
|
||||
void Read( T& dest )
|
||||
{
|
||||
Read( &dest, sizeof(dest) );
|
||||
}
|
||||
|
||||
wxFileOffset Tell() const;
|
||||
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
|
||||
};
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wx/filefn.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxStreamBase
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxStreamBase
|
||||
{
|
||||
DeclareNoncopyableObject(pxStreamBase);
|
||||
|
||||
protected:
|
||||
// Filename of the stream, provided by the creator/caller. This is typically used *only*
|
||||
// for generating comprehensive error messages when an error occurs (the stream name is
|
||||
// passed to the exception handlers).
|
||||
wxString m_filename;
|
||||
|
||||
public:
|
||||
pxStreamBase(const wxString& filename);
|
||||
virtual ~pxStreamBase() throw() {}
|
||||
|
||||
// Implementing classes should return the base wxStream object (usually either a wxInputStream
|
||||
// or wxOputStream derivative).
|
||||
virtual wxStreamBase* GetWxStreamBase() const=0;
|
||||
virtual void Close()=0;
|
||||
virtual wxFileOffset Tell() const=0;
|
||||
virtual wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart )=0;
|
||||
|
||||
virtual wxFileOffset Length() const;
|
||||
bool IsOk() const;
|
||||
wxString GetStreamName() const { return m_filename; }
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxOutputStream
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxOutputStream : public pxStreamBase
|
||||
{
|
||||
DeclareNoncopyableObject(pxOutputStream);
|
||||
|
||||
protected:
|
||||
ScopedPtr<wxOutputStream> m_stream_out;
|
||||
|
||||
public:
|
||||
pxOutputStream(const wxString& filename, ScopedPtr<wxOutputStream>& output);
|
||||
pxOutputStream(const wxString& filename, wxOutputStream* output);
|
||||
|
||||
virtual ~pxOutputStream() throw() {}
|
||||
virtual void Write( const void* data, size_t size );
|
||||
|
||||
void SetStream( const wxString& filename, ScopedPtr<wxOutputStream>& stream );
|
||||
void SetStream( const wxString& filename, wxOutputStream* stream );
|
||||
|
||||
void Close() { m_stream_out.Delete(); }
|
||||
|
||||
virtual wxStreamBase* GetWxStreamBase() const;
|
||||
|
||||
template< typename T >
|
||||
void Write( const T& data )
|
||||
{
|
||||
Write( &data, sizeof(data) );
|
||||
}
|
||||
|
||||
wxFileOffset Tell() const;
|
||||
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxInputStream
|
||||
// --------------------------------------------------------------------------------------
|
||||
class pxInputStream : public pxStreamBase
|
||||
{
|
||||
DeclareNoncopyableObject(pxInputStream);
|
||||
|
||||
protected:
|
||||
ScopedPtr<wxInputStream> m_stream_in;
|
||||
|
||||
public:
|
||||
pxInputStream(const wxString& filename, ScopedPtr<wxInputStream>& input);
|
||||
pxInputStream(const wxString& filename, wxInputStream* input);
|
||||
|
||||
virtual ~pxInputStream() throw() {}
|
||||
virtual void Read( void* dest, size_t size );
|
||||
|
||||
void SetStream( const wxString& filename, ScopedPtr<wxInputStream>& stream );
|
||||
void SetStream( const wxString& filename, wxInputStream* stream );
|
||||
|
||||
void Close() { m_stream_in.Delete(); }
|
||||
|
||||
virtual wxStreamBase* GetWxStreamBase() const;
|
||||
|
||||
template< typename T >
|
||||
void Read( T& dest )
|
||||
{
|
||||
Read( &dest, sizeof(dest) );
|
||||
}
|
||||
|
||||
wxFileOffset Tell() const;
|
||||
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
|
||||
};
|
||||
|
|
|
@ -1,112 +1,112 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "RwMutex.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// RwMutex
|
||||
// --------------------------------------------------------------------------------------
|
||||
Threading::RwMutex::RwMutex()
|
||||
{
|
||||
pthread_rwlock_init( &m_rwlock, NULL );
|
||||
}
|
||||
|
||||
Threading::RwMutex::~RwMutex() throw()
|
||||
{
|
||||
pthread_rwlock_destroy( &m_rwlock );
|
||||
}
|
||||
|
||||
void Threading::RwMutex::AcquireRead()
|
||||
{
|
||||
pthread_rwlock_rdlock( &m_rwlock );
|
||||
}
|
||||
|
||||
void Threading::RwMutex::AcquireWrite()
|
||||
{
|
||||
pthread_rwlock_wrlock( &m_rwlock );
|
||||
}
|
||||
|
||||
bool Threading::RwMutex::TryAcquireRead()
|
||||
{
|
||||
return pthread_rwlock_tryrdlock( &m_rwlock ) != EBUSY;
|
||||
}
|
||||
|
||||
bool Threading::RwMutex::TryAcquireWrite()
|
||||
{
|
||||
return pthread_rwlock_trywrlock( &m_rwlock ) != EBUSY;
|
||||
}
|
||||
|
||||
void Threading::RwMutex::Release()
|
||||
{
|
||||
pthread_rwlock_unlock( &m_rwlock );
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
//
|
||||
// --------------------------------------------------------------------------------------
|
||||
Threading::BaseScopedReadWriteLock::~BaseScopedReadWriteLock() throw()
|
||||
{
|
||||
if( m_IsLocked )
|
||||
m_lock.Release();
|
||||
}
|
||||
|
||||
// Provides manual unlocking of a scoped lock prior to object destruction.
|
||||
void Threading::BaseScopedReadWriteLock::Release()
|
||||
{
|
||||
if( !m_IsLocked ) return;
|
||||
m_IsLocked = false;
|
||||
m_lock.Release();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedReadLock / ScopedWriteLock
|
||||
// --------------------------------------------------------------------------------------
|
||||
Threading::ScopedReadLock::ScopedReadLock( RwMutex& locker )
|
||||
: BaseScopedReadWriteLock( locker )
|
||||
{
|
||||
m_IsLocked = true;
|
||||
m_lock.AcquireRead();
|
||||
}
|
||||
|
||||
// provides manual locking of a scoped lock, to re-lock after a manual unlocking.
|
||||
void Threading::ScopedReadLock::Acquire()
|
||||
{
|
||||
if( m_IsLocked ) return;
|
||||
m_lock.AcquireRead();
|
||||
m_IsLocked = true;
|
||||
}
|
||||
|
||||
Threading::ScopedWriteLock::ScopedWriteLock( RwMutex& locker )
|
||||
: BaseScopedReadWriteLock( locker )
|
||||
{
|
||||
m_IsLocked = true;
|
||||
m_lock.AcquireWrite();
|
||||
}
|
||||
|
||||
// provides manual locking of a scoped lock, to re-lock after a manual unlocking.
|
||||
void Threading::ScopedWriteLock::Acquire()
|
||||
{
|
||||
if( m_IsLocked ) return;
|
||||
m_lock.AcquireWrite();
|
||||
m_IsLocked = true;
|
||||
}
|
||||
|
||||
// Special constructor used by ScopedTryLock
|
||||
Threading::ScopedWriteLock::ScopedWriteLock( RwMutex& locker, bool isTryLock )
|
||||
: BaseScopedReadWriteLock( locker )
|
||||
{
|
||||
//m_IsLocked = isTryLock ? m_lock.TryAcquireWrite() : false;
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "RwMutex.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// RwMutex
|
||||
// --------------------------------------------------------------------------------------
|
||||
Threading::RwMutex::RwMutex()
|
||||
{
|
||||
pthread_rwlock_init( &m_rwlock, NULL );
|
||||
}
|
||||
|
||||
Threading::RwMutex::~RwMutex() throw()
|
||||
{
|
||||
pthread_rwlock_destroy( &m_rwlock );
|
||||
}
|
||||
|
||||
void Threading::RwMutex::AcquireRead()
|
||||
{
|
||||
pthread_rwlock_rdlock( &m_rwlock );
|
||||
}
|
||||
|
||||
void Threading::RwMutex::AcquireWrite()
|
||||
{
|
||||
pthread_rwlock_wrlock( &m_rwlock );
|
||||
}
|
||||
|
||||
bool Threading::RwMutex::TryAcquireRead()
|
||||
{
|
||||
return pthread_rwlock_tryrdlock( &m_rwlock ) != EBUSY;
|
||||
}
|
||||
|
||||
bool Threading::RwMutex::TryAcquireWrite()
|
||||
{
|
||||
return pthread_rwlock_trywrlock( &m_rwlock ) != EBUSY;
|
||||
}
|
||||
|
||||
void Threading::RwMutex::Release()
|
||||
{
|
||||
pthread_rwlock_unlock( &m_rwlock );
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
//
|
||||
// --------------------------------------------------------------------------------------
|
||||
Threading::BaseScopedReadWriteLock::~BaseScopedReadWriteLock() throw()
|
||||
{
|
||||
if( m_IsLocked )
|
||||
m_lock.Release();
|
||||
}
|
||||
|
||||
// Provides manual unlocking of a scoped lock prior to object destruction.
|
||||
void Threading::BaseScopedReadWriteLock::Release()
|
||||
{
|
||||
if( !m_IsLocked ) return;
|
||||
m_IsLocked = false;
|
||||
m_lock.Release();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedReadLock / ScopedWriteLock
|
||||
// --------------------------------------------------------------------------------------
|
||||
Threading::ScopedReadLock::ScopedReadLock( RwMutex& locker )
|
||||
: BaseScopedReadWriteLock( locker )
|
||||
{
|
||||
m_IsLocked = true;
|
||||
m_lock.AcquireRead();
|
||||
}
|
||||
|
||||
// provides manual locking of a scoped lock, to re-lock after a manual unlocking.
|
||||
void Threading::ScopedReadLock::Acquire()
|
||||
{
|
||||
if( m_IsLocked ) return;
|
||||
m_lock.AcquireRead();
|
||||
m_IsLocked = true;
|
||||
}
|
||||
|
||||
Threading::ScopedWriteLock::ScopedWriteLock( RwMutex& locker )
|
||||
: BaseScopedReadWriteLock( locker )
|
||||
{
|
||||
m_IsLocked = true;
|
||||
m_lock.AcquireWrite();
|
||||
}
|
||||
|
||||
// provides manual locking of a scoped lock, to re-lock after a manual unlocking.
|
||||
void Threading::ScopedWriteLock::Acquire()
|
||||
{
|
||||
if( m_IsLocked ) return;
|
||||
m_lock.AcquireWrite();
|
||||
m_IsLocked = true;
|
||||
}
|
||||
|
||||
// Special constructor used by ScopedTryLock
|
||||
Threading::ScopedWriteLock::ScopedWriteLock( RwMutex& locker, bool isTryLock )
|
||||
: BaseScopedReadWriteLock( locker )
|
||||
{
|
||||
//m_IsLocked = isTryLock ? m_lock.TryAcquireWrite() : false;
|
||||
}
|
||||
|
|
|
@ -1,83 +1,83 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ThreadingDialogs.h"
|
||||
#include "pxStaticText.h"
|
||||
|
||||
using namespace pxSizerFlags;
|
||||
|
||||
DEFINE_EVENT_TYPE(pxEvt_ThreadedTaskComplete);
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// WaitForTaskDialog Implementations
|
||||
// --------------------------------------------------------------------------------------
|
||||
IMPLEMENT_DYNAMIC_CLASS(WaitForTaskDialog, wxDialogWithHelpers)
|
||||
|
||||
Threading::WaitForTaskDialog::WaitForTaskDialog( const wxString& title, const wxString& heading )
|
||||
: wxDialogWithHelpers( NULL, _("Waiting for tasks...") )
|
||||
//, m_Timer(this)
|
||||
{
|
||||
SetMinWidth( 300 );
|
||||
|
||||
//m_sem = sem;
|
||||
//m_mutex = mutex;
|
||||
|
||||
wxString m_title( title );
|
||||
wxString m_heading( heading );
|
||||
|
||||
if( m_title.IsEmpty() ) m_title = _("Waiting for task...");
|
||||
if( m_heading.IsEmpty() ) m_heading = m_title;
|
||||
|
||||
Connect( pxEvt_ThreadedTaskComplete, wxCommandEventHandler(WaitForTaskDialog::OnTaskComplete) );
|
||||
|
||||
*this += 12;
|
||||
*this += Heading(m_heading).Unwrapped() | StdExpand();
|
||||
*this += 12;
|
||||
|
||||
// TODO : Implement a cancel button. Not quite sure the best way to do
|
||||
// that, since it requires a thread or event handler context, or something.
|
||||
|
||||
//applyDlg += new wxButton( &applyDlg, wxID_CANCEL ) | pxCenter;
|
||||
//applyDlg += 6;
|
||||
|
||||
//Connect( m_Timer.GetId(), wxEVT_TIMER, wxTimerEventHandler(WaitForTaskDialog::OnTimer) );
|
||||
//m_Timer.Start( 200 );
|
||||
//GetSysExecutorThread().PostEvent( new SysExecEvent_ApplyPlugins( this, m_sync ) );
|
||||
}
|
||||
|
||||
void Threading::WaitForTaskDialog::OnTaskComplete( wxCommandEvent& evt )
|
||||
{
|
||||
evt.Skip();
|
||||
|
||||
// Note: we don't throw exceptions from the pending task here.
|
||||
// Instead we wait until we exit the modal loop below -- this gives
|
||||
// the caller a chance to handle the exception themselves, and if
|
||||
// not the exception will still fall back on the standard app-level
|
||||
// exception handler.
|
||||
|
||||
// (this also avoids any sticky business with the modal dialog not getting
|
||||
// closed out right due to stack unwinding skipping dialog closure crap)
|
||||
|
||||
m_sync.WaitForResult_NoExceptions();
|
||||
EndModal( wxID_OK );
|
||||
}
|
||||
|
||||
int Threading::WaitForTaskDialog::ShowModal()
|
||||
{
|
||||
int result = _parent::ShowModal();
|
||||
m_sync.RethrowException();
|
||||
return result;
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ThreadingDialogs.h"
|
||||
#include "pxStaticText.h"
|
||||
|
||||
using namespace pxSizerFlags;
|
||||
|
||||
DEFINE_EVENT_TYPE(pxEvt_ThreadedTaskComplete);
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// WaitForTaskDialog Implementations
|
||||
// --------------------------------------------------------------------------------------
|
||||
IMPLEMENT_DYNAMIC_CLASS(WaitForTaskDialog, wxDialogWithHelpers)
|
||||
|
||||
Threading::WaitForTaskDialog::WaitForTaskDialog( const wxString& title, const wxString& heading )
|
||||
: wxDialogWithHelpers( NULL, _("Waiting for tasks...") )
|
||||
//, m_Timer(this)
|
||||
{
|
||||
SetMinWidth( 300 );
|
||||
|
||||
//m_sem = sem;
|
||||
//m_mutex = mutex;
|
||||
|
||||
wxString m_title( title );
|
||||
wxString m_heading( heading );
|
||||
|
||||
if( m_title.IsEmpty() ) m_title = _("Waiting for task...");
|
||||
if( m_heading.IsEmpty() ) m_heading = m_title;
|
||||
|
||||
Connect( pxEvt_ThreadedTaskComplete, wxCommandEventHandler(WaitForTaskDialog::OnTaskComplete) );
|
||||
|
||||
*this += 12;
|
||||
*this += Heading(m_heading).Unwrapped() | StdExpand();
|
||||
*this += 12;
|
||||
|
||||
// TODO : Implement a cancel button. Not quite sure the best way to do
|
||||
// that, since it requires a thread or event handler context, or something.
|
||||
|
||||
//applyDlg += new wxButton( &applyDlg, wxID_CANCEL ) | pxCenter;
|
||||
//applyDlg += 6;
|
||||
|
||||
//Connect( m_Timer.GetId(), wxEVT_TIMER, wxTimerEventHandler(WaitForTaskDialog::OnTimer) );
|
||||
//m_Timer.Start( 200 );
|
||||
//GetSysExecutorThread().PostEvent( new SysExecEvent_ApplyPlugins( this, m_sync ) );
|
||||
}
|
||||
|
||||
void Threading::WaitForTaskDialog::OnTaskComplete( wxCommandEvent& evt )
|
||||
{
|
||||
evt.Skip();
|
||||
|
||||
// Note: we don't throw exceptions from the pending task here.
|
||||
// Instead we wait until we exit the modal loop below -- this gives
|
||||
// the caller a chance to handle the exception themselves, and if
|
||||
// not the exception will still fall back on the standard app-level
|
||||
// exception handler.
|
||||
|
||||
// (this also avoids any sticky business with the modal dialog not getting
|
||||
// closed out right due to stack unwinding skipping dialog closure crap)
|
||||
|
||||
m_sync.WaitForResult_NoExceptions();
|
||||
EndModal( wxID_OK );
|
||||
}
|
||||
|
||||
int Threading::WaitForTaskDialog::ShowModal()
|
||||
{
|
||||
int result = _parent::ShowModal();
|
||||
m_sync.RethrowException();
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,250 +1,250 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "x86emitter/x86emitter.h"
|
||||
#include <xmmintrin.h>
|
||||
|
||||
using namespace x86Emitter;
|
||||
|
||||
// Max Number of qwc supported
|
||||
#define _maxSize 0x400
|
||||
|
||||
typedef void (__fastcall *_memCpyCall)(void*, void*);
|
||||
__aligned16 _memCpyCall _memcpy_vibes[_maxSize+1];
|
||||
|
||||
#if 1
|
||||
|
||||
// this version uses SSE intrinsics to perform an inline copy. MSVC disasm shows pretty
|
||||
// decent code generation on whole, but it hasn't been benchmarked at all yet --air
|
||||
__fi void memcpy_vibes(void * dest, const void * src, int size) {
|
||||
|
||||
float (*destxmm)[4] = (float(*)[4])dest, (*srcxmm)[4] = (float(*)[4])src;
|
||||
size_t count = size & ~15, extra = size & 15;
|
||||
|
||||
destxmm -= 8 - extra, srcxmm -= 8 - extra;
|
||||
switch (extra) {
|
||||
do {
|
||||
destxmm += 16, srcxmm += 16, count -= 16;
|
||||
_mm_store_ps(&destxmm[-8][0], _mm_load_ps(&srcxmm[-8][0]));
|
||||
case 15:
|
||||
_mm_store_ps(&destxmm[-7][0], _mm_load_ps(&srcxmm[-7][0]));
|
||||
case 14:
|
||||
_mm_store_ps(&destxmm[-6][0], _mm_load_ps(&srcxmm[-6][0]));
|
||||
case 13:
|
||||
_mm_store_ps(&destxmm[-5][0], _mm_load_ps(&srcxmm[-5][0]));
|
||||
case 12:
|
||||
_mm_store_ps(&destxmm[-4][0], _mm_load_ps(&srcxmm[-4][0]));
|
||||
case 11:
|
||||
_mm_store_ps(&destxmm[-3][0], _mm_load_ps(&srcxmm[-3][0]));
|
||||
case 10:
|
||||
_mm_store_ps(&destxmm[-2][0], _mm_load_ps(&srcxmm[-2][0]));
|
||||
case 9:
|
||||
_mm_store_ps(&destxmm[-1][0], _mm_load_ps(&srcxmm[-1][0]));
|
||||
case 8:
|
||||
_mm_store_ps(&destxmm[ 0][0], _mm_load_ps(&srcxmm[ 0][0]));
|
||||
case 7:
|
||||
_mm_store_ps(&destxmm[ 1][0], _mm_load_ps(&srcxmm[ 1][0]));
|
||||
case 6:
|
||||
_mm_store_ps(&destxmm[ 2][0], _mm_load_ps(&srcxmm[ 2][0]));
|
||||
case 5:
|
||||
_mm_store_ps(&destxmm[ 3][0], _mm_load_ps(&srcxmm[ 3][0]));
|
||||
case 4:
|
||||
_mm_store_ps(&destxmm[ 4][0], _mm_load_ps(&srcxmm[ 4][0]));
|
||||
case 3:
|
||||
_mm_store_ps(&destxmm[ 5][0], _mm_load_ps(&srcxmm[ 5][0]));
|
||||
case 2:
|
||||
_mm_store_ps(&destxmm[ 6][0], _mm_load_ps(&srcxmm[ 6][0]));
|
||||
case 1:
|
||||
_mm_store_ps(&destxmm[ 7][0], _mm_load_ps(&srcxmm[ 7][0]));
|
||||
case 0: NULL;
|
||||
} while (count);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#if 1
|
||||
// This version creates one function with a lot of movaps
|
||||
// It jumps to the correct movaps entry-point while adding
|
||||
// the proper offset for adjustment...
|
||||
|
||||
static __pagealigned u8 _memCpyExec[__pagesize*16];
|
||||
|
||||
void gen_memcpy_vibes() {
|
||||
HostSys::MemProtectStatic(_memCpyExec, Protect_ReadWrite, false);
|
||||
memset (_memCpyExec, 0xcc, sizeof(_memCpyExec));
|
||||
xSetPtr(_memCpyExec);
|
||||
|
||||
int off =-(((_maxSize & 0xf) - 7) << 4);
|
||||
for (int i = _maxSize, x = 0; i > 0; i--, x=(x+1)&7, off+=16) {
|
||||
|
||||
_memcpy_vibes[i] = (_memCpyCall)xGetPtr();
|
||||
|
||||
if (off >= 128) {
|
||||
off = -128;
|
||||
xADD(edx, 256);
|
||||
xADD(ecx, 256);
|
||||
}
|
||||
const xRegisterSSE xmm_t(x);
|
||||
xMOVAPS (xmm_t, ptr32[edx+off]);
|
||||
xMOVNTPS(ptr32[ecx+off], xmm_t);
|
||||
}
|
||||
|
||||
_memcpy_vibes[0] = (_memCpyCall)xGetPtr();
|
||||
|
||||
xRET();
|
||||
pxAssert(((uptr)xGetPtr() - (uptr)_memCpyExec) < sizeof(_memCpyExec));
|
||||
|
||||
HostSys::MemProtectStatic(_memCpyExec, Protect_ReadOnly, true);
|
||||
}
|
||||
|
||||
__fi void memcpy_vibes(void * dest, const void * src, int size) {
|
||||
int offset = ((size & 0xf) - 7) << 4;
|
||||
_memcpy_vibes[size]((void*)((uptr)dest + offset), (void*)((uptr)src + offset));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// This version creates '_maxSize' number of different functions,
|
||||
// and calls the appropriate one...
|
||||
|
||||
static __pagealigned u8 _memCpyExec[__pagesize*_maxSize*2];
|
||||
|
||||
void gen_memcpy_vibes() {
|
||||
HostSys::MemProtectStatic(_memCpyExec, Protect_ReadWrite, false);
|
||||
memset (_memCpyExec, 0xcc, sizeof(_memCpyExec));
|
||||
xSetPtr(_memCpyExec);
|
||||
|
||||
for (int i = 0; i < _maxSize+1; i++)
|
||||
{
|
||||
int off = 0;
|
||||
_memcpy_vibes[i] = (_memCpyCall)xGetAlignedCallTarget();
|
||||
|
||||
for (int j = 0, x = 0; j < i; j++, x=(x+1)&7, off+=16) {
|
||||
if (off >= 128) {
|
||||
off = -128;
|
||||
xADD(edx, 256);
|
||||
xADD(ecx, 256);
|
||||
}
|
||||
const xRegisterSSE xmm_t(x);
|
||||
xMOVAPS(xmm_t, ptr32[edx+off]);
|
||||
xMOVAPS(ptr32[ecx+off], xmm_t);
|
||||
}
|
||||
|
||||
xRET();
|
||||
pxAssert(((uptr)xGetPtr() - (uptr)_memCpyExec) < sizeof(_memCpyExec));
|
||||
}
|
||||
|
||||
HostSys::MemProtectStatic(_memCpyExec, Protect_ReadOnly, true);
|
||||
}
|
||||
|
||||
__fi void memcpy_vibes(void * dest, const void * src, int size) {
|
||||
_memcpy_vibes[size](dest, src);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Since MemcpyVibes is already in the project, I'll just tuck the Linux version of memcpy_amd_qwc here for the moment,
|
||||
// to get around compilation issues with having it in the headers.
|
||||
#ifdef __LINUX__
|
||||
|
||||
// This can be moved later, but Linux doesn't even compile memcpyFast.cpp, so I figured I'd stick it here for now.
|
||||
// Quadword Copy! Count is in QWCs (128 bits). Neither source nor dest need to be aligned.
|
||||
__fi void memcpy_amd_qwc(void *dest, const void *src, size_t qwc)
|
||||
{
|
||||
// Optimization Analysis: This code is *nearly* optimal. Do not think that using XMM
|
||||
// registers will improve copy performance, because they won't. Use of XMMs is only
|
||||
// warranted in situations where both source and dest are guaranteed aligned to 16 bytes,
|
||||
// and even then the benefits are typically minimal (sometimes slower depending on the
|
||||
// amount of data being copied).
|
||||
//
|
||||
// Thus: MMX are alignment safe, fast, and widely available. Lets just stick with them.
|
||||
// --air
|
||||
|
||||
// Linux Conversion note:
|
||||
// This code would benefit nicely from having inline-able GAS syntax, since it should
|
||||
// allow GCC to optimize the first 3 instructions out of existence in many scenarios.
|
||||
// And its called enough times to probably merit the extra effort to ensure proper
|
||||
// optimization. --air
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
".intel_syntax noprefix\n"
|
||||
"sub %[qwc], 1\n" // dec the counter to ease the count of 16bytes block later (optimization)
|
||||
// Note after this line, real value of the counter is %[qwc] + 1
|
||||
"jle memcpy_qwc_1_%=\n" // only one 16 byte block to copy? Or nothing.
|
||||
|
||||
"cmp %[qwc], 127\n" // "IN_CACHE_COPY/16"
|
||||
"jb memcpy_qwc_loop1_%=\n" // small copies should be cached (definite speedup --air)
|
||||
|
||||
"memcpy_qwc_loop2_%=:\n" // 32-byte blocks, uncached copy
|
||||
"prefetchnta [%[src] + 568]\n" // start reading ahead (tested: it helps! --air)
|
||||
|
||||
"movq mm0,[%[src]+0]\n" // read 64 bits
|
||||
"movq mm1,[%[src]+8]\n"
|
||||
"movq mm2,[%[src]+16]\n"
|
||||
"movntq [%[dest]+0], mm0\n" // write 64 bits, bypassing the cache
|
||||
"movntq [%[dest]+8], mm1\n"
|
||||
"movq mm3,[%[src]+24]\n"
|
||||
"movntq [%[dest]+16], mm2\n"
|
||||
"movntq [%[dest]+24], mm3\n"
|
||||
|
||||
"add %[src],32\n" // update source pointer
|
||||
"add %[dest],32\n" // update destination pointer
|
||||
"sub %[qwc],2\n"
|
||||
"jg memcpy_qwc_loop2_%=\n" // last 64-byte block?
|
||||
"sfence\n" // flush the write buffer
|
||||
"jmp memcpy_qwc_1_%=\n"
|
||||
|
||||
// 32-byte blocks, cached!
|
||||
// This *is* important. Removing this and using exclusively non-temporal stores
|
||||
// results in noticeable speed loss!
|
||||
|
||||
"memcpy_qwc_loop1_%=:\n"
|
||||
"prefetchnta [%[src] + 568]\n" // start reading ahead (tested: it helps! --air)
|
||||
|
||||
"movq mm0,[%[src]+0]\n" // read 64 bits
|
||||
"movq mm1,[%[src]+8]\n"
|
||||
"movq mm2,[%[src]+16]\n"
|
||||
"movq [%[dest]+0], mm0\n" // write 64 bits, bypassing the cache
|
||||
"movq [%[dest]+8], mm1\n"
|
||||
"movq mm3,[%[src]+24]\n"
|
||||
"movq [%[dest]+16], mm2\n"
|
||||
"movq [%[dest]+24], mm3\n"
|
||||
|
||||
"add %[src],32\n" // update source pointer
|
||||
"add %[dest],32\n" // update destination pointer
|
||||
"sub %[qwc],2\n"
|
||||
"jg memcpy_qwc_loop2_%=\n" // last 64-byte block?
|
||||
|
||||
"memcpy_qwc_1_%=:\n"
|
||||
"cmp %[qwc],0\n"
|
||||
"jne memcpy_qwc_final_%=\n"
|
||||
"movq mm0,[%[src]]\n"
|
||||
"movq mm1,[%[src]+8]\n"
|
||||
"movq [%[dest]], mm0\n"
|
||||
"movq [%[dest]+8], mm1\n"
|
||||
|
||||
"memcpy_qwc_final_%=:\n"
|
||||
"emms\n" // clean up the MMX state
|
||||
".att_syntax\n"
|
||||
: "=&r"(dest), "=&r"(src), "=&r"(qwc)
|
||||
: [dest]"0"(dest), [src]"1"(src), [qwc]"2"(qwc)
|
||||
: "memory", "mm0", "mm1", "mm2", "mm3"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "x86emitter/x86emitter.h"
|
||||
#include <xmmintrin.h>
|
||||
|
||||
using namespace x86Emitter;
|
||||
|
||||
// Max Number of qwc supported
|
||||
#define _maxSize 0x400
|
||||
|
||||
typedef void (__fastcall *_memCpyCall)(void*, void*);
|
||||
__aligned16 _memCpyCall _memcpy_vibes[_maxSize+1];
|
||||
|
||||
#if 1
|
||||
|
||||
// this version uses SSE intrinsics to perform an inline copy. MSVC disasm shows pretty
|
||||
// decent code generation on whole, but it hasn't been benchmarked at all yet --air
|
||||
__fi void memcpy_vibes(void * dest, const void * src, int size) {
|
||||
|
||||
float (*destxmm)[4] = (float(*)[4])dest, (*srcxmm)[4] = (float(*)[4])src;
|
||||
size_t count = size & ~15, extra = size & 15;
|
||||
|
||||
destxmm -= 8 - extra, srcxmm -= 8 - extra;
|
||||
switch (extra) {
|
||||
do {
|
||||
destxmm += 16, srcxmm += 16, count -= 16;
|
||||
_mm_store_ps(&destxmm[-8][0], _mm_load_ps(&srcxmm[-8][0]));
|
||||
case 15:
|
||||
_mm_store_ps(&destxmm[-7][0], _mm_load_ps(&srcxmm[-7][0]));
|
||||
case 14:
|
||||
_mm_store_ps(&destxmm[-6][0], _mm_load_ps(&srcxmm[-6][0]));
|
||||
case 13:
|
||||
_mm_store_ps(&destxmm[-5][0], _mm_load_ps(&srcxmm[-5][0]));
|
||||
case 12:
|
||||
_mm_store_ps(&destxmm[-4][0], _mm_load_ps(&srcxmm[-4][0]));
|
||||
case 11:
|
||||
_mm_store_ps(&destxmm[-3][0], _mm_load_ps(&srcxmm[-3][0]));
|
||||
case 10:
|
||||
_mm_store_ps(&destxmm[-2][0], _mm_load_ps(&srcxmm[-2][0]));
|
||||
case 9:
|
||||
_mm_store_ps(&destxmm[-1][0], _mm_load_ps(&srcxmm[-1][0]));
|
||||
case 8:
|
||||
_mm_store_ps(&destxmm[ 0][0], _mm_load_ps(&srcxmm[ 0][0]));
|
||||
case 7:
|
||||
_mm_store_ps(&destxmm[ 1][0], _mm_load_ps(&srcxmm[ 1][0]));
|
||||
case 6:
|
||||
_mm_store_ps(&destxmm[ 2][0], _mm_load_ps(&srcxmm[ 2][0]));
|
||||
case 5:
|
||||
_mm_store_ps(&destxmm[ 3][0], _mm_load_ps(&srcxmm[ 3][0]));
|
||||
case 4:
|
||||
_mm_store_ps(&destxmm[ 4][0], _mm_load_ps(&srcxmm[ 4][0]));
|
||||
case 3:
|
||||
_mm_store_ps(&destxmm[ 5][0], _mm_load_ps(&srcxmm[ 5][0]));
|
||||
case 2:
|
||||
_mm_store_ps(&destxmm[ 6][0], _mm_load_ps(&srcxmm[ 6][0]));
|
||||
case 1:
|
||||
_mm_store_ps(&destxmm[ 7][0], _mm_load_ps(&srcxmm[ 7][0]));
|
||||
case 0: NULL;
|
||||
} while (count);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#if 1
|
||||
// This version creates one function with a lot of movaps
|
||||
// It jumps to the correct movaps entry-point while adding
|
||||
// the proper offset for adjustment...
|
||||
|
||||
static __pagealigned u8 _memCpyExec[__pagesize*16];
|
||||
|
||||
void gen_memcpy_vibes() {
|
||||
HostSys::MemProtectStatic(_memCpyExec, Protect_ReadWrite, false);
|
||||
memset (_memCpyExec, 0xcc, sizeof(_memCpyExec));
|
||||
xSetPtr(_memCpyExec);
|
||||
|
||||
int off =-(((_maxSize & 0xf) - 7) << 4);
|
||||
for (int i = _maxSize, x = 0; i > 0; i--, x=(x+1)&7, off+=16) {
|
||||
|
||||
_memcpy_vibes[i] = (_memCpyCall)xGetPtr();
|
||||
|
||||
if (off >= 128) {
|
||||
off = -128;
|
||||
xADD(edx, 256);
|
||||
xADD(ecx, 256);
|
||||
}
|
||||
const xRegisterSSE xmm_t(x);
|
||||
xMOVAPS (xmm_t, ptr32[edx+off]);
|
||||
xMOVNTPS(ptr32[ecx+off], xmm_t);
|
||||
}
|
||||
|
||||
_memcpy_vibes[0] = (_memCpyCall)xGetPtr();
|
||||
|
||||
xRET();
|
||||
pxAssert(((uptr)xGetPtr() - (uptr)_memCpyExec) < sizeof(_memCpyExec));
|
||||
|
||||
HostSys::MemProtectStatic(_memCpyExec, Protect_ReadOnly, true);
|
||||
}
|
||||
|
||||
__fi void memcpy_vibes(void * dest, const void * src, int size) {
|
||||
int offset = ((size & 0xf) - 7) << 4;
|
||||
_memcpy_vibes[size]((void*)((uptr)dest + offset), (void*)((uptr)src + offset));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// This version creates '_maxSize' number of different functions,
|
||||
// and calls the appropriate one...
|
||||
|
||||
static __pagealigned u8 _memCpyExec[__pagesize*_maxSize*2];
|
||||
|
||||
void gen_memcpy_vibes() {
|
||||
HostSys::MemProtectStatic(_memCpyExec, Protect_ReadWrite, false);
|
||||
memset (_memCpyExec, 0xcc, sizeof(_memCpyExec));
|
||||
xSetPtr(_memCpyExec);
|
||||
|
||||
for (int i = 0; i < _maxSize+1; i++)
|
||||
{
|
||||
int off = 0;
|
||||
_memcpy_vibes[i] = (_memCpyCall)xGetAlignedCallTarget();
|
||||
|
||||
for (int j = 0, x = 0; j < i; j++, x=(x+1)&7, off+=16) {
|
||||
if (off >= 128) {
|
||||
off = -128;
|
||||
xADD(edx, 256);
|
||||
xADD(ecx, 256);
|
||||
}
|
||||
const xRegisterSSE xmm_t(x);
|
||||
xMOVAPS(xmm_t, ptr32[edx+off]);
|
||||
xMOVAPS(ptr32[ecx+off], xmm_t);
|
||||
}
|
||||
|
||||
xRET();
|
||||
pxAssert(((uptr)xGetPtr() - (uptr)_memCpyExec) < sizeof(_memCpyExec));
|
||||
}
|
||||
|
||||
HostSys::MemProtectStatic(_memCpyExec, Protect_ReadOnly, true);
|
||||
}
|
||||
|
||||
__fi void memcpy_vibes(void * dest, const void * src, int size) {
|
||||
_memcpy_vibes[size](dest, src);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Since MemcpyVibes is already in the project, I'll just tuck the Linux version of memcpy_amd_qwc here for the moment,
|
||||
// to get around compilation issues with having it in the headers.
|
||||
#ifdef __LINUX__
|
||||
|
||||
// This can be moved later, but Linux doesn't even compile memcpyFast.cpp, so I figured I'd stick it here for now.
|
||||
// Quadword Copy! Count is in QWCs (128 bits). Neither source nor dest need to be aligned.
|
||||
__fi void memcpy_amd_qwc(void *dest, const void *src, size_t qwc)
|
||||
{
|
||||
// Optimization Analysis: This code is *nearly* optimal. Do not think that using XMM
|
||||
// registers will improve copy performance, because they won't. Use of XMMs is only
|
||||
// warranted in situations where both source and dest are guaranteed aligned to 16 bytes,
|
||||
// and even then the benefits are typically minimal (sometimes slower depending on the
|
||||
// amount of data being copied).
|
||||
//
|
||||
// Thus: MMX are alignment safe, fast, and widely available. Lets just stick with them.
|
||||
// --air
|
||||
|
||||
// Linux Conversion note:
|
||||
// This code would benefit nicely from having inline-able GAS syntax, since it should
|
||||
// allow GCC to optimize the first 3 instructions out of existence in many scenarios.
|
||||
// And its called enough times to probably merit the extra effort to ensure proper
|
||||
// optimization. --air
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
".intel_syntax noprefix\n"
|
||||
"sub %[qwc], 1\n" // dec the counter to ease the count of 16bytes block later (optimization)
|
||||
// Note after this line, real value of the counter is %[qwc] + 1
|
||||
"jle memcpy_qwc_1_%=\n" // only one 16 byte block to copy? Or nothing.
|
||||
|
||||
"cmp %[qwc], 127\n" // "IN_CACHE_COPY/16"
|
||||
"jb memcpy_qwc_loop1_%=\n" // small copies should be cached (definite speedup --air)
|
||||
|
||||
"memcpy_qwc_loop2_%=:\n" // 32-byte blocks, uncached copy
|
||||
"prefetchnta [%[src] + 568]\n" // start reading ahead (tested: it helps! --air)
|
||||
|
||||
"movq mm0,[%[src]+0]\n" // read 64 bits
|
||||
"movq mm1,[%[src]+8]\n"
|
||||
"movq mm2,[%[src]+16]\n"
|
||||
"movntq [%[dest]+0], mm0\n" // write 64 bits, bypassing the cache
|
||||
"movntq [%[dest]+8], mm1\n"
|
||||
"movq mm3,[%[src]+24]\n"
|
||||
"movntq [%[dest]+16], mm2\n"
|
||||
"movntq [%[dest]+24], mm3\n"
|
||||
|
||||
"add %[src],32\n" // update source pointer
|
||||
"add %[dest],32\n" // update destination pointer
|
||||
"sub %[qwc],2\n"
|
||||
"jg memcpy_qwc_loop2_%=\n" // last 64-byte block?
|
||||
"sfence\n" // flush the write buffer
|
||||
"jmp memcpy_qwc_1_%=\n"
|
||||
|
||||
// 32-byte blocks, cached!
|
||||
// This *is* important. Removing this and using exclusively non-temporal stores
|
||||
// results in noticeable speed loss!
|
||||
|
||||
"memcpy_qwc_loop1_%=:\n"
|
||||
"prefetchnta [%[src] + 568]\n" // start reading ahead (tested: it helps! --air)
|
||||
|
||||
"movq mm0,[%[src]+0]\n" // read 64 bits
|
||||
"movq mm1,[%[src]+8]\n"
|
||||
"movq mm2,[%[src]+16]\n"
|
||||
"movq [%[dest]+0], mm0\n" // write 64 bits, bypassing the cache
|
||||
"movq [%[dest]+8], mm1\n"
|
||||
"movq mm3,[%[src]+24]\n"
|
||||
"movq [%[dest]+16], mm2\n"
|
||||
"movq [%[dest]+24], mm3\n"
|
||||
|
||||
"add %[src],32\n" // update source pointer
|
||||
"add %[dest],32\n" // update destination pointer
|
||||
"sub %[qwc],2\n"
|
||||
"jg memcpy_qwc_loop2_%=\n" // last 64-byte block?
|
||||
|
||||
"memcpy_qwc_1_%=:\n"
|
||||
"cmp %[qwc],0\n"
|
||||
"jne memcpy_qwc_final_%=\n"
|
||||
"movq mm0,[%[src]]\n"
|
||||
"movq mm1,[%[src]+8]\n"
|
||||
"movq [%[dest]], mm0\n"
|
||||
"movq [%[dest]+8], mm1\n"
|
||||
|
||||
"memcpy_qwc_final_%=:\n"
|
||||
"emms\n" // clean up the MMX state
|
||||
".att_syntax\n"
|
||||
: "=&r"(dest), "=&r"(src), "=&r"(qwc)
|
||||
: [dest]"0"(dest), [src]"1"(src), [qwc]"2"(qwc)
|
||||
: "memory", "mm0", "mm1", "mm2", "mm3"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
Folder: /trunk/locales
|
||||
Contains: PO files for gettext language translations
|
||||
|
||||
|
||||
The PO files in this folder are the most current/up-to-date translations for any given revision
|
||||
of PCSX2. When checking out trunk, for example, these files are usually chasing a "moving
|
||||
target" that may have a number of language string changes from PO file contents. When checking
|
||||
out a stable release branch (such as 0.9.8) the PO files should be fairly stable and unchanging.
|
||||
|
||||
In general it is recommended that translators focus time on perfecting stable releases, and
|
||||
contribute to trunk/dev-branch languages only if you're feeling eagar, or if PCSX2 devs have
|
||||
announced a scheduled stable release in the future (ie, requested translators to update and
|
||||
submit new PO files).
|
||||
Folder: /trunk/locales
|
||||
Contains: PO files for gettext language translations
|
||||
|
||||
|
||||
The PO files in this folder are the most current/up-to-date translations for any given revision
|
||||
of PCSX2. When checking out trunk, for example, these files are usually chasing a "moving
|
||||
target" that may have a number of language string changes from PO file contents. When checking
|
||||
out a stable release branch (such as 0.9.8) the PO files should be fairly stable and unchanging.
|
||||
|
||||
In general it is recommended that translators focus time on perfecting stable releases, and
|
||||
contribute to trunk/dev-branch languages only if you're feeling eagar, or if PCSX2 devs have
|
||||
announced a scheduled stable release in the future (ie, requested translators to update and
|
||||
submit new PO files).
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
|
||||
PCSX2 Language Translation Templates (POT format)
|
||||
-------------------------------------------------
|
||||
|
||||
Quick overview of using POT files:
|
||||
|
||||
POT files are essentially identical to PO files, except that they have no translated
|
||||
text strings filled in yet. Your job as a translator is to make copies of these files,
|
||||
give then .PO extensions, fill in the properly translated text for each string in the
|
||||
files, test, and then submit the new PO file to the PCSX2 Team.
|
||||
|
||||
The PCSX2 Team recommends using Poedit to help make your life easier.
|
||||
|
||||
Details on PCSX2's use of gettext, translation, and tesing/submitting new translations,
|
||||
visit our wiki at googlecode: https://code.google.com/p/pcsx2/wiki/TranslationGuide
|
||||
|
||||
|
||||
Jake Stine (Air)
|
||||
|
||||
PCSX2 Language Translation Templates (POT format)
|
||||
-------------------------------------------------
|
||||
|
||||
Quick overview of using POT files:
|
||||
|
||||
POT files are essentially identical to PO files, except that they have no translated
|
||||
text strings filled in yet. Your job as a translator is to make copies of these files,
|
||||
give then .PO extensions, fill in the properly translated text for each string in the
|
||||
files, test, and then submit the new PO file to the PCSX2 Team.
|
||||
|
||||
The PCSX2 Team recommends using Poedit to help make your life easier.
|
||||
|
||||
Details on PCSX2's use of gettext, translation, and tesing/submitting new translations,
|
||||
visit our wiki at googlecode: https://code.google.com/p/pcsx2/wiki/TranslationGuide
|
||||
|
||||
|
||||
Jake Stine (Air)
|
||||
PCSX2 Development Team
|
|
@ -1,149 +1,149 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GameDatabase.h"
|
||||
|
||||
BaseGameDatabaseImpl::BaseGameDatabaseImpl()
|
||||
: gHash( 9400 )
|
||||
, m_baseKey( L"Serial" )
|
||||
{
|
||||
m_BlockTable.reserve(48);
|
||||
|
||||
m_CurBlockWritePos = 0;
|
||||
m_BlockTableWritePos = 0;
|
||||
|
||||
m_GamesPerBlock = 256;
|
||||
|
||||
m_BlockTable.push_back(NULL);
|
||||
}
|
||||
|
||||
BaseGameDatabaseImpl::~BaseGameDatabaseImpl() throw()
|
||||
{
|
||||
for(uint blockidx=0; blockidx<=m_BlockTableWritePos; ++blockidx)
|
||||
{
|
||||
if( !m_BlockTable[blockidx] ) continue;
|
||||
|
||||
const uint endidx = (blockidx == m_BlockTableWritePos) ? m_CurBlockWritePos : m_GamesPerBlock;
|
||||
|
||||
for( uint gameidx=0; gameidx<endidx; ++gameidx )
|
||||
m_BlockTable[blockidx][gameidx].~Game_Data();
|
||||
|
||||
safe_free( m_BlockTable[blockidx] );
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the current game to the one matching the serial id given
|
||||
// Returns true if game found, false if not found...
|
||||
bool BaseGameDatabaseImpl::findGame(Game_Data& dest, const wxString& id) {
|
||||
|
||||
GameDataHash::const_iterator iter( gHash.find(id) );
|
||||
if( iter == gHash.end() ) {
|
||||
dest.clear();
|
||||
return false;
|
||||
}
|
||||
dest = *iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
Game_Data* BaseGameDatabaseImpl::createNewGame( const wxString& id )
|
||||
{
|
||||
if(!m_BlockTable[m_BlockTableWritePos])
|
||||
m_BlockTable[m_BlockTableWritePos] = (Game_Data*)malloc(m_GamesPerBlock * sizeof(Game_Data));
|
||||
|
||||
Game_Data* block = m_BlockTable[m_BlockTableWritePos];
|
||||
Game_Data* retval = &block[m_CurBlockWritePos];
|
||||
|
||||
gHash[id] = retval;
|
||||
|
||||
new (retval) Game_Data(id);
|
||||
|
||||
if( ++m_CurBlockWritePos >= m_GamesPerBlock )
|
||||
{
|
||||
++m_BlockTableWritePos;
|
||||
m_CurBlockWritePos = 0;
|
||||
m_BlockTable.push_back(NULL);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void BaseGameDatabaseImpl::updateGame(const Game_Data& game)
|
||||
{
|
||||
GameDataHash::const_iterator iter( gHash.find(game.id) );
|
||||
|
||||
if( iter == gHash.end() ) {
|
||||
*(createNewGame( game.id )) = game;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Re-assign existing vector/array entry!
|
||||
*gHash[game.id] = game;
|
||||
}
|
||||
}
|
||||
|
||||
// Searches the current game's data to see if the given key exists
|
||||
bool Game_Data::keyExists(const wxChar* key) const {
|
||||
KeyPairArray::const_iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it->CompareKey(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Totally Deletes the specified key/pair value from the current game's data
|
||||
void Game_Data::deleteKey(const wxChar* key) {
|
||||
KeyPairArray::iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it->CompareKey(key)) {
|
||||
kList.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gets a string representation of the 'value' for the given key
|
||||
wxString Game_Data::getString(const wxChar* key) const {
|
||||
KeyPairArray::const_iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it->CompareKey(key)) {
|
||||
return it->value;
|
||||
}
|
||||
}
|
||||
return wxString();
|
||||
}
|
||||
|
||||
void Game_Data::writeString(const wxString& key, const wxString& value) {
|
||||
KeyPairArray::iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it->CompareKey(key)) {
|
||||
if( value.IsEmpty() )
|
||||
kList.erase(it);
|
||||
else
|
||||
it->value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( !value.IsEmpty() ) {
|
||||
kList.push_back(key_pair(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
// Write a bool value to the specified key
|
||||
void Game_Data::writeBool(const wxString& key, bool value) {
|
||||
writeString(key, value ? L"1" : L"0");
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GameDatabase.h"
|
||||
|
||||
BaseGameDatabaseImpl::BaseGameDatabaseImpl()
|
||||
: gHash( 9400 )
|
||||
, m_baseKey( L"Serial" )
|
||||
{
|
||||
m_BlockTable.reserve(48);
|
||||
|
||||
m_CurBlockWritePos = 0;
|
||||
m_BlockTableWritePos = 0;
|
||||
|
||||
m_GamesPerBlock = 256;
|
||||
|
||||
m_BlockTable.push_back(NULL);
|
||||
}
|
||||
|
||||
BaseGameDatabaseImpl::~BaseGameDatabaseImpl() throw()
|
||||
{
|
||||
for(uint blockidx=0; blockidx<=m_BlockTableWritePos; ++blockidx)
|
||||
{
|
||||
if( !m_BlockTable[blockidx] ) continue;
|
||||
|
||||
const uint endidx = (blockidx == m_BlockTableWritePos) ? m_CurBlockWritePos : m_GamesPerBlock;
|
||||
|
||||
for( uint gameidx=0; gameidx<endidx; ++gameidx )
|
||||
m_BlockTable[blockidx][gameidx].~Game_Data();
|
||||
|
||||
safe_free( m_BlockTable[blockidx] );
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the current game to the one matching the serial id given
|
||||
// Returns true if game found, false if not found...
|
||||
bool BaseGameDatabaseImpl::findGame(Game_Data& dest, const wxString& id) {
|
||||
|
||||
GameDataHash::const_iterator iter( gHash.find(id) );
|
||||
if( iter == gHash.end() ) {
|
||||
dest.clear();
|
||||
return false;
|
||||
}
|
||||
dest = *iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
Game_Data* BaseGameDatabaseImpl::createNewGame( const wxString& id )
|
||||
{
|
||||
if(!m_BlockTable[m_BlockTableWritePos])
|
||||
m_BlockTable[m_BlockTableWritePos] = (Game_Data*)malloc(m_GamesPerBlock * sizeof(Game_Data));
|
||||
|
||||
Game_Data* block = m_BlockTable[m_BlockTableWritePos];
|
||||
Game_Data* retval = &block[m_CurBlockWritePos];
|
||||
|
||||
gHash[id] = retval;
|
||||
|
||||
new (retval) Game_Data(id);
|
||||
|
||||
if( ++m_CurBlockWritePos >= m_GamesPerBlock )
|
||||
{
|
||||
++m_BlockTableWritePos;
|
||||
m_CurBlockWritePos = 0;
|
||||
m_BlockTable.push_back(NULL);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void BaseGameDatabaseImpl::updateGame(const Game_Data& game)
|
||||
{
|
||||
GameDataHash::const_iterator iter( gHash.find(game.id) );
|
||||
|
||||
if( iter == gHash.end() ) {
|
||||
*(createNewGame( game.id )) = game;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Re-assign existing vector/array entry!
|
||||
*gHash[game.id] = game;
|
||||
}
|
||||
}
|
||||
|
||||
// Searches the current game's data to see if the given key exists
|
||||
bool Game_Data::keyExists(const wxChar* key) const {
|
||||
KeyPairArray::const_iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it->CompareKey(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Totally Deletes the specified key/pair value from the current game's data
|
||||
void Game_Data::deleteKey(const wxChar* key) {
|
||||
KeyPairArray::iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it->CompareKey(key)) {
|
||||
kList.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gets a string representation of the 'value' for the given key
|
||||
wxString Game_Data::getString(const wxChar* key) const {
|
||||
KeyPairArray::const_iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it->CompareKey(key)) {
|
||||
return it->value;
|
||||
}
|
||||
}
|
||||
return wxString();
|
||||
}
|
||||
|
||||
void Game_Data::writeString(const wxString& key, const wxString& value) {
|
||||
KeyPairArray::iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it->CompareKey(key)) {
|
||||
if( value.IsEmpty() )
|
||||
kList.erase(it);
|
||||
else
|
||||
it->value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( !value.IsEmpty() ) {
|
||||
kList.push_back(key_pair(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
// Write a bool value to the specified key
|
||||
void Game_Data::writeBool(const wxString& key, bool value) {
|
||||
writeString(key, value ? L"1" : L"0");
|
||||
}
|
|
@ -1,242 +1,242 @@
|
|||
;/********************************************************
|
||||
; * Some code. Copyright (C) 2003 by Pascal Massimino. *
|
||||
; * All Rights Reserved. (http://skal.planet-d.net) *
|
||||
; * For Educational/Academic use ONLY. See 'LICENSE.TXT'.*
|
||||
; ********************************************************/
|
||||
;//////////////////////////////////////////////////////////
|
||||
;// NASM macros
|
||||
;//////////////////////////////////////////////////////////
|
||||
|
||||
%ifdef LINUX
|
||||
|
||||
;//////////////////////////////////////////////////////////
|
||||
; LINUX / egcs / macros
|
||||
;//////////////////////////////////////////////////////////
|
||||
|
||||
%macro extrn 1
|
||||
extern %1
|
||||
%define %1 %1
|
||||
%endmacro
|
||||
%macro globl 1
|
||||
global %1
|
||||
%define %1 %1
|
||||
%endmacro
|
||||
|
||||
%macro DATA 0
|
||||
[section data align=16 write alloc USE32]
|
||||
%endmacro
|
||||
%macro TEXT 0
|
||||
[section text align=16 nowrite alloc exec USE32]
|
||||
%endmacro
|
||||
|
||||
%endif ; LINUX
|
||||
|
||||
;//////////////////////////////////////////////////////////
|
||||
|
||||
%ifdef WIN32
|
||||
|
||||
%macro extrn 1
|
||||
extern _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%macro globl 1
|
||||
global _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%macro DATA 0
|
||||
[section .data align=16 write alloc USE32]
|
||||
%endmacro
|
||||
%macro TEXT 0
|
||||
[section .text align=16 nowrite alloc exec USE32]
|
||||
%endmacro
|
||||
|
||||
%endif ; WIN32
|
||||
|
||||
;//////////////////////////////////////////////////////////
|
||||
;
|
||||
; MACRO for timing. NASM.
|
||||
; Total additional code size is 0xb0.
|
||||
; this keep code alignment right.
|
||||
|
||||
extrn Skl_Cur_Count_
|
||||
extrn Skl_Print_Tics
|
||||
|
||||
%macro SKL_USE_RDSTC 0
|
||||
extrn SKL_RDTSC_0_ASM
|
||||
extrn SKL_RDTSC_1_ASM
|
||||
extrn SKL_RDTSC_2_ASM
|
||||
%endmacro
|
||||
%define SKL_RDTSC_OFFSET 15 ; check value with skl_rdtsc.h...
|
||||
|
||||
%macro SKL_RDTSC_IN 0
|
||||
SKL_USE_RDSTC
|
||||
call SKL_RDTSC_0_ASM
|
||||
.Skl_RDTSC_Loop_:
|
||||
call SKL_RDTSC_1_ASM
|
||||
%endmacro
|
||||
|
||||
%macro SKL_RDTSC_OUT 0
|
||||
call SKL_RDTSC_2_ASM
|
||||
dec dword [Skl_Cur_Count_]
|
||||
jge near .Skl_RDTSC_Loop_
|
||||
push dword 53
|
||||
call Skl_Print_Tics
|
||||
%endmacro
|
||||
|
||||
;//////////////////////////////////////////////////////////
|
||||
|
||||
globl Skl_YUV_To_RGB32_MMX
|
||||
|
||||
;//////////////////////////////////////////////////////////////////////
|
||||
|
||||
; eax: *U
|
||||
; ebx: *V
|
||||
; esi: *Y
|
||||
; edx: Src_BpS
|
||||
; edi: *Dst
|
||||
; ebx: Dst_BpS
|
||||
; ecx: Counter
|
||||
|
||||
%define RGBp esp+20
|
||||
%define Yp esp+16
|
||||
%define Up esp+12
|
||||
%define Vp esp+8
|
||||
%define xCnt esp+4
|
||||
%define yCnt esp+0
|
||||
|
||||
Skl_YUV_To_RGB32_MMX:
|
||||
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
|
||||
mov edi, [esp+4 +16] ; RGB
|
||||
mov ebp, [esp+12 +16] ; Y
|
||||
mov eax, [esp+16 +16] ; U
|
||||
mov ebx, [esp+20 +16] ; V
|
||||
mov edx, [esp+24 +16] ; Src_BpS
|
||||
mov ecx, [esp+28 +16] ; Width
|
||||
|
||||
lea edi, [edi+4*ecx] ; RGB += Width*sizeof(32b)
|
||||
lea ebp, [ebp+ecx] ; ebp: Y1 = Y + Width
|
||||
add edx, ebp ; edx: Y2 = Y1+ BpS
|
||||
push edi ; [RGBp]
|
||||
push ebp ; [Yp]
|
||||
shr ecx, 1 ; Width/=2
|
||||
lea eax, [eax+ecx] ; U += W/2
|
||||
lea ebx, [ebx+ecx] ; V += W/2
|
||||
push eax ; [Up]
|
||||
push ebx ; [Vp]
|
||||
|
||||
neg ecx ; ecx = -Width/2
|
||||
push ecx ; save [xCnt]
|
||||
push eax ; fake ([yCnt])
|
||||
|
||||
mov ecx, [esp+32 +40] ; Height
|
||||
shr ecx, 1 ; /2
|
||||
|
||||
mov esi, [Up]
|
||||
mov edi, [Vp]
|
||||
|
||||
jmp .Go
|
||||
|
||||
align 16
|
||||
.Loop_y
|
||||
dec ecx
|
||||
jg .Add
|
||||
|
||||
add esp, 24 ; rid of all tmp
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
|
||||
ret
|
||||
|
||||
align 16
|
||||
.Add
|
||||
mov edi, [esp+8 +40] ; Dst_BpS
|
||||
mov esi, [esp+24 +40] ; Src_BpS
|
||||
mov edx, [RGBp]
|
||||
mov ebp, [Yp]
|
||||
lea edx, [edx+2*edi] ; RGB += 2*Dst_BpS
|
||||
lea ebp, [ebp+2*esi] ; Y += 2*Src_BpS
|
||||
mov [RGBp], edx
|
||||
mov edi, [Vp]
|
||||
mov [Yp], ebp ; Y1
|
||||
lea edx, [ebp+esi] ; Y2
|
||||
|
||||
lea edi, [edi+esi] ; V += Src_BpS
|
||||
add esi, [Up] ; U += Src_BpS
|
||||
mov [Vp], edi
|
||||
mov [Up], esi
|
||||
|
||||
.Go
|
||||
mov [yCnt], ecx
|
||||
mov ecx, [xCnt]
|
||||
|
||||
; 5210c@640x480
|
||||
|
||||
.Loop_x ; edi,esi: U,V; ebp,edx: Y1, Y2; ecx: xCnt
|
||||
|
||||
; R = Y + a.U
|
||||
; G = Y + c.V + b.U
|
||||
; B = Y + d.V
|
||||
|
||||
movzx eax, byte [edi+ecx+0]
|
||||
movzx ebx, byte [esi+ecx+0]
|
||||
movq mm0, [Skl_YUV_Tab32_MMX+0*2048 + eax*8]
|
||||
movzx eax, byte [edi+ecx+1]
|
||||
paddw mm0, [Skl_YUV_Tab32_MMX+1*2048 + ebx*8]
|
||||
movzx ebx, byte [esi+ecx+1]
|
||||
movq mm4, [Skl_YUV_Tab32_MMX+0*2048 + eax*8]
|
||||
movzx eax, byte [ebp + 2*ecx+0]
|
||||
paddw mm4, [Skl_YUV_Tab32_MMX+1*2048 + ebx*8]
|
||||
movzx ebx, byte [ebp + 2*ecx+1]
|
||||
|
||||
movq mm1, mm0
|
||||
movq mm2, mm0
|
||||
movq mm3, mm0
|
||||
movq mm5, mm4
|
||||
movq mm6, mm4
|
||||
movq mm7, mm4
|
||||
|
||||
paddw mm0, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
|
||||
movzx eax, byte [ebp + 2*ecx+2]
|
||||
paddw mm1, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
|
||||
movzx ebx, byte [ebp + 2*ecx+3]
|
||||
packuswb mm0, mm1
|
||||
paddw mm4, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
|
||||
movzx eax, byte [edx + 2*ecx+0]
|
||||
paddw mm5, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
|
||||
|
||||
packuswb mm4, mm5
|
||||
mov esi, [RGBp]
|
||||
movzx ebx, byte [edx + 2*ecx+1]
|
||||
movq [esi+8*ecx+0], mm0 ; 2x32b
|
||||
movq [esi+8*ecx+8], mm4 ; 2x32b
|
||||
|
||||
paddw mm2, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
|
||||
movzx eax, byte [edx + 2*ecx+2]
|
||||
paddw mm3, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
|
||||
movzx ebx, byte [edx + 2*ecx+3]
|
||||
packuswb mm2, mm3
|
||||
paddw mm6, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
|
||||
add esi, [esp+8 +40]
|
||||
paddw mm7, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
|
||||
|
||||
mov edi, [Vp]
|
||||
packuswb mm6, mm7
|
||||
movq [esi+8*ecx+0], mm2 ; 2x32b
|
||||
movq [esi+8*ecx+8], mm6 ; 2x32b
|
||||
|
||||
add ecx, 2
|
||||
mov esi, [Up]
|
||||
|
||||
jl near .Loop_x
|
||||
|
||||
mov ecx, [yCnt]
|
||||
jmp .Loop_y
|
||||
;/********************************************************
|
||||
; * Some code. Copyright (C) 2003 by Pascal Massimino. *
|
||||
; * All Rights Reserved. (http://skal.planet-d.net) *
|
||||
; * For Educational/Academic use ONLY. See 'LICENSE.TXT'.*
|
||||
; ********************************************************/
|
||||
;//////////////////////////////////////////////////////////
|
||||
;// NASM macros
|
||||
;//////////////////////////////////////////////////////////
|
||||
|
||||
%ifdef LINUX
|
||||
|
||||
;//////////////////////////////////////////////////////////
|
||||
; LINUX / egcs / macros
|
||||
;//////////////////////////////////////////////////////////
|
||||
|
||||
%macro extrn 1
|
||||
extern %1
|
||||
%define %1 %1
|
||||
%endmacro
|
||||
%macro globl 1
|
||||
global %1
|
||||
%define %1 %1
|
||||
%endmacro
|
||||
|
||||
%macro DATA 0
|
||||
[section data align=16 write alloc USE32]
|
||||
%endmacro
|
||||
%macro TEXT 0
|
||||
[section text align=16 nowrite alloc exec USE32]
|
||||
%endmacro
|
||||
|
||||
%endif ; LINUX
|
||||
|
||||
;//////////////////////////////////////////////////////////
|
||||
|
||||
%ifdef WIN32
|
||||
|
||||
%macro extrn 1
|
||||
extern _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%macro globl 1
|
||||
global _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%macro DATA 0
|
||||
[section .data align=16 write alloc USE32]
|
||||
%endmacro
|
||||
%macro TEXT 0
|
||||
[section .text align=16 nowrite alloc exec USE32]
|
||||
%endmacro
|
||||
|
||||
%endif ; WIN32
|
||||
|
||||
;//////////////////////////////////////////////////////////
|
||||
;
|
||||
; MACRO for timing. NASM.
|
||||
; Total additional code size is 0xb0.
|
||||
; this keep code alignment right.
|
||||
|
||||
extrn Skl_Cur_Count_
|
||||
extrn Skl_Print_Tics
|
||||
|
||||
%macro SKL_USE_RDSTC 0
|
||||
extrn SKL_RDTSC_0_ASM
|
||||
extrn SKL_RDTSC_1_ASM
|
||||
extrn SKL_RDTSC_2_ASM
|
||||
%endmacro
|
||||
%define SKL_RDTSC_OFFSET 15 ; check value with skl_rdtsc.h...
|
||||
|
||||
%macro SKL_RDTSC_IN 0
|
||||
SKL_USE_RDSTC
|
||||
call SKL_RDTSC_0_ASM
|
||||
.Skl_RDTSC_Loop_:
|
||||
call SKL_RDTSC_1_ASM
|
||||
%endmacro
|
||||
|
||||
%macro SKL_RDTSC_OUT 0
|
||||
call SKL_RDTSC_2_ASM
|
||||
dec dword [Skl_Cur_Count_]
|
||||
jge near .Skl_RDTSC_Loop_
|
||||
push dword 53
|
||||
call Skl_Print_Tics
|
||||
%endmacro
|
||||
|
||||
;//////////////////////////////////////////////////////////
|
||||
|
||||
globl Skl_YUV_To_RGB32_MMX
|
||||
|
||||
;//////////////////////////////////////////////////////////////////////
|
||||
|
||||
; eax: *U
|
||||
; ebx: *V
|
||||
; esi: *Y
|
||||
; edx: Src_BpS
|
||||
; edi: *Dst
|
||||
; ebx: Dst_BpS
|
||||
; ecx: Counter
|
||||
|
||||
%define RGBp esp+20
|
||||
%define Yp esp+16
|
||||
%define Up esp+12
|
||||
%define Vp esp+8
|
||||
%define xCnt esp+4
|
||||
%define yCnt esp+0
|
||||
|
||||
Skl_YUV_To_RGB32_MMX:
|
||||
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
|
||||
mov edi, [esp+4 +16] ; RGB
|
||||
mov ebp, [esp+12 +16] ; Y
|
||||
mov eax, [esp+16 +16] ; U
|
||||
mov ebx, [esp+20 +16] ; V
|
||||
mov edx, [esp+24 +16] ; Src_BpS
|
||||
mov ecx, [esp+28 +16] ; Width
|
||||
|
||||
lea edi, [edi+4*ecx] ; RGB += Width*sizeof(32b)
|
||||
lea ebp, [ebp+ecx] ; ebp: Y1 = Y + Width
|
||||
add edx, ebp ; edx: Y2 = Y1+ BpS
|
||||
push edi ; [RGBp]
|
||||
push ebp ; [Yp]
|
||||
shr ecx, 1 ; Width/=2
|
||||
lea eax, [eax+ecx] ; U += W/2
|
||||
lea ebx, [ebx+ecx] ; V += W/2
|
||||
push eax ; [Up]
|
||||
push ebx ; [Vp]
|
||||
|
||||
neg ecx ; ecx = -Width/2
|
||||
push ecx ; save [xCnt]
|
||||
push eax ; fake ([yCnt])
|
||||
|
||||
mov ecx, [esp+32 +40] ; Height
|
||||
shr ecx, 1 ; /2
|
||||
|
||||
mov esi, [Up]
|
||||
mov edi, [Vp]
|
||||
|
||||
jmp .Go
|
||||
|
||||
align 16
|
||||
.Loop_y
|
||||
dec ecx
|
||||
jg .Add
|
||||
|
||||
add esp, 24 ; rid of all tmp
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
|
||||
ret
|
||||
|
||||
align 16
|
||||
.Add
|
||||
mov edi, [esp+8 +40] ; Dst_BpS
|
||||
mov esi, [esp+24 +40] ; Src_BpS
|
||||
mov edx, [RGBp]
|
||||
mov ebp, [Yp]
|
||||
lea edx, [edx+2*edi] ; RGB += 2*Dst_BpS
|
||||
lea ebp, [ebp+2*esi] ; Y += 2*Src_BpS
|
||||
mov [RGBp], edx
|
||||
mov edi, [Vp]
|
||||
mov [Yp], ebp ; Y1
|
||||
lea edx, [ebp+esi] ; Y2
|
||||
|
||||
lea edi, [edi+esi] ; V += Src_BpS
|
||||
add esi, [Up] ; U += Src_BpS
|
||||
mov [Vp], edi
|
||||
mov [Up], esi
|
||||
|
||||
.Go
|
||||
mov [yCnt], ecx
|
||||
mov ecx, [xCnt]
|
||||
|
||||
; 5210c@640x480
|
||||
|
||||
.Loop_x ; edi,esi: U,V; ebp,edx: Y1, Y2; ecx: xCnt
|
||||
|
||||
; R = Y + a.U
|
||||
; G = Y + c.V + b.U
|
||||
; B = Y + d.V
|
||||
|
||||
movzx eax, byte [edi+ecx+0]
|
||||
movzx ebx, byte [esi+ecx+0]
|
||||
movq mm0, [Skl_YUV_Tab32_MMX+0*2048 + eax*8]
|
||||
movzx eax, byte [edi+ecx+1]
|
||||
paddw mm0, [Skl_YUV_Tab32_MMX+1*2048 + ebx*8]
|
||||
movzx ebx, byte [esi+ecx+1]
|
||||
movq mm4, [Skl_YUV_Tab32_MMX+0*2048 + eax*8]
|
||||
movzx eax, byte [ebp + 2*ecx+0]
|
||||
paddw mm4, [Skl_YUV_Tab32_MMX+1*2048 + ebx*8]
|
||||
movzx ebx, byte [ebp + 2*ecx+1]
|
||||
|
||||
movq mm1, mm0
|
||||
movq mm2, mm0
|
||||
movq mm3, mm0
|
||||
movq mm5, mm4
|
||||
movq mm6, mm4
|
||||
movq mm7, mm4
|
||||
|
||||
paddw mm0, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
|
||||
movzx eax, byte [ebp + 2*ecx+2]
|
||||
paddw mm1, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
|
||||
movzx ebx, byte [ebp + 2*ecx+3]
|
||||
packuswb mm0, mm1
|
||||
paddw mm4, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
|
||||
movzx eax, byte [edx + 2*ecx+0]
|
||||
paddw mm5, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
|
||||
|
||||
packuswb mm4, mm5
|
||||
mov esi, [RGBp]
|
||||
movzx ebx, byte [edx + 2*ecx+1]
|
||||
movq [esi+8*ecx+0], mm0 ; 2x32b
|
||||
movq [esi+8*ecx+8], mm4 ; 2x32b
|
||||
|
||||
paddw mm2, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
|
||||
movzx eax, byte [edx + 2*ecx+2]
|
||||
paddw mm3, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
|
||||
movzx ebx, byte [edx + 2*ecx+3]
|
||||
packuswb mm2, mm3
|
||||
paddw mm6, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
|
||||
add esi, [esp+8 +40]
|
||||
paddw mm7, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
|
||||
|
||||
mov edi, [Vp]
|
||||
packuswb mm6, mm7
|
||||
movq [esi+8*ecx+0], mm2 ; 2x32b
|
||||
movq [esi+8*ecx+8], mm6 ; 2x32b
|
||||
|
||||
add ecx, 2
|
||||
mov esi, [Up]
|
||||
|
||||
jl near .Loop_x
|
||||
|
||||
mov ecx, [yCnt]
|
||||
jmp .Loop_y
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,25 +1,25 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
static const int PCSX2_VersionHi = 0;
|
||||
static const int PCSX2_VersionMid = 9;
|
||||
static const int PCSX2_VersionLo = 7;
|
||||
|
||||
class SysCoreThread;
|
||||
class CpuInitializerSet;
|
||||
|
||||
struct Game_Data;
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
static const int PCSX2_VersionHi = 0;
|
||||
static const int PCSX2_VersionMid = 9;
|
||||
static const int PCSX2_VersionLo = 7;
|
||||
|
||||
class SysCoreThread;
|
||||
class CpuInitializerSet;
|
||||
|
||||
struct Game_Data;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
-------------------
|
||||
ZipTools (folder)
|
||||
-------------------
|
||||
|
||||
Contains C++ interfaces for zipping to/from various formats
|
||||
(primarily gzip and 7zip).
|
||||
|
||||
Notice: This folder is intended to be moved to a utility folder
|
||||
|
||||
-------------------
|
||||
ZipTools (folder)
|
||||
-------------------
|
||||
|
||||
Contains C++ interfaces for zipping to/from various formats
|
||||
(primarily gzip and 7zip).
|
||||
|
||||
Notice: This folder is intended to be moved to a utility folder
|
||||
outside the main PCSX2 folders at a later date.
|
|
@ -1,207 +1,207 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/PersistentThread.h"
|
||||
#include "Utilities/pxStreams.h"
|
||||
#include "wx/zipstrm.h"
|
||||
|
||||
using namespace Threading;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ArchiveEntry
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ArchiveEntry
|
||||
{
|
||||
protected:
|
||||
wxString m_filename;
|
||||
uptr m_dataidx;
|
||||
size_t m_datasize;
|
||||
|
||||
public:
|
||||
ArchiveEntry( const wxString& filename=wxEmptyString )
|
||||
: m_filename( filename )
|
||||
{
|
||||
m_dataidx = 0;
|
||||
m_datasize = 0;
|
||||
}
|
||||
|
||||
virtual ~ArchiveEntry() throw() {}
|
||||
|
||||
ArchiveEntry& SetDataIndex( uptr idx )
|
||||
{
|
||||
m_dataidx = idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArchiveEntry& SetDataSize( size_t size )
|
||||
{
|
||||
m_datasize = size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString GetFilename() const
|
||||
{
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
uptr GetDataIndex() const
|
||||
{
|
||||
return m_dataidx;
|
||||
}
|
||||
|
||||
uint GetDataSize() const
|
||||
{
|
||||
return m_datasize;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SafeArray< u8 > ArchiveDataBuffer;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ArchiveEntryList
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ArchiveEntryList
|
||||
{
|
||||
DeclareNoncopyableObject( ArchiveEntryList );
|
||||
|
||||
protected:
|
||||
std::vector<ArchiveEntry> m_list;
|
||||
ScopedPtr<ArchiveDataBuffer> m_data;
|
||||
|
||||
public:
|
||||
virtual ~ArchiveEntryList() throw() {}
|
||||
|
||||
ArchiveEntryList() {}
|
||||
|
||||
ArchiveEntryList( ArchiveDataBuffer* data )
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
ArchiveEntryList( ArchiveDataBuffer& data )
|
||||
{
|
||||
m_data = &data;
|
||||
}
|
||||
|
||||
const VmStateBuffer* GetBuffer() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
VmStateBuffer* GetBuffer()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
u8* GetPtr( uint idx )
|
||||
{
|
||||
return &(*m_data)[idx];
|
||||
}
|
||||
|
||||
const u8* GetPtr( uint idx ) const
|
||||
{
|
||||
return &(*m_data)[idx];
|
||||
}
|
||||
|
||||
ArchiveEntryList& Add( const ArchiveEntry& src )
|
||||
{
|
||||
m_list.push_back( src );
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t GetLength() const
|
||||
{
|
||||
return m_list.size();
|
||||
}
|
||||
|
||||
ArchiveEntry& operator[](uint idx)
|
||||
{
|
||||
return m_list[idx];
|
||||
}
|
||||
|
||||
const ArchiveEntry& operator[](uint idx) const
|
||||
{
|
||||
return m_list[idx];
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseCompressThread
|
||||
// --------------------------------------------------------------------------------------
|
||||
class BaseCompressThread
|
||||
: public pxThread
|
||||
{
|
||||
typedef pxThread _parent;
|
||||
|
||||
protected:
|
||||
pxOutputStream* m_gzfp;
|
||||
ArchiveEntryList* m_src_list;
|
||||
bool m_PendingSaveFlag;
|
||||
|
||||
wxString m_final_filename;
|
||||
|
||||
public:
|
||||
virtual ~BaseCompressThread() throw();
|
||||
|
||||
BaseCompressThread& SetSource( ArchiveEntryList* srcdata )
|
||||
{
|
||||
m_src_list = srcdata;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseCompressThread& SetSource( ArchiveEntryList& srcdata )
|
||||
{
|
||||
m_src_list = &srcdata;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseCompressThread& SetOutStream( pxOutputStream* out )
|
||||
{
|
||||
m_gzfp = out;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseCompressThread& SetOutStream( pxOutputStream& out )
|
||||
{
|
||||
m_gzfp = &out;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseCompressThread& SetFinishedPath( const wxString& path )
|
||||
{
|
||||
m_final_filename = path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString GetStreamName() const { return m_gzfp->GetStreamName(); }
|
||||
|
||||
BaseCompressThread& SetTargetFilename(const wxString& filename)
|
||||
{
|
||||
m_final_filename = filename;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
BaseCompressThread()
|
||||
{
|
||||
m_PendingSaveFlag = false;
|
||||
}
|
||||
|
||||
void SetPendingSave();
|
||||
void ExecuteTaskInThread();
|
||||
void OnCleanupInThread();
|
||||
};
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/PersistentThread.h"
|
||||
#include "Utilities/pxStreams.h"
|
||||
#include "wx/zipstrm.h"
|
||||
|
||||
using namespace Threading;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ArchiveEntry
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ArchiveEntry
|
||||
{
|
||||
protected:
|
||||
wxString m_filename;
|
||||
uptr m_dataidx;
|
||||
size_t m_datasize;
|
||||
|
||||
public:
|
||||
ArchiveEntry( const wxString& filename=wxEmptyString )
|
||||
: m_filename( filename )
|
||||
{
|
||||
m_dataidx = 0;
|
||||
m_datasize = 0;
|
||||
}
|
||||
|
||||
virtual ~ArchiveEntry() throw() {}
|
||||
|
||||
ArchiveEntry& SetDataIndex( uptr idx )
|
||||
{
|
||||
m_dataidx = idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArchiveEntry& SetDataSize( size_t size )
|
||||
{
|
||||
m_datasize = size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString GetFilename() const
|
||||
{
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
uptr GetDataIndex() const
|
||||
{
|
||||
return m_dataidx;
|
||||
}
|
||||
|
||||
uint GetDataSize() const
|
||||
{
|
||||
return m_datasize;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SafeArray< u8 > ArchiveDataBuffer;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ArchiveEntryList
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ArchiveEntryList
|
||||
{
|
||||
DeclareNoncopyableObject( ArchiveEntryList );
|
||||
|
||||
protected:
|
||||
std::vector<ArchiveEntry> m_list;
|
||||
ScopedPtr<ArchiveDataBuffer> m_data;
|
||||
|
||||
public:
|
||||
virtual ~ArchiveEntryList() throw() {}
|
||||
|
||||
ArchiveEntryList() {}
|
||||
|
||||
ArchiveEntryList( ArchiveDataBuffer* data )
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
ArchiveEntryList( ArchiveDataBuffer& data )
|
||||
{
|
||||
m_data = &data;
|
||||
}
|
||||
|
||||
const VmStateBuffer* GetBuffer() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
VmStateBuffer* GetBuffer()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
u8* GetPtr( uint idx )
|
||||
{
|
||||
return &(*m_data)[idx];
|
||||
}
|
||||
|
||||
const u8* GetPtr( uint idx ) const
|
||||
{
|
||||
return &(*m_data)[idx];
|
||||
}
|
||||
|
||||
ArchiveEntryList& Add( const ArchiveEntry& src )
|
||||
{
|
||||
m_list.push_back( src );
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t GetLength() const
|
||||
{
|
||||
return m_list.size();
|
||||
}
|
||||
|
||||
ArchiveEntry& operator[](uint idx)
|
||||
{
|
||||
return m_list[idx];
|
||||
}
|
||||
|
||||
const ArchiveEntry& operator[](uint idx) const
|
||||
{
|
||||
return m_list[idx];
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseCompressThread
|
||||
// --------------------------------------------------------------------------------------
|
||||
class BaseCompressThread
|
||||
: public pxThread
|
||||
{
|
||||
typedef pxThread _parent;
|
||||
|
||||
protected:
|
||||
pxOutputStream* m_gzfp;
|
||||
ArchiveEntryList* m_src_list;
|
||||
bool m_PendingSaveFlag;
|
||||
|
||||
wxString m_final_filename;
|
||||
|
||||
public:
|
||||
virtual ~BaseCompressThread() throw();
|
||||
|
||||
BaseCompressThread& SetSource( ArchiveEntryList* srcdata )
|
||||
{
|
||||
m_src_list = srcdata;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseCompressThread& SetSource( ArchiveEntryList& srcdata )
|
||||
{
|
||||
m_src_list = &srcdata;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseCompressThread& SetOutStream( pxOutputStream* out )
|
||||
{
|
||||
m_gzfp = out;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseCompressThread& SetOutStream( pxOutputStream& out )
|
||||
{
|
||||
m_gzfp = &out;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseCompressThread& SetFinishedPath( const wxString& path )
|
||||
{
|
||||
m_final_filename = path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString GetStreamName() const { return m_gzfp->GetStreamName(); }
|
||||
|
||||
BaseCompressThread& SetTargetFilename(const wxString& filename)
|
||||
{
|
||||
m_final_filename = filename;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
BaseCompressThread()
|
||||
{
|
||||
m_PendingSaveFlag = false;
|
||||
}
|
||||
|
||||
void SetPendingSave();
|
||||
void ExecuteTaskInThread();
|
||||
void OnCleanupInThread();
|
||||
};
|
||||
|
|
|
@ -1,95 +1,95 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of te License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "App.h"
|
||||
#include "SaveState.h"
|
||||
#include "ThreadedZipTools.h"
|
||||
#include "Utilities/SafeArray.inl"
|
||||
#include "wx/wfstream.h"
|
||||
|
||||
|
||||
BaseCompressThread::~BaseCompressThread() throw()
|
||||
{
|
||||
_parent::Cancel();
|
||||
if( m_PendingSaveFlag )
|
||||
{
|
||||
wxGetApp().ClearPendingSave();
|
||||
m_PendingSaveFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseCompressThread::SetPendingSave()
|
||||
{
|
||||
wxGetApp().StartPendingSave();
|
||||
m_PendingSaveFlag = true;
|
||||
}
|
||||
|
||||
void BaseCompressThread::ExecuteTaskInThread()
|
||||
{
|
||||
// TODO : Add an API to PersistentThread for this! :) --air
|
||||
//SetThreadPriority( THREAD_PRIORITY_BELOW_NORMAL );
|
||||
|
||||
// Notes:
|
||||
// * Safeguard against corruption by writing to a temp file, and then copying the final
|
||||
// result over the original.
|
||||
|
||||
if( !m_src_list ) return;
|
||||
SetPendingSave();
|
||||
|
||||
Yield( 3 );
|
||||
|
||||
uint listlen = m_src_list->GetLength();
|
||||
for( uint i=0; i<listlen; ++i )
|
||||
{
|
||||
const ArchiveEntry& entry = (*m_src_list)[i];
|
||||
if (!entry.GetDataSize()) continue;
|
||||
|
||||
wxArchiveOutputStream& woot = *(wxArchiveOutputStream*)m_gzfp->GetWxStreamBase();
|
||||
woot.PutNextEntry( entry.GetFilename() );
|
||||
|
||||
static const uint BlockSize = 0x64000;
|
||||
uint curidx = 0;
|
||||
|
||||
do {
|
||||
uint thisBlockSize = std::min( BlockSize, entry.GetDataSize() - curidx );
|
||||
m_gzfp->Write(m_src_list->GetPtr( entry.GetDataIndex() + curidx ), thisBlockSize);
|
||||
curidx += thisBlockSize;
|
||||
Yield( 2 );
|
||||
} while( curidx < entry.GetDataSize() );
|
||||
|
||||
woot.CloseEntry();
|
||||
}
|
||||
|
||||
m_gzfp->Close();
|
||||
|
||||
if( !wxRenameFile( m_gzfp->GetStreamName(), m_final_filename, true ) )
|
||||
throw Exception::BadStream( m_final_filename )
|
||||
.SetDiagMsg(L"Failed to move or copy the temporary archive to the destination filename.")
|
||||
.SetUserMsg(_("The savestate was not properly saved. The temporary file was created successfully but could not be moved to its final resting place."));
|
||||
|
||||
Console.WriteLn( "(gzipThread) Data saved to disk without error." );
|
||||
}
|
||||
|
||||
void BaseCompressThread::OnCleanupInThread()
|
||||
{
|
||||
_parent::OnCleanupInThread();
|
||||
wxGetApp().DeleteThread( this );
|
||||
|
||||
safe_delete(m_gzfp);
|
||||
safe_delete(m_src_list);
|
||||
}
|
||||
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of te License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "App.h"
|
||||
#include "SaveState.h"
|
||||
#include "ThreadedZipTools.h"
|
||||
#include "Utilities/SafeArray.inl"
|
||||
#include "wx/wfstream.h"
|
||||
|
||||
|
||||
BaseCompressThread::~BaseCompressThread() throw()
|
||||
{
|
||||
_parent::Cancel();
|
||||
if( m_PendingSaveFlag )
|
||||
{
|
||||
wxGetApp().ClearPendingSave();
|
||||
m_PendingSaveFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseCompressThread::SetPendingSave()
|
||||
{
|
||||
wxGetApp().StartPendingSave();
|
||||
m_PendingSaveFlag = true;
|
||||
}
|
||||
|
||||
void BaseCompressThread::ExecuteTaskInThread()
|
||||
{
|
||||
// TODO : Add an API to PersistentThread for this! :) --air
|
||||
//SetThreadPriority( THREAD_PRIORITY_BELOW_NORMAL );
|
||||
|
||||
// Notes:
|
||||
// * Safeguard against corruption by writing to a temp file, and then copying the final
|
||||
// result over the original.
|
||||
|
||||
if( !m_src_list ) return;
|
||||
SetPendingSave();
|
||||
|
||||
Yield( 3 );
|
||||
|
||||
uint listlen = m_src_list->GetLength();
|
||||
for( uint i=0; i<listlen; ++i )
|
||||
{
|
||||
const ArchiveEntry& entry = (*m_src_list)[i];
|
||||
if (!entry.GetDataSize()) continue;
|
||||
|
||||
wxArchiveOutputStream& woot = *(wxArchiveOutputStream*)m_gzfp->GetWxStreamBase();
|
||||
woot.PutNextEntry( entry.GetFilename() );
|
||||
|
||||
static const uint BlockSize = 0x64000;
|
||||
uint curidx = 0;
|
||||
|
||||
do {
|
||||
uint thisBlockSize = std::min( BlockSize, entry.GetDataSize() - curidx );
|
||||
m_gzfp->Write(m_src_list->GetPtr( entry.GetDataIndex() + curidx ), thisBlockSize);
|
||||
curidx += thisBlockSize;
|
||||
Yield( 2 );
|
||||
} while( curidx < entry.GetDataSize() );
|
||||
|
||||
woot.CloseEntry();
|
||||
}
|
||||
|
||||
m_gzfp->Close();
|
||||
|
||||
if( !wxRenameFile( m_gzfp->GetStreamName(), m_final_filename, true ) )
|
||||
throw Exception::BadStream( m_final_filename )
|
||||
.SetDiagMsg(L"Failed to move or copy the temporary archive to the destination filename.")
|
||||
.SetUserMsg(_("The savestate was not properly saved. The temporary file was created successfully but could not be moved to its final resting place."));
|
||||
|
||||
Console.WriteLn( "(gzipThread) Data saved to disk without error." );
|
||||
}
|
||||
|
||||
void BaseCompressThread::OnCleanupInThread()
|
||||
{
|
||||
_parent::OnCleanupInThread();
|
||||
wxGetApp().DeleteThread( this );
|
||||
|
||||
safe_delete(m_gzfp);
|
||||
safe_delete(m_src_list);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of te License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of te License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
|
|
|
@ -1,225 +1,225 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "App.h"
|
||||
#include "AppGameDatabase.h"
|
||||
|
||||
class DBLoaderHelper
|
||||
{
|
||||
DeclareNoncopyableObject( DBLoaderHelper );
|
||||
|
||||
protected:
|
||||
IGameDatabase& m_gamedb;
|
||||
wxInputStream& m_reader;
|
||||
|
||||
// temp areas used as buffers for accelerated loading of database content. These strings are
|
||||
// allocated and grown only once, and then reused for the duration of the database loading
|
||||
// process; saving thousands of heapp allocation operations.
|
||||
|
||||
wxString m_dest;
|
||||
std::string m_intermediate;
|
||||
|
||||
key_pair m_keyPair;
|
||||
|
||||
public:
|
||||
DBLoaderHelper( wxInputStream& reader, IGameDatabase& db )
|
||||
: m_gamedb(db)
|
||||
, m_reader(reader)
|
||||
{
|
||||
}
|
||||
|
||||
wxString ReadHeader();
|
||||
void ReadGames();
|
||||
|
||||
protected:
|
||||
void doError(bool doMsg = false);
|
||||
bool extractMultiLine();
|
||||
void extract();
|
||||
};
|
||||
|
||||
void DBLoaderHelper::doError(bool doMsg) {
|
||||
if (doMsg) Console.Error("GameDatabase: Bad file data [%s]", m_dest.c_str());
|
||||
m_keyPair.Clear();
|
||||
}
|
||||
|
||||
// Multiline Sections are in the form of:
|
||||
//
|
||||
// [section=value]
|
||||
// content
|
||||
// content
|
||||
// [/section]
|
||||
//
|
||||
// ... where the =value part is OPTIONAL.
|
||||
bool DBLoaderHelper::extractMultiLine() {
|
||||
|
||||
if (m_dest[0] != L'[') return false; // All multiline sections begin with a '['!
|
||||
|
||||
if (!m_dest.EndsWith(L"]")) {
|
||||
doError(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_keyPair.key = m_dest;
|
||||
|
||||
// Use Mid() to strip off the left and right side brackets.
|
||||
wxString midLine(m_dest.Mid(1, m_dest.Length()-2));
|
||||
wxString lvalue(midLine.BeforeFirst(L'=').Trim(true).Trim(false));
|
||||
//wxString rvalue(midLine.AfterFirst(L'=').Trim(true).Trim(false));
|
||||
|
||||
wxString endString;
|
||||
endString.Printf( L"[/%s]", lvalue.c_str() );
|
||||
|
||||
while(!m_reader.Eof()) {
|
||||
pxReadLine( m_reader, m_dest, m_intermediate );
|
||||
if (m_dest.CmpNoCase(endString) == 0) break;
|
||||
m_keyPair.value += m_dest + L"\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DBLoaderHelper::extract() {
|
||||
|
||||
if( !pxParseAssignmentString( m_dest, m_keyPair.key, m_keyPair.value ) ) return;
|
||||
if( m_keyPair.value.IsEmpty() ) doError(true);
|
||||
}
|
||||
|
||||
wxString DBLoaderHelper::ReadHeader()
|
||||
{
|
||||
wxString header;
|
||||
header.reserve(2048);
|
||||
|
||||
while(!m_reader.Eof()) {
|
||||
pxReadLine(m_reader, m_dest, m_intermediate);
|
||||
m_dest.Trim(false).Trim(true);
|
||||
if( !(m_dest.IsEmpty() || m_dest.StartsWith(L"--") || m_dest.StartsWith( L"//" ) || m_dest.StartsWith( L";" )) ) break;
|
||||
header += m_dest + L'\n';
|
||||
}
|
||||
|
||||
if( !m_dest.IsEmpty() )
|
||||
{
|
||||
m_keyPair.Clear();
|
||||
if( !extractMultiLine() ) extract();
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
void DBLoaderHelper::ReadGames()
|
||||
{
|
||||
Game_Data* game = NULL;
|
||||
|
||||
if (m_keyPair.IsOk())
|
||||
{
|
||||
game = m_gamedb.createNewGame(m_keyPair.value);
|
||||
game->writeString(m_keyPair.key, m_keyPair.value);
|
||||
//if( m_keyPair.CompareKey(m_gamedb.getBaseKey()) )
|
||||
// game.id = m_keyPair.value;
|
||||
}
|
||||
|
||||
while(!m_reader.Eof()) { // Fill game data, find new game, repeat...
|
||||
pthread_testcancel();
|
||||
pxReadLine(m_reader, m_dest, m_intermediate);
|
||||
m_dest.Trim(true).Trim(false);
|
||||
if( m_dest.IsEmpty() ) continue;
|
||||
|
||||
m_keyPair.Clear();
|
||||
if (!extractMultiLine()) extract();
|
||||
|
||||
if (!m_keyPair.IsOk()) continue;
|
||||
if (m_keyPair.CompareKey(m_gamedb.getBaseKey()))
|
||||
game = m_gamedb.createNewGame(m_keyPair.value);
|
||||
|
||||
game->writeString( m_keyPair.key, m_keyPair.value );
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// AppGameDatabase (implementations)
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
AppGameDatabase& AppGameDatabase::LoadFromFile(wxString file, const wxString& key )
|
||||
{
|
||||
if( wxFileName(file).IsRelative() )
|
||||
file = (InstallFolder + file).GetFullPath();
|
||||
|
||||
if (!wxFileExists(file))
|
||||
{
|
||||
Console.Error(L"(GameDB) Database Not Found! [%s]", file.c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxFFileInputStream reader( file );
|
||||
|
||||
if (!reader.IsOk())
|
||||
{
|
||||
//throw Exception::FileNotFound( file );
|
||||
Console.Error(L"(GameDB) Could not access file (permission denied?) [%s]", file.c_str());
|
||||
}
|
||||
|
||||
DBLoaderHelper loader( reader, *this );
|
||||
|
||||
u64 qpc_Start = GetCPUTicks();
|
||||
header = loader.ReadHeader();
|
||||
loader.ReadGames();
|
||||
u64 qpc_end = GetCPUTicks();
|
||||
|
||||
Console.WriteLn( "(GameDB) %d games on record (loaded in %ums)",
|
||||
gHash.size(), (u32)(((qpc_end-qpc_Start)*1000) / GetTickFrequency()) );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Saves changes to the database
|
||||
|
||||
void AppGameDatabase::SaveToFile(const wxString& file) {
|
||||
wxFFileOutputStream writer( file );
|
||||
pxWriteMultiline(writer, header);
|
||||
|
||||
for(uint blockidx=0; blockidx<=m_BlockTableWritePos; ++blockidx)
|
||||
{
|
||||
if( !m_BlockTable[blockidx] ) continue;
|
||||
|
||||
const uint endidx = (blockidx == m_BlockTableWritePos) ? m_CurBlockWritePos : m_GamesPerBlock;
|
||||
|
||||
for( uint gameidx=0; gameidx<=endidx; ++gameidx )
|
||||
{
|
||||
const Game_Data& game( m_BlockTable[blockidx][gameidx] );
|
||||
KeyPairArray::const_iterator i(game.kList.begin());
|
||||
for ( ; i != game.kList.end(); ++i) {
|
||||
pxWriteMultiline(writer, i->toString() );
|
||||
}
|
||||
|
||||
pxWriteLine(writer, L"---------------------------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AppGameDatabase* Pcsx2App::GetGameDatabase()
|
||||
{
|
||||
pxAppResources& res( GetResourceCache() );
|
||||
|
||||
ScopedLock lock( m_mtx_LoadingGameDB );
|
||||
if( !res.GameDB )
|
||||
{
|
||||
res.GameDB = new AppGameDatabase();
|
||||
res.GameDB->LoadFromFile();
|
||||
}
|
||||
return res.GameDB;
|
||||
}
|
||||
|
||||
IGameDatabase* AppHost_GetGameDatabase()
|
||||
{
|
||||
return wxGetApp().GetGameDatabase();
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "App.h"
|
||||
#include "AppGameDatabase.h"
|
||||
|
||||
class DBLoaderHelper
|
||||
{
|
||||
DeclareNoncopyableObject( DBLoaderHelper );
|
||||
|
||||
protected:
|
||||
IGameDatabase& m_gamedb;
|
||||
wxInputStream& m_reader;
|
||||
|
||||
// temp areas used as buffers for accelerated loading of database content. These strings are
|
||||
// allocated and grown only once, and then reused for the duration of the database loading
|
||||
// process; saving thousands of heapp allocation operations.
|
||||
|
||||
wxString m_dest;
|
||||
std::string m_intermediate;
|
||||
|
||||
key_pair m_keyPair;
|
||||
|
||||
public:
|
||||
DBLoaderHelper( wxInputStream& reader, IGameDatabase& db )
|
||||
: m_gamedb(db)
|
||||
, m_reader(reader)
|
||||
{
|
||||
}
|
||||
|
||||
wxString ReadHeader();
|
||||
void ReadGames();
|
||||
|
||||
protected:
|
||||
void doError(bool doMsg = false);
|
||||
bool extractMultiLine();
|
||||
void extract();
|
||||
};
|
||||
|
||||
void DBLoaderHelper::doError(bool doMsg) {
|
||||
if (doMsg) Console.Error("GameDatabase: Bad file data [%s]", m_dest.c_str());
|
||||
m_keyPair.Clear();
|
||||
}
|
||||
|
||||
// Multiline Sections are in the form of:
|
||||
//
|
||||
// [section=value]
|
||||
// content
|
||||
// content
|
||||
// [/section]
|
||||
//
|
||||
// ... where the =value part is OPTIONAL.
|
||||
bool DBLoaderHelper::extractMultiLine() {
|
||||
|
||||
if (m_dest[0] != L'[') return false; // All multiline sections begin with a '['!
|
||||
|
||||
if (!m_dest.EndsWith(L"]")) {
|
||||
doError(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_keyPair.key = m_dest;
|
||||
|
||||
// Use Mid() to strip off the left and right side brackets.
|
||||
wxString midLine(m_dest.Mid(1, m_dest.Length()-2));
|
||||
wxString lvalue(midLine.BeforeFirst(L'=').Trim(true).Trim(false));
|
||||
//wxString rvalue(midLine.AfterFirst(L'=').Trim(true).Trim(false));
|
||||
|
||||
wxString endString;
|
||||
endString.Printf( L"[/%s]", lvalue.c_str() );
|
||||
|
||||
while(!m_reader.Eof()) {
|
||||
pxReadLine( m_reader, m_dest, m_intermediate );
|
||||
if (m_dest.CmpNoCase(endString) == 0) break;
|
||||
m_keyPair.value += m_dest + L"\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DBLoaderHelper::extract() {
|
||||
|
||||
if( !pxParseAssignmentString( m_dest, m_keyPair.key, m_keyPair.value ) ) return;
|
||||
if( m_keyPair.value.IsEmpty() ) doError(true);
|
||||
}
|
||||
|
||||
wxString DBLoaderHelper::ReadHeader()
|
||||
{
|
||||
wxString header;
|
||||
header.reserve(2048);
|
||||
|
||||
while(!m_reader.Eof()) {
|
||||
pxReadLine(m_reader, m_dest, m_intermediate);
|
||||
m_dest.Trim(false).Trim(true);
|
||||
if( !(m_dest.IsEmpty() || m_dest.StartsWith(L"--") || m_dest.StartsWith( L"//" ) || m_dest.StartsWith( L";" )) ) break;
|
||||
header += m_dest + L'\n';
|
||||
}
|
||||
|
||||
if( !m_dest.IsEmpty() )
|
||||
{
|
||||
m_keyPair.Clear();
|
||||
if( !extractMultiLine() ) extract();
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
void DBLoaderHelper::ReadGames()
|
||||
{
|
||||
Game_Data* game = NULL;
|
||||
|
||||
if (m_keyPair.IsOk())
|
||||
{
|
||||
game = m_gamedb.createNewGame(m_keyPair.value);
|
||||
game->writeString(m_keyPair.key, m_keyPair.value);
|
||||
//if( m_keyPair.CompareKey(m_gamedb.getBaseKey()) )
|
||||
// game.id = m_keyPair.value;
|
||||
}
|
||||
|
||||
while(!m_reader.Eof()) { // Fill game data, find new game, repeat...
|
||||
pthread_testcancel();
|
||||
pxReadLine(m_reader, m_dest, m_intermediate);
|
||||
m_dest.Trim(true).Trim(false);
|
||||
if( m_dest.IsEmpty() ) continue;
|
||||
|
||||
m_keyPair.Clear();
|
||||
if (!extractMultiLine()) extract();
|
||||
|
||||
if (!m_keyPair.IsOk()) continue;
|
||||
if (m_keyPair.CompareKey(m_gamedb.getBaseKey()))
|
||||
game = m_gamedb.createNewGame(m_keyPair.value);
|
||||
|
||||
game->writeString( m_keyPair.key, m_keyPair.value );
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// AppGameDatabase (implementations)
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
AppGameDatabase& AppGameDatabase::LoadFromFile(wxString file, const wxString& key )
|
||||
{
|
||||
if( wxFileName(file).IsRelative() )
|
||||
file = (InstallFolder + file).GetFullPath();
|
||||
|
||||
if (!wxFileExists(file))
|
||||
{
|
||||
Console.Error(L"(GameDB) Database Not Found! [%s]", file.c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxFFileInputStream reader( file );
|
||||
|
||||
if (!reader.IsOk())
|
||||
{
|
||||
//throw Exception::FileNotFound( file );
|
||||
Console.Error(L"(GameDB) Could not access file (permission denied?) [%s]", file.c_str());
|
||||
}
|
||||
|
||||
DBLoaderHelper loader( reader, *this );
|
||||
|
||||
u64 qpc_Start = GetCPUTicks();
|
||||
header = loader.ReadHeader();
|
||||
loader.ReadGames();
|
||||
u64 qpc_end = GetCPUTicks();
|
||||
|
||||
Console.WriteLn( "(GameDB) %d games on record (loaded in %ums)",
|
||||
gHash.size(), (u32)(((qpc_end-qpc_Start)*1000) / GetTickFrequency()) );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Saves changes to the database
|
||||
|
||||
void AppGameDatabase::SaveToFile(const wxString& file) {
|
||||
wxFFileOutputStream writer( file );
|
||||
pxWriteMultiline(writer, header);
|
||||
|
||||
for(uint blockidx=0; blockidx<=m_BlockTableWritePos; ++blockidx)
|
||||
{
|
||||
if( !m_BlockTable[blockidx] ) continue;
|
||||
|
||||
const uint endidx = (blockidx == m_BlockTableWritePos) ? m_CurBlockWritePos : m_GamesPerBlock;
|
||||
|
||||
for( uint gameidx=0; gameidx<=endidx; ++gameidx )
|
||||
{
|
||||
const Game_Data& game( m_BlockTable[blockidx][gameidx] );
|
||||
KeyPairArray::const_iterator i(game.kList.begin());
|
||||
for ( ; i != game.kList.end(); ++i) {
|
||||
pxWriteMultiline(writer, i->toString() );
|
||||
}
|
||||
|
||||
pxWriteLine(writer, L"---------------------------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AppGameDatabase* Pcsx2App::GetGameDatabase()
|
||||
{
|
||||
pxAppResources& res( GetResourceCache() );
|
||||
|
||||
ScopedLock lock( m_mtx_LoadingGameDB );
|
||||
if( !res.GameDB )
|
||||
{
|
||||
res.GameDB = new AppGameDatabase();
|
||||
res.GameDB->LoadFromFile();
|
||||
}
|
||||
return res.GameDB;
|
||||
}
|
||||
|
||||
IGameDatabase* AppHost_GetGameDatabase()
|
||||
{
|
||||
return wxGetApp().GetGameDatabase();
|
||||
}
|
||||
|
|
|
@ -1,68 +1,68 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameDatabase.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// AppGameDatabase
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This class extends BaseGameDatabase_Impl and provides interfaces for loading and saving
|
||||
// the text-formatted game database.
|
||||
//
|
||||
// Example:
|
||||
// ---------------------------------------------
|
||||
// Serial = SLUS-20486
|
||||
// Name = Marvel vs. Capcom 2
|
||||
// Region = NTSC-U
|
||||
// ---------------------------------------------
|
||||
//
|
||||
// [-- separators are a standard part of the formatting]
|
||||
//
|
||||
|
||||
// To Load this game data, use "Serial" as the initial Key
|
||||
// then specify "SLUS-20486" as the value in the constructor.
|
||||
// After the constructor loads the game data, you can use the
|
||||
// GameDatabase class's methods to get the other key's values.
|
||||
// Such as dbLoader.getString("Region") returns "NTSC-U"
|
||||
|
||||
class AppGameDatabase : public BaseGameDatabaseImpl
|
||||
{
|
||||
protected:
|
||||
wxString header; // Header of the database
|
||||
wxString baseKey; // Key to separate games by ("Serial")
|
||||
|
||||
public:
|
||||
AppGameDatabase() {}
|
||||
virtual ~AppGameDatabase() throw() {
|
||||
Console.WriteLn( "(GameDB) Unloading..." );
|
||||
}
|
||||
|
||||
AppGameDatabase& LoadFromFile(wxString file = L"GameIndex.dbf", const wxString& key = L"Serial" );
|
||||
void SaveToFile(const wxString& file = L"GameIndex.dbf");
|
||||
};
|
||||
|
||||
static wxString compatToStringWX(int compat) {
|
||||
switch (compat) {
|
||||
case 6: return L"Perfect";
|
||||
case 5: return L"Playable";
|
||||
case 4: return L"In-Game";
|
||||
case 3: return L"Menu";
|
||||
case 2: return L"Intro";
|
||||
case 1: return L"Nothing";
|
||||
default: return L"Unknown";
|
||||
}
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameDatabase.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// AppGameDatabase
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This class extends BaseGameDatabase_Impl and provides interfaces for loading and saving
|
||||
// the text-formatted game database.
|
||||
//
|
||||
// Example:
|
||||
// ---------------------------------------------
|
||||
// Serial = SLUS-20486
|
||||
// Name = Marvel vs. Capcom 2
|
||||
// Region = NTSC-U
|
||||
// ---------------------------------------------
|
||||
//
|
||||
// [-- separators are a standard part of the formatting]
|
||||
//
|
||||
|
||||
// To Load this game data, use "Serial" as the initial Key
|
||||
// then specify "SLUS-20486" as the value in the constructor.
|
||||
// After the constructor loads the game data, you can use the
|
||||
// GameDatabase class's methods to get the other key's values.
|
||||
// Such as dbLoader.getString("Region") returns "NTSC-U"
|
||||
|
||||
class AppGameDatabase : public BaseGameDatabaseImpl
|
||||
{
|
||||
protected:
|
||||
wxString header; // Header of the database
|
||||
wxString baseKey; // Key to separate games by ("Serial")
|
||||
|
||||
public:
|
||||
AppGameDatabase() {}
|
||||
virtual ~AppGameDatabase() throw() {
|
||||
Console.WriteLn( "(GameDB) Unloading..." );
|
||||
}
|
||||
|
||||
AppGameDatabase& LoadFromFile(wxString file = L"GameIndex.dbf", const wxString& key = L"Serial" );
|
||||
void SaveToFile(const wxString& file = L"GameIndex.dbf");
|
||||
};
|
||||
|
||||
static wxString compatToStringWX(int compat) {
|
||||
switch (compat) {
|
||||
case 6: return L"Perfect";
|
||||
case 5: return L"Playable";
|
||||
case 4: return L"In-Game";
|
||||
case 3: return L"Menu";
|
||||
case 2: return L"Intro";
|
||||
case 1: return L"Nothing";
|
||||
default: return L"Unknown";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,307 +1,307 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "MainFrame.h"
|
||||
#include "Utilities/IniInterface.h"
|
||||
#include "Utilities/HashMap.h"
|
||||
#include "Dialogs/ModalPopups.h"
|
||||
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include "wx/msw/regconf.h"
|
||||
#endif
|
||||
|
||||
DocsModeType DocsFolderMode = DocsFolder_User;
|
||||
bool UseDefaultSettingsFolder = true;
|
||||
bool UseDefaultPluginsFolder = true;
|
||||
bool UseDefaultThemesFolder = true;
|
||||
|
||||
|
||||
wxDirName CustomDocumentsFolder;
|
||||
wxDirName SettingsFolder;
|
||||
|
||||
wxDirName InstallFolder;
|
||||
wxDirName PluginsFolder;
|
||||
wxDirName ThemesFolder;
|
||||
|
||||
// The UserLocalData folder can be redefined depending on whether or not PCSX2 is in
|
||||
// "portable install" mode or not. when PCSX2 has been configured for portable install, the
|
||||
// UserLocalData folder is the current working directory.
|
||||
//
|
||||
InstallationModeType InstallationMode;
|
||||
|
||||
static wxFileName GetPortableIniPath()
|
||||
{
|
||||
wxString programFullPath = wxStandardPaths::Get().GetExecutablePath();
|
||||
wxDirName programDir( wxFileName(programFullPath).GetPath() );
|
||||
|
||||
return programDir + "portable.ini";
|
||||
}
|
||||
|
||||
static wxString GetMsg_PortableModeRights()
|
||||
{
|
||||
return pxE( "!Notice:PortableModeRights",
|
||||
L"Please ensure that these folders are created and that your user account is granted "
|
||||
L"write permissions to them -- or re-run PCSX2 with elevated (administrator) rights, which "
|
||||
L"should grant PCSX2 the ability to create the necessary folders itself. If you "
|
||||
L"do not have elevated rights on this computer, then you will need to switch to User "
|
||||
L"Documents mode (click button below)."
|
||||
);
|
||||
};
|
||||
|
||||
bool Pcsx2App::TestUserPermissionsRights( const wxDirName& testFolder, wxString& createFailedStr, wxString& accessFailedStr )
|
||||
{
|
||||
// We need to individually verify read/write permission for each PCSX2 user documents folder.
|
||||
// If any of the folders are not writable, then the user should be informed asap via
|
||||
// friendly and courteous dialog box!
|
||||
|
||||
const wxDirName PermissionFolders[] =
|
||||
{
|
||||
PathDefs::Base::Settings(),
|
||||
PathDefs::Base::MemoryCards(),
|
||||
PathDefs::Base::Savestates(),
|
||||
PathDefs::Base::Snapshots(),
|
||||
PathDefs::Base::Logs(),
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
PathDefs::Base::Dumps(),
|
||||
#endif
|
||||
};
|
||||
|
||||
FastFormatUnicode createme, accessme;
|
||||
|
||||
for (uint i=0; i<ArraySize(PermissionFolders); ++i)
|
||||
{
|
||||
wxDirName folder( testFolder + PermissionFolders[i] );
|
||||
|
||||
if (!folder.Mkdir())
|
||||
createme += L"\t" + folder.ToString() + L"\n";
|
||||
|
||||
if (!folder.IsWritable())
|
||||
accessme += L"\t" + folder.ToString() + L"\n";
|
||||
}
|
||||
|
||||
if (!accessme.IsEmpty())
|
||||
{
|
||||
accessFailedStr = (wxString)_("The following folders exist, but are not writable:") + L"\n" + accessme;
|
||||
}
|
||||
|
||||
if (!createme.IsEmpty())
|
||||
{
|
||||
createFailedStr = (wxString)_("The following folders are missing and cannot be created:") + L"\n" + createme;
|
||||
}
|
||||
|
||||
return (createFailedStr.IsEmpty() && accessFailedStr.IsEmpty());
|
||||
}
|
||||
|
||||
// Portable installations are assumed to be run in either administrator rights mode, or run
|
||||
// from "insecure media" such as a removable flash drive. In these cases, the default path for
|
||||
// PCSX2 user documents becomes ".", which is the current working directory.
|
||||
//
|
||||
// Portable installation mode is typically enabled via the presence of an INI file in the
|
||||
// same directory that PCSX2 is installed to.
|
||||
//
|
||||
wxConfigBase* Pcsx2App::TestForPortableInstall()
|
||||
{
|
||||
InstallationMode = InstallMode_Registered;
|
||||
|
||||
const wxFileName portableIniFile( GetPortableIniPath() );
|
||||
const wxDirName portableDocsFolder( portableIniFile.GetPath() );
|
||||
|
||||
if (Startup.PortableMode || portableIniFile.FileExists())
|
||||
{
|
||||
wxString FilenameStr = portableIniFile.GetFullPath();
|
||||
if (Startup.PortableMode)
|
||||
Console.WriteLn( L"(UserMode) Portable mode requested via commandline switch!" );
|
||||
else
|
||||
Console.WriteLn( L"(UserMode) Found portable install ini @ %s", FilenameStr.c_str() );
|
||||
|
||||
// Just because the portable ini file exists doesn't mean we can actually run in portable
|
||||
// mode. In order to determine our read/write permissions to the PCSX2, we must try to
|
||||
// modify the configured documents folder, and catch any ensuing error.
|
||||
|
||||
ScopedPtr<wxFileConfig> conf_portable( OpenFileConfig( portableIniFile.GetFullPath() ) );
|
||||
conf_portable->SetRecordDefaults(false);
|
||||
|
||||
while( true )
|
||||
{
|
||||
wxString accessFailedStr, createFailedStr;
|
||||
if (TestUserPermissionsRights( portableDocsFolder, createFailedStr, accessFailedStr )) break;
|
||||
|
||||
wxDialogWithHelpers dialog( NULL, AddAppName(_("Portable mode error - %s")) );
|
||||
|
||||
wxTextCtrl* scrollText = new wxTextCtrl(
|
||||
&dialog, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_READONLY | wxTE_MULTILINE | wxTE_WORDWRAP
|
||||
);
|
||||
|
||||
if (!createFailedStr.IsEmpty())
|
||||
scrollText->AppendText( createFailedStr + L"\n" );
|
||||
|
||||
if (!accessFailedStr.IsEmpty())
|
||||
scrollText->AppendText( accessFailedStr + L"\n" );
|
||||
|
||||
dialog += dialog.Heading( _("PCSX2 has been installed as a portable application but cannot run due to the following errors:" ) );
|
||||
dialog += scrollText | pxExpand.Border(wxALL, 16);
|
||||
dialog += 6;
|
||||
dialog += dialog.Text( GetMsg_PortableModeRights() );
|
||||
|
||||
// [TODO] : Add url for platform-relevant user permissions tutorials? (low priority)
|
||||
|
||||
wxWindowID result = pxIssueConfirmation( dialog,
|
||||
MsgButtons().Retry().Cancel().Custom(_("Switch to User Documents Mode"), "switchmode")
|
||||
);
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case wxID_CANCEL:
|
||||
throw Exception::StartupAborted( L"User canceled portable mode due to insufficient user access/permissions." );
|
||||
|
||||
case wxID_RETRY:
|
||||
// do nothing (continues while loop)
|
||||
break;
|
||||
|
||||
case pxID_CUSTOM:
|
||||
wxDialogWithHelpers dialog2( NULL, AddAppName(_("%s is switching to local install mode.")) );
|
||||
dialog2 += dialog2.Heading( _("Try to remove the file called \"portable.ini\" from your installation directory manually." ) );
|
||||
dialog2 += 6;
|
||||
pxIssueConfirmation( dialog2, MsgButtons().OK() );
|
||||
conf_portable.DetachPtr(); // Not sure but can't hurt
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Success -- all user-based folders have write access. PCSX2 should be able to run error-free!
|
||||
// Force-set the custom documents mode, and set the
|
||||
|
||||
InstallationMode = InstallMode_Portable;
|
||||
DocsFolderMode = DocsFolder_Custom;
|
||||
CustomDocumentsFolder = portableDocsFolder;
|
||||
return conf_portable.DetachPtr();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Reset RunWizard so the FTWizard is run again on next PCSX2 start.
|
||||
void Pcsx2App::WipeUserModeSettings()
|
||||
{
|
||||
if (InstallationMode == InstallMode_Portable)
|
||||
{
|
||||
// Remove the portable.ini entry "RunWizard" conforming to this instance of PCSX2.
|
||||
wxFileName portableIniFile( GetPortableIniPath() );
|
||||
ScopedPtr<wxFileConfig> conf_portable( OpenFileConfig( portableIniFile.GetFullPath() ) );
|
||||
conf_portable->DeleteEntry(L"RunWizard");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the registry entry "RunWizard" conforming to this instance of PCSX2.
|
||||
ScopedPtr<wxConfigBase> conf_install( OpenInstallSettingsFile() );
|
||||
conf_install->DeleteEntry(L"RunWizard");
|
||||
}
|
||||
}
|
||||
|
||||
static void DoFirstTimeWizard()
|
||||
{
|
||||
// first time startup, so give the user the choice of user mode:
|
||||
while(true)
|
||||
{
|
||||
// PCSX2's FTWizard allows improptu restarting of the wizard without cancellation.
|
||||
// This is typically used to change the user's language selection.
|
||||
|
||||
FirstTimeWizard wiz( NULL );
|
||||
if( wiz.RunWizard( wiz.GetFirstPage() ) ) break;
|
||||
if (wiz.GetReturnCode() != pxID_RestartWizard)
|
||||
throw Exception::StartupAborted( L"User canceled FirstTime Wizard." );
|
||||
|
||||
Console.WriteLn( Color_StrongBlack, "Restarting First Time Wizard!" );
|
||||
}
|
||||
}
|
||||
|
||||
wxConfigBase* Pcsx2App::OpenInstallSettingsFile()
|
||||
{
|
||||
// Implementation Notes:
|
||||
//
|
||||
// As of 0.9.8 and beyond, PCSX2's versioning should be strong enough to base ini and
|
||||
// plugin compatibility on version information alone. This in turn allows us to ditch
|
||||
// the old system (CWD-based ini file mess) in favor of a system that simply stores
|
||||
// most core application-level settings in the registry.
|
||||
|
||||
ScopedPtr<wxConfigBase> conf_install;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
conf_install = new wxRegConfig();
|
||||
#else
|
||||
// FIXME!! Linux / Mac
|
||||
// Where the heck should this information be stored?
|
||||
|
||||
wxDirName usrlocaldir( PathDefs::GetUserLocalDataDir() );
|
||||
//wxDirName usrlocaldir( wxStandardPaths::Get().GetDataDir() );
|
||||
if( !usrlocaldir.Exists() )
|
||||
{
|
||||
Console.WriteLn( L"Creating UserLocalData folder: " + usrlocaldir.ToString() );
|
||||
usrlocaldir.Mkdir();
|
||||
}
|
||||
|
||||
wxFileName usermodefile( GetAppName() + L"-reg.ini" );
|
||||
usermodefile.SetPath( usrlocaldir.ToString() );
|
||||
conf_install = OpenFileConfig( usermodefile.GetFullPath() );
|
||||
#endif
|
||||
|
||||
return conf_install.DetachPtr();
|
||||
}
|
||||
|
||||
|
||||
void Pcsx2App::EstablishAppUserMode()
|
||||
{
|
||||
ScopedPtr<wxConfigBase> conf_install;
|
||||
|
||||
conf_install = TestForPortableInstall();
|
||||
if (!conf_install)
|
||||
conf_install = OpenInstallSettingsFile();
|
||||
|
||||
conf_install->SetRecordDefaults(false);
|
||||
|
||||
// Run the First Time Wizard!
|
||||
// ----------------------------
|
||||
// Wizard is only run once. The status of the wizard having been run is stored in
|
||||
// the installation ini file, which can be either the portable install (useful for admins)
|
||||
// or the registry/user local documents position.
|
||||
|
||||
bool runWiz;
|
||||
conf_install->Read( L"RunWizard", &runWiz, true );
|
||||
|
||||
App_LoadInstallSettings( conf_install );
|
||||
|
||||
if( !Startup.ForceWizard && !runWiz )
|
||||
{
|
||||
AppConfig_OnChangedSettingsFolder( false );
|
||||
return;
|
||||
}
|
||||
|
||||
DoFirstTimeWizard();
|
||||
|
||||
// Save user's new settings
|
||||
App_SaveInstallSettings( conf_install );
|
||||
AppConfig_OnChangedSettingsFolder( true );
|
||||
AppSaveSettings();
|
||||
|
||||
// Wizard completed successfully, so let's not torture the user with this crap again!
|
||||
conf_install->Write( L"RunWizard", false );
|
||||
}
|
||||
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "MainFrame.h"
|
||||
#include "Utilities/IniInterface.h"
|
||||
#include "Utilities/HashMap.h"
|
||||
#include "Dialogs/ModalPopups.h"
|
||||
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include "wx/msw/regconf.h"
|
||||
#endif
|
||||
|
||||
DocsModeType DocsFolderMode = DocsFolder_User;
|
||||
bool UseDefaultSettingsFolder = true;
|
||||
bool UseDefaultPluginsFolder = true;
|
||||
bool UseDefaultThemesFolder = true;
|
||||
|
||||
|
||||
wxDirName CustomDocumentsFolder;
|
||||
wxDirName SettingsFolder;
|
||||
|
||||
wxDirName InstallFolder;
|
||||
wxDirName PluginsFolder;
|
||||
wxDirName ThemesFolder;
|
||||
|
||||
// The UserLocalData folder can be redefined depending on whether or not PCSX2 is in
|
||||
// "portable install" mode or not. when PCSX2 has been configured for portable install, the
|
||||
// UserLocalData folder is the current working directory.
|
||||
//
|
||||
InstallationModeType InstallationMode;
|
||||
|
||||
static wxFileName GetPortableIniPath()
|
||||
{
|
||||
wxString programFullPath = wxStandardPaths::Get().GetExecutablePath();
|
||||
wxDirName programDir( wxFileName(programFullPath).GetPath() );
|
||||
|
||||
return programDir + "portable.ini";
|
||||
}
|
||||
|
||||
static wxString GetMsg_PortableModeRights()
|
||||
{
|
||||
return pxE( "!Notice:PortableModeRights",
|
||||
L"Please ensure that these folders are created and that your user account is granted "
|
||||
L"write permissions to them -- or re-run PCSX2 with elevated (administrator) rights, which "
|
||||
L"should grant PCSX2 the ability to create the necessary folders itself. If you "
|
||||
L"do not have elevated rights on this computer, then you will need to switch to User "
|
||||
L"Documents mode (click button below)."
|
||||
);
|
||||
};
|
||||
|
||||
bool Pcsx2App::TestUserPermissionsRights( const wxDirName& testFolder, wxString& createFailedStr, wxString& accessFailedStr )
|
||||
{
|
||||
// We need to individually verify read/write permission for each PCSX2 user documents folder.
|
||||
// If any of the folders are not writable, then the user should be informed asap via
|
||||
// friendly and courteous dialog box!
|
||||
|
||||
const wxDirName PermissionFolders[] =
|
||||
{
|
||||
PathDefs::Base::Settings(),
|
||||
PathDefs::Base::MemoryCards(),
|
||||
PathDefs::Base::Savestates(),
|
||||
PathDefs::Base::Snapshots(),
|
||||
PathDefs::Base::Logs(),
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
PathDefs::Base::Dumps(),
|
||||
#endif
|
||||
};
|
||||
|
||||
FastFormatUnicode createme, accessme;
|
||||
|
||||
for (uint i=0; i<ArraySize(PermissionFolders); ++i)
|
||||
{
|
||||
wxDirName folder( testFolder + PermissionFolders[i] );
|
||||
|
||||
if (!folder.Mkdir())
|
||||
createme += L"\t" + folder.ToString() + L"\n";
|
||||
|
||||
if (!folder.IsWritable())
|
||||
accessme += L"\t" + folder.ToString() + L"\n";
|
||||
}
|
||||
|
||||
if (!accessme.IsEmpty())
|
||||
{
|
||||
accessFailedStr = (wxString)_("The following folders exist, but are not writable:") + L"\n" + accessme;
|
||||
}
|
||||
|
||||
if (!createme.IsEmpty())
|
||||
{
|
||||
createFailedStr = (wxString)_("The following folders are missing and cannot be created:") + L"\n" + createme;
|
||||
}
|
||||
|
||||
return (createFailedStr.IsEmpty() && accessFailedStr.IsEmpty());
|
||||
}
|
||||
|
||||
// Portable installations are assumed to be run in either administrator rights mode, or run
|
||||
// from "insecure media" such as a removable flash drive. In these cases, the default path for
|
||||
// PCSX2 user documents becomes ".", which is the current working directory.
|
||||
//
|
||||
// Portable installation mode is typically enabled via the presence of an INI file in the
|
||||
// same directory that PCSX2 is installed to.
|
||||
//
|
||||
wxConfigBase* Pcsx2App::TestForPortableInstall()
|
||||
{
|
||||
InstallationMode = InstallMode_Registered;
|
||||
|
||||
const wxFileName portableIniFile( GetPortableIniPath() );
|
||||
const wxDirName portableDocsFolder( portableIniFile.GetPath() );
|
||||
|
||||
if (Startup.PortableMode || portableIniFile.FileExists())
|
||||
{
|
||||
wxString FilenameStr = portableIniFile.GetFullPath();
|
||||
if (Startup.PortableMode)
|
||||
Console.WriteLn( L"(UserMode) Portable mode requested via commandline switch!" );
|
||||
else
|
||||
Console.WriteLn( L"(UserMode) Found portable install ini @ %s", FilenameStr.c_str() );
|
||||
|
||||
// Just because the portable ini file exists doesn't mean we can actually run in portable
|
||||
// mode. In order to determine our read/write permissions to the PCSX2, we must try to
|
||||
// modify the configured documents folder, and catch any ensuing error.
|
||||
|
||||
ScopedPtr<wxFileConfig> conf_portable( OpenFileConfig( portableIniFile.GetFullPath() ) );
|
||||
conf_portable->SetRecordDefaults(false);
|
||||
|
||||
while( true )
|
||||
{
|
||||
wxString accessFailedStr, createFailedStr;
|
||||
if (TestUserPermissionsRights( portableDocsFolder, createFailedStr, accessFailedStr )) break;
|
||||
|
||||
wxDialogWithHelpers dialog( NULL, AddAppName(_("Portable mode error - %s")) );
|
||||
|
||||
wxTextCtrl* scrollText = new wxTextCtrl(
|
||||
&dialog, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_READONLY | wxTE_MULTILINE | wxTE_WORDWRAP
|
||||
);
|
||||
|
||||
if (!createFailedStr.IsEmpty())
|
||||
scrollText->AppendText( createFailedStr + L"\n" );
|
||||
|
||||
if (!accessFailedStr.IsEmpty())
|
||||
scrollText->AppendText( accessFailedStr + L"\n" );
|
||||
|
||||
dialog += dialog.Heading( _("PCSX2 has been installed as a portable application but cannot run due to the following errors:" ) );
|
||||
dialog += scrollText | pxExpand.Border(wxALL, 16);
|
||||
dialog += 6;
|
||||
dialog += dialog.Text( GetMsg_PortableModeRights() );
|
||||
|
||||
// [TODO] : Add url for platform-relevant user permissions tutorials? (low priority)
|
||||
|
||||
wxWindowID result = pxIssueConfirmation( dialog,
|
||||
MsgButtons().Retry().Cancel().Custom(_("Switch to User Documents Mode"), "switchmode")
|
||||
);
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case wxID_CANCEL:
|
||||
throw Exception::StartupAborted( L"User canceled portable mode due to insufficient user access/permissions." );
|
||||
|
||||
case wxID_RETRY:
|
||||
// do nothing (continues while loop)
|
||||
break;
|
||||
|
||||
case pxID_CUSTOM:
|
||||
wxDialogWithHelpers dialog2( NULL, AddAppName(_("%s is switching to local install mode.")) );
|
||||
dialog2 += dialog2.Heading( _("Try to remove the file called \"portable.ini\" from your installation directory manually." ) );
|
||||
dialog2 += 6;
|
||||
pxIssueConfirmation( dialog2, MsgButtons().OK() );
|
||||
conf_portable.DetachPtr(); // Not sure but can't hurt
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Success -- all user-based folders have write access. PCSX2 should be able to run error-free!
|
||||
// Force-set the custom documents mode, and set the
|
||||
|
||||
InstallationMode = InstallMode_Portable;
|
||||
DocsFolderMode = DocsFolder_Custom;
|
||||
CustomDocumentsFolder = portableDocsFolder;
|
||||
return conf_portable.DetachPtr();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Reset RunWizard so the FTWizard is run again on next PCSX2 start.
|
||||
void Pcsx2App::WipeUserModeSettings()
|
||||
{
|
||||
if (InstallationMode == InstallMode_Portable)
|
||||
{
|
||||
// Remove the portable.ini entry "RunWizard" conforming to this instance of PCSX2.
|
||||
wxFileName portableIniFile( GetPortableIniPath() );
|
||||
ScopedPtr<wxFileConfig> conf_portable( OpenFileConfig( portableIniFile.GetFullPath() ) );
|
||||
conf_portable->DeleteEntry(L"RunWizard");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the registry entry "RunWizard" conforming to this instance of PCSX2.
|
||||
ScopedPtr<wxConfigBase> conf_install( OpenInstallSettingsFile() );
|
||||
conf_install->DeleteEntry(L"RunWizard");
|
||||
}
|
||||
}
|
||||
|
||||
static void DoFirstTimeWizard()
|
||||
{
|
||||
// first time startup, so give the user the choice of user mode:
|
||||
while(true)
|
||||
{
|
||||
// PCSX2's FTWizard allows improptu restarting of the wizard without cancellation.
|
||||
// This is typically used to change the user's language selection.
|
||||
|
||||
FirstTimeWizard wiz( NULL );
|
||||
if( wiz.RunWizard( wiz.GetFirstPage() ) ) break;
|
||||
if (wiz.GetReturnCode() != pxID_RestartWizard)
|
||||
throw Exception::StartupAborted( L"User canceled FirstTime Wizard." );
|
||||
|
||||
Console.WriteLn( Color_StrongBlack, "Restarting First Time Wizard!" );
|
||||
}
|
||||
}
|
||||
|
||||
wxConfigBase* Pcsx2App::OpenInstallSettingsFile()
|
||||
{
|
||||
// Implementation Notes:
|
||||
//
|
||||
// As of 0.9.8 and beyond, PCSX2's versioning should be strong enough to base ini and
|
||||
// plugin compatibility on version information alone. This in turn allows us to ditch
|
||||
// the old system (CWD-based ini file mess) in favor of a system that simply stores
|
||||
// most core application-level settings in the registry.
|
||||
|
||||
ScopedPtr<wxConfigBase> conf_install;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
conf_install = new wxRegConfig();
|
||||
#else
|
||||
// FIXME!! Linux / Mac
|
||||
// Where the heck should this information be stored?
|
||||
|
||||
wxDirName usrlocaldir( PathDefs::GetUserLocalDataDir() );
|
||||
//wxDirName usrlocaldir( wxStandardPaths::Get().GetDataDir() );
|
||||
if( !usrlocaldir.Exists() )
|
||||
{
|
||||
Console.WriteLn( L"Creating UserLocalData folder: " + usrlocaldir.ToString() );
|
||||
usrlocaldir.Mkdir();
|
||||
}
|
||||
|
||||
wxFileName usermodefile( GetAppName() + L"-reg.ini" );
|
||||
usermodefile.SetPath( usrlocaldir.ToString() );
|
||||
conf_install = OpenFileConfig( usermodefile.GetFullPath() );
|
||||
#endif
|
||||
|
||||
return conf_install.DetachPtr();
|
||||
}
|
||||
|
||||
|
||||
void Pcsx2App::EstablishAppUserMode()
|
||||
{
|
||||
ScopedPtr<wxConfigBase> conf_install;
|
||||
|
||||
conf_install = TestForPortableInstall();
|
||||
if (!conf_install)
|
||||
conf_install = OpenInstallSettingsFile();
|
||||
|
||||
conf_install->SetRecordDefaults(false);
|
||||
|
||||
// Run the First Time Wizard!
|
||||
// ----------------------------
|
||||
// Wizard is only run once. The status of the wizard having been run is stored in
|
||||
// the installation ini file, which can be either the portable install (useful for admins)
|
||||
// or the registry/user local documents position.
|
||||
|
||||
bool runWiz;
|
||||
conf_install->Read( L"RunWizard", &runWiz, true );
|
||||
|
||||
App_LoadInstallSettings( conf_install );
|
||||
|
||||
if( !Startup.ForceWizard && !runWiz )
|
||||
{
|
||||
AppConfig_OnChangedSettingsFolder( false );
|
||||
return;
|
||||
}
|
||||
|
||||
DoFirstTimeWizard();
|
||||
|
||||
// Save user's new settings
|
||||
App_SaveInstallSettings( conf_install );
|
||||
AppConfig_OnChangedSettingsFolder( true );
|
||||
AppSaveSettings();
|
||||
|
||||
// Wizard completed successfully, so let's not torture the user with this crap again!
|
||||
conf_install->Write( L"RunWizard", false );
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ConfigurationDialog.h"
|
||||
#include "Panels/ConfigurationPanels.h"
|
||||
|
||||
using namespace Panels;
|
||||
using namespace pxSizerFlags;
|
||||
|
||||
Dialogs::GameDatabaseDialog::GameDatabaseDialog(wxWindow* parent)
|
||||
: BaseConfigurationDialog( parent, AddAppName(_("Game database - %s")), 580 )
|
||||
{
|
||||
ScopedBusyCursor busy( Cursor_ReallyBusy );
|
||||
*this += new GameDatabasePanel(this) | StdExpand();
|
||||
AddOkCancel();
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ConfigurationDialog.h"
|
||||
#include "Panels/ConfigurationPanels.h"
|
||||
|
||||
using namespace Panels;
|
||||
using namespace pxSizerFlags;
|
||||
|
||||
Dialogs::GameDatabaseDialog::GameDatabaseDialog(wxWindow* parent)
|
||||
: BaseConfigurationDialog( parent, AddAppName(_("Game database - %s")), 580 )
|
||||
{
|
||||
ScopedBusyCursor busy( Cursor_ReallyBusy );
|
||||
*this += new GameDatabasePanel(this) | StdExpand();
|
||||
AddOkCancel();
|
||||
}
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// NOTICE! This file is intended as a temporary placebo only, until such time that the
|
||||
// memorycard system is properly extracted into a plugin system (which would make it a
|
||||
// separate project file).
|
||||
//
|
||||
// Please do not move contents from MemoryCardfile.cpp, such as class definitions, into
|
||||
// this file. I'd prefer they stay in MemoryCardFile.cpp for now. --air
|
||||
|
||||
extern uint FileMcd_GetMtapPort(uint slot);
|
||||
extern uint FileMcd_GetMtapSlot(uint slot);
|
||||
extern bool FileMcd_IsMultitapSlot( uint slot );
|
||||
//extern wxFileName FileMcd_GetSimpleName(uint slot);
|
||||
extern wxString FileMcd_GetDefaultName(uint slot);
|
||||
extern bool isValidNewFilename( wxString filenameStringToTest, wxDirName atBasePath, wxString& out_errorMessage, uint minNumCharacters=5 );
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// NOTICE! This file is intended as a temporary placebo only, until such time that the
|
||||
// memorycard system is properly extracted into a plugin system (which would make it a
|
||||
// separate project file).
|
||||
//
|
||||
// Please do not move contents from MemoryCardfile.cpp, such as class definitions, into
|
||||
// this file. I'd prefer they stay in MemoryCardFile.cpp for now. --air
|
||||
|
||||
extern uint FileMcd_GetMtapPort(uint slot);
|
||||
extern uint FileMcd_GetMtapSlot(uint slot);
|
||||
extern bool FileMcd_IsMultitapSlot( uint slot );
|
||||
//extern wxFileName FileMcd_GetSimpleName(uint slot);
|
||||
extern wxString FileMcd_GetDefaultName(uint slot);
|
||||
extern bool isValidNewFilename( wxString filenameStringToTest, wxDirName atBasePath, wxString& out_errorMessage, uint minNumCharacters=5 );
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
|
||||
-/- MemoryCardFile SVN Status -/-
|
||||
|
||||
Currently the MemoryCardFile "plugin" is integrated into the main UI of PCSX2. It provides
|
||||
standard raw/block emulation of a memorycard device. The plugin-ification of the MemoryCard
|
||||
system has not yet been completed, which is why the plugin as of right now is "integrated"
|
||||
into the UI. As the new PS2E.v2 plugin API is completed, the MemoryCardFile provider will
|
||||
be moved into an external DLL.
|
||||
|
||||
Due to these future plans, and due to the number of files involved in implementing the
|
||||
user interface for memorycard management, I have arranged the MemoryCardFile plugin files
|
||||
|
||||
-/- MemoryCardFile SVN Status -/-
|
||||
|
||||
Currently the MemoryCardFile "plugin" is integrated into the main UI of PCSX2. It provides
|
||||
standard raw/block emulation of a memorycard device. The plugin-ification of the MemoryCard
|
||||
system has not yet been completed, which is why the plugin as of right now is "integrated"
|
||||
into the UI. As the new PS2E.v2 plugin API is completed, the MemoryCardFile provider will
|
||||
be moved into an external DLL.
|
||||
|
||||
Due to these future plans, and due to the number of files involved in implementing the
|
||||
user interface for memorycard management, I have arranged the MemoryCardFile plugin files
|
||||
in their own sub-folder inside the Visual Studio project.
|
|
@ -1,51 +1,51 @@
|
|||
// iVUzerorec.cpp assembly routines
|
||||
// zerofrog(@gmail.com)
|
||||
.intel_syntax noprefix
|
||||
|
||||
.extern s_TotalVUCycles
|
||||
.extern s_callstack
|
||||
.extern s_vu1esp
|
||||
.extern s_writeQ
|
||||
.extern s_writeP
|
||||
.extern g_curdebugvu
|
||||
.extern SuperVUGetProgram
|
||||
.extern SuperVUCleanupProgram
|
||||
.extern g_sseVUMXCSR
|
||||
.extern g_sseMXCSR
|
||||
|
||||
// SuperVUExecuteProgram(u32 startpc, int vuindex)
|
||||
.globl SuperVUExecuteProgram
|
||||
SuperVUExecuteProgram:
|
||||
mov eax, [esp]
|
||||
mov dword ptr s_TotalVUCycles, 0
|
||||
add esp, 4
|
||||
mov dword ptr [s_callstack], eax
|
||||
call SuperVUGetProgram
|
||||
mov s_vu1esi, esi
|
||||
mov s_vuedi, edi
|
||||
mov s_vuebx, ebx
|
||||
|
||||
mov s_vu1esp, esp
|
||||
and esp, -16 // align stack for GCC compilance
|
||||
|
||||
ldmxcsr g_sseVUMXCSR
|
||||
mov dword ptr s_writeQ, 0xffffffff
|
||||
mov dword ptr s_writeP, 0xffffffff
|
||||
jmp eax
|
||||
|
||||
.globl SuperVUEndProgram
|
||||
SuperVUEndProgram:
|
||||
// restore cpu state
|
||||
ldmxcsr g_sseMXCSR
|
||||
mov esi, s_vu1esi
|
||||
mov edi, s_vuedi
|
||||
mov ebx, s_vuebx
|
||||
|
||||
mov esp, s_vu1esp
|
||||
|
||||
call SuperVUCleanupProgram
|
||||
jmp [s_callstack] // so returns correctly
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
// iVUzerorec.cpp assembly routines
|
||||
// zerofrog(@gmail.com)
|
||||
.intel_syntax noprefix
|
||||
|
||||
.extern s_TotalVUCycles
|
||||
.extern s_callstack
|
||||
.extern s_vu1esp
|
||||
.extern s_writeQ
|
||||
.extern s_writeP
|
||||
.extern g_curdebugvu
|
||||
.extern SuperVUGetProgram
|
||||
.extern SuperVUCleanupProgram
|
||||
.extern g_sseVUMXCSR
|
||||
.extern g_sseMXCSR
|
||||
|
||||
// SuperVUExecuteProgram(u32 startpc, int vuindex)
|
||||
.globl SuperVUExecuteProgram
|
||||
SuperVUExecuteProgram:
|
||||
mov eax, [esp]
|
||||
mov dword ptr s_TotalVUCycles, 0
|
||||
add esp, 4
|
||||
mov dword ptr [s_callstack], eax
|
||||
call SuperVUGetProgram
|
||||
mov s_vu1esi, esi
|
||||
mov s_vuedi, edi
|
||||
mov s_vuebx, ebx
|
||||
|
||||
mov s_vu1esp, esp
|
||||
and esp, -16 // align stack for GCC compilance
|
||||
|
||||
ldmxcsr g_sseVUMXCSR
|
||||
mov dword ptr s_writeQ, 0xffffffff
|
||||
mov dword ptr s_writeP, 0xffffffff
|
||||
jmp eax
|
||||
|
||||
.globl SuperVUEndProgram
|
||||
SuperVUEndProgram:
|
||||
// restore cpu state
|
||||
ldmxcsr g_sseMXCSR
|
||||
mov esi, s_vu1esi
|
||||
mov edi, s_vuedi
|
||||
mov ebx, s_vuebx
|
||||
|
||||
mov esp, s_vu1esp
|
||||
|
||||
call SuperVUCleanupProgram
|
||||
jmp [s_callstack] // so returns correctly
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,78 +1,78 @@
|
|||
CDVDiso v0.5
|
||||
------------
|
||||
|
||||
This is an extension to use with play station2 emulators
|
||||
as PCSX2 (only one right now).
|
||||
The plugin is free open source code.
|
||||
|
||||
Linux requeriments:
|
||||
------------------
|
||||
You need the GTK library, compiled with GTK v1.2.5,
|
||||
the Zlib library (v1.1.3) and the bz2 library (v1.0.0).
|
||||
|
||||
Usage:
|
||||
-----
|
||||
Place the file "libCDVDiso.so" (linux) or "CDVDiso.dll" (win32) at the Plugin
|
||||
directory of the Emulator to use it.
|
||||
|
||||
Linux only: Also place the cfgCDVDiso file at your $HOME directory or at the
|
||||
Emulator directory.
|
||||
|
||||
Configuration:
|
||||
-------------
|
||||
You can either write the iso you want to use in the config dialog, or everytime
|
||||
you run the emu open it, if you're doing this don't write anything in the dialog.
|
||||
|
||||
Creating an iso (linux only):
|
||||
---------------
|
||||
To create an iso you can use the buttons 'Create Iso' or 'Create Compressed Iso',
|
||||
the file will be the one in the Iso Edit, and the Cdrom Device is the cdrom that
|
||||
will be used as source.
|
||||
The compression method is specified by the Compression Method Combo.
|
||||
|
||||
Note: This will fail if the file in the Iso Edit already exists (if it's
|
||||
compressed the .Z or .bz suffix will be added).
|
||||
|
||||
Compressed isos:
|
||||
---------------
|
||||
You must create them by the Compress Iso button, this will create a .Z or .bz
|
||||
file (the compressed image) and a .Z.table or .bz.index file (this is a table,
|
||||
for speed reasons), both will be created in the same dir the selected iso
|
||||
image, the original image will not be deleted and/or changed, and also you can
|
||||
decompress the compressed iso with Decompress Iso button.
|
||||
The compression method is specified by the Compression Method Combo.
|
||||
|
||||
Note: you only can decompress the images with the Decompress button, not with
|
||||
compress or bzip2.
|
||||
|
||||
Compression Method:
|
||||
------------------
|
||||
.Z - compress faster: this will compress faster, but not as good as the .bz.
|
||||
.bz - compress better: will compress better, but slower.
|
||||
|
||||
Changes:
|
||||
-------
|
||||
v0.5:
|
||||
* Added block dumping code
|
||||
* Added BZ2/Z2 format ;)
|
||||
* Added optimaze asm code of zlib with vsnet2003 only. Compression / Uncompression should be faster now (shadow)
|
||||
* Added Vsnet2005 beta1 project files + amd64 asm optimaze code for zlib (shadow)
|
||||
|
||||
v0.4:
|
||||
* Rewrote mostly ;)
|
||||
* .bz is still unsupported
|
||||
|
||||
v0.3:
|
||||
* Better Iso detection, thx florin :)
|
||||
* Updated to PS2Edefs v0.4.5
|
||||
|
||||
v0.2:
|
||||
* Added support for isos using 2048 blocksize
|
||||
* Nero images are supported
|
||||
* Better extension filtering
|
||||
|
||||
v0.1:
|
||||
* First Release
|
||||
* Tested with Pcsx2
|
||||
|
||||
Email: <linuzappz@hotmail.com>
|
||||
CDVDiso v0.5
|
||||
------------
|
||||
|
||||
This is an extension to use with play station2 emulators
|
||||
as PCSX2 (only one right now).
|
||||
The plugin is free open source code.
|
||||
|
||||
Linux requeriments:
|
||||
------------------
|
||||
You need the GTK library, compiled with GTK v1.2.5,
|
||||
the Zlib library (v1.1.3) and the bz2 library (v1.0.0).
|
||||
|
||||
Usage:
|
||||
-----
|
||||
Place the file "libCDVDiso.so" (linux) or "CDVDiso.dll" (win32) at the Plugin
|
||||
directory of the Emulator to use it.
|
||||
|
||||
Linux only: Also place the cfgCDVDiso file at your $HOME directory or at the
|
||||
Emulator directory.
|
||||
|
||||
Configuration:
|
||||
-------------
|
||||
You can either write the iso you want to use in the config dialog, or everytime
|
||||
you run the emu open it, if you're doing this don't write anything in the dialog.
|
||||
|
||||
Creating an iso (linux only):
|
||||
---------------
|
||||
To create an iso you can use the buttons 'Create Iso' or 'Create Compressed Iso',
|
||||
the file will be the one in the Iso Edit, and the Cdrom Device is the cdrom that
|
||||
will be used as source.
|
||||
The compression method is specified by the Compression Method Combo.
|
||||
|
||||
Note: This will fail if the file in the Iso Edit already exists (if it's
|
||||
compressed the .Z or .bz suffix will be added).
|
||||
|
||||
Compressed isos:
|
||||
---------------
|
||||
You must create them by the Compress Iso button, this will create a .Z or .bz
|
||||
file (the compressed image) and a .Z.table or .bz.index file (this is a table,
|
||||
for speed reasons), both will be created in the same dir the selected iso
|
||||
image, the original image will not be deleted and/or changed, and also you can
|
||||
decompress the compressed iso with Decompress Iso button.
|
||||
The compression method is specified by the Compression Method Combo.
|
||||
|
||||
Note: you only can decompress the images with the Decompress button, not with
|
||||
compress or bzip2.
|
||||
|
||||
Compression Method:
|
||||
------------------
|
||||
.Z - compress faster: this will compress faster, but not as good as the .bz.
|
||||
.bz - compress better: will compress better, but slower.
|
||||
|
||||
Changes:
|
||||
-------
|
||||
v0.5:
|
||||
* Added block dumping code
|
||||
* Added BZ2/Z2 format ;)
|
||||
* Added optimaze asm code of zlib with vsnet2003 only. Compression / Uncompression should be faster now (shadow)
|
||||
* Added Vsnet2005 beta1 project files + amd64 asm optimaze code for zlib (shadow)
|
||||
|
||||
v0.4:
|
||||
* Rewrote mostly ;)
|
||||
* .bz is still unsupported
|
||||
|
||||
v0.3:
|
||||
* Better Iso detection, thx florin :)
|
||||
* Updated to PS2Edefs v0.4.5
|
||||
|
||||
v0.2:
|
||||
* Added support for isos using 2048 blocksize
|
||||
* Nero images are supported
|
||||
* Better extension filtering
|
||||
|
||||
v0.1:
|
||||
* First Release
|
||||
* Tested with Pcsx2
|
||||
|
||||
Email: <linuzappz@hotmail.com>
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
CDVDisoEFP v0.6 Changes:
|
||||
--------------------
|
||||
|
||||
v0.6:
|
||||
* Completely re-wrote screens (efp)
|
||||
* Used device access sources from CDVDlinuz to get data from DVDs. (efp)
|
||||
* Added ability to read devices from Windows XP (efp)
|
||||
Note: only ISO and CDDA seem to be readable from CDs at this time.
|
||||
If your trying to get another format, use Linux.
|
||||
DVD5 is readable. Don't have a DVD9 game to test. (I think - efp)
|
||||
* Separated image file access by OS. (Linux, Windows) (efp)
|
||||
* Separated Multi-file/Compression/Image-Typing to their own source files. (efp)
|
||||
* Added a few entries to the Image Typing database, based on Linux CD-ROM sources (efp)
|
||||
* Added Table Rebuild (for those who lost .table files.) (efp)
|
||||
* Put in a separate source program to compare two ISOs for data accuracy. (efp)
|
||||
* Renamed executables and config files (so not to conflict with CDVDiso) (efp)
|
||||
* Internalized the .INI File code (to allow use in other OS-es besides Windows) (efp)
|
||||
* Added temporarily a .toc file saving track info (for PS1 and Music CDs) (efp)
|
||||
* Added a new compression format. (BZip2 Size) (efp)
|
||||
* Added .glade files at linuzappz's request (efp)
|
||||
* Upgraded to 0.6.0 beta PS2Edef.h definitions (efp)
|
||||
|
||||
* Data buffer start position re-set for CDs. (shadow caught the problem while testing)
|
||||
* Supported images grouped in "Browse" button (shadow's suggestion)
|
||||
* Initial Image reminder added to Windows CDVDOpen() (shadow's suggestion)
|
||||
* used 64 bit fstat (fstat64) for correct sizes on >2GB files in Linux (efp)
|
||||
* Adjusted CD types to allow for PS2 CDs (shadow pointed out an example iso)
|
||||
* Added changing CDs/DVDs while emulation stopped (shadow's suggestion)
|
||||
Built in an "open tray" delay when switching media. (efp)
|
||||
* Added ".img" to Image Filter (although .cue/.sub files aren't tapped.) (efp)
|
||||
* Added ".nrg" to Image Filter (shadow's suggestion)
|
||||
* In Windows, when newly selected from the PCSX2 configure screen, CDVDinit()
|
||||
(as well as InitConf()) are not called. Fixed (EFP)
|
||||
|
||||
v0.5:
|
||||
* Added block dumping code
|
||||
* Added BZ2/Z2 format ;)
|
||||
* Added optimaze asm code of zlib with vsnet2003 only. Compression / Uncompression should be faster now (shadow)
|
||||
* Added Vsnet2005 beta1 project files + amd64 asm optimaze code for zlib (shadow)
|
||||
|
||||
v0.4:
|
||||
* Rewrote mostly ;)
|
||||
* .bz is still unsupported
|
||||
|
||||
v0.3:
|
||||
* Better Iso detection, thx florin :)
|
||||
* Updated to PS2Edefs v0.4.5
|
||||
|
||||
v0.2:
|
||||
* Added support for isos using 2048 blocksize
|
||||
* Nero images are supported
|
||||
* Better extension filtering
|
||||
|
||||
v0.1:
|
||||
* First Release
|
||||
* Tested with Pcsx2
|
||||
|
||||
Email: <linuzappz@hotmail.com>
|
||||
CDVDisoEFP v0.6 Changes:
|
||||
--------------------
|
||||
|
||||
v0.6:
|
||||
* Completely re-wrote screens (efp)
|
||||
* Used device access sources from CDVDlinuz to get data from DVDs. (efp)
|
||||
* Added ability to read devices from Windows XP (efp)
|
||||
Note: only ISO and CDDA seem to be readable from CDs at this time.
|
||||
If your trying to get another format, use Linux.
|
||||
DVD5 is readable. Don't have a DVD9 game to test. (I think - efp)
|
||||
* Separated image file access by OS. (Linux, Windows) (efp)
|
||||
* Separated Multi-file/Compression/Image-Typing to their own source files. (efp)
|
||||
* Added a few entries to the Image Typing database, based on Linux CD-ROM sources (efp)
|
||||
* Added Table Rebuild (for those who lost .table files.) (efp)
|
||||
* Put in a separate source program to compare two ISOs for data accuracy. (efp)
|
||||
* Renamed executables and config files (so not to conflict with CDVDiso) (efp)
|
||||
* Internalized the .INI File code (to allow use in other OS-es besides Windows) (efp)
|
||||
* Added temporarily a .toc file saving track info (for PS1 and Music CDs) (efp)
|
||||
* Added a new compression format. (BZip2 Size) (efp)
|
||||
* Added .glade files at linuzappz's request (efp)
|
||||
* Upgraded to 0.6.0 beta PS2Edef.h definitions (efp)
|
||||
|
||||
* Data buffer start position re-set for CDs. (shadow caught the problem while testing)
|
||||
* Supported images grouped in "Browse" button (shadow's suggestion)
|
||||
* Initial Image reminder added to Windows CDVDOpen() (shadow's suggestion)
|
||||
* used 64 bit fstat (fstat64) for correct sizes on >2GB files in Linux (efp)
|
||||
* Adjusted CD types to allow for PS2 CDs (shadow pointed out an example iso)
|
||||
* Added changing CDs/DVDs while emulation stopped (shadow's suggestion)
|
||||
Built in an "open tray" delay when switching media. (efp)
|
||||
* Added ".img" to Image Filter (although .cue/.sub files aren't tapped.) (efp)
|
||||
* Added ".nrg" to Image Filter (shadow's suggestion)
|
||||
* In Windows, when newly selected from the PCSX2 configure screen, CDVDinit()
|
||||
(as well as InitConf()) are not called. Fixed (EFP)
|
||||
|
||||
v0.5:
|
||||
* Added block dumping code
|
||||
* Added BZ2/Z2 format ;)
|
||||
* Added optimaze asm code of zlib with vsnet2003 only. Compression / Uncompression should be faster now (shadow)
|
||||
* Added Vsnet2005 beta1 project files + amd64 asm optimaze code for zlib (shadow)
|
||||
|
||||
v0.4:
|
||||
* Rewrote mostly ;)
|
||||
* .bz is still unsupported
|
||||
|
||||
v0.3:
|
||||
* Better Iso detection, thx florin :)
|
||||
* Updated to PS2Edefs v0.4.5
|
||||
|
||||
v0.2:
|
||||
* Added support for isos using 2048 blocksize
|
||||
* Nero images are supported
|
||||
* Better extension filtering
|
||||
|
||||
v0.1:
|
||||
* First Release
|
||||
* Tested with Pcsx2
|
||||
|
||||
Email: <linuzappz@hotmail.com>
|
||||
|
|
|
@ -1,342 +1,342 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
||||
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
CDVDiso v0.6
|
||||
------------
|
||||
|
||||
This is an extension to use with play station2 emulators
|
||||
as PCSX2 (only one right now).
|
||||
The plugin is free open source code.
|
||||
|
||||
Linux requirements:
|
||||
------------------
|
||||
You need the GTK library, compiled with GTK v2.6.1 (at least).
|
||||
|
||||
Usage:
|
||||
-----
|
||||
For those using Windows, place the file "CDVDisoEFP.dll" in the Plugin
|
||||
directory of the Emulator to use it.
|
||||
|
||||
For Linux users, place the file "libCDVDisoEFP.so" in the plugin
|
||||
directory of the Emulator. Also, place the file "cfgCDVDisoEFP" in the "cfg"
|
||||
directory of the Emulator to use it.
|
||||
|
||||
Configuration:
|
||||
-------------
|
||||
You must select the iso you want to use in the Configuration dialog. You
|
||||
will come back to this dialog should the Emulator want another disc.
|
||||
|
||||
Creating an iso (linux, Windows XP only):
|
||||
---------------
|
||||
To create an iso you can use the button 'Make Image'. The file
|
||||
will be the one in the Iso Edit, and the Source Device is the CDRom or
|
||||
DVD drive that will have the disc you want to make an image of.
|
||||
The compression method is specified by the Compression Method Combo.
|
||||
|
||||
Note: This will fail if the file already exists (if it's compressed
|
||||
a .z or .bz2 suffix will be added).
|
||||
|
||||
Compressed isos:
|
||||
---------------
|
||||
You can create them using the Convert button. This will create a .Z or .bz
|
||||
file (the compressed image) and a .z.table or .bz2.table file (this is a
|
||||
table, for speed reasons.) Both will be created in the same dir as the
|
||||
selected image. The original image will not be deleted and/or changed. Also,
|
||||
you can decompress a compressed image by selecting "None" in the
|
||||
Compression Method Combo.
|
||||
|
||||
Note: you only can decompress the images with this program; not with
|
||||
compress or bzip2.
|
||||
|
||||
Compression Method:
|
||||
------------------
|
||||
.z speed - fast compression, small blocks, table in memory.
|
||||
.bz2 speed - average compression, 32k - 40k blocks, table in memory.
|
||||
.bz2 size - best compression, 60k - 62k blocks, table on file.
|
||||
|
||||
|
||||
Email: <linuzappz@hotmail.com>
|
||||
CDVDiso v0.6
|
||||
------------
|
||||
|
||||
This is an extension to use with play station2 emulators
|
||||
as PCSX2 (only one right now).
|
||||
The plugin is free open source code.
|
||||
|
||||
Linux requirements:
|
||||
------------------
|
||||
You need the GTK library, compiled with GTK v2.6.1 (at least).
|
||||
|
||||
Usage:
|
||||
-----
|
||||
For those using Windows, place the file "CDVDisoEFP.dll" in the Plugin
|
||||
directory of the Emulator to use it.
|
||||
|
||||
For Linux users, place the file "libCDVDisoEFP.so" in the plugin
|
||||
directory of the Emulator. Also, place the file "cfgCDVDisoEFP" in the "cfg"
|
||||
directory of the Emulator to use it.
|
||||
|
||||
Configuration:
|
||||
-------------
|
||||
You must select the iso you want to use in the Configuration dialog. You
|
||||
will come back to this dialog should the Emulator want another disc.
|
||||
|
||||
Creating an iso (linux, Windows XP only):
|
||||
---------------
|
||||
To create an iso you can use the button 'Make Image'. The file
|
||||
will be the one in the Iso Edit, and the Source Device is the CDRom or
|
||||
DVD drive that will have the disc you want to make an image of.
|
||||
The compression method is specified by the Compression Method Combo.
|
||||
|
||||
Note: This will fail if the file already exists (if it's compressed
|
||||
a .z or .bz2 suffix will be added).
|
||||
|
||||
Compressed isos:
|
||||
---------------
|
||||
You can create them using the Convert button. This will create a .Z or .bz
|
||||
file (the compressed image) and a .z.table or .bz2.table file (this is a
|
||||
table, for speed reasons.) Both will be created in the same dir as the
|
||||
selected image. The original image will not be deleted and/or changed. Also,
|
||||
you can decompress a compressed image by selecting "None" in the
|
||||
Compression Method Combo.
|
||||
|
||||
Note: you only can decompress the images with this program; not with
|
||||
compress or bzip2.
|
||||
|
||||
Compression Method:
|
||||
------------------
|
||||
.z speed - fast compression, small blocks, table in memory.
|
||||
.bz2 speed - average compression, 32k - 40k blocks, table in memory.
|
||||
.bz2 size - best compression, 60k - 62k blocks, table on file.
|
||||
|
||||
|
||||
Email: <linuzappz@hotmail.com>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,23 +1,23 @@
|
|||
PadNull v0.1
|
||||
-------------
|
||||
|
||||
This is an extension to use with play station2 emulators
|
||||
as PCSX2 (only one right now).
|
||||
The plugin is free open source code.
|
||||
|
||||
Usage:
|
||||
-----
|
||||
Place the file "libPadNull.so.0.1.0" (linux) or "PadNull.dll" (win32)
|
||||
at the Plugin directory of the Emulator to use it.
|
||||
|
||||
Changes:
|
||||
-------
|
||||
v0.1:
|
||||
* First Release
|
||||
* Tested with Pcsx2
|
||||
|
||||
Authors:
|
||||
-------
|
||||
arcum42@gmail.com
|
||||
|
||||
|
||||
PadNull v0.1
|
||||
-------------
|
||||
|
||||
This is an extension to use with play station2 emulators
|
||||
as PCSX2 (only one right now).
|
||||
The plugin is free open source code.
|
||||
|
||||
Usage:
|
||||
-----
|
||||
Place the file "libPadNull.so.0.1.0" (linux) or "PadNull.dll" (win32)
|
||||
at the Plugin directory of the Emulator to use it.
|
||||
|
||||
Changes:
|
||||
-------
|
||||
v0.1:
|
||||
* First Release
|
||||
* Tested with Pcsx2
|
||||
|
||||
Authors:
|
||||
-------
|
||||
arcum42@gmail.com
|
||||
|
||||
|
||||
|
|
|
@ -1,99 +1,99 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Spanish resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESN)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_MODERN
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_CONFIG DIALOGEX 0, 0, 184, 77
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "cdvdGigaherz"
|
||||
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,75,59,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,129,59,50,14
|
||||
COMBOBOX IDC_DRIVE,15,20,160,64,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
GROUPBOX "Source drive...",IDC_STATIC,7,7,172,48
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_CONFIG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 179
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 73
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Spanish resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Spanish resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESN)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_MODERN
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_CONFIG DIALOGEX 0, 0, 184, 77
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "cdvdGigaherz"
|
||||
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,75,59,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,129,59,50,14
|
||||
COMBOBOX IDC_DRIVE,15,20,160,64,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
GROUPBOX "Source drive...",IDC_STATIC,7,7,172,48
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_CONFIG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 179
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 73
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Spanish resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
EXPORTS
|
||||
PS2EgetLibType @2
|
||||
PS2EgetLibName @3
|
||||
PS2EgetLibVersion2 @4
|
||||
CDVDinit @5
|
||||
CDVDshutdown @6
|
||||
CDVDopen @7
|
||||
CDVDclose @8
|
||||
CDVDreadTrack @9
|
||||
CDVDgetBuffer @10
|
||||
CDVDreadSubQ @11
|
||||
CDVDgetTN @12
|
||||
CDVDgetTD @13
|
||||
CDVDgetTOC @14
|
||||
CDVDgetDiskType @15
|
||||
CDVDgetTrayStatus @16
|
||||
CDVDctrlTrayOpen @17
|
||||
CDVDctrlTrayClose @18
|
||||
CDVDconfigure @19
|
||||
CDVDtest @20
|
||||
CDVDabout @21
|
||||
CDVDnewDiskCB @22
|
||||
CDVDgetBuffer2 @23
|
||||
CDVDreadSector @24
|
||||
CDVDgetDualInfo @25
|
||||
CDVDsetSettingsDir @26
|
||||
EXPORTS
|
||||
PS2EgetLibType @2
|
||||
PS2EgetLibName @3
|
||||
PS2EgetLibVersion2 @4
|
||||
CDVDinit @5
|
||||
CDVDshutdown @6
|
||||
CDVDopen @7
|
||||
CDVDclose @8
|
||||
CDVDreadTrack @9
|
||||
CDVDgetBuffer @10
|
||||
CDVDreadSubQ @11
|
||||
CDVDgetTN @12
|
||||
CDVDgetTD @13
|
||||
CDVDgetTOC @14
|
||||
CDVDgetDiskType @15
|
||||
CDVDgetTrayStatus @16
|
||||
CDVDctrlTrayOpen @17
|
||||
CDVDctrlTrayClose @18
|
||||
CDVDconfigure @19
|
||||
CDVDtest @20
|
||||
CDVDabout @21
|
||||
CDVDnewDiskCB @22
|
||||
CDVDgetBuffer2 @23
|
||||
CDVDreadSector @24
|
||||
CDVDgetDualInfo @25
|
||||
CDVDsetSettingsDir @26
|
||||
|
|
|
@ -1,149 +1,149 @@
|
|||
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
||||
* Developed and maintained by the Pcsx2 Development Team.
|
||||
*
|
||||
* The file is based on WavFile.h from SoundTouch library.
|
||||
* Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi)
|
||||
*
|
||||
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was
|
||||
// shrunken to support only output 16 bits wav files
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "WavFile.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char riffStr[] = "RIFF";
|
||||
static const char waveStr[] = "WAVE";
|
||||
static const char fmtStr[] = "fmt ";
|
||||
static const char dataStr[] = "data";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class WavOutFile
|
||||
//
|
||||
|
||||
WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int channels)
|
||||
{
|
||||
bytesWritten = 0;
|
||||
fptr = fopen(fileName, "wb");
|
||||
if (fptr == NULL)
|
||||
{
|
||||
string msg = "Error : Unable to open file \"";
|
||||
msg += fileName;
|
||||
msg += "\" for writing.";
|
||||
//pmsg = msg.c_str;
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
fillInHeader(sampleRate, bits, channels);
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
WavOutFile::~WavOutFile()
|
||||
{
|
||||
finishHeader();
|
||||
if (fptr) fclose(fptr);
|
||||
fptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels)
|
||||
{
|
||||
// fill in the 'riff' part..
|
||||
|
||||
// copy string 'RIFF' to riff_char
|
||||
memcpy(&(header.riff.riff_char), riffStr, 4);
|
||||
// package_len unknown so far
|
||||
header.riff.package_len = 0;
|
||||
// copy string 'WAVE' to wave
|
||||
memcpy(&(header.riff.wave), waveStr, 4);
|
||||
|
||||
|
||||
// fill in the 'format' part..
|
||||
|
||||
// copy string 'fmt ' to fmt
|
||||
memcpy(&(header.format.fmt), fmtStr, 4);
|
||||
|
||||
header.format.format_len = 0x10;
|
||||
header.format.fixed = 1;
|
||||
header.format.channel_number = (short)channels;
|
||||
header.format.sample_rate = (int)sampleRate;
|
||||
header.format.bits_per_sample = (short)bits;
|
||||
header.format.byte_per_sample = (short)(bits * channels / 8);
|
||||
header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate;
|
||||
header.format.sample_rate = (int)sampleRate;
|
||||
|
||||
// fill in the 'data' part..
|
||||
|
||||
// copy string 'data' to data_field
|
||||
memcpy(&(header.data.data_field), dataStr, 4);
|
||||
// data_len unknown so far
|
||||
header.data.data_len = 0;
|
||||
}
|
||||
|
||||
|
||||
void WavOutFile::finishHeader()
|
||||
{
|
||||
// supplement the file length into the header structure
|
||||
header.riff.package_len = bytesWritten + 36;
|
||||
header.data.data_len = bytesWritten;
|
||||
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WavOutFile::writeHeader()
|
||||
{
|
||||
int res;
|
||||
|
||||
// write the supplemented header in the beginning of the file
|
||||
fseek(fptr, 0, SEEK_SET);
|
||||
res = fwrite(&header, sizeof(header), 1, fptr);
|
||||
if (res != 1)
|
||||
{
|
||||
throw runtime_error("Error while writing to a wav file.");
|
||||
}
|
||||
|
||||
// jump back to the end of the file
|
||||
fseek(fptr, 0, SEEK_END);
|
||||
}
|
||||
|
||||
|
||||
void WavOutFile::write(const short *buffer, int numElems)
|
||||
{
|
||||
int res;
|
||||
|
||||
// 16bit format & 16 bit samples
|
||||
|
||||
assert(header.format.bits_per_sample == 16);
|
||||
if (numElems < 1) return; // nothing to do
|
||||
|
||||
res = fwrite(buffer, 2, numElems, fptr);
|
||||
|
||||
if (res != numElems)
|
||||
{
|
||||
throw runtime_error("Error while writing to a wav file.");
|
||||
}
|
||||
bytesWritten += 2 * numElems;
|
||||
}
|
||||
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
||||
* Developed and maintained by the Pcsx2 Development Team.
|
||||
*
|
||||
* The file is based on WavFile.h from SoundTouch library.
|
||||
* Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi)
|
||||
*
|
||||
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was
|
||||
// shrunken to support only output 16 bits wav files
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "WavFile.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char riffStr[] = "RIFF";
|
||||
static const char waveStr[] = "WAVE";
|
||||
static const char fmtStr[] = "fmt ";
|
||||
static const char dataStr[] = "data";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class WavOutFile
|
||||
//
|
||||
|
||||
WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int channels)
|
||||
{
|
||||
bytesWritten = 0;
|
||||
fptr = fopen(fileName, "wb");
|
||||
if (fptr == NULL)
|
||||
{
|
||||
string msg = "Error : Unable to open file \"";
|
||||
msg += fileName;
|
||||
msg += "\" for writing.";
|
||||
//pmsg = msg.c_str;
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
fillInHeader(sampleRate, bits, channels);
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
WavOutFile::~WavOutFile()
|
||||
{
|
||||
finishHeader();
|
||||
if (fptr) fclose(fptr);
|
||||
fptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels)
|
||||
{
|
||||
// fill in the 'riff' part..
|
||||
|
||||
// copy string 'RIFF' to riff_char
|
||||
memcpy(&(header.riff.riff_char), riffStr, 4);
|
||||
// package_len unknown so far
|
||||
header.riff.package_len = 0;
|
||||
// copy string 'WAVE' to wave
|
||||
memcpy(&(header.riff.wave), waveStr, 4);
|
||||
|
||||
|
||||
// fill in the 'format' part..
|
||||
|
||||
// copy string 'fmt ' to fmt
|
||||
memcpy(&(header.format.fmt), fmtStr, 4);
|
||||
|
||||
header.format.format_len = 0x10;
|
||||
header.format.fixed = 1;
|
||||
header.format.channel_number = (short)channels;
|
||||
header.format.sample_rate = (int)sampleRate;
|
||||
header.format.bits_per_sample = (short)bits;
|
||||
header.format.byte_per_sample = (short)(bits * channels / 8);
|
||||
header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate;
|
||||
header.format.sample_rate = (int)sampleRate;
|
||||
|
||||
// fill in the 'data' part..
|
||||
|
||||
// copy string 'data' to data_field
|
||||
memcpy(&(header.data.data_field), dataStr, 4);
|
||||
// data_len unknown so far
|
||||
header.data.data_len = 0;
|
||||
}
|
||||
|
||||
|
||||
void WavOutFile::finishHeader()
|
||||
{
|
||||
// supplement the file length into the header structure
|
||||
header.riff.package_len = bytesWritten + 36;
|
||||
header.data.data_len = bytesWritten;
|
||||
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WavOutFile::writeHeader()
|
||||
{
|
||||
int res;
|
||||
|
||||
// write the supplemented header in the beginning of the file
|
||||
fseek(fptr, 0, SEEK_SET);
|
||||
res = fwrite(&header, sizeof(header), 1, fptr);
|
||||
if (res != 1)
|
||||
{
|
||||
throw runtime_error("Error while writing to a wav file.");
|
||||
}
|
||||
|
||||
// jump back to the end of the file
|
||||
fseek(fptr, 0, SEEK_END);
|
||||
}
|
||||
|
||||
|
||||
void WavOutFile::write(const short *buffer, int numElems)
|
||||
{
|
||||
int res;
|
||||
|
||||
// 16bit format & 16 bit samples
|
||||
|
||||
assert(header.format.bits_per_sample == 16);
|
||||
if (numElems < 1) return; // nothing to do
|
||||
|
||||
res = fwrite(buffer, 2, numElems, fptr);
|
||||
|
||||
if (res != numElems)
|
||||
{
|
||||
throw runtime_error("Error while writing to a wav file.");
|
||||
}
|
||||
bytesWritten += 2 * numElems;
|
||||
}
|
||||
|
|
|
@ -1,113 +1,113 @@
|
|||
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
||||
* Developed and maintained by the Pcsx2 Development Team.
|
||||
*
|
||||
* The file is based on WavFile.h from SoundTouch library.
|
||||
* Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi)
|
||||
*
|
||||
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was
|
||||
// shrunken to support only output 16 bits wav files
|
||||
|
||||
#ifndef WAVFILE_H
|
||||
#define WAVFILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
|
||||
/// WAV audio file 'riff' section header
|
||||
typedef struct
|
||||
{
|
||||
char riff_char[4];
|
||||
int package_len;
|
||||
char wave[4];
|
||||
} WavRiff;
|
||||
|
||||
/// WAV audio file 'format' section header
|
||||
typedef struct
|
||||
{
|
||||
char fmt[4];
|
||||
int format_len;
|
||||
short fixed;
|
||||
short channel_number;
|
||||
int sample_rate;
|
||||
int byte_rate;
|
||||
short byte_per_sample;
|
||||
short bits_per_sample;
|
||||
} WavFormat;
|
||||
|
||||
/// WAV audio file 'data' section header
|
||||
typedef struct
|
||||
{
|
||||
char data_field[4];
|
||||
uint data_len;
|
||||
} WavData;
|
||||
|
||||
|
||||
/// WAV audio file header
|
||||
typedef struct
|
||||
{
|
||||
WavRiff riff;
|
||||
WavFormat format;
|
||||
WavData data;
|
||||
} WavHeader;
|
||||
|
||||
|
||||
/// Class for writing WAV audio files.
|
||||
class WavOutFile
|
||||
{
|
||||
private:
|
||||
/// Pointer to the WAV file
|
||||
FILE *fptr;
|
||||
|
||||
/// WAV file header data.
|
||||
WavHeader header;
|
||||
|
||||
/// Counter of how many bytes have been written to the file so far.
|
||||
int bytesWritten;
|
||||
|
||||
/// Fills in WAV file header information.
|
||||
void fillInHeader(const uint sampleRate, const uint bits, const uint channels);
|
||||
|
||||
/// Finishes the WAV file header by supplementing information of amount of
|
||||
/// data written to file etc
|
||||
void finishHeader();
|
||||
|
||||
/// Writes the WAV file header.
|
||||
void writeHeader();
|
||||
|
||||
public:
|
||||
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
||||
/// if file creation fails.
|
||||
WavOutFile(const char *fileName, ///< Filename
|
||||
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
||||
int bits, ///< Bits per sample (8 or 16 bits)
|
||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||
);
|
||||
|
||||
/// Destructor: Finalizes & closes the WAV file.
|
||||
~WavOutFile();
|
||||
|
||||
/// Write data to WAV file. Throws a 'runtime_error' exception if writing to
|
||||
/// file fails.
|
||||
void write(const short *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
||||
* Developed and maintained by the Pcsx2 Development Team.
|
||||
*
|
||||
* The file is based on WavFile.h from SoundTouch library.
|
||||
* Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi)
|
||||
*
|
||||
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was
|
||||
// shrunken to support only output 16 bits wav files
|
||||
|
||||
#ifndef WAVFILE_H
|
||||
#define WAVFILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
|
||||
/// WAV audio file 'riff' section header
|
||||
typedef struct
|
||||
{
|
||||
char riff_char[4];
|
||||
int package_len;
|
||||
char wave[4];
|
||||
} WavRiff;
|
||||
|
||||
/// WAV audio file 'format' section header
|
||||
typedef struct
|
||||
{
|
||||
char fmt[4];
|
||||
int format_len;
|
||||
short fixed;
|
||||
short channel_number;
|
||||
int sample_rate;
|
||||
int byte_rate;
|
||||
short byte_per_sample;
|
||||
short bits_per_sample;
|
||||
} WavFormat;
|
||||
|
||||
/// WAV audio file 'data' section header
|
||||
typedef struct
|
||||
{
|
||||
char data_field[4];
|
||||
uint data_len;
|
||||
} WavData;
|
||||
|
||||
|
||||
/// WAV audio file header
|
||||
typedef struct
|
||||
{
|
||||
WavRiff riff;
|
||||
WavFormat format;
|
||||
WavData data;
|
||||
} WavHeader;
|
||||
|
||||
|
||||
/// Class for writing WAV audio files.
|
||||
class WavOutFile
|
||||
{
|
||||
private:
|
||||
/// Pointer to the WAV file
|
||||
FILE *fptr;
|
||||
|
||||
/// WAV file header data.
|
||||
WavHeader header;
|
||||
|
||||
/// Counter of how many bytes have been written to the file so far.
|
||||
int bytesWritten;
|
||||
|
||||
/// Fills in WAV file header information.
|
||||
void fillInHeader(const uint sampleRate, const uint bits, const uint channels);
|
||||
|
||||
/// Finishes the WAV file header by supplementing information of amount of
|
||||
/// data written to file etc
|
||||
void finishHeader();
|
||||
|
||||
/// Writes the WAV file header.
|
||||
void writeHeader();
|
||||
|
||||
public:
|
||||
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
||||
/// if file creation fails.
|
||||
WavOutFile(const char *fileName, ///< Filename
|
||||
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
||||
int bits, ///< Bits per sample (8 or 16 bits)
|
||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||
);
|
||||
|
||||
/// Destructor: Finalizes & closes the WAV file.
|
||||
~WavOutFile();
|
||||
|
||||
/// Write data to WAV file. Throws a 'runtime_error' exception if writing to
|
||||
/// file fails.
|
||||
void write(const short *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
ZeroGS DirectX
|
||||
--------------
|
||||
author: zerofrog (@gmail.com)
|
||||
|
||||
ZeroGS heavily uses GPU shaders. All the shaders are written in Microsoft's HLSL language and can be found in ps2hw.fx, ps2hw_ctx0.fx and ps2hw_ctx1.fx.
|
||||
|
||||
'Dev' versions of ZeroGS directly read ps2hw.fx
|
||||
'Release' versions of ZeroGS read a precompiled version of ps2hw.fx from ps2hw.dat. In order to build ps2hw.dat, compile ZeroGSShaders and execute:
|
||||
|
||||
./ZeroGSShaders ps2hw.fx ps2hw.dat
|
||||
|
||||
For Windows users, once ZeroGSShaders is built, run buildshaders.bat directly. It will update all necessary resource files.
|
||||
Note that ZeroGSShaders has only been tested in Windows so far, but the Windows ps2hw.dat can be used in linux builds.
|
||||
ZeroGS DirectX
|
||||
--------------
|
||||
author: zerofrog (@gmail.com)
|
||||
|
||||
ZeroGS heavily uses GPU shaders. All the shaders are written in Microsoft's HLSL language and can be found in ps2hw.fx, ps2hw_ctx0.fx and ps2hw_ctx1.fx.
|
||||
|
||||
'Dev' versions of ZeroGS directly read ps2hw.fx
|
||||
'Release' versions of ZeroGS read a precompiled version of ps2hw.fx from ps2hw.dat. In order to build ps2hw.dat, compile ZeroGSShaders and execute:
|
||||
|
||||
./ZeroGSShaders ps2hw.fx ps2hw.dat
|
||||
|
||||
For Windows users, once ZeroGSShaders is built, run buildshaders.bat directly. It will update all necessary resource files.
|
||||
Note that ZeroGSShaders has only been tested in Windows so far, but the Windows ps2hw.dat can be used in linux builds.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,33 +1,33 @@
|
|||
// main ps2 memory, each pixel is stored in 32bit color
|
||||
texture g_txMem0;
|
||||
|
||||
sampler g_sMemory : register(s0) = sampler_state {
|
||||
Texture = <g_txMem0>;
|
||||
MipFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
MagFilter = POINT;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
// per context pixel shader constants
|
||||
half4 fTexAlpha2 : register(c2);
|
||||
|
||||
float4 g_fTexOffset : register(c4); // converts the page and block offsets into the mem addr/1024
|
||||
float4 g_fTexDims : register(c6); // mult by tex dims when accessing the block texture
|
||||
float4 g_fTexBlock : register(c8);
|
||||
|
||||
float4 g_fClampExts : register(c10); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
float4 TexWrapMode : register(c12); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
float4 g_fRealTexDims : register(c14); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
half4 g_fTestBlack : register(c16); // used for aem bit
|
||||
|
||||
float4 g_fPageOffset : register(c18);
|
||||
|
||||
half4 fTexAlpha : register(c20);
|
||||
|
||||
// vertex shader constants
|
||||
// main ps2 memory, each pixel is stored in 32bit color
|
||||
texture g_txMem0;
|
||||
|
||||
sampler g_sMemory : register(s0) = sampler_state {
|
||||
Texture = <g_txMem0>;
|
||||
MipFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
MagFilter = POINT;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
// per context pixel shader constants
|
||||
half4 fTexAlpha2 : register(c2);
|
||||
|
||||
float4 g_fTexOffset : register(c4); // converts the page and block offsets into the mem addr/1024
|
||||
float4 g_fTexDims : register(c6); // mult by tex dims when accessing the block texture
|
||||
float4 g_fTexBlock : register(c8);
|
||||
|
||||
float4 g_fClampExts : register(c10); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
float4 TexWrapMode : register(c12); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
float4 g_fRealTexDims : register(c14); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
half4 g_fTestBlack : register(c16); // used for aem bit
|
||||
|
||||
float4 g_fPageOffset : register(c18);
|
||||
|
||||
half4 fTexAlpha : register(c20);
|
||||
|
||||
// vertex shader constants
|
||||
float4 g_fPosXY : register(c2);
|
|
@ -1,32 +1,32 @@
|
|||
texture g_txMem1;
|
||||
|
||||
sampler g_sMemory : register(s1) = sampler_state {
|
||||
Texture = <g_txMem1>;
|
||||
MipFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
MagFilter = POINT;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
// per context pixel shader constants
|
||||
half4 fTexAlpha2 : register(c3);
|
||||
|
||||
float4 g_fTexOffset : register(c5); // converts the page and block offsets into the mem addr/1024
|
||||
float4 g_fTexDims : register(c7); // mult by tex dims when accessing the block texture
|
||||
float4 g_fTexBlock : register(c9);
|
||||
|
||||
float4 g_fClampExts : register(c11); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
float4 TexWrapMode : register(c13); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
float4 g_fRealTexDims : register(c15); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
half4 g_fTestBlack : register(c17); // used for aem bit
|
||||
|
||||
float4 g_fPageOffset : register(c19);
|
||||
|
||||
half4 fTexAlpha : register(c21);
|
||||
|
||||
// vertex shader constants
|
||||
texture g_txMem1;
|
||||
|
||||
sampler g_sMemory : register(s1) = sampler_state {
|
||||
Texture = <g_txMem1>;
|
||||
MipFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
MagFilter = POINT;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
// per context pixel shader constants
|
||||
half4 fTexAlpha2 : register(c3);
|
||||
|
||||
float4 g_fTexOffset : register(c5); // converts the page and block offsets into the mem addr/1024
|
||||
float4 g_fTexDims : register(c7); // mult by tex dims when accessing the block texture
|
||||
float4 g_fTexBlock : register(c9);
|
||||
|
||||
float4 g_fClampExts : register(c11); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
float4 TexWrapMode : register(c13); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
float4 g_fRealTexDims : register(c15); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
half4 g_fTestBlack : register(c17); // used for aem bit
|
||||
|
||||
float4 g_fPageOffset : register(c19);
|
||||
|
||||
half4 fTexAlpha : register(c21);
|
||||
|
||||
// vertex shader constants
|
||||
float4 g_fPosXY : register(c3);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,24 +1,24 @@
|
|||
// main ps2 memory, each pixel is stored in 32bit color
|
||||
uniform samplerRECT g_sMemory : register(s0);
|
||||
|
||||
// per context pixel shader constants
|
||||
uniform half4 fTexAlpha2 : register(c2);
|
||||
|
||||
uniform float4 g_fTexOffset : register(c4); // converts the page and block offsets into the mem addr/1024
|
||||
uniform float4 g_fTexDims : register(c6); // mult by tex dims when accessing the block texture
|
||||
uniform float4 g_fTexBlock : register(c8);
|
||||
|
||||
uniform float4 g_fClampExts : register(c10); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
uniform float4 TexWrapMode : register(c12); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
uniform float4 g_fRealTexDims : register(c14); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
uniform half4 g_fTestBlack : register(c16); // used for aem bit
|
||||
|
||||
uniform float4 g_fPageOffset : register(c18);
|
||||
|
||||
uniform half4 fTexAlpha : register(c20);
|
||||
|
||||
// vertex shader constants
|
||||
uniform float4 g_fPosXY : register(c2);
|
||||
// main ps2 memory, each pixel is stored in 32bit color
|
||||
uniform samplerRECT g_sMemory : register(s0);
|
||||
|
||||
// per context pixel shader constants
|
||||
uniform half4 fTexAlpha2 : register(c2);
|
||||
|
||||
uniform float4 g_fTexOffset : register(c4); // converts the page and block offsets into the mem addr/1024
|
||||
uniform float4 g_fTexDims : register(c6); // mult by tex dims when accessing the block texture
|
||||
uniform float4 g_fTexBlock : register(c8);
|
||||
|
||||
uniform float4 g_fClampExts : register(c10); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
uniform float4 TexWrapMode : register(c12); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
uniform float4 g_fRealTexDims : register(c14); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
uniform half4 g_fTestBlack : register(c16); // used for aem bit
|
||||
|
||||
uniform float4 g_fPageOffset : register(c18);
|
||||
|
||||
uniform half4 fTexAlpha : register(c20);
|
||||
|
||||
// vertex shader constants
|
||||
uniform float4 g_fPosXY : register(c2);
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
uniform samplerRECT g_sMemory : register(s1);
|
||||
|
||||
// per context pixel shader constants
|
||||
uniform half4 fTexAlpha2 : register(c3);
|
||||
|
||||
uniform float4 g_fTexOffset : register(c5); // converts the page and block offsets into the mem addr/1024
|
||||
uniform float4 g_fTexDims : register(c7); // mult by tex dims when accessing the block texture
|
||||
uniform float4 g_fTexBlock : register(c9);
|
||||
|
||||
uniform float4 g_fClampExts : register(c11); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
uniform float4 TexWrapMode : register(c13); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
uniform float4 g_fRealTexDims : register(c15); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
uniform half4 g_fTestBlack : register(c17); // used for aem bit
|
||||
|
||||
uniform float4 g_fPageOffset : register(c19);
|
||||
|
||||
uniform half4 fTexAlpha : register(c21);
|
||||
|
||||
// vertex shader constants
|
||||
uniform samplerRECT g_sMemory : register(s1);
|
||||
|
||||
// per context pixel shader constants
|
||||
uniform half4 fTexAlpha2 : register(c3);
|
||||
|
||||
uniform float4 g_fTexOffset : register(c5); // converts the page and block offsets into the mem addr/1024
|
||||
uniform float4 g_fTexDims : register(c7); // mult by tex dims when accessing the block texture
|
||||
uniform float4 g_fTexBlock : register(c9);
|
||||
|
||||
uniform float4 g_fClampExts : register(c11); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
uniform float4 TexWrapMode : register(c13); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
uniform float4 g_fRealTexDims : register(c15); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
uniform half4 g_fTestBlack : register(c17); // used for aem bit
|
||||
|
||||
uniform float4 g_fPageOffset : register(c19);
|
||||
|
||||
uniform half4 fTexAlpha : register(c21);
|
||||
|
||||
// vertex shader constants
|
||||
uniform float4 g_fPosXY : register(c3);
|
File diff suppressed because it is too large
Load Diff
|
@ -1,149 +1,149 @@
|
|||
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
||||
* Developed and maintained by the Pcsx2 Development Team.
|
||||
*
|
||||
* The file is based on WavFile.h from SoundTouch library.
|
||||
* Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi)
|
||||
*
|
||||
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was
|
||||
// shrunken to support only output 16 bits wav files
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "WavFile.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char riffStr[] = "RIFF";
|
||||
static const char waveStr[] = "WAVE";
|
||||
static const char fmtStr[] = "fmt ";
|
||||
static const char dataStr[] = "data";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class WavOutFile
|
||||
//
|
||||
|
||||
WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int channels)
|
||||
{
|
||||
bytesWritten = 0;
|
||||
fptr = fopen(fileName, "wb");
|
||||
if (fptr == NULL)
|
||||
{
|
||||
string msg = "Error : Unable to open file \"";
|
||||
msg += fileName;
|
||||
msg += "\" for writing.";
|
||||
//pmsg = msg.c_str;
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
fillInHeader(sampleRate, bits, channels);
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
WavOutFile::~WavOutFile()
|
||||
{
|
||||
finishHeader();
|
||||
if (fptr) fclose(fptr);
|
||||
fptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels)
|
||||
{
|
||||
// fill in the 'riff' part..
|
||||
|
||||
// copy string 'RIFF' to riff_char
|
||||
memcpy(&(header.riff.riff_char), riffStr, 4);
|
||||
// package_len unknown so far
|
||||
header.riff.package_len = 0;
|
||||
// copy string 'WAVE' to wave
|
||||
memcpy(&(header.riff.wave), waveStr, 4);
|
||||
|
||||
|
||||
// fill in the 'format' part..
|
||||
|
||||
// copy string 'fmt ' to fmt
|
||||
memcpy(&(header.format.fmt), fmtStr, 4);
|
||||
|
||||
header.format.format_len = 0x10;
|
||||
header.format.fixed = 1;
|
||||
header.format.channel_number = (short)channels;
|
||||
header.format.sample_rate = (int)sampleRate;
|
||||
header.format.bits_per_sample = (short)bits;
|
||||
header.format.byte_per_sample = (short)(bits * channels / 8);
|
||||
header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate;
|
||||
header.format.sample_rate = (int)sampleRate;
|
||||
|
||||
// fill in the 'data' part..
|
||||
|
||||
// copy string 'data' to data_field
|
||||
memcpy(&(header.data.data_field), dataStr, 4);
|
||||
// data_len unknown so far
|
||||
header.data.data_len = 0;
|
||||
}
|
||||
|
||||
|
||||
void WavOutFile::finishHeader()
|
||||
{
|
||||
// supplement the file length into the header structure
|
||||
header.riff.package_len = bytesWritten + 36;
|
||||
header.data.data_len = bytesWritten;
|
||||
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WavOutFile::writeHeader()
|
||||
{
|
||||
int res;
|
||||
|
||||
// write the supplemented header in the beginning of the file
|
||||
fseek(fptr, 0, SEEK_SET);
|
||||
res = fwrite(&header, sizeof(header), 1, fptr);
|
||||
if (res != 1)
|
||||
{
|
||||
throw runtime_error("Error while writing to a wav file.");
|
||||
}
|
||||
|
||||
// jump back to the end of the file
|
||||
fseek(fptr, 0, SEEK_END);
|
||||
}
|
||||
|
||||
|
||||
void WavOutFile::write(const short *buffer, int numElems)
|
||||
{
|
||||
int res;
|
||||
|
||||
// 16bit format & 16 bit samples
|
||||
|
||||
assert(header.format.bits_per_sample == 16);
|
||||
if (numElems < 1) return; // nothing to do
|
||||
|
||||
res = fwrite(buffer, 2, numElems, fptr);
|
||||
|
||||
if (res != numElems)
|
||||
{
|
||||
throw runtime_error("Error while writing to a wav file.");
|
||||
}
|
||||
bytesWritten += 2 * numElems;
|
||||
}
|
||||
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
||||
* Developed and maintained by the Pcsx2 Development Team.
|
||||
*
|
||||
* The file is based on WavFile.h from SoundTouch library.
|
||||
* Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi)
|
||||
*
|
||||
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was
|
||||
// shrunken to support only output 16 bits wav files
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "WavFile.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char riffStr[] = "RIFF";
|
||||
static const char waveStr[] = "WAVE";
|
||||
static const char fmtStr[] = "fmt ";
|
||||
static const char dataStr[] = "data";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class WavOutFile
|
||||
//
|
||||
|
||||
WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int channels)
|
||||
{
|
||||
bytesWritten = 0;
|
||||
fptr = fopen(fileName, "wb");
|
||||
if (fptr == NULL)
|
||||
{
|
||||
string msg = "Error : Unable to open file \"";
|
||||
msg += fileName;
|
||||
msg += "\" for writing.";
|
||||
//pmsg = msg.c_str;
|
||||
throw runtime_error(msg);
|
||||
}
|
||||
|
||||
fillInHeader(sampleRate, bits, channels);
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
WavOutFile::~WavOutFile()
|
||||
{
|
||||
finishHeader();
|
||||
if (fptr) fclose(fptr);
|
||||
fptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels)
|
||||
{
|
||||
// fill in the 'riff' part..
|
||||
|
||||
// copy string 'RIFF' to riff_char
|
||||
memcpy(&(header.riff.riff_char), riffStr, 4);
|
||||
// package_len unknown so far
|
||||
header.riff.package_len = 0;
|
||||
// copy string 'WAVE' to wave
|
||||
memcpy(&(header.riff.wave), waveStr, 4);
|
||||
|
||||
|
||||
// fill in the 'format' part..
|
||||
|
||||
// copy string 'fmt ' to fmt
|
||||
memcpy(&(header.format.fmt), fmtStr, 4);
|
||||
|
||||
header.format.format_len = 0x10;
|
||||
header.format.fixed = 1;
|
||||
header.format.channel_number = (short)channels;
|
||||
header.format.sample_rate = (int)sampleRate;
|
||||
header.format.bits_per_sample = (short)bits;
|
||||
header.format.byte_per_sample = (short)(bits * channels / 8);
|
||||
header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate;
|
||||
header.format.sample_rate = (int)sampleRate;
|
||||
|
||||
// fill in the 'data' part..
|
||||
|
||||
// copy string 'data' to data_field
|
||||
memcpy(&(header.data.data_field), dataStr, 4);
|
||||
// data_len unknown so far
|
||||
header.data.data_len = 0;
|
||||
}
|
||||
|
||||
|
||||
void WavOutFile::finishHeader()
|
||||
{
|
||||
// supplement the file length into the header structure
|
||||
header.riff.package_len = bytesWritten + 36;
|
||||
header.data.data_len = bytesWritten;
|
||||
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WavOutFile::writeHeader()
|
||||
{
|
||||
int res;
|
||||
|
||||
// write the supplemented header in the beginning of the file
|
||||
fseek(fptr, 0, SEEK_SET);
|
||||
res = fwrite(&header, sizeof(header), 1, fptr);
|
||||
if (res != 1)
|
||||
{
|
||||
throw runtime_error("Error while writing to a wav file.");
|
||||
}
|
||||
|
||||
// jump back to the end of the file
|
||||
fseek(fptr, 0, SEEK_END);
|
||||
}
|
||||
|
||||
|
||||
void WavOutFile::write(const short *buffer, int numElems)
|
||||
{
|
||||
int res;
|
||||
|
||||
// 16bit format & 16 bit samples
|
||||
|
||||
assert(header.format.bits_per_sample == 16);
|
||||
if (numElems < 1) return; // nothing to do
|
||||
|
||||
res = fwrite(buffer, 2, numElems, fptr);
|
||||
|
||||
if (res != numElems)
|
||||
{
|
||||
throw runtime_error("Error while writing to a wav file.");
|
||||
}
|
||||
bytesWritten += 2 * numElems;
|
||||
}
|
||||
|
|
|
@ -1,113 +1,113 @@
|
|||
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
||||
* Developed and maintained by the Pcsx2 Development Team.
|
||||
*
|
||||
* The file is based on WavFile.h from SoundTouch library.
|
||||
* Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi)
|
||||
*
|
||||
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was
|
||||
// shrunken to support only output 16 bits wav files
|
||||
|
||||
#ifndef WAVFILE_H
|
||||
#define WAVFILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
|
||||
/// WAV audio file 'riff' section header
|
||||
typedef struct
|
||||
{
|
||||
char riff_char[4];
|
||||
int package_len;
|
||||
char wave[4];
|
||||
} WavRiff;
|
||||
|
||||
/// WAV audio file 'format' section header
|
||||
typedef struct
|
||||
{
|
||||
char fmt[4];
|
||||
int format_len;
|
||||
short fixed;
|
||||
short channel_number;
|
||||
int sample_rate;
|
||||
int byte_rate;
|
||||
short byte_per_sample;
|
||||
short bits_per_sample;
|
||||
} WavFormat;
|
||||
|
||||
/// WAV audio file 'data' section header
|
||||
typedef struct
|
||||
{
|
||||
char data_field[4];
|
||||
uint data_len;
|
||||
} WavData;
|
||||
|
||||
|
||||
/// WAV audio file header
|
||||
typedef struct
|
||||
{
|
||||
WavRiff riff;
|
||||
WavFormat format;
|
||||
WavData data;
|
||||
} WavHeader;
|
||||
|
||||
|
||||
/// Class for writing WAV audio files.
|
||||
class WavOutFile
|
||||
{
|
||||
private:
|
||||
/// Pointer to the WAV file
|
||||
FILE *fptr;
|
||||
|
||||
/// WAV file header data.
|
||||
WavHeader header;
|
||||
|
||||
/// Counter of how many bytes have been written to the file so far.
|
||||
int bytesWritten;
|
||||
|
||||
/// Fills in WAV file header information.
|
||||
void fillInHeader(const uint sampleRate, const uint bits, const uint channels);
|
||||
|
||||
/// Finishes the WAV file header by supplementing information of amount of
|
||||
/// data written to file etc
|
||||
void finishHeader();
|
||||
|
||||
/// Writes the WAV file header.
|
||||
void writeHeader();
|
||||
|
||||
public:
|
||||
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
||||
/// if file creation fails.
|
||||
WavOutFile(const char *fileName, ///< Filename
|
||||
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
||||
int bits, ///< Bits per sample (8 or 16 bits)
|
||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||
);
|
||||
|
||||
/// Destructor: Finalizes & closes the WAV file.
|
||||
~WavOutFile();
|
||||
|
||||
/// Write data to WAV file. Throws a 'runtime_error' exception if writing to
|
||||
/// file fails.
|
||||
void write(const short *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
||||
* Developed and maintained by the Pcsx2 Development Team.
|
||||
*
|
||||
* The file is based on WavFile.h from SoundTouch library.
|
||||
* Original portions are (c) 2009 by Olli Parviainen (oparviai 'at' iki.fi)
|
||||
*
|
||||
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Note the file is mostly a copy paste of the WavFile.h from SoundTouch library. It was
|
||||
// shrunken to support only output 16 bits wav files
|
||||
|
||||
#ifndef WAVFILE_H
|
||||
#define WAVFILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
|
||||
/// WAV audio file 'riff' section header
|
||||
typedef struct
|
||||
{
|
||||
char riff_char[4];
|
||||
int package_len;
|
||||
char wave[4];
|
||||
} WavRiff;
|
||||
|
||||
/// WAV audio file 'format' section header
|
||||
typedef struct
|
||||
{
|
||||
char fmt[4];
|
||||
int format_len;
|
||||
short fixed;
|
||||
short channel_number;
|
||||
int sample_rate;
|
||||
int byte_rate;
|
||||
short byte_per_sample;
|
||||
short bits_per_sample;
|
||||
} WavFormat;
|
||||
|
||||
/// WAV audio file 'data' section header
|
||||
typedef struct
|
||||
{
|
||||
char data_field[4];
|
||||
uint data_len;
|
||||
} WavData;
|
||||
|
||||
|
||||
/// WAV audio file header
|
||||
typedef struct
|
||||
{
|
||||
WavRiff riff;
|
||||
WavFormat format;
|
||||
WavData data;
|
||||
} WavHeader;
|
||||
|
||||
|
||||
/// Class for writing WAV audio files.
|
||||
class WavOutFile
|
||||
{
|
||||
private:
|
||||
/// Pointer to the WAV file
|
||||
FILE *fptr;
|
||||
|
||||
/// WAV file header data.
|
||||
WavHeader header;
|
||||
|
||||
/// Counter of how many bytes have been written to the file so far.
|
||||
int bytesWritten;
|
||||
|
||||
/// Fills in WAV file header information.
|
||||
void fillInHeader(const uint sampleRate, const uint bits, const uint channels);
|
||||
|
||||
/// Finishes the WAV file header by supplementing information of amount of
|
||||
/// data written to file etc
|
||||
void finishHeader();
|
||||
|
||||
/// Writes the WAV file header.
|
||||
void writeHeader();
|
||||
|
||||
public:
|
||||
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
||||
/// if file creation fails.
|
||||
WavOutFile(const char *fileName, ///< Filename
|
||||
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
||||
int bits, ///< Bits per sample (8 or 16 bits)
|
||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||
);
|
||||
|
||||
/// Destructor: Finalizes & closes the WAV file.
|
||||
~WavOutFile();
|
||||
|
||||
/// Write data to WAV file. Throws a 'runtime_error' exception if writing to
|
||||
/// file fails.
|
||||
void write(const short *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,172 +1,172 @@
|
|||
/* ZZ Open GL graphics plugin
|
||||
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
|
||||
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef PROFILE_H_INCLUDED
|
||||
#define PROFILE_H_INCLUDED
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
#if !defined(ZEROGS_DEVBUILD)
|
||||
#define g_bWriteProfile 0
|
||||
#else
|
||||
extern bool g_bWriteProfile;
|
||||
#endif
|
||||
|
||||
extern u64 luPerfFreq;
|
||||
|
||||
|
||||
// Copied from Utilities; remove later.
|
||||
#ifdef __LINUX__
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h> // ftime(), struct timeb
|
||||
|
||||
inline unsigned long timeGetTime()
|
||||
{
|
||||
timeb t;
|
||||
ftime(&t);
|
||||
|
||||
return (unsigned long)(t.time*1000 + t.millitm);
|
||||
}
|
||||
|
||||
inline unsigned long timeGetPreciseTime()
|
||||
{
|
||||
timespec t;
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
|
||||
|
||||
return t.tv_nsec;
|
||||
}
|
||||
|
||||
static __forceinline void InitCPUTicks()
|
||||
{
|
||||
}
|
||||
|
||||
static __forceinline u64 GetTickFrequency()
|
||||
{
|
||||
return 1000000; // unix measures in microseconds
|
||||
}
|
||||
|
||||
static __forceinline u64 GetCPUTicks()
|
||||
{
|
||||
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
return ((u64)t.tv_sec*GetTickFrequency()) + t.tv_usec;
|
||||
}
|
||||
|
||||
#else
|
||||
static __aligned16 LARGE_INTEGER lfreq;
|
||||
|
||||
inline unsigned long timeGetPreciseTime()
|
||||
{
|
||||
// Implement later.
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __forceinline void InitCPUTicks()
|
||||
{
|
||||
QueryPerformanceFrequency(&lfreq);
|
||||
}
|
||||
|
||||
static __forceinline u64 GetTickFrequency()
|
||||
{
|
||||
return lfreq.QuadPart;
|
||||
}
|
||||
|
||||
static __forceinline u64 GetCPUTicks()
|
||||
{
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
return count.QuadPart;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// IMPORTANT: For every Register there must be an End
|
||||
void DVProfRegister(char* pname); // first checks if this profiler exists in g_listProfilers
|
||||
void DVProfEnd(u32 dwUserData);
|
||||
void DVProfWrite(char* pfilename, u32 frames = 0);
|
||||
void DVProfClear(); // clears all the profilers
|
||||
|
||||
#define DVPROFILE
|
||||
#ifdef DVPROFILE
|
||||
|
||||
class DVProfileFunc
|
||||
{
|
||||
public:
|
||||
u32 dwUserData;
|
||||
DVProfileFunc(char* pname) { DVProfRegister(pname); dwUserData = 0; }
|
||||
DVProfileFunc(char* pname, u32 dwUserData) : dwUserData(dwUserData) { DVProfRegister(pname); }
|
||||
~DVProfileFunc() { DVProfEnd(dwUserData); }
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class DVProfileFunc
|
||||
{
|
||||
|
||||
public:
|
||||
u32 dwUserData;
|
||||
static __forceinline DVProfileFunc(char* pname) {}
|
||||
static __forceinline DVProfileFunc(char* pname, u32 dwUserData) { }
|
||||
~DVProfileFunc() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
template <typename T>
|
||||
class CInterfacePtr
|
||||
{
|
||||
|
||||
public:
|
||||
inline CInterfacePtr() : ptr(NULL) {}
|
||||
inline explicit CInterfacePtr(T* newptr) : ptr(newptr) { if (ptr != NULL) ptr->AddRef(); }
|
||||
inline ~CInterfacePtr() { if (ptr != NULL) ptr->Release(); }
|
||||
inline T* operator*() { assert(ptr != NULL); return *ptr; }
|
||||
inline T* operator->() { return ptr; }
|
||||
inline T* get() { return ptr; }
|
||||
|
||||
inline void release()
|
||||
{
|
||||
if (ptr != NULL) { ptr->Release(); ptr = NULL; }
|
||||
}
|
||||
|
||||
inline operator T*() { return ptr; }
|
||||
inline bool operator==(T* rhs) { return ptr == rhs; }
|
||||
inline bool operator!=(T* rhs) { return ptr != rhs; }
|
||||
|
||||
inline CInterfacePtr& operator= (T* newptr)
|
||||
{
|
||||
if (ptr != NULL) ptr->Release();
|
||||
|
||||
ptr = newptr;
|
||||
|
||||
if (ptr != NULL) ptr->AddRef();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T* ptr;
|
||||
};
|
||||
|
||||
extern void InitProfile();
|
||||
|
||||
#endif // PROFILE_H_INCLUDED
|
||||
/* ZZ Open GL graphics plugin
|
||||
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
|
||||
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef PROFILE_H_INCLUDED
|
||||
#define PROFILE_H_INCLUDED
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
#if !defined(ZEROGS_DEVBUILD)
|
||||
#define g_bWriteProfile 0
|
||||
#else
|
||||
extern bool g_bWriteProfile;
|
||||
#endif
|
||||
|
||||
extern u64 luPerfFreq;
|
||||
|
||||
|
||||
// Copied from Utilities; remove later.
|
||||
#ifdef __LINUX__
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h> // ftime(), struct timeb
|
||||
|
||||
inline unsigned long timeGetTime()
|
||||
{
|
||||
timeb t;
|
||||
ftime(&t);
|
||||
|
||||
return (unsigned long)(t.time*1000 + t.millitm);
|
||||
}
|
||||
|
||||
inline unsigned long timeGetPreciseTime()
|
||||
{
|
||||
timespec t;
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
|
||||
|
||||
return t.tv_nsec;
|
||||
}
|
||||
|
||||
static __forceinline void InitCPUTicks()
|
||||
{
|
||||
}
|
||||
|
||||
static __forceinline u64 GetTickFrequency()
|
||||
{
|
||||
return 1000000; // unix measures in microseconds
|
||||
}
|
||||
|
||||
static __forceinline u64 GetCPUTicks()
|
||||
{
|
||||
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
return ((u64)t.tv_sec*GetTickFrequency()) + t.tv_usec;
|
||||
}
|
||||
|
||||
#else
|
||||
static __aligned16 LARGE_INTEGER lfreq;
|
||||
|
||||
inline unsigned long timeGetPreciseTime()
|
||||
{
|
||||
// Implement later.
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __forceinline void InitCPUTicks()
|
||||
{
|
||||
QueryPerformanceFrequency(&lfreq);
|
||||
}
|
||||
|
||||
static __forceinline u64 GetTickFrequency()
|
||||
{
|
||||
return lfreq.QuadPart;
|
||||
}
|
||||
|
||||
static __forceinline u64 GetCPUTicks()
|
||||
{
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
return count.QuadPart;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// IMPORTANT: For every Register there must be an End
|
||||
void DVProfRegister(char* pname); // first checks if this profiler exists in g_listProfilers
|
||||
void DVProfEnd(u32 dwUserData);
|
||||
void DVProfWrite(char* pfilename, u32 frames = 0);
|
||||
void DVProfClear(); // clears all the profilers
|
||||
|
||||
#define DVPROFILE
|
||||
#ifdef DVPROFILE
|
||||
|
||||
class DVProfileFunc
|
||||
{
|
||||
public:
|
||||
u32 dwUserData;
|
||||
DVProfileFunc(char* pname) { DVProfRegister(pname); dwUserData = 0; }
|
||||
DVProfileFunc(char* pname, u32 dwUserData) : dwUserData(dwUserData) { DVProfRegister(pname); }
|
||||
~DVProfileFunc() { DVProfEnd(dwUserData); }
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class DVProfileFunc
|
||||
{
|
||||
|
||||
public:
|
||||
u32 dwUserData;
|
||||
static __forceinline DVProfileFunc(char* pname) {}
|
||||
static __forceinline DVProfileFunc(char* pname, u32 dwUserData) { }
|
||||
~DVProfileFunc() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
template <typename T>
|
||||
class CInterfacePtr
|
||||
{
|
||||
|
||||
public:
|
||||
inline CInterfacePtr() : ptr(NULL) {}
|
||||
inline explicit CInterfacePtr(T* newptr) : ptr(newptr) { if (ptr != NULL) ptr->AddRef(); }
|
||||
inline ~CInterfacePtr() { if (ptr != NULL) ptr->Release(); }
|
||||
inline T* operator*() { assert(ptr != NULL); return *ptr; }
|
||||
inline T* operator->() { return ptr; }
|
||||
inline T* get() { return ptr; }
|
||||
|
||||
inline void release()
|
||||
{
|
||||
if (ptr != NULL) { ptr->Release(); ptr = NULL; }
|
||||
}
|
||||
|
||||
inline operator T*() { return ptr; }
|
||||
inline bool operator==(T* rhs) { return ptr == rhs; }
|
||||
inline bool operator!=(T* rhs) { return ptr != rhs; }
|
||||
|
||||
inline CInterfacePtr& operator= (T* newptr)
|
||||
{
|
||||
if (ptr != NULL) ptr->Release();
|
||||
|
||||
ptr = newptr;
|
||||
|
||||
if (ptr != NULL) ptr->AddRef();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T* ptr;
|
||||
};
|
||||
|
||||
extern void InitProfile();
|
||||
|
||||
#endif // PROFILE_H_INCLUDED
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
ZeroGS OpenGL
|
||||
-------------
|
||||
author: zerofrog (@gmail.com)
|
||||
|
||||
ZeroGS heavily uses GPU shaders. All the shaders are written in nVidia's Cg language and can be found in ps2hw.fx.
|
||||
|
||||
'Dev' versions of ZeroGS directly read ps2hw.fx
|
||||
'Release' versions of ZeroGS read a precompiled version of ps2hw.fx from ps2hw.dat. In order to build ps2hw.dat, compile ZeroGSShaders and execute:
|
||||
|
||||
./ZeroGSShaders ps2hw.fx ps2hw.dat
|
||||
|
||||
For Windows users, once ZeroGSShaders is built, run buildshaders.bat directly. It will update all necessary resource files.
|
||||
ZeroGS OpenGL
|
||||
-------------
|
||||
author: zerofrog (@gmail.com)
|
||||
|
||||
ZeroGS heavily uses GPU shaders. All the shaders are written in nVidia's Cg language and can be found in ps2hw.fx.
|
||||
|
||||
'Dev' versions of ZeroGS directly read ps2hw.fx
|
||||
'Release' versions of ZeroGS read a precompiled version of ps2hw.fx from ps2hw.dat. In order to build ps2hw.dat, compile ZeroGSShaders and execute:
|
||||
|
||||
./ZeroGSShaders ps2hw.fx ps2hw.dat
|
||||
|
||||
For Windows users, once ZeroGSShaders is built, run buildshaders.bat directly. It will update all necessary resource files.
|
||||
Note that ZeroGSShaders has only been tested in Windows so far, but the Windows ps2hw.dat can be used in linux builds.
|
|
@ -1,134 +1,134 @@
|
|||
/* ZZ Open GL graphics plugin
|
||||
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
|
||||
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef ZZGL_H_INCLUDED
|
||||
#define ZZGL_H_INCLUDED
|
||||
|
||||
#include "PS2Etypes.h"
|
||||
#include "PS2Edefs.h"
|
||||
|
||||
// Need this before gl.h
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "Utilities/RedtapeWindows.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include "glprocs.h"
|
||||
|
||||
#else
|
||||
|
||||
// adding glew support instead of glXGetProcAddress (thanks to scaught)
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
inline void* wglGetProcAddress(const char* x)
|
||||
{
|
||||
return (void*)glXGetProcAddress((const GLubyte*)x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern u32 s_stencilfunc, s_stencilref, s_stencilmask;
|
||||
// Defines
|
||||
|
||||
#ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils
|
||||
# define GL_DEPTH_STENCIL_EXT 0x84F9
|
||||
# define GL_UNSIGNED_INT_24_8_EXT 0x84FA
|
||||
# define GL_DEPTH24_STENCIL8_EXT 0x88F0
|
||||
# define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
|
||||
#endif
|
||||
|
||||
#define GL_STENCILFUNC(func, ref, mask) { \
|
||||
s_stencilfunc = func; \
|
||||
s_stencilref = ref; \
|
||||
s_stencilmask = mask; \
|
||||
glStencilFunc(func, ref, mask); \
|
||||
}
|
||||
|
||||
#define GL_STENCILFUNC_SET() glStencilFunc(s_stencilfunc, s_stencilref, s_stencilmask)
|
||||
|
||||
|
||||
// sets the data stream
|
||||
#define SET_STREAM() { \
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)8); \
|
||||
glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)12); \
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(VertexGPU), (void*)16); \
|
||||
glVertexPointer(4, GL_SHORT, sizeof(VertexGPU), (void*)0); \
|
||||
}
|
||||
|
||||
|
||||
// global alpha blending settings
|
||||
extern GLenum g_internalRGBAFloat16Fmt;
|
||||
|
||||
#define SAFE_RELEASE_TEX(x) { if( (x) != 0 ) { glDeleteTextures(1, &(x)); x = 0; } }
|
||||
|
||||
// inline for an extremely often used sequence
|
||||
// This is turning off all gl functions. Safe to do updates.
|
||||
inline void DisableAllgl()
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(0);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
//--------------------- Dummies
|
||||
|
||||
#ifdef _WIN32
|
||||
extern void (__stdcall *zgsBlendEquationSeparateEXT)(GLenum, GLenum);
|
||||
extern void (__stdcall *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum);
|
||||
#else
|
||||
extern void (APIENTRY *zgsBlendEquationSeparateEXT)(GLenum, GLenum);
|
||||
extern void (APIENTRY *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum);
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------ Types -------------------------
|
||||
|
||||
/////////////////////
|
||||
// graphics resources
|
||||
extern GLenum s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha; // set by zgsBlendFuncSeparateEXT
|
||||
|
||||
// GL prototypes
|
||||
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
|
||||
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
|
||||
extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
|
||||
extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
|
||||
extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
|
||||
extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT;
|
||||
extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT;
|
||||
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
|
||||
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
|
||||
extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
|
||||
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
|
||||
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
||||
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
||||
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
||||
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||
|
||||
#endif // ZZGL_H_INCLUDED
|
||||
/* ZZ Open GL graphics plugin
|
||||
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
|
||||
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef ZZGL_H_INCLUDED
|
||||
#define ZZGL_H_INCLUDED
|
||||
|
||||
#include "PS2Etypes.h"
|
||||
#include "PS2Edefs.h"
|
||||
|
||||
// Need this before gl.h
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "Utilities/RedtapeWindows.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include "glprocs.h"
|
||||
|
||||
#else
|
||||
|
||||
// adding glew support instead of glXGetProcAddress (thanks to scaught)
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
inline void* wglGetProcAddress(const char* x)
|
||||
{
|
||||
return (void*)glXGetProcAddress((const GLubyte*)x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern u32 s_stencilfunc, s_stencilref, s_stencilmask;
|
||||
// Defines
|
||||
|
||||
#ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils
|
||||
# define GL_DEPTH_STENCIL_EXT 0x84F9
|
||||
# define GL_UNSIGNED_INT_24_8_EXT 0x84FA
|
||||
# define GL_DEPTH24_STENCIL8_EXT 0x88F0
|
||||
# define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
|
||||
#endif
|
||||
|
||||
#define GL_STENCILFUNC(func, ref, mask) { \
|
||||
s_stencilfunc = func; \
|
||||
s_stencilref = ref; \
|
||||
s_stencilmask = mask; \
|
||||
glStencilFunc(func, ref, mask); \
|
||||
}
|
||||
|
||||
#define GL_STENCILFUNC_SET() glStencilFunc(s_stencilfunc, s_stencilref, s_stencilmask)
|
||||
|
||||
|
||||
// sets the data stream
|
||||
#define SET_STREAM() { \
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)8); \
|
||||
glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)12); \
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(VertexGPU), (void*)16); \
|
||||
glVertexPointer(4, GL_SHORT, sizeof(VertexGPU), (void*)0); \
|
||||
}
|
||||
|
||||
|
||||
// global alpha blending settings
|
||||
extern GLenum g_internalRGBAFloat16Fmt;
|
||||
|
||||
#define SAFE_RELEASE_TEX(x) { if( (x) != 0 ) { glDeleteTextures(1, &(x)); x = 0; } }
|
||||
|
||||
// inline for an extremely often used sequence
|
||||
// This is turning off all gl functions. Safe to do updates.
|
||||
inline void DisableAllgl()
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(0);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
//--------------------- Dummies
|
||||
|
||||
#ifdef _WIN32
|
||||
extern void (__stdcall *zgsBlendEquationSeparateEXT)(GLenum, GLenum);
|
||||
extern void (__stdcall *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum);
|
||||
#else
|
||||
extern void (APIENTRY *zgsBlendEquationSeparateEXT)(GLenum, GLenum);
|
||||
extern void (APIENTRY *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum);
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------ Types -------------------------
|
||||
|
||||
/////////////////////
|
||||
// graphics resources
|
||||
extern GLenum s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha; // set by zgsBlendFuncSeparateEXT
|
||||
|
||||
// GL prototypes
|
||||
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
|
||||
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
|
||||
extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
|
||||
extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
|
||||
extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
|
||||
extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT;
|
||||
extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT;
|
||||
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
|
||||
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
|
||||
extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
|
||||
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
|
||||
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
||||
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
||||
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
||||
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||
|
||||
#endif // ZZGL_H_INCLUDED
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef ZZHACKS_H_INCLUDED
|
||||
#define ZZHACKS_H_INCLUDED
|
||||
#ifndef ZZHACKS_H_INCLUDED
|
||||
#define ZZHACKS_H_INCLUDED
|
||||
|
||||
#include "PS2Edefs.h"
|
||||
|
||||
|
@ -42,7 +42,7 @@ enum GAME_HACK_OPTIONS
|
|||
GAME_RESERVED_HACK = 0x80000000
|
||||
};
|
||||
|
||||
#define USEALPHATESTING (!(conf.settings().no_alpha_test))
|
||||
#define USEALPHATESTING (!(conf.settings().no_alpha_test))
|
||||
|
||||
typedef union
|
||||
{
|
||||
|
@ -95,5 +95,5 @@ extern void ListHacks();
|
|||
|
||||
extern void DisplayHack(int hack);
|
||||
extern void ChangeCurrentHack(int hack);
|
||||
|
||||
#endif // ZZHACKS_H_INCLUDED
|
||||
|
||||
#endif // ZZHACKS_H_INCLUDED
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* To avoid severals combo-box, the hack detects the game based on crc
|
||||
*/
|
||||
|
||||
#ifndef ZZOGL_FLUSH_HACK_H_INCLUDED
|
||||
#ifndef ZZOGL_FLUSH_HACK_H_INCLUDED
|
||||
#define ZZOGL_FLUSH_HACK_H_INCLUDED
|
||||
|
||||
#include "GS.h"
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
// Zerogs:VB implementation.
|
||||
// VB stands for Visual Buffer, as I think
|
||||
|
||||
#ifndef ZZOGLVB_H_INCLUDED
|
||||
#define ZZOGLVB_H_INCLUDED
|
||||
#ifndef ZZOGLVB_H_INCLUDED
|
||||
#define ZZOGLVB_H_INCLUDED
|
||||
|
||||
#include "targets.h"
|
||||
|
||||
|
@ -150,9 +150,9 @@ class VB
|
|||
CRenderTarget* prndr;
|
||||
CDepthTarget* pdepth;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// VB variables
|
||||
extern VB vb[2];
|
||||
|
||||
#endif // ZZOGLVB_H_INCLUDED
|
||||
|
||||
#endif // ZZOGLVB_H_INCLUDED
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
ZeroGSShaders.exe ps2hw.fx ps2hw.dat
|
||||
del Win32\ps2hw.dat Win32\Release\*.res Win32\Debug\*.res
|
||||
ZeroGSShaders.exe ps2hw.fx ps2hw.dat
|
||||
del Win32\ps2hw.dat Win32\Release\*.res Win32\Debug\*.res
|
||||
move /y ps2hw.dat Win32\ps2hw.dat
|
|
@ -1,24 +1,24 @@
|
|||
// main ps2 memory, each pixel is stored in 32bit color
|
||||
uniform samplerRECT g_sMemory : register(s0);
|
||||
|
||||
// per context pixel shader constants
|
||||
uniform half4 fTexAlpha2 : register(c2);
|
||||
|
||||
uniform float4 g_fTexOffset : register(c4); // converts the page and block offsets into the mem addr/1024
|
||||
uniform float4 g_fTexDims : register(c6); // mult by tex dims when accessing the block texture
|
||||
uniform float4 g_fTexBlock : register(c8);
|
||||
|
||||
uniform float4 g_fClampExts : register(c10); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
uniform float4 TexWrapMode : register(c12); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
uniform float4 g_fRealTexDims : register(c14); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
uniform half4 g_fTestBlack : register(c16); // used for aem bit
|
||||
|
||||
uniform float4 g_fPageOffset : register(c18);
|
||||
|
||||
uniform half4 fTexAlpha : register(c20);
|
||||
|
||||
// vertex shader constants
|
||||
// main ps2 memory, each pixel is stored in 32bit color
|
||||
uniform samplerRECT g_sMemory : register(s0);
|
||||
|
||||
// per context pixel shader constants
|
||||
uniform half4 fTexAlpha2 : register(c2);
|
||||
|
||||
uniform float4 g_fTexOffset : register(c4); // converts the page and block offsets into the mem addr/1024
|
||||
uniform float4 g_fTexDims : register(c6); // mult by tex dims when accessing the block texture
|
||||
uniform float4 g_fTexBlock : register(c8);
|
||||
|
||||
uniform float4 g_fClampExts : register(c10); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
uniform float4 TexWrapMode : register(c12); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
uniform float4 g_fRealTexDims : register(c14); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
uniform half4 g_fTestBlack : register(c16); // used for aem bit
|
||||
|
||||
uniform float4 g_fPageOffset : register(c18);
|
||||
|
||||
uniform half4 fTexAlpha : register(c20);
|
||||
|
||||
// vertex shader constants
|
||||
uniform float4 g_fPosXY : register(c2);
|
|
@ -1,23 +1,23 @@
|
|||
uniform samplerRECT g_sMemory : register(s1);
|
||||
|
||||
// per context pixel shader constants
|
||||
uniform half4 fTexAlpha2 : register(c3);
|
||||
|
||||
uniform float4 g_fTexOffset : register(c5); // converts the page and block offsets into the mem addr/1024
|
||||
uniform float4 g_fTexDims : register(c7); // mult by tex dims when accessing the block texture
|
||||
uniform float4 g_fTexBlock : register(c9);
|
||||
|
||||
uniform float4 g_fClampExts : register(c11); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
uniform float4 TexWrapMode : register(c13); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
uniform float4 g_fRealTexDims : register(c15); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
uniform half4 g_fTestBlack : register(c17); // used for aem bit
|
||||
|
||||
uniform float4 g_fPageOffset : register(c19);
|
||||
|
||||
uniform half4 fTexAlpha : register(c21);
|
||||
|
||||
// vertex shader constants
|
||||
uniform samplerRECT g_sMemory : register(s1);
|
||||
|
||||
// per context pixel shader constants
|
||||
uniform half4 fTexAlpha2 : register(c3);
|
||||
|
||||
uniform float4 g_fTexOffset : register(c5); // converts the page and block offsets into the mem addr/1024
|
||||
uniform float4 g_fTexDims : register(c7); // mult by tex dims when accessing the block texture
|
||||
uniform float4 g_fTexBlock : register(c9);
|
||||
|
||||
uniform float4 g_fClampExts : register(c11); // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||
uniform float4 TexWrapMode : register(c13); // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||
|
||||
uniform float4 g_fRealTexDims : register(c15); // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||
|
||||
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||
uniform half4 g_fTestBlack : register(c17); // used for aem bit
|
||||
|
||||
uniform float4 g_fPageOffset : register(c19);
|
||||
|
||||
uniform half4 fTexAlpha : register(c21);
|
||||
|
||||
// vertex shader constants
|
||||
uniform float4 g_fPosXY : register(c3);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,450 +1,450 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using Specialized = System.Collections.Specialized;
|
||||
using Reflection = System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using GSDumpGUI.Properties;
|
||||
using System.IO;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
using System.Drawing;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
static public GSDumpGUI frmMain;
|
||||
static public TCPLibrary.MessageBased.Core.BaseMessageServer Server;
|
||||
static public List<TCPLibrary.MessageBased.Core.BaseMessageClientS> Clients;
|
||||
|
||||
static public TCPLibrary.MessageBased.Core.BaseMessageClient Client;
|
||||
static private Boolean ChangeIcon;
|
||||
static private GSDump dump;
|
||||
static private GSDXWrapper wrap;
|
||||
|
||||
static private TreeNode CurrentNode;
|
||||
|
||||
[STAThread]
|
||||
static void Main(String[] args)
|
||||
{
|
||||
if (args.Length == 4)
|
||||
{
|
||||
// do this first, else racy mess ;)
|
||||
wrap = new GSDXWrapper();
|
||||
|
||||
try
|
||||
{
|
||||
Client = new TCPLibrary.MessageBased.Core.BaseMessageClient();
|
||||
Client.OnMessageReceived += new TCPLibrary.MessageBased.Core.BaseMessageClient.MessageReceivedHandler(Client_OnMessageReceived);
|
||||
Client.Connect("localhost", 9999);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Client = null;
|
||||
}
|
||||
|
||||
Thread thd = new Thread(new ThreadStart(delegate
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
IntPtr pt = Process.GetCurrentProcess().MainWindowHandle;
|
||||
if (ChangeIcon)
|
||||
{
|
||||
if (pt.ToInt64() != 0)
|
||||
{
|
||||
NativeMethods.SetClassLong(pt, -14, Resources.AppIcon.Handle.ToInt64());
|
||||
ChangeIcon = false;
|
||||
}
|
||||
}
|
||||
|
||||
Int32 tmp = NativeMethods.GetAsyncKeyState(0x1b) & 0xf;
|
||||
if (tmp != 0)
|
||||
Process.GetCurrentProcess().Kill();
|
||||
Thread.Sleep(16);
|
||||
}
|
||||
}));
|
||||
thd.IsBackground = true;
|
||||
thd.Start();
|
||||
|
||||
// Retrieve parameters
|
||||
String DLLPath = args[0];
|
||||
String DumpPath = args[1];
|
||||
String Operation = args[2];
|
||||
Int32 Renderer = Convert.ToInt32(args[3]);
|
||||
|
||||
wrap.Load(DLLPath);
|
||||
Directory.SetCurrentDirectory(Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + Path.GetFileName(DLLPath) + "\\"));
|
||||
if (Operation == "GSReplay")
|
||||
{
|
||||
dump = GSDump.LoadDump(DumpPath);
|
||||
|
||||
if (Client != null)
|
||||
{
|
||||
SendStatistics();
|
||||
SendDumpSize();
|
||||
}
|
||||
|
||||
wrap.Run(dump, Renderer);
|
||||
ChangeIcon = true;
|
||||
}
|
||||
else
|
||||
wrap.GSConfig();
|
||||
wrap.Unload();
|
||||
|
||||
if (GSDXWrapper.DumpTooOld)
|
||||
{
|
||||
if (Client != null)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.StateOld;
|
||||
Client.Send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (Client != null)
|
||||
Client.Disconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
Clients = new List<TCPLibrary.MessageBased.Core.BaseMessageClientS>();
|
||||
|
||||
Server = new TCPLibrary.MessageBased.Core.BaseMessageServer();
|
||||
Server.OnClientMessageReceived += new BaseMessageServer.MessageReceivedHandler(Server_OnClientMessageReceived);
|
||||
Server.OnClientAfterConnect += new TCPLibrary.Core.Server.ConnectedHandler(Server_OnClientAfterConnect);
|
||||
Server.OnClientAfterDisconnected += new TCPLibrary.Core.Server.DisconnectedHandler(Server_OnClientAfterDisconnected);
|
||||
Server.Port = 9999;
|
||||
Server.Enabled = true;
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
frmMain = new GSDumpGUI();
|
||||
Application.Run(frmMain);
|
||||
|
||||
Server.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void Server_OnClientAfterDisconnected(TCPLibrary.Core.Server server, TCPLibrary.Core.ClientS sender)
|
||||
{
|
||||
Clients.Remove((TCPLibrary.MessageBased.Core.BaseMessageClientS)sender);
|
||||
RefreshList(false);
|
||||
}
|
||||
|
||||
static void Server_OnClientMessageReceived(BaseMessageServer server, BaseMessageClientS sender, TCPMessage Mess)
|
||||
{
|
||||
switch (Mess.MessageType)
|
||||
{
|
||||
case MessageType.Connect:
|
||||
break;
|
||||
case MessageType.MaxUsers:
|
||||
break;
|
||||
case MessageType.SizeDump:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
frmMain.txtDumpSize.Text = (((int)Mess.Parameters[0]) / 1024f / 1024f).ToString("F2") + " MB";
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.Statistics:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
frmMain.txtGIFPackets.Text = ((int)Mess.Parameters[0]).ToString();
|
||||
frmMain.txtPath1.Text = ((int)Mess.Parameters[1]).ToString();
|
||||
frmMain.txtPath2.Text = ((int)Mess.Parameters[2]).ToString();
|
||||
frmMain.txtPath3.Text = ((int)Mess.Parameters[3]).ToString();
|
||||
frmMain.txtReadFifo.Text = ((int)Mess.Parameters[5]).ToString();
|
||||
frmMain.txtVSync.Text = ((int)Mess.Parameters[4]).ToString();
|
||||
frmMain.txtRegisters.Text = ((int)Mess.Parameters[6]).ToString();
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.StateOld:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
MessageBox.Show("Savestate too old to be read. :(", "Warning");
|
||||
frmMain.Focus();
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.GetDebugMode:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
frmMain.chkDebugMode.Checked = (Boolean)Mess.Parameters[0];
|
||||
|
||||
frmMain.lblGif.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.btnRunToSelection.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.treTreeView.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.btnStep.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.cmdGoToStart.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.cmdGoToNextVSync.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.treeGifPacketContent.Enabled = frmMain.chkDebugMode.Checked;
|
||||
if (frmMain.chkDebugMode.Checked == false)
|
||||
frmMain.treTreeView.Nodes.Clear();
|
||||
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.DebugState:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
frmMain.treTreeView.Nodes.Clear();
|
||||
List<TreeNode> parents = new List<TreeNode>();
|
||||
List<TreeNode> nodes = new List<TreeNode>();
|
||||
foreach (var itm in Mess.Parameters)
|
||||
{
|
||||
String[] parts = itm.ToString().Split(new char[] { '|' });
|
||||
switch (parts[1])
|
||||
{
|
||||
case "Transfer":
|
||||
TreeNode tn2 = new TreeNode();
|
||||
tn2.Name = parts[0];
|
||||
tn2.Text = parts[0] + " - " + parts[1] + " - " + parts[2] + " - " + parts[3] + " byte";
|
||||
nodes.Add(tn2);
|
||||
break;
|
||||
case "ReadFIFO2":
|
||||
TreeNode tn3 = new TreeNode();
|
||||
tn3.Name = parts[0];
|
||||
tn3.Text = parts[0] + " - " + parts[1] + " - " + parts[2] + " byte";
|
||||
nodes.Add(tn3);
|
||||
break;
|
||||
case "VSync":
|
||||
TreeNode tn = new TreeNode();
|
||||
tn.Name = parts[0];
|
||||
tn.Text = parts[0] + " - " + parts[1] + " - " + parts[2] + " byte";
|
||||
tn.Nodes.AddRange(nodes.ToArray());
|
||||
parents.Add(tn);
|
||||
|
||||
nodes.Clear();
|
||||
break;
|
||||
case "Registers":
|
||||
TreeNode tn4 = new TreeNode();
|
||||
tn4.Name = parts[0];
|
||||
tn4.Text = parts[0] + " - " + parts[1] + " - " + parts[2] + " byte";
|
||||
nodes.Add(tn4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
frmMain.treTreeView.Nodes.AddRange(parents.ToArray());
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.Step:
|
||||
case MessageType.RunToCursor:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
int idtoselect = (int)Mess.Parameters[0];
|
||||
TreeNode[] noes = frmMain.treTreeView.Nodes.Find(idtoselect.ToString(), true);
|
||||
if (noes.Length > 0)
|
||||
{
|
||||
if (CurrentNode != null)
|
||||
CurrentNode.BackColor = Color.White;
|
||||
noes[0].BackColor = Color.LightBlue;
|
||||
CurrentNode = noes[0];
|
||||
frmMain.treTreeView.SelectedNode = noes[0];
|
||||
}
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.PacketInfo:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
if (Mess.Parameters[0].GetType() == typeof(GIFTag))
|
||||
{
|
||||
GIFTag tag = (GIFTag)Mess.Parameters[0];
|
||||
|
||||
frmMain.txtGifPacketSize.Text = tag.size + " bytes";
|
||||
frmMain.treeGifPacketContent.Nodes.Clear();
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes.Add("Transfer Path " + tag.path);
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("nloop = " + tag.nloop);
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("eop = " + tag.eop);
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("flg = " + tag.flg.ToString());
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("pre = " + tag.pre);
|
||||
|
||||
TreeNode nodePrim = new TreeNode("Prim");
|
||||
string[] prim = tag.prim.ToString().Split(new char[] { '@' });
|
||||
for (int j = 0; j < prim.Length; j++)
|
||||
nodePrim.Nodes.Add(prim[j]);
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add(nodePrim);
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("nreg = " + (tag.nreg == 0 ? (16).ToString() : tag.nreg.ToString()));
|
||||
|
||||
TreeNode nodeReg = new TreeNode("reg");
|
||||
for (int j = 0; j < tag.regs.Count; j++)
|
||||
{
|
||||
string[] fvals = tag.regs[j].ToString().Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
TreeNode nodeObj = new TreeNode(fvals[0]);
|
||||
for (int z = 1; z < fvals.Length; z++)
|
||||
{
|
||||
TreeNode item = new TreeNode(fvals[z]);
|
||||
nodeObj.Nodes.Add(item);
|
||||
}
|
||||
nodeReg.Nodes.Add(nodeObj);
|
||||
}
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add(nodeReg);
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes[0].ExpandAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
String[] vals = Mess.Parameters[0].ToString().Split('|');
|
||||
frmMain.txtGifPacketSize.Text = vals[0] + " bytes";
|
||||
frmMain.treeGifPacketContent.Nodes.Clear();
|
||||
frmMain.treeGifPacketContent.Nodes.Add(vals[1]);
|
||||
frmMain.treeGifPacketContent.Nodes[0].ExpandAll();
|
||||
}
|
||||
}), new object[] { null });
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void Client_OnMessageReceived(TCPLibrary.Core.Client sender, TCPLibrary.MessageBased.Core.TCPMessage Mess)
|
||||
{
|
||||
TCPMessage msg;
|
||||
switch (Mess.MessageType)
|
||||
{
|
||||
case TCPLibrary.MessageBased.Core.MessageType.Connect:
|
||||
break;
|
||||
case TCPLibrary.MessageBased.Core.MessageType.MaxUsers:
|
||||
break;
|
||||
case TCPLibrary.MessageBased.Core.MessageType.SizeDump:
|
||||
SendDumpSize();
|
||||
break;
|
||||
case MessageType.Statistics:
|
||||
SendStatistics();
|
||||
break;
|
||||
case MessageType.SetDebugMode:
|
||||
wrap.DebugMode = (Boolean)Mess.Parameters[0];
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.GetDebugMode;
|
||||
msg.Parameters.Add(wrap.DebugMode);
|
||||
Client.Send(msg);
|
||||
|
||||
if (wrap.DebugMode)
|
||||
{
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.DebugState;
|
||||
msg.Parameters.AddRange(wrap.GetGifPackets(dump));
|
||||
Client.Send(msg);
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Step;
|
||||
msg.Parameters.Add(dump.Data.FindIndex(a => a == wrap.CurrentGIFPacket));
|
||||
Client.Send(msg);
|
||||
}
|
||||
break;
|
||||
case MessageType.GetDebugMode:
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.GetDebugMode;
|
||||
msg.Parameters.Add(wrap.DebugMode);
|
||||
Client.Send(msg);
|
||||
|
||||
if (wrap.DebugMode)
|
||||
{
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.DebugState;
|
||||
msg.Parameters.AddRange(wrap.GetGifPackets(dump));
|
||||
Client.Send(msg);
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Step;
|
||||
msg.Parameters.Add(dump.Data.FindIndex(a => a == wrap.CurrentGIFPacket));
|
||||
Client.Send(msg);
|
||||
}
|
||||
break;
|
||||
|
||||
case MessageType.PacketInfo:
|
||||
int id = (int)Mess.Parameters[0];
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.PacketInfo;
|
||||
msg.Parameters.Add(wrap.GetGifPacketInfo(dump, id));
|
||||
Client.Send(msg);
|
||||
break;
|
||||
case MessageType.Step:
|
||||
case MessageType.RunToCursor:
|
||||
case MessageType.RunToNextVSync:
|
||||
wrap.ExternalEvent.WaitOne();
|
||||
wrap.ExternalEvent.Reset();
|
||||
wrap.QueueMessage.Enqueue(Mess);
|
||||
wrap.ThereIsWork = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendDumpSize()
|
||||
{
|
||||
TCPMessage msg;
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.SizeDump;
|
||||
if (dump != null)
|
||||
msg.Parameters.Add(dump.Size);
|
||||
else
|
||||
msg.Parameters.Add(0);
|
||||
Client.Send(msg);
|
||||
}
|
||||
|
||||
private static void SendStatistics()
|
||||
{
|
||||
TCPMessage msg;
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Statistics;
|
||||
if (dump != null)
|
||||
{
|
||||
msg.Parameters.Add(dump.Data.Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 0 && (a.data[0] == 3 || a.data[0] == 0)).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 0 && a.data[0] == 1).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 0 && a.data[0] == 2).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 1).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 2).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 3).Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
}
|
||||
Client.Send(msg);
|
||||
}
|
||||
|
||||
static void Server_OnClientAfterConnect(TCPLibrary.Core.Server server, TCPLibrary.Core.ClientS sender)
|
||||
{
|
||||
Clients.Add((TCPLibrary.MessageBased.Core.BaseMessageClientS)sender);
|
||||
RefreshList(true);
|
||||
}
|
||||
|
||||
private static void RefreshList(bool SelectLast)
|
||||
{
|
||||
frmMain.Invoke(new Action<object>( delegate(object e)
|
||||
{
|
||||
frmMain.lstProcesses.Items.Clear();
|
||||
|
||||
foreach (var itm in Clients)
|
||||
{
|
||||
frmMain.lstProcesses.Items.Add(itm.IPAddress);
|
||||
}
|
||||
if (SelectLast)
|
||||
frmMain.lstProcesses.SelectedIndex = frmMain.lstProcesses.Items.Count - 1;
|
||||
if (frmMain.lstProcesses.SelectedIndex == -1)
|
||||
{
|
||||
frmMain.chkDebugMode.Checked = false;
|
||||
frmMain.lblGif.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.btnRunToSelection.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.treTreeView.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.btnStep.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.cmdGoToStart.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.cmdGoToNextVSync.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.treTreeView.Nodes.Clear();
|
||||
frmMain.treeGifPacketContent.Nodes.Clear();
|
||||
}
|
||||
}), new object[] { null});
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using Specialized = System.Collections.Specialized;
|
||||
using Reflection = System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using GSDumpGUI.Properties;
|
||||
using System.IO;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
using System.Drawing;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
static public GSDumpGUI frmMain;
|
||||
static public TCPLibrary.MessageBased.Core.BaseMessageServer Server;
|
||||
static public List<TCPLibrary.MessageBased.Core.BaseMessageClientS> Clients;
|
||||
|
||||
static public TCPLibrary.MessageBased.Core.BaseMessageClient Client;
|
||||
static private Boolean ChangeIcon;
|
||||
static private GSDump dump;
|
||||
static private GSDXWrapper wrap;
|
||||
|
||||
static private TreeNode CurrentNode;
|
||||
|
||||
[STAThread]
|
||||
static void Main(String[] args)
|
||||
{
|
||||
if (args.Length == 4)
|
||||
{
|
||||
// do this first, else racy mess ;)
|
||||
wrap = new GSDXWrapper();
|
||||
|
||||
try
|
||||
{
|
||||
Client = new TCPLibrary.MessageBased.Core.BaseMessageClient();
|
||||
Client.OnMessageReceived += new TCPLibrary.MessageBased.Core.BaseMessageClient.MessageReceivedHandler(Client_OnMessageReceived);
|
||||
Client.Connect("localhost", 9999);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Client = null;
|
||||
}
|
||||
|
||||
Thread thd = new Thread(new ThreadStart(delegate
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
IntPtr pt = Process.GetCurrentProcess().MainWindowHandle;
|
||||
if (ChangeIcon)
|
||||
{
|
||||
if (pt.ToInt64() != 0)
|
||||
{
|
||||
NativeMethods.SetClassLong(pt, -14, Resources.AppIcon.Handle.ToInt64());
|
||||
ChangeIcon = false;
|
||||
}
|
||||
}
|
||||
|
||||
Int32 tmp = NativeMethods.GetAsyncKeyState(0x1b) & 0xf;
|
||||
if (tmp != 0)
|
||||
Process.GetCurrentProcess().Kill();
|
||||
Thread.Sleep(16);
|
||||
}
|
||||
}));
|
||||
thd.IsBackground = true;
|
||||
thd.Start();
|
||||
|
||||
// Retrieve parameters
|
||||
String DLLPath = args[0];
|
||||
String DumpPath = args[1];
|
||||
String Operation = args[2];
|
||||
Int32 Renderer = Convert.ToInt32(args[3]);
|
||||
|
||||
wrap.Load(DLLPath);
|
||||
Directory.SetCurrentDirectory(Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + Path.GetFileName(DLLPath) + "\\"));
|
||||
if (Operation == "GSReplay")
|
||||
{
|
||||
dump = GSDump.LoadDump(DumpPath);
|
||||
|
||||
if (Client != null)
|
||||
{
|
||||
SendStatistics();
|
||||
SendDumpSize();
|
||||
}
|
||||
|
||||
wrap.Run(dump, Renderer);
|
||||
ChangeIcon = true;
|
||||
}
|
||||
else
|
||||
wrap.GSConfig();
|
||||
wrap.Unload();
|
||||
|
||||
if (GSDXWrapper.DumpTooOld)
|
||||
{
|
||||
if (Client != null)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.StateOld;
|
||||
Client.Send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (Client != null)
|
||||
Client.Disconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
Clients = new List<TCPLibrary.MessageBased.Core.BaseMessageClientS>();
|
||||
|
||||
Server = new TCPLibrary.MessageBased.Core.BaseMessageServer();
|
||||
Server.OnClientMessageReceived += new BaseMessageServer.MessageReceivedHandler(Server_OnClientMessageReceived);
|
||||
Server.OnClientAfterConnect += new TCPLibrary.Core.Server.ConnectedHandler(Server_OnClientAfterConnect);
|
||||
Server.OnClientAfterDisconnected += new TCPLibrary.Core.Server.DisconnectedHandler(Server_OnClientAfterDisconnected);
|
||||
Server.Port = 9999;
|
||||
Server.Enabled = true;
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
frmMain = new GSDumpGUI();
|
||||
Application.Run(frmMain);
|
||||
|
||||
Server.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void Server_OnClientAfterDisconnected(TCPLibrary.Core.Server server, TCPLibrary.Core.ClientS sender)
|
||||
{
|
||||
Clients.Remove((TCPLibrary.MessageBased.Core.BaseMessageClientS)sender);
|
||||
RefreshList(false);
|
||||
}
|
||||
|
||||
static void Server_OnClientMessageReceived(BaseMessageServer server, BaseMessageClientS sender, TCPMessage Mess)
|
||||
{
|
||||
switch (Mess.MessageType)
|
||||
{
|
||||
case MessageType.Connect:
|
||||
break;
|
||||
case MessageType.MaxUsers:
|
||||
break;
|
||||
case MessageType.SizeDump:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
frmMain.txtDumpSize.Text = (((int)Mess.Parameters[0]) / 1024f / 1024f).ToString("F2") + " MB";
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.Statistics:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
frmMain.txtGIFPackets.Text = ((int)Mess.Parameters[0]).ToString();
|
||||
frmMain.txtPath1.Text = ((int)Mess.Parameters[1]).ToString();
|
||||
frmMain.txtPath2.Text = ((int)Mess.Parameters[2]).ToString();
|
||||
frmMain.txtPath3.Text = ((int)Mess.Parameters[3]).ToString();
|
||||
frmMain.txtReadFifo.Text = ((int)Mess.Parameters[5]).ToString();
|
||||
frmMain.txtVSync.Text = ((int)Mess.Parameters[4]).ToString();
|
||||
frmMain.txtRegisters.Text = ((int)Mess.Parameters[6]).ToString();
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.StateOld:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
MessageBox.Show("Savestate too old to be read. :(", "Warning");
|
||||
frmMain.Focus();
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.GetDebugMode:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
frmMain.chkDebugMode.Checked = (Boolean)Mess.Parameters[0];
|
||||
|
||||
frmMain.lblGif.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.btnRunToSelection.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.treTreeView.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.btnStep.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.cmdGoToStart.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.cmdGoToNextVSync.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.treeGifPacketContent.Enabled = frmMain.chkDebugMode.Checked;
|
||||
if (frmMain.chkDebugMode.Checked == false)
|
||||
frmMain.treTreeView.Nodes.Clear();
|
||||
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.DebugState:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
frmMain.treTreeView.Nodes.Clear();
|
||||
List<TreeNode> parents = new List<TreeNode>();
|
||||
List<TreeNode> nodes = new List<TreeNode>();
|
||||
foreach (var itm in Mess.Parameters)
|
||||
{
|
||||
String[] parts = itm.ToString().Split(new char[] { '|' });
|
||||
switch (parts[1])
|
||||
{
|
||||
case "Transfer":
|
||||
TreeNode tn2 = new TreeNode();
|
||||
tn2.Name = parts[0];
|
||||
tn2.Text = parts[0] + " - " + parts[1] + " - " + parts[2] + " - " + parts[3] + " byte";
|
||||
nodes.Add(tn2);
|
||||
break;
|
||||
case "ReadFIFO2":
|
||||
TreeNode tn3 = new TreeNode();
|
||||
tn3.Name = parts[0];
|
||||
tn3.Text = parts[0] + " - " + parts[1] + " - " + parts[2] + " byte";
|
||||
nodes.Add(tn3);
|
||||
break;
|
||||
case "VSync":
|
||||
TreeNode tn = new TreeNode();
|
||||
tn.Name = parts[0];
|
||||
tn.Text = parts[0] + " - " + parts[1] + " - " + parts[2] + " byte";
|
||||
tn.Nodes.AddRange(nodes.ToArray());
|
||||
parents.Add(tn);
|
||||
|
||||
nodes.Clear();
|
||||
break;
|
||||
case "Registers":
|
||||
TreeNode tn4 = new TreeNode();
|
||||
tn4.Name = parts[0];
|
||||
tn4.Text = parts[0] + " - " + parts[1] + " - " + parts[2] + " byte";
|
||||
nodes.Add(tn4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
frmMain.treTreeView.Nodes.AddRange(parents.ToArray());
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.Step:
|
||||
case MessageType.RunToCursor:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
int idtoselect = (int)Mess.Parameters[0];
|
||||
TreeNode[] noes = frmMain.treTreeView.Nodes.Find(idtoselect.ToString(), true);
|
||||
if (noes.Length > 0)
|
||||
{
|
||||
if (CurrentNode != null)
|
||||
CurrentNode.BackColor = Color.White;
|
||||
noes[0].BackColor = Color.LightBlue;
|
||||
CurrentNode = noes[0];
|
||||
frmMain.treTreeView.SelectedNode = noes[0];
|
||||
}
|
||||
}), new object[] { null });
|
||||
break;
|
||||
case MessageType.PacketInfo:
|
||||
frmMain.Invoke(new Action<object>(delegate(object e)
|
||||
{
|
||||
if (Mess.Parameters[0].GetType() == typeof(GIFTag))
|
||||
{
|
||||
GIFTag tag = (GIFTag)Mess.Parameters[0];
|
||||
|
||||
frmMain.txtGifPacketSize.Text = tag.size + " bytes";
|
||||
frmMain.treeGifPacketContent.Nodes.Clear();
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes.Add("Transfer Path " + tag.path);
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("nloop = " + tag.nloop);
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("eop = " + tag.eop);
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("flg = " + tag.flg.ToString());
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("pre = " + tag.pre);
|
||||
|
||||
TreeNode nodePrim = new TreeNode("Prim");
|
||||
string[] prim = tag.prim.ToString().Split(new char[] { '@' });
|
||||
for (int j = 0; j < prim.Length; j++)
|
||||
nodePrim.Nodes.Add(prim[j]);
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add(nodePrim);
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add("nreg = " + (tag.nreg == 0 ? (16).ToString() : tag.nreg.ToString()));
|
||||
|
||||
TreeNode nodeReg = new TreeNode("reg");
|
||||
for (int j = 0; j < tag.regs.Count; j++)
|
||||
{
|
||||
string[] fvals = tag.regs[j].ToString().Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
TreeNode nodeObj = new TreeNode(fvals[0]);
|
||||
for (int z = 1; z < fvals.Length; z++)
|
||||
{
|
||||
TreeNode item = new TreeNode(fvals[z]);
|
||||
nodeObj.Nodes.Add(item);
|
||||
}
|
||||
nodeReg.Nodes.Add(nodeObj);
|
||||
}
|
||||
frmMain.treeGifPacketContent.Nodes[0].Nodes.Add(nodeReg);
|
||||
|
||||
frmMain.treeGifPacketContent.Nodes[0].ExpandAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
String[] vals = Mess.Parameters[0].ToString().Split('|');
|
||||
frmMain.txtGifPacketSize.Text = vals[0] + " bytes";
|
||||
frmMain.treeGifPacketContent.Nodes.Clear();
|
||||
frmMain.treeGifPacketContent.Nodes.Add(vals[1]);
|
||||
frmMain.treeGifPacketContent.Nodes[0].ExpandAll();
|
||||
}
|
||||
}), new object[] { null });
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void Client_OnMessageReceived(TCPLibrary.Core.Client sender, TCPLibrary.MessageBased.Core.TCPMessage Mess)
|
||||
{
|
||||
TCPMessage msg;
|
||||
switch (Mess.MessageType)
|
||||
{
|
||||
case TCPLibrary.MessageBased.Core.MessageType.Connect:
|
||||
break;
|
||||
case TCPLibrary.MessageBased.Core.MessageType.MaxUsers:
|
||||
break;
|
||||
case TCPLibrary.MessageBased.Core.MessageType.SizeDump:
|
||||
SendDumpSize();
|
||||
break;
|
||||
case MessageType.Statistics:
|
||||
SendStatistics();
|
||||
break;
|
||||
case MessageType.SetDebugMode:
|
||||
wrap.DebugMode = (Boolean)Mess.Parameters[0];
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.GetDebugMode;
|
||||
msg.Parameters.Add(wrap.DebugMode);
|
||||
Client.Send(msg);
|
||||
|
||||
if (wrap.DebugMode)
|
||||
{
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.DebugState;
|
||||
msg.Parameters.AddRange(wrap.GetGifPackets(dump));
|
||||
Client.Send(msg);
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Step;
|
||||
msg.Parameters.Add(dump.Data.FindIndex(a => a == wrap.CurrentGIFPacket));
|
||||
Client.Send(msg);
|
||||
}
|
||||
break;
|
||||
case MessageType.GetDebugMode:
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.GetDebugMode;
|
||||
msg.Parameters.Add(wrap.DebugMode);
|
||||
Client.Send(msg);
|
||||
|
||||
if (wrap.DebugMode)
|
||||
{
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.DebugState;
|
||||
msg.Parameters.AddRange(wrap.GetGifPackets(dump));
|
||||
Client.Send(msg);
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Step;
|
||||
msg.Parameters.Add(dump.Data.FindIndex(a => a == wrap.CurrentGIFPacket));
|
||||
Client.Send(msg);
|
||||
}
|
||||
break;
|
||||
|
||||
case MessageType.PacketInfo:
|
||||
int id = (int)Mess.Parameters[0];
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.PacketInfo;
|
||||
msg.Parameters.Add(wrap.GetGifPacketInfo(dump, id));
|
||||
Client.Send(msg);
|
||||
break;
|
||||
case MessageType.Step:
|
||||
case MessageType.RunToCursor:
|
||||
case MessageType.RunToNextVSync:
|
||||
wrap.ExternalEvent.WaitOne();
|
||||
wrap.ExternalEvent.Reset();
|
||||
wrap.QueueMessage.Enqueue(Mess);
|
||||
wrap.ThereIsWork = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendDumpSize()
|
||||
{
|
||||
TCPMessage msg;
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.SizeDump;
|
||||
if (dump != null)
|
||||
msg.Parameters.Add(dump.Size);
|
||||
else
|
||||
msg.Parameters.Add(0);
|
||||
Client.Send(msg);
|
||||
}
|
||||
|
||||
private static void SendStatistics()
|
||||
{
|
||||
TCPMessage msg;
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Statistics;
|
||||
if (dump != null)
|
||||
{
|
||||
msg.Parameters.Add(dump.Data.Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 0 && (a.data[0] == 3 || a.data[0] == 0)).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 0 && a.data[0] == 1).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 0 && a.data[0] == 2).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 1).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 2).Count);
|
||||
msg.Parameters.Add(dump.Data.FindAll(a => (int)a.id == 3).Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
msg.Parameters.Add(0);
|
||||
}
|
||||
Client.Send(msg);
|
||||
}
|
||||
|
||||
static void Server_OnClientAfterConnect(TCPLibrary.Core.Server server, TCPLibrary.Core.ClientS sender)
|
||||
{
|
||||
Clients.Add((TCPLibrary.MessageBased.Core.BaseMessageClientS)sender);
|
||||
RefreshList(true);
|
||||
}
|
||||
|
||||
private static void RefreshList(bool SelectLast)
|
||||
{
|
||||
frmMain.Invoke(new Action<object>( delegate(object e)
|
||||
{
|
||||
frmMain.lstProcesses.Items.Clear();
|
||||
|
||||
foreach (var itm in Clients)
|
||||
{
|
||||
frmMain.lstProcesses.Items.Add(itm.IPAddress);
|
||||
}
|
||||
if (SelectLast)
|
||||
frmMain.lstProcesses.SelectedIndex = frmMain.lstProcesses.Items.Count - 1;
|
||||
if (frmMain.lstProcesses.SelectedIndex == -1)
|
||||
{
|
||||
frmMain.chkDebugMode.Checked = false;
|
||||
frmMain.lblGif.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.btnRunToSelection.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.treTreeView.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.btnStep.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.cmdGoToStart.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.cmdGoToNextVSync.Enabled = frmMain.chkDebugMode.Checked;
|
||||
frmMain.treTreeView.Nodes.Clear();
|
||||
frmMain.treeGifPacketContent.Nodes.Clear();
|
||||
}
|
||||
}), new object[] { null});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,444 +1,444 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Security;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public partial class GSDumpGUI : Form
|
||||
{
|
||||
public List<Process> Processes;
|
||||
|
||||
private Int32 _selected;
|
||||
public Int32 SelectedRad
|
||||
{
|
||||
get { return _selected; }
|
||||
set
|
||||
{
|
||||
if (value > 4)
|
||||
value = 0;
|
||||
_selected = value;
|
||||
switch (_selected)
|
||||
{
|
||||
case 0:
|
||||
rdaNone.Checked = true;
|
||||
break;
|
||||
case 1:
|
||||
rdaDX9HW.Checked = true;
|
||||
break;
|
||||
case 2:
|
||||
rdaDX10HW.Checked = true;
|
||||
break;
|
||||
case 3:
|
||||
rdaDX9SW.Checked = true;
|
||||
break;
|
||||
case 4:
|
||||
rdaDX10SW.Checked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap NoImage;
|
||||
|
||||
public GSDumpGUI()
|
||||
{
|
||||
InitializeComponent();
|
||||
Processes = new List<Process>();
|
||||
|
||||
NoImage = new Bitmap(320, 240, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
Graphics g = Graphics.FromImage(NoImage);
|
||||
g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, 320, 240));
|
||||
g.DrawString("No Image", new Font(FontFamily.GenericSansSerif, 48, FontStyle.Regular), new SolidBrush(Color.White), new PointF(0, 70));
|
||||
g.Dispose();
|
||||
}
|
||||
|
||||
public void ReloadGSDXs()
|
||||
{
|
||||
txtIntLog.Text += "Starting GSDX Loading Procedures" + Environment.NewLine + Environment.NewLine;
|
||||
|
||||
txtGSDXDirectory.Text = Properties.Settings.Default.GSDXDir;
|
||||
txtDumpsDirectory.Text = Properties.Settings.Default.DumpDir;
|
||||
|
||||
lstGSDX.Items.Clear();
|
||||
lstDumps.Items.Clear();
|
||||
|
||||
if (Directory.Exists(txtGSDXDirectory.Text))
|
||||
{
|
||||
String[] File = Directory.GetFiles(txtGSDXDirectory.Text, "*.dll", SearchOption.TopDirectoryOnly);
|
||||
|
||||
GSDXWrapper wrap = new GSDXWrapper();
|
||||
foreach (var itm in File)
|
||||
{
|
||||
try
|
||||
{
|
||||
wrap.Load(itm);
|
||||
|
||||
lstGSDX.Items.Add(Path.GetFileName(itm) + " | " + wrap.PSEGetLibName());
|
||||
txtIntLog.Text += "\"" + itm + "\" correctly identified as " + wrap.PSEGetLibName() + Environment.NewLine;
|
||||
|
||||
wrap.Unload();
|
||||
}
|
||||
catch (InvalidGSPlugin)
|
||||
{
|
||||
txtIntLog.Text += "Failed to load \"" + itm + "\". Is it really a GSDX DLL?" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
txtIntLog.Text += Environment.NewLine + "Completed GSDX Loading Procedures" + Environment.NewLine + Environment.NewLine;
|
||||
|
||||
txtIntLog.Text += "Starting GSDX Dumps Loading Procedures : " + Environment.NewLine + Environment.NewLine;
|
||||
if (Directory.Exists(txtDumpsDirectory.Text))
|
||||
{
|
||||
String[] Dumps = Directory.GetFiles(txtDumpsDirectory.Text, "*.gs", SearchOption.TopDirectoryOnly);
|
||||
|
||||
foreach (var itm in Dumps)
|
||||
{
|
||||
BinaryReader br = new BinaryReader(System.IO.File.Open(itm, FileMode.Open));
|
||||
Int32 CRC = br.ReadInt32();
|
||||
br.Close();
|
||||
lstDumps.Items.Add(Path.GetFileName(itm) + " | CRC : " + CRC.ToString("X"));
|
||||
txtIntLog.Text += "Identified Dump for game (" + CRC.ToString("X") + ") with filename \"" + itm + "\"" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
txtIntLog.Text += Environment.NewLine + "Completed GSDX Dumps Loading Procedures : " + Environment.NewLine + Environment.NewLine;
|
||||
txtIntLog.SelectionStart = txtIntLog.TextLength;
|
||||
txtIntLog.ScrollToCaret();
|
||||
}
|
||||
|
||||
private void GSDumpGUI_Load(object sender, EventArgs e)
|
||||
{
|
||||
ReloadGSDXs();
|
||||
lstDumps.Focus();
|
||||
if (lstDumps.Items.Count > 0)
|
||||
lstDumps.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void cmdBrowseGSDX_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderBrowserDialog fbd = new FolderBrowserDialog();
|
||||
fbd.Description = "Select the GSDX DLL Directory";
|
||||
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||
if (fbd.ShowDialog() == DialogResult.OK)
|
||||
txtGSDXDirectory.Text = fbd.SelectedPath;
|
||||
SaveConfig();
|
||||
ReloadGSDXs();
|
||||
}
|
||||
|
||||
private void cmdBrowseDumps_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderBrowserDialog fbd = new FolderBrowserDialog();
|
||||
fbd.Description = "Select the GSDX Dumps Directory";
|
||||
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||
if (fbd.ShowDialog() == DialogResult.OK)
|
||||
txtDumpsDirectory.Text = fbd.SelectedPath;
|
||||
SaveConfig();
|
||||
ReloadGSDXs();
|
||||
}
|
||||
|
||||
private void cmdStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Execute the GSReplay function
|
||||
if (lstDumps.SelectedIndex != -1)
|
||||
{
|
||||
if (lstGSDX.SelectedIndex != -1)
|
||||
ExecuteFunction("GSReplay");
|
||||
else
|
||||
MessageBox.Show("Select your GSDX first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
else
|
||||
MessageBox.Show("Select your Dump first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void ExecuteFunction(String Function)
|
||||
{
|
||||
txtLog.Text = "";
|
||||
String GSDXName = lstGSDX.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
|
||||
CreateDirs(GSDXName);
|
||||
|
||||
// Set the Arguments to pass to the child
|
||||
String DLLPath = Properties.Settings.Default.GSDXDir + "\\" + GSDXName;
|
||||
String DumpPath = "";
|
||||
String SelectedRenderer = "";
|
||||
switch (SelectedRad)
|
||||
{
|
||||
case 0:
|
||||
SelectedRenderer = "-1";
|
||||
break;
|
||||
case 1:
|
||||
SelectedRenderer = "0";
|
||||
break;
|
||||
case 2:
|
||||
SelectedRenderer = "3";
|
||||
break;
|
||||
case 3:
|
||||
SelectedRenderer = "1";
|
||||
break;
|
||||
case 4:
|
||||
SelectedRenderer = "4";
|
||||
break;
|
||||
}
|
||||
if (SelectedRenderer != "-1")
|
||||
{
|
||||
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini"))
|
||||
{
|
||||
String ini = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini");
|
||||
int pos = ini.IndexOf("Renderer=", 0);
|
||||
if (pos != -1)
|
||||
{
|
||||
String newini = ini.Substring(0, pos + 9);
|
||||
newini += SelectedRenderer;
|
||||
newini += ini.Substring(pos + 10, ini.Length - pos - 10);
|
||||
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini", newini);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini", ini + Environment.NewLine + "Renderer=" + SelectedRenderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lstDumps.SelectedItem != null)
|
||||
DumpPath = Properties.Settings.Default.DumpDir + "\\" +
|
||||
lstDumps.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
|
||||
// Start the child and link the events.
|
||||
ProcessStartInfo psi = new ProcessStartInfo();
|
||||
psi.UseShellExecute = false;
|
||||
psi.RedirectStandardOutput = true;
|
||||
psi.RedirectStandardError = false;
|
||||
psi.CreateNoWindow = true;
|
||||
psi.FileName = AppDomain.CurrentDomain.BaseDirectory + "GsDumpGUI.exe";
|
||||
psi.Arguments = "\"" + DLLPath + "\"" + " \"" + DumpPath + "\"" + " \"" + Function + "\"" + " " + SelectedRenderer;
|
||||
Process p = Process.Start(psi);
|
||||
p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
|
||||
p.BeginOutputReadLine();
|
||||
p.Exited += new EventHandler(p_Exited);
|
||||
Processes.Add(p);
|
||||
}
|
||||
|
||||
private static void CreateDirs(String GSDXName)
|
||||
{
|
||||
// Create and set the config directory.
|
||||
String Dir = AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\";
|
||||
if (!Directory.Exists(Dir))
|
||||
{
|
||||
Directory.CreateDirectory(Dir);
|
||||
}
|
||||
Dir += GSDXName;
|
||||
if (!Directory.Exists(Dir))
|
||||
{
|
||||
Directory.CreateDirectory(Dir);
|
||||
}
|
||||
Dir += "\\Inis\\";
|
||||
if (!Directory.Exists(Dir))
|
||||
{
|
||||
Directory.CreateDirectory(Dir);
|
||||
File.Create(Dir + "\\gsdx.ini").Close();
|
||||
}
|
||||
Dir = AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName;
|
||||
Directory.SetCurrentDirectory(Dir);
|
||||
}
|
||||
|
||||
void p_Exited(object sender, EventArgs e)
|
||||
{
|
||||
// Remove the child if is closed
|
||||
Processes.Remove((Process)sender);
|
||||
}
|
||||
|
||||
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
// Write the log.
|
||||
txtLog.Invoke(new Action<object>(delegate(object o)
|
||||
{
|
||||
txtLog.Text += e.Data + Environment.NewLine;
|
||||
txtLog.SelectionStart = txtLog.Text.Length - 1;
|
||||
txtLog.ScrollToCaret();
|
||||
}), new object[] { null });
|
||||
}
|
||||
|
||||
private void cmdConfigGSDX_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Execute the GSconfigure function
|
||||
if (lstGSDX.SelectedIndex != -1)
|
||||
ExecuteFunction("GSconfigure");
|
||||
else
|
||||
MessageBox.Show("Select your GSDX first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void cmdOpenIni_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Execute the GSconfigure function
|
||||
if (lstGSDX.SelectedIndex != -1)
|
||||
{
|
||||
String GSDXName = lstGSDX.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
CreateDirs(GSDXName);
|
||||
Process.Start(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini");
|
||||
}
|
||||
else
|
||||
MessageBox.Show("Select your GSDX first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void lstDumps_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lstDumps.SelectedIndex != -1)
|
||||
{
|
||||
String DumpFileName = lstDumps.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
String Filename = Path.GetDirectoryName(Properties.Settings.Default.DumpDir + "\\") +
|
||||
"\\" + Path.GetFileNameWithoutExtension(DumpFileName) + ".bmp";
|
||||
if (File.Exists(Filename))
|
||||
{
|
||||
pctBox.Image = Image.FromFile(Filename);
|
||||
pctBox.Cursor = Cursors.Hand;
|
||||
}
|
||||
else
|
||||
{
|
||||
pctBox.Image = NoImage;
|
||||
pctBox.Cursor = Cursors.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void pctBox_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (pctBox.Cursor == Cursors.Hand)
|
||||
{
|
||||
String DumpFileName = lstDumps.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
String Filename = Path.GetDirectoryName(Properties.Settings.Default.DumpDir + "\\") +
|
||||
"\\" + Path.GetFileNameWithoutExtension(DumpFileName) + ".bmp";
|
||||
Process.Start(Filename);
|
||||
}
|
||||
}
|
||||
|
||||
private void GSDumpGUI_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Return)
|
||||
cmdStart_Click(sender, e);
|
||||
|
||||
if (e.KeyCode == Keys.F1)
|
||||
cmdConfigGSDX_Click(sender, e);
|
||||
|
||||
if ((e.KeyCode == Keys.F2))
|
||||
SelectedRad++;
|
||||
}
|
||||
|
||||
private void rda_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
RadioButton itm = ((RadioButton)(sender));
|
||||
if (itm.Checked == true)
|
||||
SelectedRad = Convert.ToInt32(itm.Tag);
|
||||
}
|
||||
|
||||
private void txtGSDXDirectory_Leave(object sender, EventArgs e)
|
||||
{
|
||||
SaveConfig();
|
||||
ReloadGSDXs();
|
||||
}
|
||||
|
||||
private void txtDumpsDirectory_Leave(object sender, EventArgs e)
|
||||
{
|
||||
SaveConfig();
|
||||
ReloadGSDXs();
|
||||
}
|
||||
|
||||
private void SaveConfig()
|
||||
{
|
||||
Properties.Settings.Default.GSDXDir = txtGSDXDirectory.Text;
|
||||
Properties.Settings.Default.DumpDir = txtDumpsDirectory.Text;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
private void lstProcesses_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lstProcesses.SelectedIndex != -1)
|
||||
{
|
||||
chkDebugMode.Enabled = true;
|
||||
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.GetDebugMode;
|
||||
msg.Parameters.Add(chkDebugMode.Checked);
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.SizeDump;
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Statistics;
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
chkDebugMode.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void chkDebugMode_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lstProcesses.SelectedIndex != -1)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.SetDebugMode;
|
||||
msg.Parameters.Add(chkDebugMode.Checked);
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnStep_Click(object sender, EventArgs e)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Step;
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
|
||||
private void btnRunToSelection_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (treTreeView.SelectedNode != null)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.RunToCursor;
|
||||
msg.Parameters.Add(Convert.ToInt32(treTreeView.SelectedNode.Text.Split(new string[]{" - "}, StringSplitOptions.None)[0]));
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
else
|
||||
MessageBox.Show("You have not selected a node to jump to");
|
||||
}
|
||||
|
||||
private void cmdGoToStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.RunToCursor;
|
||||
msg.Parameters.Add(0);
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
|
||||
private void cmdGoToNextVSync_Click(object sender, EventArgs e)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.RunToNextVSync;
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
|
||||
private void treTreeView_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
if (treTreeView.SelectedNode != null)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.PacketInfo;
|
||||
msg.Parameters.Add(Convert.ToInt32(treTreeView.SelectedNode.Text.Split(new string[] { " - " }, StringSplitOptions.None)[0]));
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
treTreeView.SelectedNode = e.Node;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Security;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public partial class GSDumpGUI : Form
|
||||
{
|
||||
public List<Process> Processes;
|
||||
|
||||
private Int32 _selected;
|
||||
public Int32 SelectedRad
|
||||
{
|
||||
get { return _selected; }
|
||||
set
|
||||
{
|
||||
if (value > 4)
|
||||
value = 0;
|
||||
_selected = value;
|
||||
switch (_selected)
|
||||
{
|
||||
case 0:
|
||||
rdaNone.Checked = true;
|
||||
break;
|
||||
case 1:
|
||||
rdaDX9HW.Checked = true;
|
||||
break;
|
||||
case 2:
|
||||
rdaDX10HW.Checked = true;
|
||||
break;
|
||||
case 3:
|
||||
rdaDX9SW.Checked = true;
|
||||
break;
|
||||
case 4:
|
||||
rdaDX10SW.Checked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap NoImage;
|
||||
|
||||
public GSDumpGUI()
|
||||
{
|
||||
InitializeComponent();
|
||||
Processes = new List<Process>();
|
||||
|
||||
NoImage = new Bitmap(320, 240, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
Graphics g = Graphics.FromImage(NoImage);
|
||||
g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, 320, 240));
|
||||
g.DrawString("No Image", new Font(FontFamily.GenericSansSerif, 48, FontStyle.Regular), new SolidBrush(Color.White), new PointF(0, 70));
|
||||
g.Dispose();
|
||||
}
|
||||
|
||||
public void ReloadGSDXs()
|
||||
{
|
||||
txtIntLog.Text += "Starting GSDX Loading Procedures" + Environment.NewLine + Environment.NewLine;
|
||||
|
||||
txtGSDXDirectory.Text = Properties.Settings.Default.GSDXDir;
|
||||
txtDumpsDirectory.Text = Properties.Settings.Default.DumpDir;
|
||||
|
||||
lstGSDX.Items.Clear();
|
||||
lstDumps.Items.Clear();
|
||||
|
||||
if (Directory.Exists(txtGSDXDirectory.Text))
|
||||
{
|
||||
String[] File = Directory.GetFiles(txtGSDXDirectory.Text, "*.dll", SearchOption.TopDirectoryOnly);
|
||||
|
||||
GSDXWrapper wrap = new GSDXWrapper();
|
||||
foreach (var itm in File)
|
||||
{
|
||||
try
|
||||
{
|
||||
wrap.Load(itm);
|
||||
|
||||
lstGSDX.Items.Add(Path.GetFileName(itm) + " | " + wrap.PSEGetLibName());
|
||||
txtIntLog.Text += "\"" + itm + "\" correctly identified as " + wrap.PSEGetLibName() + Environment.NewLine;
|
||||
|
||||
wrap.Unload();
|
||||
}
|
||||
catch (InvalidGSPlugin)
|
||||
{
|
||||
txtIntLog.Text += "Failed to load \"" + itm + "\". Is it really a GSDX DLL?" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
txtIntLog.Text += Environment.NewLine + "Completed GSDX Loading Procedures" + Environment.NewLine + Environment.NewLine;
|
||||
|
||||
txtIntLog.Text += "Starting GSDX Dumps Loading Procedures : " + Environment.NewLine + Environment.NewLine;
|
||||
if (Directory.Exists(txtDumpsDirectory.Text))
|
||||
{
|
||||
String[] Dumps = Directory.GetFiles(txtDumpsDirectory.Text, "*.gs", SearchOption.TopDirectoryOnly);
|
||||
|
||||
foreach (var itm in Dumps)
|
||||
{
|
||||
BinaryReader br = new BinaryReader(System.IO.File.Open(itm, FileMode.Open));
|
||||
Int32 CRC = br.ReadInt32();
|
||||
br.Close();
|
||||
lstDumps.Items.Add(Path.GetFileName(itm) + " | CRC : " + CRC.ToString("X"));
|
||||
txtIntLog.Text += "Identified Dump for game (" + CRC.ToString("X") + ") with filename \"" + itm + "\"" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
txtIntLog.Text += Environment.NewLine + "Completed GSDX Dumps Loading Procedures : " + Environment.NewLine + Environment.NewLine;
|
||||
txtIntLog.SelectionStart = txtIntLog.TextLength;
|
||||
txtIntLog.ScrollToCaret();
|
||||
}
|
||||
|
||||
private void GSDumpGUI_Load(object sender, EventArgs e)
|
||||
{
|
||||
ReloadGSDXs();
|
||||
lstDumps.Focus();
|
||||
if (lstDumps.Items.Count > 0)
|
||||
lstDumps.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void cmdBrowseGSDX_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderBrowserDialog fbd = new FolderBrowserDialog();
|
||||
fbd.Description = "Select the GSDX DLL Directory";
|
||||
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||
if (fbd.ShowDialog() == DialogResult.OK)
|
||||
txtGSDXDirectory.Text = fbd.SelectedPath;
|
||||
SaveConfig();
|
||||
ReloadGSDXs();
|
||||
}
|
||||
|
||||
private void cmdBrowseDumps_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderBrowserDialog fbd = new FolderBrowserDialog();
|
||||
fbd.Description = "Select the GSDX Dumps Directory";
|
||||
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||
if (fbd.ShowDialog() == DialogResult.OK)
|
||||
txtDumpsDirectory.Text = fbd.SelectedPath;
|
||||
SaveConfig();
|
||||
ReloadGSDXs();
|
||||
}
|
||||
|
||||
private void cmdStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Execute the GSReplay function
|
||||
if (lstDumps.SelectedIndex != -1)
|
||||
{
|
||||
if (lstGSDX.SelectedIndex != -1)
|
||||
ExecuteFunction("GSReplay");
|
||||
else
|
||||
MessageBox.Show("Select your GSDX first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
else
|
||||
MessageBox.Show("Select your Dump first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void ExecuteFunction(String Function)
|
||||
{
|
||||
txtLog.Text = "";
|
||||
String GSDXName = lstGSDX.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
|
||||
CreateDirs(GSDXName);
|
||||
|
||||
// Set the Arguments to pass to the child
|
||||
String DLLPath = Properties.Settings.Default.GSDXDir + "\\" + GSDXName;
|
||||
String DumpPath = "";
|
||||
String SelectedRenderer = "";
|
||||
switch (SelectedRad)
|
||||
{
|
||||
case 0:
|
||||
SelectedRenderer = "-1";
|
||||
break;
|
||||
case 1:
|
||||
SelectedRenderer = "0";
|
||||
break;
|
||||
case 2:
|
||||
SelectedRenderer = "3";
|
||||
break;
|
||||
case 3:
|
||||
SelectedRenderer = "1";
|
||||
break;
|
||||
case 4:
|
||||
SelectedRenderer = "4";
|
||||
break;
|
||||
}
|
||||
if (SelectedRenderer != "-1")
|
||||
{
|
||||
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini"))
|
||||
{
|
||||
String ini = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini");
|
||||
int pos = ini.IndexOf("Renderer=", 0);
|
||||
if (pos != -1)
|
||||
{
|
||||
String newini = ini.Substring(0, pos + 9);
|
||||
newini += SelectedRenderer;
|
||||
newini += ini.Substring(pos + 10, ini.Length - pos - 10);
|
||||
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini", newini);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini", ini + Environment.NewLine + "Renderer=" + SelectedRenderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lstDumps.SelectedItem != null)
|
||||
DumpPath = Properties.Settings.Default.DumpDir + "\\" +
|
||||
lstDumps.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
|
||||
// Start the child and link the events.
|
||||
ProcessStartInfo psi = new ProcessStartInfo();
|
||||
psi.UseShellExecute = false;
|
||||
psi.RedirectStandardOutput = true;
|
||||
psi.RedirectStandardError = false;
|
||||
psi.CreateNoWindow = true;
|
||||
psi.FileName = AppDomain.CurrentDomain.BaseDirectory + "GsDumpGUI.exe";
|
||||
psi.Arguments = "\"" + DLLPath + "\"" + " \"" + DumpPath + "\"" + " \"" + Function + "\"" + " " + SelectedRenderer;
|
||||
Process p = Process.Start(psi);
|
||||
p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
|
||||
p.BeginOutputReadLine();
|
||||
p.Exited += new EventHandler(p_Exited);
|
||||
Processes.Add(p);
|
||||
}
|
||||
|
||||
private static void CreateDirs(String GSDXName)
|
||||
{
|
||||
// Create and set the config directory.
|
||||
String Dir = AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\";
|
||||
if (!Directory.Exists(Dir))
|
||||
{
|
||||
Directory.CreateDirectory(Dir);
|
||||
}
|
||||
Dir += GSDXName;
|
||||
if (!Directory.Exists(Dir))
|
||||
{
|
||||
Directory.CreateDirectory(Dir);
|
||||
}
|
||||
Dir += "\\Inis\\";
|
||||
if (!Directory.Exists(Dir))
|
||||
{
|
||||
Directory.CreateDirectory(Dir);
|
||||
File.Create(Dir + "\\gsdx.ini").Close();
|
||||
}
|
||||
Dir = AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName;
|
||||
Directory.SetCurrentDirectory(Dir);
|
||||
}
|
||||
|
||||
void p_Exited(object sender, EventArgs e)
|
||||
{
|
||||
// Remove the child if is closed
|
||||
Processes.Remove((Process)sender);
|
||||
}
|
||||
|
||||
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
// Write the log.
|
||||
txtLog.Invoke(new Action<object>(delegate(object o)
|
||||
{
|
||||
txtLog.Text += e.Data + Environment.NewLine;
|
||||
txtLog.SelectionStart = txtLog.Text.Length - 1;
|
||||
txtLog.ScrollToCaret();
|
||||
}), new object[] { null });
|
||||
}
|
||||
|
||||
private void cmdConfigGSDX_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Execute the GSconfigure function
|
||||
if (lstGSDX.SelectedIndex != -1)
|
||||
ExecuteFunction("GSconfigure");
|
||||
else
|
||||
MessageBox.Show("Select your GSDX first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void cmdOpenIni_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Execute the GSconfigure function
|
||||
if (lstGSDX.SelectedIndex != -1)
|
||||
{
|
||||
String GSDXName = lstGSDX.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
CreateDirs(GSDXName);
|
||||
Process.Start(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\" + GSDXName + "\\inis\\gsdx.ini");
|
||||
}
|
||||
else
|
||||
MessageBox.Show("Select your GSDX first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void lstDumps_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lstDumps.SelectedIndex != -1)
|
||||
{
|
||||
String DumpFileName = lstDumps.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
String Filename = Path.GetDirectoryName(Properties.Settings.Default.DumpDir + "\\") +
|
||||
"\\" + Path.GetFileNameWithoutExtension(DumpFileName) + ".bmp";
|
||||
if (File.Exists(Filename))
|
||||
{
|
||||
pctBox.Image = Image.FromFile(Filename);
|
||||
pctBox.Cursor = Cursors.Hand;
|
||||
}
|
||||
else
|
||||
{
|
||||
pctBox.Image = NoImage;
|
||||
pctBox.Cursor = Cursors.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void pctBox_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (pctBox.Cursor == Cursors.Hand)
|
||||
{
|
||||
String DumpFileName = lstDumps.SelectedItem.ToString().Split(new char[] { '|' })[0];
|
||||
String Filename = Path.GetDirectoryName(Properties.Settings.Default.DumpDir + "\\") +
|
||||
"\\" + Path.GetFileNameWithoutExtension(DumpFileName) + ".bmp";
|
||||
Process.Start(Filename);
|
||||
}
|
||||
}
|
||||
|
||||
private void GSDumpGUI_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Return)
|
||||
cmdStart_Click(sender, e);
|
||||
|
||||
if (e.KeyCode == Keys.F1)
|
||||
cmdConfigGSDX_Click(sender, e);
|
||||
|
||||
if ((e.KeyCode == Keys.F2))
|
||||
SelectedRad++;
|
||||
}
|
||||
|
||||
private void rda_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
RadioButton itm = ((RadioButton)(sender));
|
||||
if (itm.Checked == true)
|
||||
SelectedRad = Convert.ToInt32(itm.Tag);
|
||||
}
|
||||
|
||||
private void txtGSDXDirectory_Leave(object sender, EventArgs e)
|
||||
{
|
||||
SaveConfig();
|
||||
ReloadGSDXs();
|
||||
}
|
||||
|
||||
private void txtDumpsDirectory_Leave(object sender, EventArgs e)
|
||||
{
|
||||
SaveConfig();
|
||||
ReloadGSDXs();
|
||||
}
|
||||
|
||||
private void SaveConfig()
|
||||
{
|
||||
Properties.Settings.Default.GSDXDir = txtGSDXDirectory.Text;
|
||||
Properties.Settings.Default.DumpDir = txtDumpsDirectory.Text;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
private void lstProcesses_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lstProcesses.SelectedIndex != -1)
|
||||
{
|
||||
chkDebugMode.Enabled = true;
|
||||
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.GetDebugMode;
|
||||
msg.Parameters.Add(chkDebugMode.Checked);
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.SizeDump;
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
|
||||
msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Statistics;
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
chkDebugMode.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void chkDebugMode_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lstProcesses.SelectedIndex != -1)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.SetDebugMode;
|
||||
msg.Parameters.Add(chkDebugMode.Checked);
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnStep_Click(object sender, EventArgs e)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.Step;
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
|
||||
private void btnRunToSelection_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (treTreeView.SelectedNode != null)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.RunToCursor;
|
||||
msg.Parameters.Add(Convert.ToInt32(treTreeView.SelectedNode.Text.Split(new string[]{" - "}, StringSplitOptions.None)[0]));
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
else
|
||||
MessageBox.Show("You have not selected a node to jump to");
|
||||
}
|
||||
|
||||
private void cmdGoToStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.RunToCursor;
|
||||
msg.Parameters.Add(0);
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
|
||||
private void cmdGoToNextVSync_Click(object sender, EventArgs e)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.RunToNextVSync;
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
|
||||
private void treTreeView_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
if (treTreeView.SelectedNode != null)
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.PacketInfo;
|
||||
msg.Parameters.Add(Convert.ToInt32(treTreeView.SelectedNode.Text.Split(new string[] { " - " }, StringSplitOptions.None)[0]));
|
||||
Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg);
|
||||
}
|
||||
treTreeView.SelectedNode = e.Node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,408 +1,408 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
using System.Threading;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public delegate void GSgifTransfer(IntPtr data, int size);
|
||||
public delegate void GSgifTransfer1(IntPtr data, int size);
|
||||
public delegate void GSgifTransfer2(IntPtr data, int size);
|
||||
public delegate void GSgifTransfer3(IntPtr data, int size);
|
||||
public delegate void GSVSync(byte field);
|
||||
public delegate void GSreset();
|
||||
public delegate void GSreadFIFO2(IntPtr data, int size);
|
||||
public delegate void GSsetGameCRC(int crc, int options);
|
||||
public delegate int GSfreeze(int mode, IntPtr data);
|
||||
public delegate void GSopen(IntPtr hwnd, String Title, int renderer);
|
||||
public delegate void GSclose();
|
||||
public delegate void GSshutdown();
|
||||
public delegate void GSConfigure();
|
||||
public delegate void GSsetBaseMem(IntPtr data);
|
||||
public delegate IntPtr PSEgetLibName();
|
||||
public delegate void GSinit();
|
||||
|
||||
public class InvalidGSPlugin : Exception
|
||||
{
|
||||
public InvalidGSPlugin(string reason) : base(reason) {}
|
||||
}
|
||||
|
||||
public class GSDXWrapper
|
||||
{
|
||||
static public bool DumpTooOld = false;
|
||||
|
||||
private GSConfigure gsConfigure;
|
||||
private PSEgetLibName PsegetLibName;
|
||||
private GSgifTransfer GSgifTransfer;
|
||||
private GSgifTransfer1 GSgifTransfer1;
|
||||
private GSgifTransfer2 GSgifTransfer2;
|
||||
private GSgifTransfer3 GSgifTransfer3;
|
||||
private GSVSync GSVSync;
|
||||
private GSreadFIFO2 GSreadFIFO2;
|
||||
private GSsetGameCRC GSsetGameCRC;
|
||||
private GSfreeze GSfreeze;
|
||||
private GSopen GSopen;
|
||||
private GSclose GSclose;
|
||||
private GSshutdown GSshutdown;
|
||||
private GSsetBaseMem GSsetBaseMem;
|
||||
private GSinit GSinit;
|
||||
private GSreset GSreset;
|
||||
|
||||
private Boolean Loaded;
|
||||
|
||||
private String DLL;
|
||||
private IntPtr DLLAddr;
|
||||
|
||||
private Boolean Running;
|
||||
|
||||
public Queue<TCPMessage> QueueMessage;
|
||||
public Boolean DebugMode;
|
||||
public GSData CurrentGIFPacket;
|
||||
public bool ThereIsWork;
|
||||
public AutoResetEvent ExternalEvent;
|
||||
public int RunTo;
|
||||
|
||||
public void Load(String DLL)
|
||||
{
|
||||
this.DLL = DLL;
|
||||
NativeMethods.SetErrorMode(0x8007);
|
||||
|
||||
if (Loaded)
|
||||
Unload();
|
||||
|
||||
string dir = DLL;
|
||||
while (true)
|
||||
{
|
||||
dir = Path.GetDirectoryName(dir);
|
||||
if (dir == null)
|
||||
break;
|
||||
Directory.SetCurrentDirectory(dir);
|
||||
IntPtr hmod = NativeMethods.LoadLibrary(DLL);
|
||||
if (hmod.ToInt64() > 0)
|
||||
{
|
||||
DLLAddr = hmod;
|
||||
|
||||
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
|
||||
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
|
||||
|
||||
IntPtr funcaddrGIF = NativeMethods.GetProcAddress(hmod, "GSgifTransfer");
|
||||
IntPtr funcaddrGIF1 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer1");
|
||||
IntPtr funcaddrGIF2 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer2");
|
||||
IntPtr funcaddrGIF3 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer3");
|
||||
IntPtr funcaddrVSync = NativeMethods.GetProcAddress(hmod, "GSvsync");
|
||||
IntPtr funcaddrSetBaseMem = NativeMethods.GetProcAddress(hmod, "GSsetBaseMem");
|
||||
IntPtr funcaddrGSReset = NativeMethods.GetProcAddress(hmod, "GSreset");
|
||||
IntPtr funcaddrOpen = NativeMethods.GetProcAddress(hmod, "GSopen");
|
||||
IntPtr funcaddrSetCRC = NativeMethods.GetProcAddress(hmod, "GSsetGameCRC");
|
||||
IntPtr funcaddrClose = NativeMethods.GetProcAddress(hmod, "GSclose");
|
||||
IntPtr funcaddrShutdown = NativeMethods.GetProcAddress(hmod, "GSshutdown");
|
||||
IntPtr funcaddrFreeze = NativeMethods.GetProcAddress(hmod, "GSfreeze");
|
||||
IntPtr funcaddrGSreadFIFO2 = NativeMethods.GetProcAddress(hmod, "GSreadFIFO2");
|
||||
IntPtr funcaddrinit = NativeMethods.GetProcAddress(hmod, "GSinit");
|
||||
|
||||
if (!((funcaddrConfig.ToInt64() > 0) && (funcaddrLibName.ToInt64() > 0) && (funcaddrGIF.ToInt64() > 0)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
gsConfigure = (GSConfigure)Marshal.GetDelegateForFunctionPointer(funcaddrConfig, typeof(GSConfigure));
|
||||
PsegetLibName = (PSEgetLibName)Marshal.GetDelegateForFunctionPointer(funcaddrLibName, typeof(PSEgetLibName));
|
||||
|
||||
this.GSgifTransfer = (GSgifTransfer)Marshal.GetDelegateForFunctionPointer(funcaddrGIF, typeof(GSgifTransfer));
|
||||
this.GSgifTransfer1 = (GSgifTransfer1)Marshal.GetDelegateForFunctionPointer(funcaddrGIF1, typeof(GSgifTransfer1));
|
||||
this.GSgifTransfer2 = (GSgifTransfer2)Marshal.GetDelegateForFunctionPointer(funcaddrGIF2, typeof(GSgifTransfer2));
|
||||
this.GSgifTransfer3 = (GSgifTransfer3)Marshal.GetDelegateForFunctionPointer(funcaddrGIF3, typeof(GSgifTransfer3));
|
||||
this.GSVSync = (GSVSync)Marshal.GetDelegateForFunctionPointer(funcaddrVSync, typeof(GSVSync));
|
||||
this.GSsetBaseMem = (GSsetBaseMem)Marshal.GetDelegateForFunctionPointer(funcaddrSetBaseMem, typeof(GSsetBaseMem));
|
||||
this.GSopen = (GSopen)Marshal.GetDelegateForFunctionPointer(funcaddrOpen, typeof(GSopen));
|
||||
this.GSsetGameCRC = (GSsetGameCRC)Marshal.GetDelegateForFunctionPointer(funcaddrSetCRC, typeof(GSsetGameCRC));
|
||||
this.GSclose = (GSclose)Marshal.GetDelegateForFunctionPointer(funcaddrClose, typeof(GSclose));
|
||||
this.GSshutdown = (GSshutdown)Marshal.GetDelegateForFunctionPointer(funcaddrShutdown, typeof(GSshutdown));
|
||||
this.GSfreeze = (GSfreeze)Marshal.GetDelegateForFunctionPointer(funcaddrFreeze, typeof(GSfreeze));
|
||||
this.GSreset = (GSreset)Marshal.GetDelegateForFunctionPointer(funcaddrGSReset, typeof(GSreset));
|
||||
this.GSreadFIFO2 = (GSreadFIFO2)Marshal.GetDelegateForFunctionPointer(funcaddrGSreadFIFO2, typeof(GSreadFIFO2));
|
||||
this.GSinit = (GSinit)Marshal.GetDelegateForFunctionPointer(funcaddrinit, typeof(GSinit));
|
||||
|
||||
Loaded = true;
|
||||
}
|
||||
}
|
||||
if (!Loaded)
|
||||
{
|
||||
Exception lasterror = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
|
||||
System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", DLL + " failed to load. Error " + lasterror.ToString() + Environment.NewLine);
|
||||
NativeMethods.SetErrorMode(0x0000);
|
||||
Unload();
|
||||
throw new InvalidGSPlugin(lasterror.ToString());
|
||||
}
|
||||
NativeMethods.SetErrorMode(0x0000);
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
NativeMethods.FreeLibrary(DLLAddr);
|
||||
Loaded = false;
|
||||
}
|
||||
|
||||
public void GSConfig()
|
||||
{
|
||||
if (!Loaded)
|
||||
throw new Exception("GSDX is not loaded");
|
||||
gsConfigure.Invoke();
|
||||
}
|
||||
|
||||
public String PSEGetLibName()
|
||||
{
|
||||
if (!Loaded)
|
||||
throw new Exception("GSDX is not loaded");
|
||||
return Marshal.PtrToStringAnsi(PsegetLibName.Invoke());
|
||||
}
|
||||
|
||||
public unsafe void Run(GSDump dump, int rendererOverride)
|
||||
{
|
||||
QueueMessage = new Queue<TCPMessage>();
|
||||
Running = true;
|
||||
ExternalEvent = new AutoResetEvent(true);
|
||||
|
||||
GSinit();
|
||||
byte[] tempregisters = new byte[8192];
|
||||
Array.Copy(dump.Registers, tempregisters, 8192);
|
||||
fixed (byte* pointer = tempregisters)
|
||||
{
|
||||
GSsetBaseMem(new IntPtr(pointer));
|
||||
Int32 HWND = 0;
|
||||
GSopen(new IntPtr(&HWND), "", rendererOverride);
|
||||
GSsetGameCRC(dump.CRC, 0);
|
||||
|
||||
fixed (byte* freeze = dump.StateData)
|
||||
{
|
||||
byte[] GSFreez = new byte[8];
|
||||
Array.Copy(BitConverter.GetBytes(dump.StateData.Length), 0, GSFreez, 0, 4);
|
||||
Array.Copy(BitConverter.GetBytes(new IntPtr(freeze).ToInt32()), 0, GSFreez, 4, 4);
|
||||
|
||||
fixed (byte* fr = GSFreez)
|
||||
{
|
||||
int ris = GSfreeze(0, new IntPtr(fr));
|
||||
if (ris == -1)
|
||||
{
|
||||
DumpTooOld = true;
|
||||
return;
|
||||
}
|
||||
GSVSync(1);
|
||||
|
||||
while (Running)
|
||||
{
|
||||
if (!NativeMethods.IsWindowVisible(new IntPtr(HWND)))
|
||||
{
|
||||
Running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
GSreset();
|
||||
Marshal.Copy(dump.Registers, 0, new IntPtr(pointer), 8192);
|
||||
GSsetBaseMem(new IntPtr(pointer));
|
||||
GSfreeze(0, new IntPtr(fr));
|
||||
|
||||
for (int i = 0; i < dump.Data.Count; i++)
|
||||
{
|
||||
GSData itm = dump.Data[i];
|
||||
CurrentGIFPacket = itm;
|
||||
|
||||
if (DebugMode)
|
||||
{
|
||||
if (RunTo != -1)
|
||||
{
|
||||
if (i == RunTo)
|
||||
{
|
||||
RunTo = -1;
|
||||
int idxnextReg = dump.Data.FindIndex(i, a => a.id == GSType.Registers);
|
||||
if (idxnextReg != -1)
|
||||
{
|
||||
Step(dump.Data[idxnextReg], pointer);
|
||||
}
|
||||
|
||||
GSData g = new GSData();
|
||||
g.id = GSType.VSync;
|
||||
Step(g, pointer);
|
||||
|
||||
TCPMessage Msg = new TCPMessage();
|
||||
Msg.MessageType = MessageType.RunToCursor;
|
||||
Msg.Parameters.Add(i);
|
||||
Program.Client.Send(Msg);
|
||||
|
||||
ExternalEvent.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
Step(itm, pointer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!ThereIsWork && Running)
|
||||
{
|
||||
NativeMessage message;
|
||||
while (NativeMethods.PeekMessage(out message, IntPtr.Zero, 0, 0, 1))
|
||||
{
|
||||
if (!NativeMethods.IsWindowVisible(new IntPtr(HWND)))
|
||||
{
|
||||
Running = false;
|
||||
}
|
||||
NativeMethods.TranslateMessage(ref message);
|
||||
NativeMethods.DispatchMessage(ref message);
|
||||
}
|
||||
}
|
||||
|
||||
ThereIsWork = false;
|
||||
if (QueueMessage.Count > 0)
|
||||
{
|
||||
TCPMessage Mess = QueueMessage.Dequeue();
|
||||
switch (Mess.MessageType)
|
||||
{
|
||||
case MessageType.Step:
|
||||
RunTo = i;
|
||||
break;
|
||||
case MessageType.RunToCursor:
|
||||
RunTo = (int)Mess.Parameters[0];
|
||||
break;
|
||||
case MessageType.RunToNextVSync:
|
||||
RunTo = dump.Data.FindIndex(i, a => a.id == GSType.VSync);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Step(itm, pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSclose();
|
||||
GSshutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void Step(GSData itm, byte* registers)
|
||||
{
|
||||
/*"C:\Users\Alessio\Desktop\Plugins\Dll\GSdx-SSE4.dll" "C:\Users\Alessio\Desktop\Plugins\Dumps\gsdx_20101222215004.gs" "GSReplay" 0*/
|
||||
switch (itm.id)
|
||||
{
|
||||
case GSType.Transfer:
|
||||
switch (((GSTransfer)itm).Path)
|
||||
{
|
||||
case GSTransferPath.Path1Old:
|
||||
byte[] data = new byte[16384];
|
||||
int addr = 16384 - itm.data.Length;
|
||||
Array.Copy(itm.data, 0, data, addr, itm.data.Length);
|
||||
fixed (byte* gifdata = data)
|
||||
{
|
||||
GSgifTransfer1(new IntPtr(gifdata), addr);
|
||||
}
|
||||
break;
|
||||
case GSTransferPath.Path2:
|
||||
fixed (byte* gifdata = itm.data)
|
||||
{
|
||||
GSgifTransfer2(new IntPtr(gifdata), (itm.data.Length) / 16);
|
||||
}
|
||||
break;
|
||||
case GSTransferPath.Path3:
|
||||
fixed (byte* gifdata = itm.data)
|
||||
{
|
||||
GSgifTransfer3(new IntPtr(gifdata), (itm.data.Length) / 16);
|
||||
}
|
||||
break;
|
||||
case GSTransferPath.Path1New:
|
||||
fixed (byte* gifdata = itm.data)
|
||||
{
|
||||
GSgifTransfer(new IntPtr(gifdata), (itm.data.Length) / 16);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GSType.VSync:
|
||||
GSVSync((*((int*)(registers + 4096)) & 0x2000) > 0 ? (byte)1 : (byte)0);
|
||||
break;
|
||||
case GSType.ReadFIFO2:
|
||||
fixed (byte* FIFO = itm.data)
|
||||
{
|
||||
byte[] arrnew = new byte[*((int*)FIFO)];
|
||||
fixed (byte* arrn = arrnew)
|
||||
{
|
||||
GSreadFIFO2(new IntPtr(arrn), *((int*)FIFO));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GSType.Registers:
|
||||
Marshal.Copy(itm.data, 0, new IntPtr(registers), 8192);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Running = false;
|
||||
}
|
||||
|
||||
internal List<Object> GetGifPackets(GSDump dump)
|
||||
{
|
||||
List<Object> Data = new List<Object>();
|
||||
for (int i = 0; i < dump.Data.Count; i++)
|
||||
{
|
||||
String act = i.ToString() + "|";
|
||||
act += dump.Data[i].id.ToString() + "|";
|
||||
if (dump.Data[i].GetType().IsSubclassOf(typeof(GSData)))
|
||||
{
|
||||
act += ((GSTransfer)dump.Data[i]).Path.ToString() + "|";
|
||||
act += ((GSTransfer)dump.Data[i]).data.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
act += ((GSData)dump.Data[i]).data.Length;
|
||||
}
|
||||
Data.Add(act);
|
||||
}
|
||||
return Data;
|
||||
}
|
||||
|
||||
internal object GetGifPacketInfo(GSDump dump, int i)
|
||||
{
|
||||
if (dump.Data[i].id == GSType.Transfer)
|
||||
{
|
||||
try
|
||||
{
|
||||
GIFTag val = GIFTag.ExtractGifTag(dump.Data[i].data, ((GSTransfer)dump.Data[i]).Path);
|
||||
return val;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new GIFTag();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (dump.Data[i].id)
|
||||
{
|
||||
case GSType.VSync:
|
||||
return dump.Data[i].data.Length + "|Field = " + dump.Data[i].data[0].ToString();
|
||||
case GSType.ReadFIFO2:
|
||||
return dump.Data[i].data.Length + "|ReadFIFO2 : Size = " + BitConverter.ToInt32(dump.Data[i].data, 0).ToString() + " byte";
|
||||
case GSType.Registers:
|
||||
return dump.Data[i].data.Length + "|Registers";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
using System.Threading;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public delegate void GSgifTransfer(IntPtr data, int size);
|
||||
public delegate void GSgifTransfer1(IntPtr data, int size);
|
||||
public delegate void GSgifTransfer2(IntPtr data, int size);
|
||||
public delegate void GSgifTransfer3(IntPtr data, int size);
|
||||
public delegate void GSVSync(byte field);
|
||||
public delegate void GSreset();
|
||||
public delegate void GSreadFIFO2(IntPtr data, int size);
|
||||
public delegate void GSsetGameCRC(int crc, int options);
|
||||
public delegate int GSfreeze(int mode, IntPtr data);
|
||||
public delegate void GSopen(IntPtr hwnd, String Title, int renderer);
|
||||
public delegate void GSclose();
|
||||
public delegate void GSshutdown();
|
||||
public delegate void GSConfigure();
|
||||
public delegate void GSsetBaseMem(IntPtr data);
|
||||
public delegate IntPtr PSEgetLibName();
|
||||
public delegate void GSinit();
|
||||
|
||||
public class InvalidGSPlugin : Exception
|
||||
{
|
||||
public InvalidGSPlugin(string reason) : base(reason) {}
|
||||
}
|
||||
|
||||
public class GSDXWrapper
|
||||
{
|
||||
static public bool DumpTooOld = false;
|
||||
|
||||
private GSConfigure gsConfigure;
|
||||
private PSEgetLibName PsegetLibName;
|
||||
private GSgifTransfer GSgifTransfer;
|
||||
private GSgifTransfer1 GSgifTransfer1;
|
||||
private GSgifTransfer2 GSgifTransfer2;
|
||||
private GSgifTransfer3 GSgifTransfer3;
|
||||
private GSVSync GSVSync;
|
||||
private GSreadFIFO2 GSreadFIFO2;
|
||||
private GSsetGameCRC GSsetGameCRC;
|
||||
private GSfreeze GSfreeze;
|
||||
private GSopen GSopen;
|
||||
private GSclose GSclose;
|
||||
private GSshutdown GSshutdown;
|
||||
private GSsetBaseMem GSsetBaseMem;
|
||||
private GSinit GSinit;
|
||||
private GSreset GSreset;
|
||||
|
||||
private Boolean Loaded;
|
||||
|
||||
private String DLL;
|
||||
private IntPtr DLLAddr;
|
||||
|
||||
private Boolean Running;
|
||||
|
||||
public Queue<TCPMessage> QueueMessage;
|
||||
public Boolean DebugMode;
|
||||
public GSData CurrentGIFPacket;
|
||||
public bool ThereIsWork;
|
||||
public AutoResetEvent ExternalEvent;
|
||||
public int RunTo;
|
||||
|
||||
public void Load(String DLL)
|
||||
{
|
||||
this.DLL = DLL;
|
||||
NativeMethods.SetErrorMode(0x8007);
|
||||
|
||||
if (Loaded)
|
||||
Unload();
|
||||
|
||||
string dir = DLL;
|
||||
while (true)
|
||||
{
|
||||
dir = Path.GetDirectoryName(dir);
|
||||
if (dir == null)
|
||||
break;
|
||||
Directory.SetCurrentDirectory(dir);
|
||||
IntPtr hmod = NativeMethods.LoadLibrary(DLL);
|
||||
if (hmod.ToInt64() > 0)
|
||||
{
|
||||
DLLAddr = hmod;
|
||||
|
||||
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
|
||||
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
|
||||
|
||||
IntPtr funcaddrGIF = NativeMethods.GetProcAddress(hmod, "GSgifTransfer");
|
||||
IntPtr funcaddrGIF1 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer1");
|
||||
IntPtr funcaddrGIF2 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer2");
|
||||
IntPtr funcaddrGIF3 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer3");
|
||||
IntPtr funcaddrVSync = NativeMethods.GetProcAddress(hmod, "GSvsync");
|
||||
IntPtr funcaddrSetBaseMem = NativeMethods.GetProcAddress(hmod, "GSsetBaseMem");
|
||||
IntPtr funcaddrGSReset = NativeMethods.GetProcAddress(hmod, "GSreset");
|
||||
IntPtr funcaddrOpen = NativeMethods.GetProcAddress(hmod, "GSopen");
|
||||
IntPtr funcaddrSetCRC = NativeMethods.GetProcAddress(hmod, "GSsetGameCRC");
|
||||
IntPtr funcaddrClose = NativeMethods.GetProcAddress(hmod, "GSclose");
|
||||
IntPtr funcaddrShutdown = NativeMethods.GetProcAddress(hmod, "GSshutdown");
|
||||
IntPtr funcaddrFreeze = NativeMethods.GetProcAddress(hmod, "GSfreeze");
|
||||
IntPtr funcaddrGSreadFIFO2 = NativeMethods.GetProcAddress(hmod, "GSreadFIFO2");
|
||||
IntPtr funcaddrinit = NativeMethods.GetProcAddress(hmod, "GSinit");
|
||||
|
||||
if (!((funcaddrConfig.ToInt64() > 0) && (funcaddrLibName.ToInt64() > 0) && (funcaddrGIF.ToInt64() > 0)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
gsConfigure = (GSConfigure)Marshal.GetDelegateForFunctionPointer(funcaddrConfig, typeof(GSConfigure));
|
||||
PsegetLibName = (PSEgetLibName)Marshal.GetDelegateForFunctionPointer(funcaddrLibName, typeof(PSEgetLibName));
|
||||
|
||||
this.GSgifTransfer = (GSgifTransfer)Marshal.GetDelegateForFunctionPointer(funcaddrGIF, typeof(GSgifTransfer));
|
||||
this.GSgifTransfer1 = (GSgifTransfer1)Marshal.GetDelegateForFunctionPointer(funcaddrGIF1, typeof(GSgifTransfer1));
|
||||
this.GSgifTransfer2 = (GSgifTransfer2)Marshal.GetDelegateForFunctionPointer(funcaddrGIF2, typeof(GSgifTransfer2));
|
||||
this.GSgifTransfer3 = (GSgifTransfer3)Marshal.GetDelegateForFunctionPointer(funcaddrGIF3, typeof(GSgifTransfer3));
|
||||
this.GSVSync = (GSVSync)Marshal.GetDelegateForFunctionPointer(funcaddrVSync, typeof(GSVSync));
|
||||
this.GSsetBaseMem = (GSsetBaseMem)Marshal.GetDelegateForFunctionPointer(funcaddrSetBaseMem, typeof(GSsetBaseMem));
|
||||
this.GSopen = (GSopen)Marshal.GetDelegateForFunctionPointer(funcaddrOpen, typeof(GSopen));
|
||||
this.GSsetGameCRC = (GSsetGameCRC)Marshal.GetDelegateForFunctionPointer(funcaddrSetCRC, typeof(GSsetGameCRC));
|
||||
this.GSclose = (GSclose)Marshal.GetDelegateForFunctionPointer(funcaddrClose, typeof(GSclose));
|
||||
this.GSshutdown = (GSshutdown)Marshal.GetDelegateForFunctionPointer(funcaddrShutdown, typeof(GSshutdown));
|
||||
this.GSfreeze = (GSfreeze)Marshal.GetDelegateForFunctionPointer(funcaddrFreeze, typeof(GSfreeze));
|
||||
this.GSreset = (GSreset)Marshal.GetDelegateForFunctionPointer(funcaddrGSReset, typeof(GSreset));
|
||||
this.GSreadFIFO2 = (GSreadFIFO2)Marshal.GetDelegateForFunctionPointer(funcaddrGSreadFIFO2, typeof(GSreadFIFO2));
|
||||
this.GSinit = (GSinit)Marshal.GetDelegateForFunctionPointer(funcaddrinit, typeof(GSinit));
|
||||
|
||||
Loaded = true;
|
||||
}
|
||||
}
|
||||
if (!Loaded)
|
||||
{
|
||||
Exception lasterror = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
|
||||
System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", DLL + " failed to load. Error " + lasterror.ToString() + Environment.NewLine);
|
||||
NativeMethods.SetErrorMode(0x0000);
|
||||
Unload();
|
||||
throw new InvalidGSPlugin(lasterror.ToString());
|
||||
}
|
||||
NativeMethods.SetErrorMode(0x0000);
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
NativeMethods.FreeLibrary(DLLAddr);
|
||||
Loaded = false;
|
||||
}
|
||||
|
||||
public void GSConfig()
|
||||
{
|
||||
if (!Loaded)
|
||||
throw new Exception("GSDX is not loaded");
|
||||
gsConfigure.Invoke();
|
||||
}
|
||||
|
||||
public String PSEGetLibName()
|
||||
{
|
||||
if (!Loaded)
|
||||
throw new Exception("GSDX is not loaded");
|
||||
return Marshal.PtrToStringAnsi(PsegetLibName.Invoke());
|
||||
}
|
||||
|
||||
public unsafe void Run(GSDump dump, int rendererOverride)
|
||||
{
|
||||
QueueMessage = new Queue<TCPMessage>();
|
||||
Running = true;
|
||||
ExternalEvent = new AutoResetEvent(true);
|
||||
|
||||
GSinit();
|
||||
byte[] tempregisters = new byte[8192];
|
||||
Array.Copy(dump.Registers, tempregisters, 8192);
|
||||
fixed (byte* pointer = tempregisters)
|
||||
{
|
||||
GSsetBaseMem(new IntPtr(pointer));
|
||||
Int32 HWND = 0;
|
||||
GSopen(new IntPtr(&HWND), "", rendererOverride);
|
||||
GSsetGameCRC(dump.CRC, 0);
|
||||
|
||||
fixed (byte* freeze = dump.StateData)
|
||||
{
|
||||
byte[] GSFreez = new byte[8];
|
||||
Array.Copy(BitConverter.GetBytes(dump.StateData.Length), 0, GSFreez, 0, 4);
|
||||
Array.Copy(BitConverter.GetBytes(new IntPtr(freeze).ToInt32()), 0, GSFreez, 4, 4);
|
||||
|
||||
fixed (byte* fr = GSFreez)
|
||||
{
|
||||
int ris = GSfreeze(0, new IntPtr(fr));
|
||||
if (ris == -1)
|
||||
{
|
||||
DumpTooOld = true;
|
||||
return;
|
||||
}
|
||||
GSVSync(1);
|
||||
|
||||
while (Running)
|
||||
{
|
||||
if (!NativeMethods.IsWindowVisible(new IntPtr(HWND)))
|
||||
{
|
||||
Running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
GSreset();
|
||||
Marshal.Copy(dump.Registers, 0, new IntPtr(pointer), 8192);
|
||||
GSsetBaseMem(new IntPtr(pointer));
|
||||
GSfreeze(0, new IntPtr(fr));
|
||||
|
||||
for (int i = 0; i < dump.Data.Count; i++)
|
||||
{
|
||||
GSData itm = dump.Data[i];
|
||||
CurrentGIFPacket = itm;
|
||||
|
||||
if (DebugMode)
|
||||
{
|
||||
if (RunTo != -1)
|
||||
{
|
||||
if (i == RunTo)
|
||||
{
|
||||
RunTo = -1;
|
||||
int idxnextReg = dump.Data.FindIndex(i, a => a.id == GSType.Registers);
|
||||
if (idxnextReg != -1)
|
||||
{
|
||||
Step(dump.Data[idxnextReg], pointer);
|
||||
}
|
||||
|
||||
GSData g = new GSData();
|
||||
g.id = GSType.VSync;
|
||||
Step(g, pointer);
|
||||
|
||||
TCPMessage Msg = new TCPMessage();
|
||||
Msg.MessageType = MessageType.RunToCursor;
|
||||
Msg.Parameters.Add(i);
|
||||
Program.Client.Send(Msg);
|
||||
|
||||
ExternalEvent.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
Step(itm, pointer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!ThereIsWork && Running)
|
||||
{
|
||||
NativeMessage message;
|
||||
while (NativeMethods.PeekMessage(out message, IntPtr.Zero, 0, 0, 1))
|
||||
{
|
||||
if (!NativeMethods.IsWindowVisible(new IntPtr(HWND)))
|
||||
{
|
||||
Running = false;
|
||||
}
|
||||
NativeMethods.TranslateMessage(ref message);
|
||||
NativeMethods.DispatchMessage(ref message);
|
||||
}
|
||||
}
|
||||
|
||||
ThereIsWork = false;
|
||||
if (QueueMessage.Count > 0)
|
||||
{
|
||||
TCPMessage Mess = QueueMessage.Dequeue();
|
||||
switch (Mess.MessageType)
|
||||
{
|
||||
case MessageType.Step:
|
||||
RunTo = i;
|
||||
break;
|
||||
case MessageType.RunToCursor:
|
||||
RunTo = (int)Mess.Parameters[0];
|
||||
break;
|
||||
case MessageType.RunToNextVSync:
|
||||
RunTo = dump.Data.FindIndex(i, a => a.id == GSType.VSync);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Step(itm, pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSclose();
|
||||
GSshutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void Step(GSData itm, byte* registers)
|
||||
{
|
||||
/*"C:\Users\Alessio\Desktop\Plugins\Dll\GSdx-SSE4.dll" "C:\Users\Alessio\Desktop\Plugins\Dumps\gsdx_20101222215004.gs" "GSReplay" 0*/
|
||||
switch (itm.id)
|
||||
{
|
||||
case GSType.Transfer:
|
||||
switch (((GSTransfer)itm).Path)
|
||||
{
|
||||
case GSTransferPath.Path1Old:
|
||||
byte[] data = new byte[16384];
|
||||
int addr = 16384 - itm.data.Length;
|
||||
Array.Copy(itm.data, 0, data, addr, itm.data.Length);
|
||||
fixed (byte* gifdata = data)
|
||||
{
|
||||
GSgifTransfer1(new IntPtr(gifdata), addr);
|
||||
}
|
||||
break;
|
||||
case GSTransferPath.Path2:
|
||||
fixed (byte* gifdata = itm.data)
|
||||
{
|
||||
GSgifTransfer2(new IntPtr(gifdata), (itm.data.Length) / 16);
|
||||
}
|
||||
break;
|
||||
case GSTransferPath.Path3:
|
||||
fixed (byte* gifdata = itm.data)
|
||||
{
|
||||
GSgifTransfer3(new IntPtr(gifdata), (itm.data.Length) / 16);
|
||||
}
|
||||
break;
|
||||
case GSTransferPath.Path1New:
|
||||
fixed (byte* gifdata = itm.data)
|
||||
{
|
||||
GSgifTransfer(new IntPtr(gifdata), (itm.data.Length) / 16);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GSType.VSync:
|
||||
GSVSync((*((int*)(registers + 4096)) & 0x2000) > 0 ? (byte)1 : (byte)0);
|
||||
break;
|
||||
case GSType.ReadFIFO2:
|
||||
fixed (byte* FIFO = itm.data)
|
||||
{
|
||||
byte[] arrnew = new byte[*((int*)FIFO)];
|
||||
fixed (byte* arrn = arrnew)
|
||||
{
|
||||
GSreadFIFO2(new IntPtr(arrn), *((int*)FIFO));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GSType.Registers:
|
||||
Marshal.Copy(itm.data, 0, new IntPtr(registers), 8192);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Running = false;
|
||||
}
|
||||
|
||||
internal List<Object> GetGifPackets(GSDump dump)
|
||||
{
|
||||
List<Object> Data = new List<Object>();
|
||||
for (int i = 0; i < dump.Data.Count; i++)
|
||||
{
|
||||
String act = i.ToString() + "|";
|
||||
act += dump.Data[i].id.ToString() + "|";
|
||||
if (dump.Data[i].GetType().IsSubclassOf(typeof(GSData)))
|
||||
{
|
||||
act += ((GSTransfer)dump.Data[i]).Path.ToString() + "|";
|
||||
act += ((GSTransfer)dump.Data[i]).data.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
act += ((GSData)dump.Data[i]).data.Length;
|
||||
}
|
||||
Data.Add(act);
|
||||
}
|
||||
return Data;
|
||||
}
|
||||
|
||||
internal object GetGifPacketInfo(GSDump dump, int i)
|
||||
{
|
||||
if (dump.Data[i].id == GSType.Transfer)
|
||||
{
|
||||
try
|
||||
{
|
||||
GIFTag val = GIFTag.ExtractGifTag(dump.Data[i].data, ((GSTransfer)dump.Data[i]).Path);
|
||||
return val;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new GIFTag();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (dump.Data[i].id)
|
||||
{
|
||||
case GSType.VSync:
|
||||
return dump.Data[i].data.Length + "|Field = " + dump.Data[i].data[0].ToString();
|
||||
case GSType.ReadFIFO2:
|
||||
return dump.Data[i].data.Length + "|ReadFIFO2 : Size = " + BitConverter.ToInt32(dump.Data[i].data, 0).ToString() + " byte";
|
||||
case GSType.Registers:
|
||||
return dump.Data[i].data.Length + "|Registers";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFPrim : GIFUtil
|
||||
{
|
||||
public GS_PRIM PrimitiveType;
|
||||
public GSIIP IIP;
|
||||
public bool TME;
|
||||
public bool FGE;
|
||||
public bool ABE;
|
||||
public bool AA1;
|
||||
public GSFST FST;
|
||||
public GSCTXT CTXT;
|
||||
public GSFIX FIX;
|
||||
|
||||
static internal GIFPrim ExtractGIFPrim(UInt32 LowData)
|
||||
{
|
||||
GIFPrim pr = new GIFPrim();
|
||||
pr.PrimitiveType = (GS_PRIM)GetBit(LowData, 0, 3);
|
||||
pr.IIP = (GSIIP)GetBit(LowData, 3, 1);
|
||||
pr.TME = Convert.ToBoolean(GetBit(LowData, 4, 1));
|
||||
pr.FGE = Convert.ToBoolean(GetBit(LowData, 5, 1));
|
||||
pr.ABE = Convert.ToBoolean(GetBit(LowData, 6, 1));
|
||||
pr.AA1 = Convert.ToBoolean(GetBit(LowData, 7, 1));
|
||||
pr.FST = (GSFST)(GetBit(LowData, 8, 1));
|
||||
pr.CTXT = (GSCTXT)(GetBit(LowData, 9, 1));
|
||||
pr.FIX = (GSFIX)(GetBit(LowData, 10, 1));
|
||||
return pr;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Primitive Type : " + PrimitiveType.ToString() + "@IIP : " + IIP.ToString() + "@TME : " + TME.ToString() + "@FGE : " + FGE.ToString()
|
||||
+ "@ABE : " + ABE.ToString() + "@AA1 : " + AA1.ToString() + "@FST : " + FST.ToString() + "@CTXT : " + CTXT.ToString() + "@FIX : " + FIX.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum GS_PRIM
|
||||
{
|
||||
GS_POINTLIST = 0,
|
||||
GS_LINELIST = 1,
|
||||
GS_LINESTRIP = 2,
|
||||
GS_TRIANGLELIST = 3,
|
||||
GS_TRIANGLESTRIP = 4,
|
||||
GS_TRIANGLEFAN = 5,
|
||||
GS_SPRITE = 6,
|
||||
GS_INVALID = 7,
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFPrim : GIFUtil
|
||||
{
|
||||
public GS_PRIM PrimitiveType;
|
||||
public GSIIP IIP;
|
||||
public bool TME;
|
||||
public bool FGE;
|
||||
public bool ABE;
|
||||
public bool AA1;
|
||||
public GSFST FST;
|
||||
public GSCTXT CTXT;
|
||||
public GSFIX FIX;
|
||||
|
||||
static internal GIFPrim ExtractGIFPrim(UInt32 LowData)
|
||||
{
|
||||
GIFPrim pr = new GIFPrim();
|
||||
pr.PrimitiveType = (GS_PRIM)GetBit(LowData, 0, 3);
|
||||
pr.IIP = (GSIIP)GetBit(LowData, 3, 1);
|
||||
pr.TME = Convert.ToBoolean(GetBit(LowData, 4, 1));
|
||||
pr.FGE = Convert.ToBoolean(GetBit(LowData, 5, 1));
|
||||
pr.ABE = Convert.ToBoolean(GetBit(LowData, 6, 1));
|
||||
pr.AA1 = Convert.ToBoolean(GetBit(LowData, 7, 1));
|
||||
pr.FST = (GSFST)(GetBit(LowData, 8, 1));
|
||||
pr.CTXT = (GSCTXT)(GetBit(LowData, 9, 1));
|
||||
pr.FIX = (GSFIX)(GetBit(LowData, 10, 1));
|
||||
return pr;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Primitive Type : " + PrimitiveType.ToString() + "@IIP : " + IIP.ToString() + "@TME : " + TME.ToString() + "@FGE : " + FGE.ToString()
|
||||
+ "@ABE : " + ABE.ToString() + "@AA1 : " + AA1.ToString() + "@FST : " + FST.ToString() + "@CTXT : " + CTXT.ToString() + "@FIX : " + FIX.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum GS_PRIM
|
||||
{
|
||||
GS_POINTLIST = 0,
|
||||
GS_LINELIST = 1,
|
||||
GS_LINESTRIP = 2,
|
||||
GS_TRIANGLELIST = 3,
|
||||
GS_TRIANGLESTRIP = 4,
|
||||
GS_TRIANGLEFAN = 5,
|
||||
GS_SPRITE = 6,
|
||||
GS_INVALID = 7,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,86 +1,86 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
abstract public class GIFReg : GIFUtil, IGifData
|
||||
{
|
||||
public GIFRegDescriptor Descriptor;
|
||||
public UInt64 LowData, HighData;
|
||||
public bool PackedFormat;
|
||||
|
||||
private GIFReg() { }
|
||||
|
||||
public GIFReg(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
this.LowData = LowData;
|
||||
this.HighData = HighData;
|
||||
this.PackedFormat = PackedFormat;
|
||||
}
|
||||
|
||||
abstract public new String ToString();
|
||||
}
|
||||
|
||||
public enum GIFRegDescriptor
|
||||
{
|
||||
PRIM = 0x00,
|
||||
RGBAQ = 0x01,
|
||||
ST = 0x02,
|
||||
UV = 0x03,
|
||||
XYZF2 = 0x04,
|
||||
XYZ2 = 0x05,
|
||||
TEX0_1 = 0x06,
|
||||
TEX0_2 = 0x07,
|
||||
CLAMP_1 = 0x08,
|
||||
CLAMP_2 = 0x09,
|
||||
FOG = 0x0a,
|
||||
XYZF3 = 0x0c,
|
||||
XYZ3 = 0x0d,
|
||||
AD = 0x0e,
|
||||
NOP = 0x0f, // actually, 0xf is the standard GIF NOP and 0x7f is the standard GS NOP, but all unregistered addresses act as NOPs... probably
|
||||
TEX1_1 = 0x14,
|
||||
TEX1_2 = 0x15,
|
||||
TEX2_1 = 0x16,
|
||||
TEX2_2 = 0x17,
|
||||
XYOFFSET_1 = 0x18,
|
||||
XYOFFSET_2 = 0x19,
|
||||
PRMODECONT = 0x1a,
|
||||
PRMODE = 0x1b,
|
||||
TEXCLUT = 0x1c,
|
||||
SCANMSK = 0x22,
|
||||
MIPTBP1_1 = 0x34,
|
||||
MIPTBP1_2 = 0x35,
|
||||
MIPTBP2_1 = 0x36,
|
||||
MIPTBP2_2 = 0x37,
|
||||
TEXA = 0x3b,
|
||||
FOGCOL = 0x3d,
|
||||
TEXFLUSH = 0x3f,
|
||||
SCISSOR_1 = 0x40,
|
||||
SCISSOR_2 = 0x41,
|
||||
ALPHA_1 = 0x42,
|
||||
ALPHA_2 = 0x43,
|
||||
DIMX = 0x44,
|
||||
DTHE = 0x45,
|
||||
COLCLAMP = 0x46,
|
||||
TEST_1 = 0x47,
|
||||
TEST_2 = 0x48,
|
||||
PABE = 0x49,
|
||||
FBA_1 = 0x4a,
|
||||
FBA_2 = 0x4b,
|
||||
FRAME_1 = 0x4c,
|
||||
FRAME_2 = 0x4d,
|
||||
ZBUF_1 = 0x4e,
|
||||
ZBUF_2 = 0x4f,
|
||||
BITBLTBUF = 0x50,
|
||||
TRXPOS = 0x51,
|
||||
TRXREG = 0x52,
|
||||
TRXDIR = 0x53,
|
||||
HWREG = 0x54,
|
||||
SIGNAL = 0x60,
|
||||
FINISH = 0x61,
|
||||
LABEL = 0x62,
|
||||
}
|
||||
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
abstract public class GIFReg : GIFUtil, IGifData
|
||||
{
|
||||
public GIFRegDescriptor Descriptor;
|
||||
public UInt64 LowData, HighData;
|
||||
public bool PackedFormat;
|
||||
|
||||
private GIFReg() { }
|
||||
|
||||
public GIFReg(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
this.LowData = LowData;
|
||||
this.HighData = HighData;
|
||||
this.PackedFormat = PackedFormat;
|
||||
}
|
||||
|
||||
abstract public new String ToString();
|
||||
}
|
||||
|
||||
public enum GIFRegDescriptor
|
||||
{
|
||||
PRIM = 0x00,
|
||||
RGBAQ = 0x01,
|
||||
ST = 0x02,
|
||||
UV = 0x03,
|
||||
XYZF2 = 0x04,
|
||||
XYZ2 = 0x05,
|
||||
TEX0_1 = 0x06,
|
||||
TEX0_2 = 0x07,
|
||||
CLAMP_1 = 0x08,
|
||||
CLAMP_2 = 0x09,
|
||||
FOG = 0x0a,
|
||||
XYZF3 = 0x0c,
|
||||
XYZ3 = 0x0d,
|
||||
AD = 0x0e,
|
||||
NOP = 0x0f, // actually, 0xf is the standard GIF NOP and 0x7f is the standard GS NOP, but all unregistered addresses act as NOPs... probably
|
||||
TEX1_1 = 0x14,
|
||||
TEX1_2 = 0x15,
|
||||
TEX2_1 = 0x16,
|
||||
TEX2_2 = 0x17,
|
||||
XYOFFSET_1 = 0x18,
|
||||
XYOFFSET_2 = 0x19,
|
||||
PRMODECONT = 0x1a,
|
||||
PRMODE = 0x1b,
|
||||
TEXCLUT = 0x1c,
|
||||
SCANMSK = 0x22,
|
||||
MIPTBP1_1 = 0x34,
|
||||
MIPTBP1_2 = 0x35,
|
||||
MIPTBP2_1 = 0x36,
|
||||
MIPTBP2_2 = 0x37,
|
||||
TEXA = 0x3b,
|
||||
FOGCOL = 0x3d,
|
||||
TEXFLUSH = 0x3f,
|
||||
SCISSOR_1 = 0x40,
|
||||
SCISSOR_2 = 0x41,
|
||||
ALPHA_1 = 0x42,
|
||||
ALPHA_2 = 0x43,
|
||||
DIMX = 0x44,
|
||||
DTHE = 0x45,
|
||||
COLCLAMP = 0x46,
|
||||
TEST_1 = 0x47,
|
||||
TEST_2 = 0x48,
|
||||
PABE = 0x49,
|
||||
FBA_1 = 0x4a,
|
||||
FBA_2 = 0x4b,
|
||||
FRAME_1 = 0x4c,
|
||||
FRAME_2 = 0x4d,
|
||||
ZBUF_1 = 0x4e,
|
||||
ZBUF_2 = 0x4f,
|
||||
BITBLTBUF = 0x50,
|
||||
TRXPOS = 0x51,
|
||||
TRXREG = 0x52,
|
||||
TRXDIR = 0x53,
|
||||
HWREG = 0x54,
|
||||
SIGNAL = 0x60,
|
||||
FINISH = 0x61,
|
||||
LABEL = 0x62,
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public static class GIFRegAD
|
||||
{
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
byte reg = (byte)GIFReg.GetBit(HighData, 0, 8);
|
||||
if (reg == (byte)GIFRegDescriptor.AD)
|
||||
return GIFRegNOP.Unpack(tag, reg, LowData, HighData, PackedFormat);
|
||||
return GIFTag.GetUnpack(reg)(tag, reg, LowData, HighData, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public static class GIFRegAD
|
||||
{
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
byte reg = (byte)GIFReg.GetBit(HighData, 0, 8);
|
||||
if (reg == (byte)GIFRegDescriptor.AD)
|
||||
return GIFRegNOP.Unpack(tag, reg, LowData, HighData, PackedFormat);
|
||||
return GIFTag.GetUnpack(reg)(tag, reg, LowData, HighData, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegFOG : GIFReg
|
||||
{
|
||||
public double F;
|
||||
|
||||
public GIFRegFOG(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegFOG u = new GIFRegFOG(addr, LowData, HighData, PackedFormat);
|
||||
u.Descriptor = (GIFRegDescriptor)addr;
|
||||
if (PackedFormat)
|
||||
u.F = (UInt16)(GetBit(HighData, 36, 8));
|
||||
else
|
||||
u.F = GetBit(LowData, 56, 8);
|
||||
return u;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@F : " + F.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegFOG : GIFReg
|
||||
{
|
||||
public double F;
|
||||
|
||||
public GIFRegFOG(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegFOG u = new GIFRegFOG(addr, LowData, HighData, PackedFormat);
|
||||
u.Descriptor = (GIFRegDescriptor)addr;
|
||||
if (PackedFormat)
|
||||
u.F = (UInt16)(GetBit(HighData, 36, 8));
|
||||
else
|
||||
u.F = GetBit(LowData, 56, 8);
|
||||
return u;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@F : " + F.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegNOP : GIFReg
|
||||
{
|
||||
public byte addr;
|
||||
|
||||
public GIFRegNOP(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegNOP nop = new GIFRegNOP(addr, LowData, HighData, PackedFormat);
|
||||
nop.Descriptor = GIFRegDescriptor.NOP;
|
||||
|
||||
return nop;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + " (0x" + addr.ToString("X2") + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegNOP : GIFReg
|
||||
{
|
||||
public byte addr;
|
||||
|
||||
public GIFRegNOP(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegNOP nop = new GIFRegNOP(addr, LowData, HighData, PackedFormat);
|
||||
nop.Descriptor = GIFRegDescriptor.NOP;
|
||||
|
||||
return nop;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + " (0x" + addr.ToString("X2") + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,68 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegPRIM : GIFReg
|
||||
{
|
||||
public GS_PRIM PrimitiveType;
|
||||
public GSIIP IIP;
|
||||
public bool TME;
|
||||
public bool FGE;
|
||||
public bool ABE;
|
||||
public bool AA1;
|
||||
public GSFST FST;
|
||||
public GSCTXT CTXT;
|
||||
public GSFIX FIX;
|
||||
|
||||
public GIFRegPRIM(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegPRIM pr = new GIFRegPRIM(addr, LowData, HighData, PackedFormat);
|
||||
pr.Descriptor = (GIFRegDescriptor)addr;
|
||||
pr.PrimitiveType = (GS_PRIM)GetBit(LowData, 0, 3);
|
||||
pr.IIP = (GSIIP)GetBit(LowData, 3, 1);
|
||||
pr.TME = Convert.ToBoolean(GetBit(LowData, 4, 1));
|
||||
pr.FGE = Convert.ToBoolean(GetBit(LowData, 5, 1));
|
||||
pr.ABE = Convert.ToBoolean(GetBit(LowData, 6, 1));
|
||||
pr.AA1 = Convert.ToBoolean(GetBit(LowData, 7, 1));
|
||||
pr.FST = (GSFST)(GetBit(LowData, 8, 1));
|
||||
pr.CTXT = (GSCTXT)(GetBit(LowData, 9, 1));
|
||||
pr.FIX = (GSFIX)(GetBit(LowData, 10, 1));
|
||||
return pr;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@Primitive Type : " + PrimitiveType.ToString() + "@IIP : " + IIP.ToString() + "@TME : " + TME.ToString() + "@FGE : " + FGE.ToString()
|
||||
+ "@ABE : " + ABE.ToString() + "@AA1 : " + AA1.ToString() + "@FST : " + FST.ToString() + "@CTXT : " + CTXT.ToString() + "@FIX : " + FIX.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum GSIIP
|
||||
{
|
||||
FlatShading=0,
|
||||
Gouraud=1
|
||||
}
|
||||
|
||||
public enum GSFST
|
||||
{
|
||||
STQValue=0,
|
||||
UVValue=1
|
||||
}
|
||||
|
||||
public enum GSCTXT
|
||||
{
|
||||
Context1 =0,
|
||||
Context2 =1
|
||||
}
|
||||
|
||||
public enum GSFIX
|
||||
{
|
||||
Unfixed =0,
|
||||
Fixed = 1
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegPRIM : GIFReg
|
||||
{
|
||||
public GS_PRIM PrimitiveType;
|
||||
public GSIIP IIP;
|
||||
public bool TME;
|
||||
public bool FGE;
|
||||
public bool ABE;
|
||||
public bool AA1;
|
||||
public GSFST FST;
|
||||
public GSCTXT CTXT;
|
||||
public GSFIX FIX;
|
||||
|
||||
public GIFRegPRIM(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegPRIM pr = new GIFRegPRIM(addr, LowData, HighData, PackedFormat);
|
||||
pr.Descriptor = (GIFRegDescriptor)addr;
|
||||
pr.PrimitiveType = (GS_PRIM)GetBit(LowData, 0, 3);
|
||||
pr.IIP = (GSIIP)GetBit(LowData, 3, 1);
|
||||
pr.TME = Convert.ToBoolean(GetBit(LowData, 4, 1));
|
||||
pr.FGE = Convert.ToBoolean(GetBit(LowData, 5, 1));
|
||||
pr.ABE = Convert.ToBoolean(GetBit(LowData, 6, 1));
|
||||
pr.AA1 = Convert.ToBoolean(GetBit(LowData, 7, 1));
|
||||
pr.FST = (GSFST)(GetBit(LowData, 8, 1));
|
||||
pr.CTXT = (GSCTXT)(GetBit(LowData, 9, 1));
|
||||
pr.FIX = (GSFIX)(GetBit(LowData, 10, 1));
|
||||
return pr;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@Primitive Type : " + PrimitiveType.ToString() + "@IIP : " + IIP.ToString() + "@TME : " + TME.ToString() + "@FGE : " + FGE.ToString()
|
||||
+ "@ABE : " + ABE.ToString() + "@AA1 : " + AA1.ToString() + "@FST : " + FST.ToString() + "@CTXT : " + CTXT.ToString() + "@FIX : " + FIX.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum GSIIP
|
||||
{
|
||||
FlatShading=0,
|
||||
Gouraud=1
|
||||
}
|
||||
|
||||
public enum GSFST
|
||||
{
|
||||
STQValue=0,
|
||||
UVValue=1
|
||||
}
|
||||
|
||||
public enum GSCTXT
|
||||
{
|
||||
Context1 =0,
|
||||
Context2 =1
|
||||
}
|
||||
|
||||
public enum GSFIX
|
||||
{
|
||||
Unfixed =0,
|
||||
Fixed = 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegRGBAQ : GIFReg
|
||||
{
|
||||
public byte R;
|
||||
public byte G;
|
||||
public byte B;
|
||||
public byte A;
|
||||
public float Q;
|
||||
|
||||
public GIFRegRGBAQ(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegRGBAQ r = new GIFRegRGBAQ(addr, LowData, HighData, PackedFormat);
|
||||
r.Descriptor = (GIFRegDescriptor)addr;
|
||||
if (PackedFormat)
|
||||
{
|
||||
r.R = (byte)GetBit(LowData, 0, 8);
|
||||
r.G = (byte)GetBit(LowData, 32, 8);
|
||||
r.B = (byte)GetBit(HighData, 0, 8);
|
||||
r.A = (byte)GetBit(HighData, 32, 8);
|
||||
r.Q = tag.Q;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.R = (byte)GetBit(LowData, 0, 8);
|
||||
r.G = (byte)GetBit(LowData, 8, 8);
|
||||
r.B = (byte)GetBit(LowData, 16, 8);
|
||||
r.A = (byte)GetBit(LowData, 24, 8);
|
||||
r.Q = BitConverter.ToSingle(BitConverter.GetBytes(LowData), 4);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@Red : " + R.ToString() + "@Green : " + G.ToString() + "@Blue : " + B.ToString() + "@Alpha : " + A.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegRGBAQ : GIFReg
|
||||
{
|
||||
public byte R;
|
||||
public byte G;
|
||||
public byte B;
|
||||
public byte A;
|
||||
public float Q;
|
||||
|
||||
public GIFRegRGBAQ(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegRGBAQ r = new GIFRegRGBAQ(addr, LowData, HighData, PackedFormat);
|
||||
r.Descriptor = (GIFRegDescriptor)addr;
|
||||
if (PackedFormat)
|
||||
{
|
||||
r.R = (byte)GetBit(LowData, 0, 8);
|
||||
r.G = (byte)GetBit(LowData, 32, 8);
|
||||
r.B = (byte)GetBit(HighData, 0, 8);
|
||||
r.A = (byte)GetBit(HighData, 32, 8);
|
||||
r.Q = tag.Q;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.R = (byte)GetBit(LowData, 0, 8);
|
||||
r.G = (byte)GetBit(LowData, 8, 8);
|
||||
r.B = (byte)GetBit(LowData, 16, 8);
|
||||
r.A = (byte)GetBit(LowData, 24, 8);
|
||||
r.Q = BitConverter.ToSingle(BitConverter.GetBytes(LowData), 4);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@Red : " + R.ToString() + "@Green : " + G.ToString() + "@Blue : " + B.ToString() + "@Alpha : " + A.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegST : GIFReg
|
||||
{
|
||||
public float S;
|
||||
public float T;
|
||||
public float Q;
|
||||
|
||||
public bool isSTQ;
|
||||
|
||||
public GIFRegST(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegST st = new GIFRegST(addr, LowData, HighData, PackedFormat);
|
||||
st.Descriptor = (GIFRegDescriptor)addr;
|
||||
|
||||
st.S = BitConverter.ToSingle(BitConverter.GetBytes(LowData), 0);
|
||||
st.T = BitConverter.ToSingle(BitConverter.GetBytes(LowData), 4);
|
||||
if (PackedFormat)
|
||||
{
|
||||
st.Q = BitConverter.ToSingle(BitConverter.GetBytes(HighData), 0);
|
||||
tag.Q = st.Q;
|
||||
st.isSTQ = true;
|
||||
}
|
||||
else
|
||||
st.isSTQ = false;
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@S : " + S.ToString("F8") + "@T : " + T.ToString("F8") + (isSTQ ? "@Q : " + Q.ToString("F8") : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegST : GIFReg
|
||||
{
|
||||
public float S;
|
||||
public float T;
|
||||
public float Q;
|
||||
|
||||
public bool isSTQ;
|
||||
|
||||
public GIFRegST(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegST st = new GIFRegST(addr, LowData, HighData, PackedFormat);
|
||||
st.Descriptor = (GIFRegDescriptor)addr;
|
||||
|
||||
st.S = BitConverter.ToSingle(BitConverter.GetBytes(LowData), 0);
|
||||
st.T = BitConverter.ToSingle(BitConverter.GetBytes(LowData), 4);
|
||||
if (PackedFormat)
|
||||
{
|
||||
st.Q = BitConverter.ToSingle(BitConverter.GetBytes(HighData), 0);
|
||||
tag.Q = st.Q;
|
||||
st.isSTQ = true;
|
||||
}
|
||||
else
|
||||
st.isSTQ = false;
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@S : " + S.ToString("F8") + "@T : " + T.ToString("F8") + (isSTQ ? "@Q : " + Q.ToString("F8") : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,95 +1,95 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegTEX0 : GIFReg
|
||||
{
|
||||
public ushort TBP0;
|
||||
public byte TBW;
|
||||
public TEXPSM PSM;
|
||||
public byte TW;
|
||||
public byte TH;
|
||||
public TEXTCC TCC;
|
||||
public TEXTFX TFX;
|
||||
public ushort CBP;
|
||||
public TEXCPSM CPSM;
|
||||
public TEXCSM CSM;
|
||||
public byte CSA;
|
||||
public byte CLD;
|
||||
|
||||
public GIFRegTEX0(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegTEX0 tex0 = new GIFRegTEX0(addr, LowData, HighData, PackedFormat);
|
||||
tex0.Descriptor = (GIFRegDescriptor)addr;
|
||||
tex0.TBP0 = (ushort)GetBit(LowData, 0, 14);
|
||||
tex0.TBW = (byte)GetBit(LowData, 14, 6);
|
||||
tex0.PSM = (TEXPSM)GetBit(LowData, 20, 6);
|
||||
tex0.TW = (byte)GetBit(LowData, 26, 4);
|
||||
tex0.TH = (byte)GetBit(LowData, 30, 4);
|
||||
tex0.TCC = (TEXTCC)GetBit(LowData, 34, 1);
|
||||
tex0.TFX = (TEXTFX)GetBit(LowData, 35, 2);
|
||||
tex0.CBP = (ushort)GetBit(LowData, 37, 14);
|
||||
tex0.CPSM = (TEXCPSM)GetBit(LowData, 51, 4);
|
||||
tex0.CSM = (TEXCSM)GetBit(LowData, 55, 1);
|
||||
tex0.CSA = (byte)GetBit(LowData, 56, 5);
|
||||
tex0.CLD = (byte)GetBit(LowData, 61, 3);
|
||||
return tex0;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@TBP0 : " + TBP0.ToString() + "@TBW : " + TBW.ToString() + "@PSM : " + PSM.ToString() + "@TW : " + TW.ToString() + "@TH : " + TH.ToString()
|
||||
+ "@TCC : " + TCC.ToString() + "@TFX : " + TFX.ToString() + "@CBP : " + CBP.ToString() + "@CPSM : " + CPSM.ToString() + "@CSM : " + CSM.ToString()
|
||||
+ "@CSA : " + CSA.ToString() + "@CLD : " + CLD.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum TEXPSM
|
||||
{
|
||||
PSMCT32 = 0,
|
||||
PSMCT24 = 1,
|
||||
PSMCT16 = 2,
|
||||
PSMCT16S = 10,
|
||||
PSMT8 = 19,
|
||||
PSMT4 = 20,
|
||||
PSMT8H = 27,
|
||||
PSMT4HL = 36,
|
||||
PSMT4HH = 44,
|
||||
PSMZ32 = 48,
|
||||
PSMZ24 = 49,
|
||||
PSMZ16 = 50,
|
||||
PSMZ16S = 58
|
||||
}
|
||||
|
||||
public enum TEXTCC
|
||||
{
|
||||
RGB = 0,
|
||||
RGBA = 1
|
||||
}
|
||||
|
||||
public enum TEXTFX
|
||||
{
|
||||
MODULATE = 0,
|
||||
DECAL = 1,
|
||||
HIGHLIGHT = 2,
|
||||
HIGHLIGHT2 = 3
|
||||
}
|
||||
|
||||
public enum TEXCPSM
|
||||
{
|
||||
PSMCT32 = 0,
|
||||
PSMCT16 = 2,
|
||||
PSMCT16S = 10
|
||||
}
|
||||
|
||||
public enum TEXCSM
|
||||
{
|
||||
CSM1 = 0,
|
||||
CSM2 = 1
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegTEX0 : GIFReg
|
||||
{
|
||||
public ushort TBP0;
|
||||
public byte TBW;
|
||||
public TEXPSM PSM;
|
||||
public byte TW;
|
||||
public byte TH;
|
||||
public TEXTCC TCC;
|
||||
public TEXTFX TFX;
|
||||
public ushort CBP;
|
||||
public TEXCPSM CPSM;
|
||||
public TEXCSM CSM;
|
||||
public byte CSA;
|
||||
public byte CLD;
|
||||
|
||||
public GIFRegTEX0(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegTEX0 tex0 = new GIFRegTEX0(addr, LowData, HighData, PackedFormat);
|
||||
tex0.Descriptor = (GIFRegDescriptor)addr;
|
||||
tex0.TBP0 = (ushort)GetBit(LowData, 0, 14);
|
||||
tex0.TBW = (byte)GetBit(LowData, 14, 6);
|
||||
tex0.PSM = (TEXPSM)GetBit(LowData, 20, 6);
|
||||
tex0.TW = (byte)GetBit(LowData, 26, 4);
|
||||
tex0.TH = (byte)GetBit(LowData, 30, 4);
|
||||
tex0.TCC = (TEXTCC)GetBit(LowData, 34, 1);
|
||||
tex0.TFX = (TEXTFX)GetBit(LowData, 35, 2);
|
||||
tex0.CBP = (ushort)GetBit(LowData, 37, 14);
|
||||
tex0.CPSM = (TEXCPSM)GetBit(LowData, 51, 4);
|
||||
tex0.CSM = (TEXCSM)GetBit(LowData, 55, 1);
|
||||
tex0.CSA = (byte)GetBit(LowData, 56, 5);
|
||||
tex0.CLD = (byte)GetBit(LowData, 61, 3);
|
||||
return tex0;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@TBP0 : " + TBP0.ToString() + "@TBW : " + TBW.ToString() + "@PSM : " + PSM.ToString() + "@TW : " + TW.ToString() + "@TH : " + TH.ToString()
|
||||
+ "@TCC : " + TCC.ToString() + "@TFX : " + TFX.ToString() + "@CBP : " + CBP.ToString() + "@CPSM : " + CPSM.ToString() + "@CSM : " + CSM.ToString()
|
||||
+ "@CSA : " + CSA.ToString() + "@CLD : " + CLD.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum TEXPSM
|
||||
{
|
||||
PSMCT32 = 0,
|
||||
PSMCT24 = 1,
|
||||
PSMCT16 = 2,
|
||||
PSMCT16S = 10,
|
||||
PSMT8 = 19,
|
||||
PSMT4 = 20,
|
||||
PSMT8H = 27,
|
||||
PSMT4HL = 36,
|
||||
PSMT4HH = 44,
|
||||
PSMZ32 = 48,
|
||||
PSMZ24 = 49,
|
||||
PSMZ16 = 50,
|
||||
PSMZ16S = 58
|
||||
}
|
||||
|
||||
public enum TEXTCC
|
||||
{
|
||||
RGB = 0,
|
||||
RGBA = 1
|
||||
}
|
||||
|
||||
public enum TEXTFX
|
||||
{
|
||||
MODULATE = 0,
|
||||
DECAL = 1,
|
||||
HIGHLIGHT = 2,
|
||||
HIGHLIGHT2 = 3
|
||||
}
|
||||
|
||||
public enum TEXCPSM
|
||||
{
|
||||
PSMCT32 = 0,
|
||||
PSMCT16 = 2,
|
||||
PSMCT16S = 10
|
||||
}
|
||||
|
||||
public enum TEXCSM
|
||||
{
|
||||
CSM1 = 0,
|
||||
CSM2 = 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegUV : GIFReg
|
||||
{
|
||||
public double U;
|
||||
public double V;
|
||||
|
||||
public GIFRegUV(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegUV uv = new GIFRegUV(addr, LowData, HighData, PackedFormat);
|
||||
uv.Descriptor = (GIFRegDescriptor)addr;
|
||||
if (PackedFormat)
|
||||
{
|
||||
uv.U = GetBit(LowData, 0, 14) / 16d;
|
||||
uv.V = GetBit(LowData, 32, 14) / 16d;
|
||||
}
|
||||
else
|
||||
{
|
||||
uv.U = GetBit(LowData, 0, 14) / 16d;
|
||||
uv.V = GetBit(LowData, 16, 14) / 16d;
|
||||
}
|
||||
return uv;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@U : " + U.ToString("F4") + "@V : " + V.ToString("F4");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegUV : GIFReg
|
||||
{
|
||||
public double U;
|
||||
public double V;
|
||||
|
||||
public GIFRegUV(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegUV uv = new GIFRegUV(addr, LowData, HighData, PackedFormat);
|
||||
uv.Descriptor = (GIFRegDescriptor)addr;
|
||||
if (PackedFormat)
|
||||
{
|
||||
uv.U = GetBit(LowData, 0, 14) / 16d;
|
||||
uv.V = GetBit(LowData, 32, 14) / 16d;
|
||||
}
|
||||
else
|
||||
{
|
||||
uv.U = GetBit(LowData, 0, 14) / 16d;
|
||||
uv.V = GetBit(LowData, 16, 14) / 16d;
|
||||
}
|
||||
return uv;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@U : " + U.ToString("F4") + "@V : " + V.ToString("F4");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegUnimpl : GIFReg
|
||||
{
|
||||
public GIFRegUnimpl(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegUnimpl u = new GIFRegUnimpl(addr, LowData, HighData, PackedFormat);
|
||||
u.Descriptor = (GIFRegDescriptor)addr;
|
||||
return u;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegUnimpl : GIFReg
|
||||
{
|
||||
public GIFRegUnimpl(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegUnimpl u = new GIFRegUnimpl(addr, LowData, HighData, PackedFormat);
|
||||
u.Descriptor = (GIFRegDescriptor)addr;
|
||||
return u;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,76 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegXYZF : GIFReg
|
||||
{
|
||||
public double X;
|
||||
public double Y;
|
||||
public UInt32 Z;
|
||||
public UInt16 F;
|
||||
|
||||
public bool IsXYZF;
|
||||
|
||||
public GIFRegXYZF(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg UnpackXYZ(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegXYZF xyzf = new GIFRegXYZF(addr, LowData, HighData, PackedFormat);
|
||||
|
||||
xyzf.IsXYZF = false;
|
||||
if (PackedFormat && addr == (int)GIFRegDescriptor.XYZ2 && GetBit(HighData, 47, 1) == 1)
|
||||
xyzf.Descriptor = GIFRegDescriptor.XYZ3;
|
||||
else
|
||||
xyzf.Descriptor = (GIFRegDescriptor)addr;
|
||||
|
||||
if (PackedFormat)
|
||||
{
|
||||
xyzf.X = GetBit(LowData, 0, 16) / 16d;
|
||||
xyzf.Y = GetBit(LowData, 32, 16) / 16d;
|
||||
xyzf.Z = (UInt32)(GetBit(HighData, 0, 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
xyzf.X = GetBit(LowData, 0, 16) / 16d;
|
||||
xyzf.Y = GetBit(LowData, 16, 16) / 16d;
|
||||
xyzf.Z = (UInt32)(GetBit(LowData, 32, 32));
|
||||
}
|
||||
return xyzf;
|
||||
}
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegXYZF xyzf = new GIFRegXYZF(addr, LowData, HighData, PackedFormat);
|
||||
|
||||
xyzf.IsXYZF = true;
|
||||
if (PackedFormat && addr == (int)GIFRegDescriptor.XYZF2 && GetBit(HighData, 47, 1) == 1)
|
||||
xyzf.Descriptor = GIFRegDescriptor.XYZF3;
|
||||
else
|
||||
xyzf.Descriptor = (GIFRegDescriptor)addr;
|
||||
|
||||
if (PackedFormat)
|
||||
{
|
||||
xyzf.X = GetBit(LowData, 0, 16) / 16d;
|
||||
xyzf.Y = GetBit(LowData, 32, 16) / 16d;
|
||||
xyzf.Z = (UInt32)(GetBit(HighData, 4, 24));
|
||||
xyzf.F = (UInt16)(GetBit(HighData, 36, 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
xyzf.X = GetBit(LowData, 0, 16) / 16d;
|
||||
xyzf.Y = GetBit(LowData, 16, 16) / 16d;
|
||||
xyzf.Z = (UInt32)(GetBit(LowData, 32, 24));
|
||||
xyzf.F = (UInt16)(GetBit(LowData, 56, 8));
|
||||
}
|
||||
return xyzf;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@X : " + X.ToString("F4") + "@Y : " + Y.ToString("F4") + "@Z : " + Z.ToString() + (IsXYZF ? "@F : " + F.ToString() : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFRegXYZF : GIFReg
|
||||
{
|
||||
public double X;
|
||||
public double Y;
|
||||
public UInt32 Z;
|
||||
public UInt16 F;
|
||||
|
||||
public bool IsXYZF;
|
||||
|
||||
public GIFRegXYZF(byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat) : base(addr, LowData, HighData, PackedFormat) { }
|
||||
|
||||
static public GIFReg UnpackXYZ(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegXYZF xyzf = new GIFRegXYZF(addr, LowData, HighData, PackedFormat);
|
||||
|
||||
xyzf.IsXYZF = false;
|
||||
if (PackedFormat && addr == (int)GIFRegDescriptor.XYZ2 && GetBit(HighData, 47, 1) == 1)
|
||||
xyzf.Descriptor = GIFRegDescriptor.XYZ3;
|
||||
else
|
||||
xyzf.Descriptor = (GIFRegDescriptor)addr;
|
||||
|
||||
if (PackedFormat)
|
||||
{
|
||||
xyzf.X = GetBit(LowData, 0, 16) / 16d;
|
||||
xyzf.Y = GetBit(LowData, 32, 16) / 16d;
|
||||
xyzf.Z = (UInt32)(GetBit(HighData, 0, 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
xyzf.X = GetBit(LowData, 0, 16) / 16d;
|
||||
xyzf.Y = GetBit(LowData, 16, 16) / 16d;
|
||||
xyzf.Z = (UInt32)(GetBit(LowData, 32, 32));
|
||||
}
|
||||
return xyzf;
|
||||
}
|
||||
|
||||
static public GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat)
|
||||
{
|
||||
GIFRegXYZF xyzf = new GIFRegXYZF(addr, LowData, HighData, PackedFormat);
|
||||
|
||||
xyzf.IsXYZF = true;
|
||||
if (PackedFormat && addr == (int)GIFRegDescriptor.XYZF2 && GetBit(HighData, 47, 1) == 1)
|
||||
xyzf.Descriptor = GIFRegDescriptor.XYZF3;
|
||||
else
|
||||
xyzf.Descriptor = (GIFRegDescriptor)addr;
|
||||
|
||||
if (PackedFormat)
|
||||
{
|
||||
xyzf.X = GetBit(LowData, 0, 16) / 16d;
|
||||
xyzf.Y = GetBit(LowData, 32, 16) / 16d;
|
||||
xyzf.Z = (UInt32)(GetBit(HighData, 4, 24));
|
||||
xyzf.F = (UInt16)(GetBit(HighData, 36, 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
xyzf.X = GetBit(LowData, 0, 16) / 16d;
|
||||
xyzf.Y = GetBit(LowData, 16, 16) / 16d;
|
||||
xyzf.Z = (UInt32)(GetBit(LowData, 32, 24));
|
||||
xyzf.F = (UInt16)(GetBit(LowData, 56, 8));
|
||||
}
|
||||
return xyzf;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Descriptor.ToString() + "@X : " + X.ToString("F4") + "@Y : " + Y.ToString("F4") + "@Z : " + Z.ToString() + (IsXYZF ? "@F : " + F.ToString() : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GifImage : IGifData
|
||||
{
|
||||
public byte[] Data;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "IMAGE@" + Data.Length.ToString() + " bytes";
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GifImage : IGifData
|
||||
{
|
||||
public byte[] Data;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "IMAGE@" + Data.Length.ToString() + " bytes";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public interface IGifData
|
||||
{
|
||||
String ToString();
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public interface IGifData
|
||||
{
|
||||
String ToString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,170 +1,170 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFTag : GIFUtil
|
||||
{
|
||||
public delegate GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat);
|
||||
static public Dictionary<int, Unpack> UnpackReg;
|
||||
|
||||
private UInt64 TAG, REGS;
|
||||
internal float Q; // GIF has an internal Q register which is reset to 1.0 at the tag and updated on packed ST(Q) for output at next RGBAQ
|
||||
|
||||
public GSTransferPath path;
|
||||
public UInt32 nloop;
|
||||
public UInt32 eop;
|
||||
public UInt32 pre;
|
||||
public GIFPrim prim;
|
||||
public GIFFLG flg;
|
||||
public UInt32 nreg;
|
||||
public List<IGifData> regs;
|
||||
public int size;
|
||||
|
||||
static GIFTag()
|
||||
{
|
||||
UnpackReg = new Dictionary<int, Unpack>();
|
||||
UnpackReg.Add((int)GIFRegDescriptor.PRIM, GIFRegPRIM.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.RGBAQ, GIFRegRGBAQ.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ST, GIFRegST.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.UV, GIFRegUV.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYZF2, GIFRegXYZF.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYZ2, GIFRegXYZF.UnpackXYZ);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX0_1, GIFRegTEX0.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX0_2, GIFRegTEX0.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.CLAMP_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.CLAMP_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FOG, GIFRegFOG.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYZF3, GIFRegXYZF.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYZ3, GIFRegXYZF.UnpackXYZ);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.AD, GIFRegAD.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX1_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX1_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX2_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX2_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYOFFSET_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYOFFSET_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.PRMODECONT, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.PRMODE, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEXCLUT, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.SCANMSK, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.MIPTBP1_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.MIPTBP1_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.MIPTBP2_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.MIPTBP2_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEXA, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FOGCOL, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEXFLUSH, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.SCISSOR_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.SCISSOR_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ALPHA_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ALPHA_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.DIMX, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.DTHE, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.COLCLAMP, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEST_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEST_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.PABE, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FBA_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FBA_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FRAME_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FRAME_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ZBUF_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ZBUF_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.BITBLTBUF, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TRXPOS, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TRXREG, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TRXDIR, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.HWREG, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.SIGNAL, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FINISH, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.LABEL, GIFRegUnimpl.Unpack);
|
||||
}
|
||||
|
||||
public static Unpack GetUnpack(int reg)
|
||||
{
|
||||
Unpack ret;
|
||||
if (!UnpackReg.TryGetValue(reg, out ret))
|
||||
return GIFRegNOP.Unpack;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static internal GIFTag ExtractGifTag(byte[] data, GSTransferPath path)
|
||||
{
|
||||
GIFTag t = new GIFTag();
|
||||
t.size = data.Length;
|
||||
t.path = path;
|
||||
t.TAG = BitConverter.ToUInt64(data, 0);
|
||||
t.REGS = BitConverter.ToUInt64(data, 8);
|
||||
|
||||
t.Q = 1f;
|
||||
t.nloop = (uint)GetBit(t.TAG, 0, 15);
|
||||
t.eop = (uint)GetBit(t.TAG, 15, 1);
|
||||
t.pre = (uint)GetBit(t.TAG, 46, 1);
|
||||
t.prim = GIFPrim.ExtractGIFPrim((uint)GetBit(t.TAG, 47, 11));
|
||||
t.flg = (GIFFLG)GetBit(t.TAG, 58, 2);
|
||||
t.nreg = (uint)GetBit(t.TAG, 60, 4);
|
||||
if (t.nreg == 0)
|
||||
t.nreg = 16;
|
||||
|
||||
byte[] registers = new byte[t.nreg];
|
||||
Unpack[] regsunpack = new Unpack[t.nreg];
|
||||
|
||||
t.regs = new List<IGifData>();
|
||||
for (byte i = 0; i < t.nreg; i++)
|
||||
{
|
||||
byte reg = (byte)GetBit(t.REGS, i * 4, 4);
|
||||
registers[i] = reg;
|
||||
regsunpack[i] = GetUnpack(reg);
|
||||
}
|
||||
|
||||
int p = 16;
|
||||
switch (t.flg)
|
||||
{
|
||||
case GIFFLG.GIF_FLG_PACKED:
|
||||
for (int j = 0; j < t.nloop; j++)
|
||||
for (int i = 0; i < t.nreg; i++)
|
||||
{
|
||||
UInt64 LowData = BitConverter.ToUInt64(data, p);
|
||||
UInt64 HighData = BitConverter.ToUInt64(data, p + 8);
|
||||
t.regs.Add(regsunpack[i](t, registers[i], LowData, HighData, true));
|
||||
p += 16;
|
||||
}
|
||||
break;
|
||||
case GIFFLG.GIF_FLG_REGLIST:
|
||||
for (int j = 0; j < t.nloop; j++)
|
||||
for (int i = 0; i < t.nreg; i++)
|
||||
{
|
||||
UInt64 Data = BitConverter.ToUInt64(data, p);
|
||||
t.regs.Add(regsunpack[i](t, registers[i], Data, 0, false));
|
||||
p += 8;
|
||||
}
|
||||
break;
|
||||
case GIFFLG.GIF_FLG_IMAGE:
|
||||
case GIFFLG.GIF_FLG_IMAGE2:
|
||||
GifImage image = new GifImage();
|
||||
image.Data = new byte[t.nloop * 16];
|
||||
try
|
||||
{
|
||||
Array.Copy(data, 16, image.Data, 0, t.nloop * 16);
|
||||
}
|
||||
catch (ArgumentException) { }
|
||||
t.regs.Add(image);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GIFFLG
|
||||
{
|
||||
GIF_FLG_PACKED =0,
|
||||
GIF_FLG_REGLIST =1,
|
||||
GIF_FLG_IMAGE = 2,
|
||||
GIF_FLG_IMAGE2 = 3
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFTag : GIFUtil
|
||||
{
|
||||
public delegate GIFReg Unpack(GIFTag tag, byte addr, UInt64 LowData, UInt64 HighData, bool PackedFormat);
|
||||
static public Dictionary<int, Unpack> UnpackReg;
|
||||
|
||||
private UInt64 TAG, REGS;
|
||||
internal float Q; // GIF has an internal Q register which is reset to 1.0 at the tag and updated on packed ST(Q) for output at next RGBAQ
|
||||
|
||||
public GSTransferPath path;
|
||||
public UInt32 nloop;
|
||||
public UInt32 eop;
|
||||
public UInt32 pre;
|
||||
public GIFPrim prim;
|
||||
public GIFFLG flg;
|
||||
public UInt32 nreg;
|
||||
public List<IGifData> regs;
|
||||
public int size;
|
||||
|
||||
static GIFTag()
|
||||
{
|
||||
UnpackReg = new Dictionary<int, Unpack>();
|
||||
UnpackReg.Add((int)GIFRegDescriptor.PRIM, GIFRegPRIM.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.RGBAQ, GIFRegRGBAQ.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ST, GIFRegST.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.UV, GIFRegUV.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYZF2, GIFRegXYZF.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYZ2, GIFRegXYZF.UnpackXYZ);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX0_1, GIFRegTEX0.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX0_2, GIFRegTEX0.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.CLAMP_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.CLAMP_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FOG, GIFRegFOG.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYZF3, GIFRegXYZF.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYZ3, GIFRegXYZF.UnpackXYZ);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.AD, GIFRegAD.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX1_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX1_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX2_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEX2_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYOFFSET_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.XYOFFSET_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.PRMODECONT, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.PRMODE, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEXCLUT, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.SCANMSK, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.MIPTBP1_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.MIPTBP1_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.MIPTBP2_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.MIPTBP2_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEXA, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FOGCOL, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEXFLUSH, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.SCISSOR_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.SCISSOR_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ALPHA_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ALPHA_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.DIMX, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.DTHE, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.COLCLAMP, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEST_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TEST_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.PABE, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FBA_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FBA_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FRAME_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FRAME_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ZBUF_1, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.ZBUF_2, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.BITBLTBUF, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TRXPOS, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TRXREG, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.TRXDIR, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.HWREG, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.SIGNAL, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.FINISH, GIFRegUnimpl.Unpack);
|
||||
UnpackReg.Add((int)GIFRegDescriptor.LABEL, GIFRegUnimpl.Unpack);
|
||||
}
|
||||
|
||||
public static Unpack GetUnpack(int reg)
|
||||
{
|
||||
Unpack ret;
|
||||
if (!UnpackReg.TryGetValue(reg, out ret))
|
||||
return GIFRegNOP.Unpack;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static internal GIFTag ExtractGifTag(byte[] data, GSTransferPath path)
|
||||
{
|
||||
GIFTag t = new GIFTag();
|
||||
t.size = data.Length;
|
||||
t.path = path;
|
||||
t.TAG = BitConverter.ToUInt64(data, 0);
|
||||
t.REGS = BitConverter.ToUInt64(data, 8);
|
||||
|
||||
t.Q = 1f;
|
||||
t.nloop = (uint)GetBit(t.TAG, 0, 15);
|
||||
t.eop = (uint)GetBit(t.TAG, 15, 1);
|
||||
t.pre = (uint)GetBit(t.TAG, 46, 1);
|
||||
t.prim = GIFPrim.ExtractGIFPrim((uint)GetBit(t.TAG, 47, 11));
|
||||
t.flg = (GIFFLG)GetBit(t.TAG, 58, 2);
|
||||
t.nreg = (uint)GetBit(t.TAG, 60, 4);
|
||||
if (t.nreg == 0)
|
||||
t.nreg = 16;
|
||||
|
||||
byte[] registers = new byte[t.nreg];
|
||||
Unpack[] regsunpack = new Unpack[t.nreg];
|
||||
|
||||
t.regs = new List<IGifData>();
|
||||
for (byte i = 0; i < t.nreg; i++)
|
||||
{
|
||||
byte reg = (byte)GetBit(t.REGS, i * 4, 4);
|
||||
registers[i] = reg;
|
||||
regsunpack[i] = GetUnpack(reg);
|
||||
}
|
||||
|
||||
int p = 16;
|
||||
switch (t.flg)
|
||||
{
|
||||
case GIFFLG.GIF_FLG_PACKED:
|
||||
for (int j = 0; j < t.nloop; j++)
|
||||
for (int i = 0; i < t.nreg; i++)
|
||||
{
|
||||
UInt64 LowData = BitConverter.ToUInt64(data, p);
|
||||
UInt64 HighData = BitConverter.ToUInt64(data, p + 8);
|
||||
t.regs.Add(regsunpack[i](t, registers[i], LowData, HighData, true));
|
||||
p += 16;
|
||||
}
|
||||
break;
|
||||
case GIFFLG.GIF_FLG_REGLIST:
|
||||
for (int j = 0; j < t.nloop; j++)
|
||||
for (int i = 0; i < t.nreg; i++)
|
||||
{
|
||||
UInt64 Data = BitConverter.ToUInt64(data, p);
|
||||
t.regs.Add(regsunpack[i](t, registers[i], Data, 0, false));
|
||||
p += 8;
|
||||
}
|
||||
break;
|
||||
case GIFFLG.GIF_FLG_IMAGE:
|
||||
case GIFFLG.GIF_FLG_IMAGE2:
|
||||
GifImage image = new GifImage();
|
||||
image.Data = new byte[t.nloop * 16];
|
||||
try
|
||||
{
|
||||
Array.Copy(data, 16, image.Data, 0, t.nloop * 16);
|
||||
}
|
||||
catch (ArgumentException) { }
|
||||
t.regs.Add(image);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GIFFLG
|
||||
{
|
||||
GIF_FLG_PACKED =0,
|
||||
GIF_FLG_REGLIST =1,
|
||||
GIF_FLG_IMAGE = 2,
|
||||
GIF_FLG_IMAGE2 = 3
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFUtil
|
||||
{
|
||||
public static UInt64 GetBit(UInt64 value, int lower, int count)
|
||||
{
|
||||
return (value >> lower) & (ulong)((1ul << count) - 1);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
[Serializable]
|
||||
public class GIFUtil
|
||||
{
|
||||
public static UInt64 GetBit(UInt64 value, int lower, int count)
|
||||
{
|
||||
return (value >> lower) & (ulong)((1ul << count) - 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public class GSData
|
||||
{
|
||||
public GSType id;
|
||||
public byte[] data;
|
||||
}
|
||||
|
||||
public enum GSType
|
||||
{
|
||||
Transfer = 0,
|
||||
VSync = 1,
|
||||
ReadFIFO2 = 2,
|
||||
Registers = 3
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public class GSData
|
||||
{
|
||||
public GSType id;
|
||||
public byte[] data;
|
||||
}
|
||||
|
||||
public enum GSType
|
||||
{
|
||||
Transfer = 0,
|
||||
VSync = 1,
|
||||
ReadFIFO2 = 2,
|
||||
Registers = 3
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public class GSTransfer : GSData
|
||||
{
|
||||
public GSTransferPath Path;
|
||||
}
|
||||
|
||||
public enum GSTransferPath
|
||||
{
|
||||
Path1Old = 0,
|
||||
Path2 = 1,
|
||||
Path3 = 2,
|
||||
Path1New = 3
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public class GSTransfer : GSData
|
||||
{
|
||||
public GSTransferPath Path;
|
||||
}
|
||||
|
||||
public enum GSTransferPath
|
||||
{
|
||||
Path1Old = 0,
|
||||
Path2 = 1,
|
||||
Path3 = 2,
|
||||
Path1New = 3
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,133 +1,133 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public class GSDump
|
||||
{
|
||||
public Int32 CRC;
|
||||
public byte[] GSFreeze;
|
||||
public byte[] StateData;
|
||||
public byte[] Registers; // 8192 bytes
|
||||
|
||||
public int Size
|
||||
{
|
||||
get
|
||||
{
|
||||
int size = 0;
|
||||
size = 4;
|
||||
size += StateData.Length;
|
||||
size += Registers.Length;
|
||||
foreach (var itm in Data)
|
||||
{
|
||||
size += itm.data.Length;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
public List<GSData> Data;
|
||||
|
||||
public GSDump()
|
||||
{
|
||||
Data = new List<GSData>();
|
||||
}
|
||||
|
||||
public GSDump Clone()
|
||||
{
|
||||
GSDump newDump = new GSDump();
|
||||
newDump.CRC = this.CRC;
|
||||
|
||||
byte[] state = new byte[StateData.Length];
|
||||
Array.Copy(StateData,state, StateData.Length);
|
||||
newDump.StateData = state;
|
||||
|
||||
newDump.Registers = new byte[8192];
|
||||
Array.Copy(this.Registers, newDump.Registers, 8192);
|
||||
|
||||
foreach (var itm in this.Data)
|
||||
{
|
||||
if (itm.GetType().IsInstanceOfType(typeof(GSTransfer)))
|
||||
{
|
||||
GSTransfer gt = new GSTransfer();
|
||||
gt.id = itm.id;
|
||||
gt.Path = ((GSTransfer)itm).Path;
|
||||
gt.data = new byte[itm.data.Length];
|
||||
Array.Copy(itm.data, gt.data, itm.data.Length);
|
||||
newDump.Data.Add(gt);
|
||||
}
|
||||
else
|
||||
{
|
||||
GSData gt = new GSData();
|
||||
gt.id = itm.id;
|
||||
gt.data = new byte[itm.data.Length];
|
||||
Array.Copy(itm.data, gt.data, itm.data.Length);
|
||||
newDump.Data.Add(gt);
|
||||
}
|
||||
}
|
||||
return newDump;
|
||||
}
|
||||
|
||||
static public GSDump LoadDump(String FileName)
|
||||
{
|
||||
GSDump dmp = new GSDump();
|
||||
|
||||
BinaryReader br = new BinaryReader(System.IO.File.Open(FileName, FileMode.Open));
|
||||
dmp.CRC = br.ReadInt32();
|
||||
|
||||
Int32 ss = br.ReadInt32();
|
||||
dmp.StateData = br.ReadBytes(ss);
|
||||
|
||||
dmp.Registers = br.ReadBytes(8192);
|
||||
|
||||
while (br.PeekChar() != -1)
|
||||
{
|
||||
GSType id = (GSType)br.ReadByte();
|
||||
switch (id)
|
||||
{
|
||||
case GSType.Transfer:
|
||||
GSTransfer data = new GSTransfer();
|
||||
|
||||
byte index = br.ReadByte();
|
||||
|
||||
data.id = id;
|
||||
data.Path = (GSTransferPath)index;
|
||||
|
||||
Int32 size = br.ReadInt32();
|
||||
|
||||
List<byte> Data = new List<byte>();
|
||||
Data.AddRange(br.ReadBytes(size));
|
||||
data.data = Data.ToArray();
|
||||
dmp.Data.Add(data);
|
||||
break;
|
||||
case GSType.VSync:
|
||||
GSData dataV = new GSData();
|
||||
dataV.id = id;
|
||||
dataV.data = br.ReadBytes(1);
|
||||
dmp.Data.Add(dataV);
|
||||
break;
|
||||
case GSType.ReadFIFO2:
|
||||
GSData dataR = new GSData();
|
||||
dataR.id = id;
|
||||
Int32 sF = br.ReadInt32();
|
||||
dataR.data = BitConverter.GetBytes(sF);
|
||||
dmp.Data.Add(dataR);
|
||||
break;
|
||||
case GSType.Registers:
|
||||
GSData dataRR = new GSData();
|
||||
dataRR.id = id;
|
||||
dataRR.data = br.ReadBytes(8192);
|
||||
dmp.Data.Add(dataRR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
br.Close();
|
||||
|
||||
return dmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
public class GSDump
|
||||
{
|
||||
public Int32 CRC;
|
||||
public byte[] GSFreeze;
|
||||
public byte[] StateData;
|
||||
public byte[] Registers; // 8192 bytes
|
||||
|
||||
public int Size
|
||||
{
|
||||
get
|
||||
{
|
||||
int size = 0;
|
||||
size = 4;
|
||||
size += StateData.Length;
|
||||
size += Registers.Length;
|
||||
foreach (var itm in Data)
|
||||
{
|
||||
size += itm.data.Length;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
public List<GSData> Data;
|
||||
|
||||
public GSDump()
|
||||
{
|
||||
Data = new List<GSData>();
|
||||
}
|
||||
|
||||
public GSDump Clone()
|
||||
{
|
||||
GSDump newDump = new GSDump();
|
||||
newDump.CRC = this.CRC;
|
||||
|
||||
byte[] state = new byte[StateData.Length];
|
||||
Array.Copy(StateData,state, StateData.Length);
|
||||
newDump.StateData = state;
|
||||
|
||||
newDump.Registers = new byte[8192];
|
||||
Array.Copy(this.Registers, newDump.Registers, 8192);
|
||||
|
||||
foreach (var itm in this.Data)
|
||||
{
|
||||
if (itm.GetType().IsInstanceOfType(typeof(GSTransfer)))
|
||||
{
|
||||
GSTransfer gt = new GSTransfer();
|
||||
gt.id = itm.id;
|
||||
gt.Path = ((GSTransfer)itm).Path;
|
||||
gt.data = new byte[itm.data.Length];
|
||||
Array.Copy(itm.data, gt.data, itm.data.Length);
|
||||
newDump.Data.Add(gt);
|
||||
}
|
||||
else
|
||||
{
|
||||
GSData gt = new GSData();
|
||||
gt.id = itm.id;
|
||||
gt.data = new byte[itm.data.Length];
|
||||
Array.Copy(itm.data, gt.data, itm.data.Length);
|
||||
newDump.Data.Add(gt);
|
||||
}
|
||||
}
|
||||
return newDump;
|
||||
}
|
||||
|
||||
static public GSDump LoadDump(String FileName)
|
||||
{
|
||||
GSDump dmp = new GSDump();
|
||||
|
||||
BinaryReader br = new BinaryReader(System.IO.File.Open(FileName, FileMode.Open));
|
||||
dmp.CRC = br.ReadInt32();
|
||||
|
||||
Int32 ss = br.ReadInt32();
|
||||
dmp.StateData = br.ReadBytes(ss);
|
||||
|
||||
dmp.Registers = br.ReadBytes(8192);
|
||||
|
||||
while (br.PeekChar() != -1)
|
||||
{
|
||||
GSType id = (GSType)br.ReadByte();
|
||||
switch (id)
|
||||
{
|
||||
case GSType.Transfer:
|
||||
GSTransfer data = new GSTransfer();
|
||||
|
||||
byte index = br.ReadByte();
|
||||
|
||||
data.id = id;
|
||||
data.Path = (GSTransferPath)index;
|
||||
|
||||
Int32 size = br.ReadInt32();
|
||||
|
||||
List<byte> Data = new List<byte>();
|
||||
Data.AddRange(br.ReadBytes(size));
|
||||
data.data = Data.ToArray();
|
||||
dmp.Data.Add(data);
|
||||
break;
|
||||
case GSType.VSync:
|
||||
GSData dataV = new GSData();
|
||||
dataV.id = id;
|
||||
dataV.data = br.ReadBytes(1);
|
||||
dmp.Data.Add(dataV);
|
||||
break;
|
||||
case GSType.ReadFIFO2:
|
||||
GSData dataR = new GSData();
|
||||
dataR.id = id;
|
||||
Int32 sF = br.ReadInt32();
|
||||
dataR.data = BitConverter.GetBytes(sF);
|
||||
dmp.Data.Add(dataR);
|
||||
break;
|
||||
case GSType.Registers:
|
||||
GSData dataRR = new GSData();
|
||||
dataRR.id = id;
|
||||
dataRR.data = br.ReadBytes(8192);
|
||||
dmp.Data.Add(dataRR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
br.Close();
|
||||
|
||||
return dmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,71 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Drawing;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
static public class NativeMethods
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32")]
|
||||
public extern static IntPtr LoadLibrary(string lpLibFileName);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32")]
|
||||
public extern static bool FreeLibrary(IntPtr hLibModule);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi)]
|
||||
public extern static IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi)]
|
||||
public extern static int SetErrorMode(int Value);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi)]
|
||||
public extern static int GetLastError();
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32", CharSet = CharSet.Ansi)]
|
||||
public extern static short GetAsyncKeyState(int key);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32", CharSet = CharSet.Ansi)]
|
||||
public extern static int SetClassLong(IntPtr HWND, int index, long newlong);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32", CharSet = CharSet.Ansi)]
|
||||
public extern static bool IsWindowVisible(IntPtr HWND);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool PeekMessage(out NativeMessage message, IntPtr hwnd, uint messageFilterMin, uint messageFilterMax, uint flags);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool TranslateMessage(ref NativeMessage message);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool DispatchMessage(ref NativeMessage message);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NativeMessage
|
||||
{
|
||||
public IntPtr hWnd;
|
||||
public uint msg;
|
||||
public IntPtr wParam;
|
||||
public IntPtr lParam;
|
||||
public uint time;
|
||||
public Point p;
|
||||
}
|
||||
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Drawing;
|
||||
|
||||
namespace GSDumpGUI
|
||||
{
|
||||
static public class NativeMethods
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32")]
|
||||
public extern static IntPtr LoadLibrary(string lpLibFileName);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32")]
|
||||
public extern static bool FreeLibrary(IntPtr hLibModule);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi)]
|
||||
public extern static IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi)]
|
||||
public extern static int SetErrorMode(int Value);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi)]
|
||||
public extern static int GetLastError();
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32", CharSet = CharSet.Ansi)]
|
||||
public extern static short GetAsyncKeyState(int key);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32", CharSet = CharSet.Ansi)]
|
||||
public extern static int SetClassLong(IntPtr HWND, int index, long newlong);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32", CharSet = CharSet.Ansi)]
|
||||
public extern static bool IsWindowVisible(IntPtr HWND);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool PeekMessage(out NativeMessage message, IntPtr hwnd, uint messageFilterMin, uint messageFilterMax, uint flags);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool TranslateMessage(ref NativeMessage message);
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool DispatchMessage(ref NativeMessage message);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NativeMessage
|
||||
{
|
||||
public IntPtr hWnd;
|
||||
public uint msg;
|
||||
public IntPtr wParam;
|
||||
public IntPtr lParam;
|
||||
public uint time;
|
||||
public Point p;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for containing information regarding the acceptance of a determinate situation.
|
||||
/// </summary>
|
||||
public class CancelArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the operation should be cancelled.
|
||||
/// </summary>
|
||||
private Boolean _cancel;
|
||||
/// <summary>
|
||||
/// Get/set the flag that determines if the operation should be cancelled.
|
||||
/// </summary>
|
||||
public Boolean Cancel
|
||||
{
|
||||
get { return _cancel; }
|
||||
set { _cancel = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
/// <param name="cancel">Whether the operation should be cancelled.</param>
|
||||
public CancelArgs(Boolean cancel)
|
||||
{
|
||||
this._cancel = cancel;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for containing information regarding the acceptance of a determinate situation.
|
||||
/// </summary>
|
||||
public class CancelArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the operation should be cancelled.
|
||||
/// </summary>
|
||||
private Boolean _cancel;
|
||||
/// <summary>
|
||||
/// Get/set the flag that determines if the operation should be cancelled.
|
||||
/// </summary>
|
||||
public Boolean Cancel
|
||||
{
|
||||
get { return _cancel; }
|
||||
set { _cancel = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
/// <param name="cancel">Whether the operation should be cancelled.</param>
|
||||
public CancelArgs(Boolean cancel)
|
||||
{
|
||||
this._cancel = cancel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,323 +1,323 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base TCP client class wrapped around TcpClient.
|
||||
/// </summary>
|
||||
public class Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Lock object to assure that certain operation over the socket class are executed
|
||||
/// in an exclusive way.
|
||||
/// </summary>
|
||||
private Object _lock;
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper around the Network Stream of the socket. (Read-Only)
|
||||
/// </summary>
|
||||
private BinaryReader tr;
|
||||
/// <summary>
|
||||
/// Wrapper around the Network Stream of the socket. (Write-Only)
|
||||
/// </summary>
|
||||
private BinaryWriter tw;
|
||||
/// <summary>
|
||||
/// Address to which the client is connected.
|
||||
/// </summary>
|
||||
private IPEndPoint _address;
|
||||
|
||||
/// <summary>
|
||||
/// Flag to permit thread exit from the external.
|
||||
/// </summary>
|
||||
protected Boolean _active;
|
||||
/// <summary>
|
||||
/// Socket maintaining the connection.
|
||||
/// </summary>
|
||||
protected TcpClient _socket;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the address to which the client is connected.
|
||||
/// </summary>
|
||||
public IPEndPoint Address
|
||||
{
|
||||
get { return _address; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the state of the connection.
|
||||
/// </summary>
|
||||
public Boolean Connected
|
||||
{
|
||||
get { return _socket != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of receiving/sending a line of data from/to the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Data">Line of data received.</param>
|
||||
public delegate void DataCommunicationHandler(Client sender, Data Data);
|
||||
/// <summary>
|
||||
/// Occurs when a line of data is received from the server.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnDataReceived;
|
||||
/// <summary>
|
||||
/// Occurs before the client send a line of data to the server.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnBeforeDataSent;
|
||||
/// <summary>
|
||||
/// Occurs after the client send a line of data to the server.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnAfterDataSent;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of connection/disconnection to the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
public delegate void ConnectionStateHandler(Client sender);
|
||||
/// <summary>
|
||||
/// Occurs when the client successfully connect the server.
|
||||
/// </summary>
|
||||
public event ConnectionStateHandler OnConnected;
|
||||
/// <summary>
|
||||
/// Occurs when the client is disconnected from the server.
|
||||
/// </summary>
|
||||
public event ConnectionStateHandler OnDisconnected;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of connection failed for rejection by the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Message">Message of fail sent by the server.</param>
|
||||
public delegate void ConnectionFailedHandler(Client sender, byte[] Message);
|
||||
/// <summary>
|
||||
/// Occurs when the client failed to connect to the server because the server rejected the connection.
|
||||
/// </summary>
|
||||
public event ConnectionFailedHandler OnConnectFailed;
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public Client()
|
||||
{
|
||||
_lock = new object();
|
||||
_address = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to connect to the server specified.
|
||||
/// </summary>
|
||||
/// <param name="Indirizzo">Address of the server to connect.</param>
|
||||
/// <param name="Port">Port of the server to connect.</param>
|
||||
/// <returns>True if the connection is successfull, false otherwise.</returns>
|
||||
/// <exception cref="TCPLibrary.Core.AlreadyConnectedException" />
|
||||
/// <exception cref="System.Net.Sockets.SocketException" />
|
||||
public virtual Boolean Connect(String Indirizzo, Int32 Port)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
IPHostEntry addr = Dns.GetHostEntry(Indirizzo);
|
||||
IPAddress ip = null;
|
||||
|
||||
foreach (var itm in addr.AddressList)
|
||||
{
|
||||
if (itm.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
ip = itm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ip != null)
|
||||
{
|
||||
_address = new IPEndPoint(ip, Port);
|
||||
_socket = new TcpClient();
|
||||
|
||||
try
|
||||
{
|
||||
_socket.Connect(_address);
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
_socket = null;
|
||||
_address = null;
|
||||
throw;
|
||||
}
|
||||
|
||||
tr = new BinaryReader(_socket.GetStream());
|
||||
tw = new BinaryWriter(_socket.GetStream());
|
||||
|
||||
// Receive the confirmation of the status of the connection to the server.
|
||||
// Is CONNECTEDTCPSERVER if the connection is successfull, all other cases are wrong.
|
||||
|
||||
Int32 Length = Convert.ToInt32(tr.ReadInt32());
|
||||
byte[] arr = new byte[Length];
|
||||
tr.Read(arr, 0, Length);
|
||||
ASCIIEncoding ae = new ASCIIEncoding();
|
||||
String Accept = ae.GetString(arr, 0, arr.Length);
|
||||
|
||||
if (Accept == "CONNECTEDTCPSERVER")
|
||||
{
|
||||
_active = true;
|
||||
|
||||
Thread thd = new Thread(new ThreadStart(MainThread));
|
||||
thd.IsBackground = true;
|
||||
thd.Name = "Client connected to " + Indirizzo + ":" + Port.ToString();
|
||||
thd.Start();
|
||||
|
||||
if (OnConnected != null)
|
||||
OnConnected(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Stop();
|
||||
if (OnConnectFailed != null)
|
||||
OnConnectFailed(this, arr);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("The client is already connected!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnect a Client if connected.
|
||||
/// </summary>
|
||||
public virtual void Disconnect()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_active = false;
|
||||
tr.Close();
|
||||
tw.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnect a Client if connected.
|
||||
/// </summary>
|
||||
protected virtual void Stop()
|
||||
{
|
||||
if (_socket != null)
|
||||
{
|
||||
tr.Close();
|
||||
tw.Close();
|
||||
_socket.Close();
|
||||
|
||||
_socket = null;
|
||||
_address = null;
|
||||
|
||||
if (OnDisconnected != null)
|
||||
OnDisconnected(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thread function that actually run the socket work.
|
||||
/// </summary>
|
||||
private void MainThread()
|
||||
{
|
||||
while (_active)
|
||||
{
|
||||
byte[] arr = null;
|
||||
|
||||
try
|
||||
{
|
||||
int length = Convert.ToInt32(tr.ReadInt32());
|
||||
arr = new byte[length];
|
||||
int index = 0;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
|
||||
int receivedBytes = tr.Read(arr, index, length);
|
||||
length -= receivedBytes;
|
||||
index += receivedBytes;
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
Boolean Stato = _socket.Client.Poll(100, SelectMode.SelectRead);
|
||||
if ((arr == null) && (Stato == true))
|
||||
break;
|
||||
else
|
||||
if (OnDataReceived != null)
|
||||
OnDataReceived(this, new Data(arr));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a line of data to the server.
|
||||
/// </summary>
|
||||
/// <param name="msg">Data to send to the server.</param>
|
||||
/// <exception cref="TCPLibrary.Core.NotConnectedException" />
|
||||
public void Send(Data msg)
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
if (OnBeforeDataSent != null)
|
||||
OnBeforeDataSent(this, msg);
|
||||
try
|
||||
{
|
||||
tw.Write(msg.Message.Length);
|
||||
tw.Write(msg.Message);
|
||||
tw.Flush();
|
||||
|
||||
if (OnAfterDataSent != null)
|
||||
OnAfterDataSent(this, msg);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Pensare a cosa fare quà. Questo è il caso in cui il server ha chiuso forzatamente
|
||||
// la connessione mentre il client mandava roba.
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("The link is closed. Unable to send data.");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base TCP client class wrapped around TcpClient.
|
||||
/// </summary>
|
||||
public class Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Lock object to assure that certain operation over the socket class are executed
|
||||
/// in an exclusive way.
|
||||
/// </summary>
|
||||
private Object _lock;
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper around the Network Stream of the socket. (Read-Only)
|
||||
/// </summary>
|
||||
private BinaryReader tr;
|
||||
/// <summary>
|
||||
/// Wrapper around the Network Stream of the socket. (Write-Only)
|
||||
/// </summary>
|
||||
private BinaryWriter tw;
|
||||
/// <summary>
|
||||
/// Address to which the client is connected.
|
||||
/// </summary>
|
||||
private IPEndPoint _address;
|
||||
|
||||
/// <summary>
|
||||
/// Flag to permit thread exit from the external.
|
||||
/// </summary>
|
||||
protected Boolean _active;
|
||||
/// <summary>
|
||||
/// Socket maintaining the connection.
|
||||
/// </summary>
|
||||
protected TcpClient _socket;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the address to which the client is connected.
|
||||
/// </summary>
|
||||
public IPEndPoint Address
|
||||
{
|
||||
get { return _address; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the state of the connection.
|
||||
/// </summary>
|
||||
public Boolean Connected
|
||||
{
|
||||
get { return _socket != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of receiving/sending a line of data from/to the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Data">Line of data received.</param>
|
||||
public delegate void DataCommunicationHandler(Client sender, Data Data);
|
||||
/// <summary>
|
||||
/// Occurs when a line of data is received from the server.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnDataReceived;
|
||||
/// <summary>
|
||||
/// Occurs before the client send a line of data to the server.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnBeforeDataSent;
|
||||
/// <summary>
|
||||
/// Occurs after the client send a line of data to the server.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnAfterDataSent;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of connection/disconnection to the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
public delegate void ConnectionStateHandler(Client sender);
|
||||
/// <summary>
|
||||
/// Occurs when the client successfully connect the server.
|
||||
/// </summary>
|
||||
public event ConnectionStateHandler OnConnected;
|
||||
/// <summary>
|
||||
/// Occurs when the client is disconnected from the server.
|
||||
/// </summary>
|
||||
public event ConnectionStateHandler OnDisconnected;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of connection failed for rejection by the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Message">Message of fail sent by the server.</param>
|
||||
public delegate void ConnectionFailedHandler(Client sender, byte[] Message);
|
||||
/// <summary>
|
||||
/// Occurs when the client failed to connect to the server because the server rejected the connection.
|
||||
/// </summary>
|
||||
public event ConnectionFailedHandler OnConnectFailed;
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public Client()
|
||||
{
|
||||
_lock = new object();
|
||||
_address = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to connect to the server specified.
|
||||
/// </summary>
|
||||
/// <param name="Indirizzo">Address of the server to connect.</param>
|
||||
/// <param name="Port">Port of the server to connect.</param>
|
||||
/// <returns>True if the connection is successfull, false otherwise.</returns>
|
||||
/// <exception cref="TCPLibrary.Core.AlreadyConnectedException" />
|
||||
/// <exception cref="System.Net.Sockets.SocketException" />
|
||||
public virtual Boolean Connect(String Indirizzo, Int32 Port)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
IPHostEntry addr = Dns.GetHostEntry(Indirizzo);
|
||||
IPAddress ip = null;
|
||||
|
||||
foreach (var itm in addr.AddressList)
|
||||
{
|
||||
if (itm.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
ip = itm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ip != null)
|
||||
{
|
||||
_address = new IPEndPoint(ip, Port);
|
||||
_socket = new TcpClient();
|
||||
|
||||
try
|
||||
{
|
||||
_socket.Connect(_address);
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
_socket = null;
|
||||
_address = null;
|
||||
throw;
|
||||
}
|
||||
|
||||
tr = new BinaryReader(_socket.GetStream());
|
||||
tw = new BinaryWriter(_socket.GetStream());
|
||||
|
||||
// Receive the confirmation of the status of the connection to the server.
|
||||
// Is CONNECTEDTCPSERVER if the connection is successfull, all other cases are wrong.
|
||||
|
||||
Int32 Length = Convert.ToInt32(tr.ReadInt32());
|
||||
byte[] arr = new byte[Length];
|
||||
tr.Read(arr, 0, Length);
|
||||
ASCIIEncoding ae = new ASCIIEncoding();
|
||||
String Accept = ae.GetString(arr, 0, arr.Length);
|
||||
|
||||
if (Accept == "CONNECTEDTCPSERVER")
|
||||
{
|
||||
_active = true;
|
||||
|
||||
Thread thd = new Thread(new ThreadStart(MainThread));
|
||||
thd.IsBackground = true;
|
||||
thd.Name = "Client connected to " + Indirizzo + ":" + Port.ToString();
|
||||
thd.Start();
|
||||
|
||||
if (OnConnected != null)
|
||||
OnConnected(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Stop();
|
||||
if (OnConnectFailed != null)
|
||||
OnConnectFailed(this, arr);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("The client is already connected!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnect a Client if connected.
|
||||
/// </summary>
|
||||
public virtual void Disconnect()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_active = false;
|
||||
tr.Close();
|
||||
tw.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnect a Client if connected.
|
||||
/// </summary>
|
||||
protected virtual void Stop()
|
||||
{
|
||||
if (_socket != null)
|
||||
{
|
||||
tr.Close();
|
||||
tw.Close();
|
||||
_socket.Close();
|
||||
|
||||
_socket = null;
|
||||
_address = null;
|
||||
|
||||
if (OnDisconnected != null)
|
||||
OnDisconnected(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thread function that actually run the socket work.
|
||||
/// </summary>
|
||||
private void MainThread()
|
||||
{
|
||||
while (_active)
|
||||
{
|
||||
byte[] arr = null;
|
||||
|
||||
try
|
||||
{
|
||||
int length = Convert.ToInt32(tr.ReadInt32());
|
||||
arr = new byte[length];
|
||||
int index = 0;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
|
||||
int receivedBytes = tr.Read(arr, index, length);
|
||||
length -= receivedBytes;
|
||||
index += receivedBytes;
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
Boolean Stato = _socket.Client.Poll(100, SelectMode.SelectRead);
|
||||
if ((arr == null) && (Stato == true))
|
||||
break;
|
||||
else
|
||||
if (OnDataReceived != null)
|
||||
OnDataReceived(this, new Data(arr));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a line of data to the server.
|
||||
/// </summary>
|
||||
/// <param name="msg">Data to send to the server.</param>
|
||||
/// <exception cref="TCPLibrary.Core.NotConnectedException" />
|
||||
public void Send(Data msg)
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
if (OnBeforeDataSent != null)
|
||||
OnBeforeDataSent(this, msg);
|
||||
try
|
||||
{
|
||||
tw.Write(msg.Message.Length);
|
||||
tw.Write(msg.Message);
|
||||
tw.Flush();
|
||||
|
||||
if (OnAfterDataSent != null)
|
||||
OnAfterDataSent(this, msg);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Pensare a cosa fare quà. Questo è il caso in cui il server ha chiuso forzatamente
|
||||
// la connessione mentre il client mandava roba.
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("The link is closed. Unable to send data.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,226 +1,226 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class that manages the single connection between a client and the server.
|
||||
/// </summary>
|
||||
public class ClientS
|
||||
{
|
||||
/// <summary>
|
||||
/// Lock object to assure that certain operation over the socket class are executed
|
||||
/// in an exclusive way.
|
||||
/// </summary>
|
||||
private Object _lock;
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper around the Network Stream of the socket. (Read-Only)
|
||||
/// </summary>
|
||||
private BinaryReader tr;
|
||||
/// <summary>
|
||||
/// Wrapper around the Network Stream of the socket. (Write-Only)
|
||||
/// </summary>
|
||||
private BinaryWriter tw;
|
||||
/// <summary>
|
||||
/// Current IP address of the client.
|
||||
/// </summary>
|
||||
private String _ipaddress;
|
||||
|
||||
/// <summary>
|
||||
/// Flag to permit thread exit from the external.
|
||||
/// </summary>
|
||||
protected Boolean _active;
|
||||
/// <summary>
|
||||
/// Link to the server to which this client is connected.
|
||||
/// </summary>
|
||||
protected Server _server;
|
||||
/// <summary>
|
||||
/// Actual socket of the client.
|
||||
/// </summary>
|
||||
protected TcpClient _client;
|
||||
|
||||
/// <summary>
|
||||
/// Get the state of the connection.
|
||||
/// </summary>
|
||||
public Boolean Connected
|
||||
{
|
||||
get { return _client != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IP Address of the client.
|
||||
/// </summary>
|
||||
public String IPAddress
|
||||
{
|
||||
get { return _ipaddress; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class constructor.
|
||||
/// </summary>
|
||||
/// <param name="server">Server to which this client is linked to.</param>
|
||||
/// <param name="client">Socket of the client.</param>
|
||||
protected internal ClientS(Server server, TcpClient client)
|
||||
{
|
||||
_lock = new object();
|
||||
|
||||
_active = true;
|
||||
_server = server;
|
||||
_client = client;
|
||||
_ipaddress = _client.Client.RemoteEndPoint.ToString();
|
||||
|
||||
NetworkStream ns = _client.GetStream();
|
||||
tr = new BinaryReader(ns);
|
||||
tw = new BinaryWriter(ns);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start up the thread managing this Client-Server connection.
|
||||
/// </summary>
|
||||
protected internal virtual void Start()
|
||||
{
|
||||
Thread _thread = new Thread(new ThreadStart(MainThread));
|
||||
_thread.IsBackground = true;
|
||||
_thread.Name = "Thread Client " + _ipaddress;
|
||||
_thread.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thread function that actually run the socket work.
|
||||
/// </summary>
|
||||
private void MainThread()
|
||||
{
|
||||
while (_active)
|
||||
{
|
||||
byte[] arr = null;
|
||||
|
||||
try
|
||||
{
|
||||
int length = Convert.ToInt32(tr.ReadInt32());
|
||||
arr = new byte[length];
|
||||
int index = 0;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
|
||||
int receivedBytes = tr.Read(arr, index, length);
|
||||
length -= receivedBytes;
|
||||
index += receivedBytes;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
Boolean Stato = _client.Client.Poll(100, SelectMode.SelectRead);
|
||||
if ((arr == null) && (Stato == true))
|
||||
break;
|
||||
else
|
||||
_server.RaiseDataReceivedEvent(this, new Data(arr));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a line of data to the client.
|
||||
/// </summary>
|
||||
/// <param name="Data">Data to send to the client.</param>
|
||||
/// <exception cref="TCPLibrary.Core.NotConnectedException" />
|
||||
public void Send(Data Data)
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
_server.RaiseBeforeDataSentEvent(this, Data);
|
||||
|
||||
try
|
||||
{
|
||||
tw.Write(Data.Message.Length);
|
||||
tw.Write(Data.Message);
|
||||
tw.Flush();
|
||||
|
||||
_server.RaiseAfterDataSentEvent(this, Data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Write(ex.ToString());
|
||||
// Pensare a cosa fare quà. Questo è il caso in cui il client ha chiuso forzatamente
|
||||
// la connessione mentre il server mandava roba.
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("The link is closed. Unable to send data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close the link between Client e Server.
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_active = false;
|
||||
tr.Close();
|
||||
tw.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close the link between Client e Server.
|
||||
/// </summary>
|
||||
protected internal void Stop()
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_server.RaiseClientBeforeDisconnectedEvent(this);
|
||||
|
||||
tr.Close();
|
||||
tw.Close();
|
||||
|
||||
_client.Close();
|
||||
_client = null;
|
||||
|
||||
lock (_server.Clients)
|
||||
{
|
||||
_server.Clients.Remove(this);
|
||||
}
|
||||
|
||||
_server.RaiseClientAfterDisconnectedEvent(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class that manages the single connection between a client and the server.
|
||||
/// </summary>
|
||||
public class ClientS
|
||||
{
|
||||
/// <summary>
|
||||
/// Lock object to assure that certain operation over the socket class are executed
|
||||
/// in an exclusive way.
|
||||
/// </summary>
|
||||
private Object _lock;
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper around the Network Stream of the socket. (Read-Only)
|
||||
/// </summary>
|
||||
private BinaryReader tr;
|
||||
/// <summary>
|
||||
/// Wrapper around the Network Stream of the socket. (Write-Only)
|
||||
/// </summary>
|
||||
private BinaryWriter tw;
|
||||
/// <summary>
|
||||
/// Current IP address of the client.
|
||||
/// </summary>
|
||||
private String _ipaddress;
|
||||
|
||||
/// <summary>
|
||||
/// Flag to permit thread exit from the external.
|
||||
/// </summary>
|
||||
protected Boolean _active;
|
||||
/// <summary>
|
||||
/// Link to the server to which this client is connected.
|
||||
/// </summary>
|
||||
protected Server _server;
|
||||
/// <summary>
|
||||
/// Actual socket of the client.
|
||||
/// </summary>
|
||||
protected TcpClient _client;
|
||||
|
||||
/// <summary>
|
||||
/// Get the state of the connection.
|
||||
/// </summary>
|
||||
public Boolean Connected
|
||||
{
|
||||
get { return _client != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IP Address of the client.
|
||||
/// </summary>
|
||||
public String IPAddress
|
||||
{
|
||||
get { return _ipaddress; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class constructor.
|
||||
/// </summary>
|
||||
/// <param name="server">Server to which this client is linked to.</param>
|
||||
/// <param name="client">Socket of the client.</param>
|
||||
protected internal ClientS(Server server, TcpClient client)
|
||||
{
|
||||
_lock = new object();
|
||||
|
||||
_active = true;
|
||||
_server = server;
|
||||
_client = client;
|
||||
_ipaddress = _client.Client.RemoteEndPoint.ToString();
|
||||
|
||||
NetworkStream ns = _client.GetStream();
|
||||
tr = new BinaryReader(ns);
|
||||
tw = new BinaryWriter(ns);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start up the thread managing this Client-Server connection.
|
||||
/// </summary>
|
||||
protected internal virtual void Start()
|
||||
{
|
||||
Thread _thread = new Thread(new ThreadStart(MainThread));
|
||||
_thread.IsBackground = true;
|
||||
_thread.Name = "Thread Client " + _ipaddress;
|
||||
_thread.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thread function that actually run the socket work.
|
||||
/// </summary>
|
||||
private void MainThread()
|
||||
{
|
||||
while (_active)
|
||||
{
|
||||
byte[] arr = null;
|
||||
|
||||
try
|
||||
{
|
||||
int length = Convert.ToInt32(tr.ReadInt32());
|
||||
arr = new byte[length];
|
||||
int index = 0;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
|
||||
int receivedBytes = tr.Read(arr, index, length);
|
||||
length -= receivedBytes;
|
||||
index += receivedBytes;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
Boolean Stato = _client.Client.Poll(100, SelectMode.SelectRead);
|
||||
if ((arr == null) && (Stato == true))
|
||||
break;
|
||||
else
|
||||
_server.RaiseDataReceivedEvent(this, new Data(arr));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a line of data to the client.
|
||||
/// </summary>
|
||||
/// <param name="Data">Data to send to the client.</param>
|
||||
/// <exception cref="TCPLibrary.Core.NotConnectedException" />
|
||||
public void Send(Data Data)
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
_server.RaiseBeforeDataSentEvent(this, Data);
|
||||
|
||||
try
|
||||
{
|
||||
tw.Write(Data.Message.Length);
|
||||
tw.Write(Data.Message);
|
||||
tw.Flush();
|
||||
|
||||
_server.RaiseAfterDataSentEvent(this, Data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Write(ex.ToString());
|
||||
// Pensare a cosa fare quà. Questo è il caso in cui il client ha chiuso forzatamente
|
||||
// la connessione mentre il server mandava roba.
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("The link is closed. Unable to send data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close the link between Client e Server.
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_active = false;
|
||||
tr.Close();
|
||||
tw.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close the link between Client e Server.
|
||||
/// </summary>
|
||||
protected internal void Stop()
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_server.RaiseClientBeforeDisconnectedEvent(this);
|
||||
|
||||
tr.Close();
|
||||
tw.Close();
|
||||
|
||||
_client.Close();
|
||||
_client = null;
|
||||
|
||||
lock (_server.Clients)
|
||||
{
|
||||
_server.Clients.Remove(this);
|
||||
}
|
||||
|
||||
_server.RaiseClientAfterDisconnectedEvent(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Structure for containing the data to be sent over a base client/server
|
||||
/// </summary>
|
||||
public class Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Data to be sent.
|
||||
/// </summary>
|
||||
private byte[] _message;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the data to be sent.
|
||||
/// </summary>
|
||||
public byte[] Message
|
||||
{
|
||||
get { return _message; }
|
||||
set { _message = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
/// <param name="msg">Data to be sent.</param>
|
||||
public Data(byte[] msg)
|
||||
{
|
||||
this._message = msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Structure for containing the data to be sent over a base client/server
|
||||
/// </summary>
|
||||
public class Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Data to be sent.
|
||||
/// </summary>
|
||||
private byte[] _message;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the data to be sent.
|
||||
/// </summary>
|
||||
public byte[] Message
|
||||
{
|
||||
get { return _message; }
|
||||
set { _message = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
/// <param name="msg">Data to be sent.</param>
|
||||
public Data(byte[] msg)
|
||||
{
|
||||
this._message = msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,365 +1,365 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base TCP server class wrapped around TcpListener.
|
||||
/// </summary>
|
||||
public class Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Socket maintaining the connection.
|
||||
/// </summary>
|
||||
private TcpListener _socket;
|
||||
/// <summary>
|
||||
/// Port to which the server will listen.
|
||||
/// </summary>
|
||||
private Int32 _port;
|
||||
/// <summary>
|
||||
/// Whether the server is enabled or not.
|
||||
/// </summary>
|
||||
private Boolean _enabled;
|
||||
/// <summary>
|
||||
/// List of the clients connected to the server.
|
||||
/// </summary>
|
||||
private List<ClientS> _clients;
|
||||
/// <summary>
|
||||
/// Number of connection permitted in the backlog of the server.
|
||||
/// </summary>
|
||||
private Int32 _connectionbacklog;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of the Enabled property change.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
public delegate void EnabledChangedHandler(Server sender);
|
||||
/// <summary>
|
||||
/// Occurs when the Enabled property is changed.
|
||||
/// </summary>
|
||||
public event EnabledChangedHandler OnEnabledChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of receiving a line of data from a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="client">Client involved in the communication.</param>
|
||||
/// <param name="Data">Line of data received.</param>
|
||||
public delegate void DataCommunicationHandler(Server server, ClientS client, Data Data);
|
||||
/// <summary>
|
||||
/// Occurs when a client send a line of data to the server.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnClientDataReceived;
|
||||
/// <summary>
|
||||
/// Occurs before the server send a line of data to a client.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnClientBeforeDataSent;
|
||||
/// <summary>
|
||||
/// Occurs after the server send a line of data to a client.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnClientAfterDataSent;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of a connection of a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="sender">The new client connected.</param>
|
||||
public delegate void ConnectedHandler(Server server, ClientS sender);
|
||||
/// <summary>
|
||||
/// Occurs after a client is connected to the server.
|
||||
/// </summary>
|
||||
public event ConnectedHandler OnClientAfterConnect;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of a connection of a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="client">The new client to be connected.</param>
|
||||
/// <param name="args">Specify if the client should be accepted into the server.</param>
|
||||
public delegate void BeforeConnectedHandler(Server server, ClientS client, CancelArgs args);
|
||||
/// <summary>
|
||||
/// Occurs before a client is allowed to connect to the server.
|
||||
/// </summary>
|
||||
public event BeforeConnectedHandler OnClientBeforeConnect;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of disconnection of a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="sender">The client disconnected.</param>
|
||||
public delegate void DisconnectedHandler(Server server, ClientS sender);
|
||||
/// <summary>
|
||||
/// Occurs right after a client disconnect from the server.
|
||||
/// </summary>
|
||||
public event DisconnectedHandler OnClientAfterDisconnected;
|
||||
/// <summary>
|
||||
/// Occurs before a client disconnect from the server.
|
||||
/// </summary>
|
||||
public event DisconnectedHandler OnClientBeforeDisconnected;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the port number to which the server will listen. Cannot be set while the server is active.
|
||||
/// </summary>
|
||||
/// <exception cref="TCPLibrary.Core.ServerAttivoException" />
|
||||
public Int32 Port
|
||||
{
|
||||
get { return _port; }
|
||||
set
|
||||
{
|
||||
if (Enabled == false)
|
||||
_port = value;
|
||||
else
|
||||
throw new ArgumentException("Impossibile eseguire l'operazione a server attivo");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the enabled state of the server. Setting this to true will actually activate the server.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Net.Sockets.SocketException" />
|
||||
public Boolean Enabled
|
||||
{
|
||||
get { return _enabled; }
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
{
|
||||
if (_enabled == false)
|
||||
ActivateServer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_enabled == true)
|
||||
DeactivateServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the number of connection permitted in the backlog of the server.
|
||||
/// </summary>
|
||||
/// <exception cref="TCPLibrary.Core.ServerAttivoException" />
|
||||
public Int32 ConnectionBackLog
|
||||
{
|
||||
get { return _connectionbacklog; }
|
||||
set
|
||||
{
|
||||
if (Enabled == false)
|
||||
_connectionbacklog = value;
|
||||
else
|
||||
throw new ArgumentException("Impossibile eseguire l'operazione a server attivo");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of the clients connected to the server.
|
||||
/// </summary>
|
||||
public List<ClientS> Clients
|
||||
{
|
||||
get { return _clients; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deactivate the server.
|
||||
/// </summary>
|
||||
protected virtual void DeactivateServer()
|
||||
{
|
||||
_enabled = false;
|
||||
_socket.Stop();
|
||||
_socket = null;
|
||||
|
||||
lock (_clients)
|
||||
{
|
||||
for (int i = 0; i < _clients.Count; i++)
|
||||
_clients[i].Disconnect();
|
||||
}
|
||||
|
||||
if (OnEnabledChanged != null)
|
||||
OnEnabledChanged(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activate the server.
|
||||
/// </summary>
|
||||
protected virtual void ActivateServer()
|
||||
{
|
||||
_socket = new TcpListener(IPAddress.Any, Port);
|
||||
_socket.Start(ConnectionBackLog);
|
||||
Thread thd = new Thread(new ThreadStart(MainThread));
|
||||
thd.Name = "Server on port " + Port.ToString();
|
||||
thd.IsBackground = true;
|
||||
thd.Start();
|
||||
_enabled = true;
|
||||
if (OnEnabledChanged != null)
|
||||
OnEnabledChanged(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcast a line of data to all the clients connected to the server.
|
||||
/// </summary>
|
||||
/// <param name="Data">Line of data to be sent.</param>
|
||||
/// <exception cref="TCPLibrary.Core.ServerNonAttivoException" />
|
||||
public void Broadcast(Data Data)
|
||||
{
|
||||
if (Enabled)
|
||||
{
|
||||
lock (_clients)
|
||||
{
|
||||
foreach (var itm in _clients)
|
||||
if (itm.Connected)
|
||||
itm.Send(Data);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("Unable to execute this operation when the server is inactive.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public Server()
|
||||
{
|
||||
_clients = new List<ClientS>();
|
||||
_port = 0;
|
||||
_connectionbacklog = 0;
|
||||
_enabled = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thread function that actually run the server socket work.
|
||||
/// </summary>
|
||||
private void MainThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (Enabled == true)
|
||||
{
|
||||
TcpClient client = _socket.AcceptTcpClient();
|
||||
|
||||
CancelArgs args = new CancelArgs(false);
|
||||
ClientS cl = CreateClient(client);
|
||||
if (OnClientBeforeConnect != null)
|
||||
OnClientBeforeConnect(this, cl, args);
|
||||
|
||||
if (args.Cancel != true)
|
||||
{
|
||||
lock (_clients)
|
||||
{
|
||||
_clients.Add(cl);
|
||||
}
|
||||
|
||||
ASCIIEncoding ae = new ASCIIEncoding();
|
||||
byte[] arr = ae.GetBytes("CONNECTEDTCPSERVER");
|
||||
|
||||
cl.Send(new Data(arr));
|
||||
|
||||
if (OnClientAfterConnect != null)
|
||||
OnClientAfterConnect(this, cl);
|
||||
cl.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
client.GetStream().Close();
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridable function that create the structure to memorize the client data.
|
||||
/// </summary>
|
||||
/// <param name="socket">Socket of the client.</param>
|
||||
/// <returns>The structure in which memorize all the information of the client.</returns>
|
||||
protected virtual ClientS CreateClient(TcpClient socket)
|
||||
{
|
||||
ClientS cl = new ClientS(this, socket);
|
||||
return cl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientAfterDataSent event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
/// <param name="data">Line of data sent.</param>
|
||||
internal void RaiseAfterDataSentEvent(ClientS cl, Data data)
|
||||
{
|
||||
if (OnClientAfterDataSent != null)
|
||||
OnClientAfterDataSent(this, cl, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientBeforeDataSent event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
/// <param name="data">Line of data sent.</param>
|
||||
internal void RaiseBeforeDataSentEvent(ClientS cl, Data data)
|
||||
{
|
||||
if (OnClientBeforeDataSent != null)
|
||||
OnClientBeforeDataSent(this, cl, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnDataReceived event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
/// <param name="data">Line of data received.</param>
|
||||
internal void RaiseDataReceivedEvent(ClientS cl, Data data)
|
||||
{
|
||||
if (OnClientDataReceived != null)
|
||||
OnClientDataReceived(this, cl, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientAfterDisconnected event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
internal void RaiseClientAfterDisconnectedEvent(ClientS cl)
|
||||
{
|
||||
if (OnClientAfterDisconnected != null)
|
||||
OnClientAfterDisconnected(this, cl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientBeforeDisconnected event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
internal void RaiseClientBeforeDisconnectedEvent(ClientS cl)
|
||||
{
|
||||
if (OnClientBeforeDisconnected != null)
|
||||
OnClientBeforeDisconnected(this, cl);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2009 Ferreri Alessio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace TCPLibrary.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base TCP server class wrapped around TcpListener.
|
||||
/// </summary>
|
||||
public class Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Socket maintaining the connection.
|
||||
/// </summary>
|
||||
private TcpListener _socket;
|
||||
/// <summary>
|
||||
/// Port to which the server will listen.
|
||||
/// </summary>
|
||||
private Int32 _port;
|
||||
/// <summary>
|
||||
/// Whether the server is enabled or not.
|
||||
/// </summary>
|
||||
private Boolean _enabled;
|
||||
/// <summary>
|
||||
/// List of the clients connected to the server.
|
||||
/// </summary>
|
||||
private List<ClientS> _clients;
|
||||
/// <summary>
|
||||
/// Number of connection permitted in the backlog of the server.
|
||||
/// </summary>
|
||||
private Int32 _connectionbacklog;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of the Enabled property change.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
public delegate void EnabledChangedHandler(Server sender);
|
||||
/// <summary>
|
||||
/// Occurs when the Enabled property is changed.
|
||||
/// </summary>
|
||||
public event EnabledChangedHandler OnEnabledChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of receiving a line of data from a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="client">Client involved in the communication.</param>
|
||||
/// <param name="Data">Line of data received.</param>
|
||||
public delegate void DataCommunicationHandler(Server server, ClientS client, Data Data);
|
||||
/// <summary>
|
||||
/// Occurs when a client send a line of data to the server.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnClientDataReceived;
|
||||
/// <summary>
|
||||
/// Occurs before the server send a line of data to a client.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnClientBeforeDataSent;
|
||||
/// <summary>
|
||||
/// Occurs after the server send a line of data to a client.
|
||||
/// </summary>
|
||||
public event DataCommunicationHandler OnClientAfterDataSent;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of a connection of a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="sender">The new client connected.</param>
|
||||
public delegate void ConnectedHandler(Server server, ClientS sender);
|
||||
/// <summary>
|
||||
/// Occurs after a client is connected to the server.
|
||||
/// </summary>
|
||||
public event ConnectedHandler OnClientAfterConnect;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of a connection of a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="client">The new client to be connected.</param>
|
||||
/// <param name="args">Specify if the client should be accepted into the server.</param>
|
||||
public delegate void BeforeConnectedHandler(Server server, ClientS client, CancelArgs args);
|
||||
/// <summary>
|
||||
/// Occurs before a client is allowed to connect to the server.
|
||||
/// </summary>
|
||||
public event BeforeConnectedHandler OnClientBeforeConnect;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of disconnection of a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="sender">The client disconnected.</param>
|
||||
public delegate void DisconnectedHandler(Server server, ClientS sender);
|
||||
/// <summary>
|
||||
/// Occurs right after a client disconnect from the server.
|
||||
/// </summary>
|
||||
public event DisconnectedHandler OnClientAfterDisconnected;
|
||||
/// <summary>
|
||||
/// Occurs before a client disconnect from the server.
|
||||
/// </summary>
|
||||
public event DisconnectedHandler OnClientBeforeDisconnected;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the port number to which the server will listen. Cannot be set while the server is active.
|
||||
/// </summary>
|
||||
/// <exception cref="TCPLibrary.Core.ServerAttivoException" />
|
||||
public Int32 Port
|
||||
{
|
||||
get { return _port; }
|
||||
set
|
||||
{
|
||||
if (Enabled == false)
|
||||
_port = value;
|
||||
else
|
||||
throw new ArgumentException("Impossibile eseguire l'operazione a server attivo");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the enabled state of the server. Setting this to true will actually activate the server.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Net.Sockets.SocketException" />
|
||||
public Boolean Enabled
|
||||
{
|
||||
get { return _enabled; }
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
{
|
||||
if (_enabled == false)
|
||||
ActivateServer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_enabled == true)
|
||||
DeactivateServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the number of connection permitted in the backlog of the server.
|
||||
/// </summary>
|
||||
/// <exception cref="TCPLibrary.Core.ServerAttivoException" />
|
||||
public Int32 ConnectionBackLog
|
||||
{
|
||||
get { return _connectionbacklog; }
|
||||
set
|
||||
{
|
||||
if (Enabled == false)
|
||||
_connectionbacklog = value;
|
||||
else
|
||||
throw new ArgumentException("Impossibile eseguire l'operazione a server attivo");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of the clients connected to the server.
|
||||
/// </summary>
|
||||
public List<ClientS> Clients
|
||||
{
|
||||
get { return _clients; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deactivate the server.
|
||||
/// </summary>
|
||||
protected virtual void DeactivateServer()
|
||||
{
|
||||
_enabled = false;
|
||||
_socket.Stop();
|
||||
_socket = null;
|
||||
|
||||
lock (_clients)
|
||||
{
|
||||
for (int i = 0; i < _clients.Count; i++)
|
||||
_clients[i].Disconnect();
|
||||
}
|
||||
|
||||
if (OnEnabledChanged != null)
|
||||
OnEnabledChanged(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activate the server.
|
||||
/// </summary>
|
||||
protected virtual void ActivateServer()
|
||||
{
|
||||
_socket = new TcpListener(IPAddress.Any, Port);
|
||||
_socket.Start(ConnectionBackLog);
|
||||
Thread thd = new Thread(new ThreadStart(MainThread));
|
||||
thd.Name = "Server on port " + Port.ToString();
|
||||
thd.IsBackground = true;
|
||||
thd.Start();
|
||||
_enabled = true;
|
||||
if (OnEnabledChanged != null)
|
||||
OnEnabledChanged(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcast a line of data to all the clients connected to the server.
|
||||
/// </summary>
|
||||
/// <param name="Data">Line of data to be sent.</param>
|
||||
/// <exception cref="TCPLibrary.Core.ServerNonAttivoException" />
|
||||
public void Broadcast(Data Data)
|
||||
{
|
||||
if (Enabled)
|
||||
{
|
||||
lock (_clients)
|
||||
{
|
||||
foreach (var itm in _clients)
|
||||
if (itm.Connected)
|
||||
itm.Send(Data);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("Unable to execute this operation when the server is inactive.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public Server()
|
||||
{
|
||||
_clients = new List<ClientS>();
|
||||
_port = 0;
|
||||
_connectionbacklog = 0;
|
||||
_enabled = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thread function that actually run the server socket work.
|
||||
/// </summary>
|
||||
private void MainThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (Enabled == true)
|
||||
{
|
||||
TcpClient client = _socket.AcceptTcpClient();
|
||||
|
||||
CancelArgs args = new CancelArgs(false);
|
||||
ClientS cl = CreateClient(client);
|
||||
if (OnClientBeforeConnect != null)
|
||||
OnClientBeforeConnect(this, cl, args);
|
||||
|
||||
if (args.Cancel != true)
|
||||
{
|
||||
lock (_clients)
|
||||
{
|
||||
_clients.Add(cl);
|
||||
}
|
||||
|
||||
ASCIIEncoding ae = new ASCIIEncoding();
|
||||
byte[] arr = ae.GetBytes("CONNECTEDTCPSERVER");
|
||||
|
||||
cl.Send(new Data(arr));
|
||||
|
||||
if (OnClientAfterConnect != null)
|
||||
OnClientAfterConnect(this, cl);
|
||||
cl.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
client.GetStream().Close();
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridable function that create the structure to memorize the client data.
|
||||
/// </summary>
|
||||
/// <param name="socket">Socket of the client.</param>
|
||||
/// <returns>The structure in which memorize all the information of the client.</returns>
|
||||
protected virtual ClientS CreateClient(TcpClient socket)
|
||||
{
|
||||
ClientS cl = new ClientS(this, socket);
|
||||
return cl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientAfterDataSent event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
/// <param name="data">Line of data sent.</param>
|
||||
internal void RaiseAfterDataSentEvent(ClientS cl, Data data)
|
||||
{
|
||||
if (OnClientAfterDataSent != null)
|
||||
OnClientAfterDataSent(this, cl, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientBeforeDataSent event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
/// <param name="data">Line of data sent.</param>
|
||||
internal void RaiseBeforeDataSentEvent(ClientS cl, Data data)
|
||||
{
|
||||
if (OnClientBeforeDataSent != null)
|
||||
OnClientBeforeDataSent(this, cl, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnDataReceived event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
/// <param name="data">Line of data received.</param>
|
||||
internal void RaiseDataReceivedEvent(ClientS cl, Data data)
|
||||
{
|
||||
if (OnClientDataReceived != null)
|
||||
OnClientDataReceived(this, cl, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientAfterDisconnected event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
internal void RaiseClientAfterDisconnectedEvent(ClientS cl)
|
||||
{
|
||||
if (OnClientAfterDisconnected != null)
|
||||
OnClientAfterDisconnected(this, cl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientBeforeDisconnected event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
internal void RaiseClientBeforeDisconnectedEvent(ClientS cl)
|
||||
{
|
||||
if (OnClientBeforeDisconnected != null)
|
||||
OnClientBeforeDisconnected(this, cl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,137 +1,137 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2008 Ferreri Alessio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
using TCPLibrary.Core;
|
||||
using System;
|
||||
|
||||
namespace TCPLibrary.MessageBased.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// TCP Client Class that work with Message structures.
|
||||
/// </summary>
|
||||
public class BaseMessageClient : Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate for the event of receiving a message structure from the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Mess">Message received.</param>
|
||||
public delegate void MessageReceivedHandler(Client sender, TCPMessage Mess);
|
||||
/// <summary>
|
||||
/// Occurs when the client receive a message structure from the server.
|
||||
/// </summary>
|
||||
public event MessageReceivedHandler OnMessageReceived;
|
||||
/// <summary>
|
||||
/// Delegate for the event of sending a message structure to the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Mess">Message sent.</param>
|
||||
public delegate void MessageSentHandler(Client sender, TCPMessage Mess);
|
||||
/// <summary>
|
||||
/// Occurs before the client send a message structure to the server.
|
||||
/// </summary>
|
||||
public event MessageSentHandler OnBeforeMessageSent;
|
||||
/// <summary>
|
||||
/// Occurs after the client send a message structure to the server.
|
||||
/// </summary>
|
||||
public event MessageSentHandler OnAfterMessageSent;
|
||||
/// <summary>
|
||||
/// Delegate for the event of connection fail for max users number reached.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
public delegate void MaxUsersReached(Client sender);
|
||||
/// <summary>
|
||||
/// Occurs when the connection fail as the server reached the maximum number of clients allowed.
|
||||
/// </summary>
|
||||
public event MaxUsersReached OnMaxUsersConnectionFail;
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public BaseMessageClient()
|
||||
{
|
||||
OnDataReceived += new DataCommunicationHandler(BaseMessageClient_OnDataReceived);
|
||||
OnAfterDataSent += new DataCommunicationHandler(BaseMessageClient_OnDataSent);
|
||||
OnConnectFailed += new ConnectionFailedHandler(BaseMessageClient_OnConnectFailed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the connection is rejected by the server raise the correct event.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Message">Message of the server.</param>
|
||||
void BaseMessageClient_OnConnectFailed(Client sender, byte[] Message)
|
||||
{
|
||||
if (TCPLibrary.MessageBased.Core.TCPMessage.FromByteArray(Message).MessageType == MessageType.MaxUsers)
|
||||
if (OnMaxUsersConnectionFail != null)
|
||||
OnMaxUsersConnectionFail(sender);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the raw data sent to the server and create Message structures.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Data">Line of data sent.</param>
|
||||
void BaseMessageClient_OnDataSent(Client sender, Data Data)
|
||||
{
|
||||
TCPMessage msg = TCPMessage.FromByteArray(Data.Message);
|
||||
if (OnAfterMessageSent != null)
|
||||
OnAfterMessageSent(sender, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the raw data received from the server and create Message structures.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Data">Line of data received.</param>
|
||||
void BaseMessageClient_OnDataReceived(Client sender, Data Data)
|
||||
{
|
||||
TCPMessage msg = null;
|
||||
try
|
||||
{
|
||||
msg = TCPMessage.FromByteArray(Data.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
if (msg != null)
|
||||
if (OnMessageReceived != null)
|
||||
OnMessageReceived(sender, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message structure to the server.
|
||||
/// </summary>
|
||||
/// <param name="msg">Message structure to be send.</param>
|
||||
/// <exception cref="TCPLibrary.Core.NotConnectedException"></exception>
|
||||
public void Send(TCPMessage msg)
|
||||
{
|
||||
if (OnBeforeMessageSent != null)
|
||||
OnBeforeMessageSent(this, msg);
|
||||
base.Send(new Data(msg.ToByteArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2008 Ferreri Alessio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
using TCPLibrary.Core;
|
||||
using System;
|
||||
|
||||
namespace TCPLibrary.MessageBased.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// TCP Client Class that work with Message structures.
|
||||
/// </summary>
|
||||
public class BaseMessageClient : Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate for the event of receiving a message structure from the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Mess">Message received.</param>
|
||||
public delegate void MessageReceivedHandler(Client sender, TCPMessage Mess);
|
||||
/// <summary>
|
||||
/// Occurs when the client receive a message structure from the server.
|
||||
/// </summary>
|
||||
public event MessageReceivedHandler OnMessageReceived;
|
||||
/// <summary>
|
||||
/// Delegate for the event of sending a message structure to the server.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Mess">Message sent.</param>
|
||||
public delegate void MessageSentHandler(Client sender, TCPMessage Mess);
|
||||
/// <summary>
|
||||
/// Occurs before the client send a message structure to the server.
|
||||
/// </summary>
|
||||
public event MessageSentHandler OnBeforeMessageSent;
|
||||
/// <summary>
|
||||
/// Occurs after the client send a message structure to the server.
|
||||
/// </summary>
|
||||
public event MessageSentHandler OnAfterMessageSent;
|
||||
/// <summary>
|
||||
/// Delegate for the event of connection fail for max users number reached.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
public delegate void MaxUsersReached(Client sender);
|
||||
/// <summary>
|
||||
/// Occurs when the connection fail as the server reached the maximum number of clients allowed.
|
||||
/// </summary>
|
||||
public event MaxUsersReached OnMaxUsersConnectionFail;
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public BaseMessageClient()
|
||||
{
|
||||
OnDataReceived += new DataCommunicationHandler(BaseMessageClient_OnDataReceived);
|
||||
OnAfterDataSent += new DataCommunicationHandler(BaseMessageClient_OnDataSent);
|
||||
OnConnectFailed += new ConnectionFailedHandler(BaseMessageClient_OnConnectFailed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the connection is rejected by the server raise the correct event.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Message">Message of the server.</param>
|
||||
void BaseMessageClient_OnConnectFailed(Client sender, byte[] Message)
|
||||
{
|
||||
if (TCPLibrary.MessageBased.Core.TCPMessage.FromByteArray(Message).MessageType == MessageType.MaxUsers)
|
||||
if (OnMaxUsersConnectionFail != null)
|
||||
OnMaxUsersConnectionFail(sender);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the raw data sent to the server and create Message structures.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Data">Line of data sent.</param>
|
||||
void BaseMessageClient_OnDataSent(Client sender, Data Data)
|
||||
{
|
||||
TCPMessage msg = TCPMessage.FromByteArray(Data.Message);
|
||||
if (OnAfterMessageSent != null)
|
||||
OnAfterMessageSent(sender, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the raw data received from the server and create Message structures.
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender of the event.</param>
|
||||
/// <param name="Data">Line of data received.</param>
|
||||
void BaseMessageClient_OnDataReceived(Client sender, Data Data)
|
||||
{
|
||||
TCPMessage msg = null;
|
||||
try
|
||||
{
|
||||
msg = TCPMessage.FromByteArray(Data.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
if (msg != null)
|
||||
if (OnMessageReceived != null)
|
||||
OnMessageReceived(sender, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message structure to the server.
|
||||
/// </summary>
|
||||
/// <param name="msg">Message structure to be send.</param>
|
||||
/// <exception cref="TCPLibrary.Core.NotConnectedException"></exception>
|
||||
public void Send(TCPMessage msg)
|
||||
{
|
||||
if (OnBeforeMessageSent != null)
|
||||
OnBeforeMessageSent(this, msg);
|
||||
base.Send(new Data(msg.ToByteArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,59 +1,59 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2008 Ferreri Alessio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Net.Sockets;
|
||||
using TCPLibrary.Core;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
|
||||
namespace TCPLibrary.MessageBased.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that manages the single connection between a client and the server based
|
||||
/// on Message structures.
|
||||
/// </summary>
|
||||
public class BaseMessageClientS : ClientS
|
||||
{
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
/// <param name="server">Server to which this client is linked to.</param>
|
||||
/// <param name="client">Socket of the client.</param>
|
||||
protected internal BaseMessageClientS(Server server, TcpClient client)
|
||||
: base(server, client)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a Message structure to the client.
|
||||
/// </summary>
|
||||
/// <param name="msg">Message to be sent.</param>
|
||||
/// <exception cref="TCPLibrary.Core.NotConnectedException" />
|
||||
public void Send(TCPMessage msg)
|
||||
{
|
||||
((BaseMessageServer)_server).RaiseBeforeMessageSentEvent(this, msg);
|
||||
base.Send(new Data(msg.ToByteArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2008 Ferreri Alessio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Net.Sockets;
|
||||
using TCPLibrary.Core;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
|
||||
namespace TCPLibrary.MessageBased.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that manages the single connection between a client and the server based
|
||||
/// on Message structures.
|
||||
/// </summary>
|
||||
public class BaseMessageClientS : ClientS
|
||||
{
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
/// <param name="server">Server to which this client is linked to.</param>
|
||||
/// <param name="client">Socket of the client.</param>
|
||||
protected internal BaseMessageClientS(Server server, TcpClient client)
|
||||
: base(server, client)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a Message structure to the client.
|
||||
/// </summary>
|
||||
/// <param name="msg">Message to be sent.</param>
|
||||
/// <exception cref="TCPLibrary.Core.NotConnectedException" />
|
||||
public void Send(TCPMessage msg)
|
||||
{
|
||||
((BaseMessageServer)_server).RaiseBeforeMessageSentEvent(this, msg);
|
||||
base.Send(new Data(msg.ToByteArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,186 +1,186 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2008 Ferreri Alessio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using TCPLibrary.Core;
|
||||
|
||||
namespace TCPLibrary.MessageBased.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// TCP Server Class that work with Message structures.
|
||||
/// </summary>
|
||||
public class BaseMessageServer : Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Limit of user allowed inside the server.
|
||||
/// </summary>
|
||||
protected Int32 _userlimit;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of receiving a Message from a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="sender">Client sending the message.</param>
|
||||
/// <param name="Mess">Message received.</param>
|
||||
public delegate void MessageReceivedHandler(BaseMessageServer server, BaseMessageClientS sender, TCPMessage Mess);
|
||||
/// <summary>
|
||||
/// Occurs when a Message is received by the server.
|
||||
/// </summary>
|
||||
public event MessageReceivedHandler OnClientMessageReceived;
|
||||
/// <summary>
|
||||
/// Delegate for the event of sending a Message to a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="receiver">Client that will receive the message.</param>
|
||||
/// <param name="Mess">Message to be sent.</param>
|
||||
public delegate void MessageSentHandler(BaseMessageServer server, BaseMessageClientS receiver, TCPMessage Mess);
|
||||
/// <summary>
|
||||
/// Occurs when the server send a Message to a client.
|
||||
/// </summary>
|
||||
public event MessageSentHandler OnClientBeforeMessageSent;
|
||||
/// <summary>
|
||||
/// Occurs when the server send a Message to a client.
|
||||
/// </summary>
|
||||
public event MessageSentHandler OnClientAfterMessageSent;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the limit of users allowed inside the server.
|
||||
/// </summary>
|
||||
public Int32 UserLimit
|
||||
{
|
||||
get { return _userlimit; }
|
||||
set { _userlimit = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public BaseMessageServer() : base()
|
||||
{
|
||||
OnClientBeforeConnect += new BeforeConnectedHandler(BaseMessageServer_OnClientBeforeConnect);
|
||||
OnClientDataReceived += new DataCommunicationHandler(BaseMessageServer_OnDataReceived);
|
||||
OnClientAfterDataSent += new DataCommunicationHandler(BaseMessageServer_OnDataSent);
|
||||
_userlimit = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kick the client if the server reached the maximum allowed number of clients.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="client">Client connecting to the server.</param>
|
||||
/// <param name="args">Specify if the client should be accepted into the server.</param>
|
||||
void BaseMessageServer_OnClientBeforeConnect(Server server, ClientS client, CancelArgs args)
|
||||
{
|
||||
if ((Clients.Count >= UserLimit) && (UserLimit != 0))
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.MaxUsers;
|
||||
((BaseMessageClientS)client).Send(msg);
|
||||
|
||||
args.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trasform the line of data sent into a Message structure and raise
|
||||
/// the event linked.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="receiver">Client that will receive the Message.</param>
|
||||
/// <param name="Data">Line of data sent.</param>
|
||||
void BaseMessageServer_OnDataSent(Server server, ClientS receiver, Data Data)
|
||||
{
|
||||
TCPMessage msg = null;
|
||||
try
|
||||
{
|
||||
msg = TCPMessage.FromByteArray(Data.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
if (msg != null)
|
||||
if (OnClientAfterMessageSent != null)
|
||||
OnClientAfterMessageSent(this, (BaseMessageClientS)receiver, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientBeforeMessageSent event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
/// <param name="msg">Message to be sent.</param>
|
||||
internal void RaiseBeforeMessageSentEvent(ClientS cl, TCPMessage msg)
|
||||
{
|
||||
if (OnClientBeforeMessageSent != null)
|
||||
OnClientBeforeMessageSent(this, (BaseMessageClientS)cl, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trasform the line of data received into a Message structure and raise
|
||||
/// the event linked.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="sender">Client sending the data.</param>
|
||||
/// <param name="Data">Line of data received.</param>
|
||||
void BaseMessageServer_OnDataReceived(Server server, ClientS sender, Data Data)
|
||||
{
|
||||
TCPMessage msg = null;
|
||||
try
|
||||
{
|
||||
msg = TCPMessage.FromByteArray(Data.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
if (msg != null)
|
||||
if (OnClientMessageReceived != null)
|
||||
OnClientMessageReceived(this, (BaseMessageClientS)sender, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function that create the structure to memorize the client data.
|
||||
/// </summary>
|
||||
/// <param name="socket">Socket of the client.</param>
|
||||
/// <returns>The structure in which memorize all the information of the client.</returns>
|
||||
protected override ClientS CreateClient(TcpClient socket)
|
||||
{
|
||||
return new BaseMessageClientS(this, socket);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to all clients in broadcast.
|
||||
/// </summary>
|
||||
/// <param name="Data">Message to be sent.</param>
|
||||
public void Broadcast(TCPMessage Data)
|
||||
{
|
||||
base.Broadcast(new Data(Data.ToByteArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2008 Ferreri Alessio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using TCPLibrary.MessageBased.Core;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using TCPLibrary.Core;
|
||||
|
||||
namespace TCPLibrary.MessageBased.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// TCP Server Class that work with Message structures.
|
||||
/// </summary>
|
||||
public class BaseMessageServer : Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Limit of user allowed inside the server.
|
||||
/// </summary>
|
||||
protected Int32 _userlimit;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for the event of receiving a Message from a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="sender">Client sending the message.</param>
|
||||
/// <param name="Mess">Message received.</param>
|
||||
public delegate void MessageReceivedHandler(BaseMessageServer server, BaseMessageClientS sender, TCPMessage Mess);
|
||||
/// <summary>
|
||||
/// Occurs when a Message is received by the server.
|
||||
/// </summary>
|
||||
public event MessageReceivedHandler OnClientMessageReceived;
|
||||
/// <summary>
|
||||
/// Delegate for the event of sending a Message to a client.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="receiver">Client that will receive the message.</param>
|
||||
/// <param name="Mess">Message to be sent.</param>
|
||||
public delegate void MessageSentHandler(BaseMessageServer server, BaseMessageClientS receiver, TCPMessage Mess);
|
||||
/// <summary>
|
||||
/// Occurs when the server send a Message to a client.
|
||||
/// </summary>
|
||||
public event MessageSentHandler OnClientBeforeMessageSent;
|
||||
/// <summary>
|
||||
/// Occurs when the server send a Message to a client.
|
||||
/// </summary>
|
||||
public event MessageSentHandler OnClientAfterMessageSent;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the limit of users allowed inside the server.
|
||||
/// </summary>
|
||||
public Int32 UserLimit
|
||||
{
|
||||
get { return _userlimit; }
|
||||
set { _userlimit = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public BaseMessageServer() : base()
|
||||
{
|
||||
OnClientBeforeConnect += new BeforeConnectedHandler(BaseMessageServer_OnClientBeforeConnect);
|
||||
OnClientDataReceived += new DataCommunicationHandler(BaseMessageServer_OnDataReceived);
|
||||
OnClientAfterDataSent += new DataCommunicationHandler(BaseMessageServer_OnDataSent);
|
||||
_userlimit = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kick the client if the server reached the maximum allowed number of clients.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="client">Client connecting to the server.</param>
|
||||
/// <param name="args">Specify if the client should be accepted into the server.</param>
|
||||
void BaseMessageServer_OnClientBeforeConnect(Server server, ClientS client, CancelArgs args)
|
||||
{
|
||||
if ((Clients.Count >= UserLimit) && (UserLimit != 0))
|
||||
{
|
||||
TCPMessage msg = new TCPMessage();
|
||||
msg.MessageType = MessageType.MaxUsers;
|
||||
((BaseMessageClientS)client).Send(msg);
|
||||
|
||||
args.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trasform the line of data sent into a Message structure and raise
|
||||
/// the event linked.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="receiver">Client that will receive the Message.</param>
|
||||
/// <param name="Data">Line of data sent.</param>
|
||||
void BaseMessageServer_OnDataSent(Server server, ClientS receiver, Data Data)
|
||||
{
|
||||
TCPMessage msg = null;
|
||||
try
|
||||
{
|
||||
msg = TCPMessage.FromByteArray(Data.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
if (msg != null)
|
||||
if (OnClientAfterMessageSent != null)
|
||||
OnClientAfterMessageSent(this, (BaseMessageClientS)receiver, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise the OnClientBeforeMessageSent event.
|
||||
/// </summary>
|
||||
/// <param name="cl">Client that raised the event.</param>
|
||||
/// <param name="msg">Message to be sent.</param>
|
||||
internal void RaiseBeforeMessageSentEvent(ClientS cl, TCPMessage msg)
|
||||
{
|
||||
if (OnClientBeforeMessageSent != null)
|
||||
OnClientBeforeMessageSent(this, (BaseMessageClientS)cl, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trasform the line of data received into a Message structure and raise
|
||||
/// the event linked.
|
||||
/// </summary>
|
||||
/// <param name="server">Server raising the event.</param>
|
||||
/// <param name="sender">Client sending the data.</param>
|
||||
/// <param name="Data">Line of data received.</param>
|
||||
void BaseMessageServer_OnDataReceived(Server server, ClientS sender, Data Data)
|
||||
{
|
||||
TCPMessage msg = null;
|
||||
try
|
||||
{
|
||||
msg = TCPMessage.FromByteArray(Data.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
if (msg != null)
|
||||
if (OnClientMessageReceived != null)
|
||||
OnClientMessageReceived(this, (BaseMessageClientS)sender, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function that create the structure to memorize the client data.
|
||||
/// </summary>
|
||||
/// <param name="socket">Socket of the client.</param>
|
||||
/// <returns>The structure in which memorize all the information of the client.</returns>
|
||||
protected override ClientS CreateClient(TcpClient socket)
|
||||
{
|
||||
return new BaseMessageClientS(this, socket);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to all clients in broadcast.
|
||||
/// </summary>
|
||||
/// <param name="Data">Message to be sent.</param>
|
||||
public void Broadcast(TCPMessage Data)
|
||||
{
|
||||
base.Broadcast(new Data(Data.ToByteArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,125 +1,125 @@
|
|||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2008 Ferreri Alessio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace TCPLibrary.MessageBased.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Message structure that contains all the information of the message exchanged between
|
||||
/// Message driven server/client.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TCPMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Message Type.
|
||||
/// </summary>
|
||||
private MessageType _messageType;
|
||||
/// <summary>
|
||||
/// Messages parameters.
|
||||
/// </summary>
|
||||
private List<object> _parameters;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the message type.
|
||||
/// </summary>
|
||||
public MessageType MessageType
|
||||
{
|
||||
get { return _messageType; }
|
||||
set { _messageType = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the message parameters.
|
||||
/// </summary>
|
||||
public List<object> Parameters
|
||||
{
|
||||
get { return _parameters; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public TCPMessage()
|
||||
{
|
||||
_messageType = MessageType.Connect;
|
||||
_parameters = new List<object>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a string and create a Message structure.
|
||||
/// </summary>
|
||||
/// <param name="data">Raw data.</param>
|
||||
/// <returns>Parsed message structure.</returns>
|
||||
static public TCPMessage FromByteArray(byte[] data)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryWriter sw = new BinaryWriter(ms);
|
||||
sw.Write(data, 0, data.Length);
|
||||
sw.Flush();
|
||||
ms.Position = 0;
|
||||
|
||||
BinaryFormatter formatter = new BinaryFormatter();
|
||||
TCPMessage msg = formatter.Deserialize(ms) as TCPMessage;
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trasform the structure into a String.
|
||||
/// </summary>
|
||||
/// <returns>The structure in a String format.</returns>
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryFormatter formatter = new BinaryFormatter();
|
||||
formatter.Serialize(ms, this);
|
||||
ms.Position = 0;
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public enum MessageType
|
||||
{
|
||||
Connect,
|
||||
MaxUsers,
|
||||
SizeDump,
|
||||
Statistics,
|
||||
StateOld,
|
||||
|
||||
GetDebugMode,
|
||||
SetDebugMode,
|
||||
DebugState,
|
||||
PacketInfo,
|
||||
|
||||
Step,
|
||||
RunToCursor,
|
||||
RunToNextVSync
|
||||
}
|
||||
}
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2008 Ferreri Alessio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace TCPLibrary.MessageBased.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Message structure that contains all the information of the message exchanged between
|
||||
/// Message driven server/client.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TCPMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Message Type.
|
||||
/// </summary>
|
||||
private MessageType _messageType;
|
||||
/// <summary>
|
||||
/// Messages parameters.
|
||||
/// </summary>
|
||||
private List<object> _parameters;
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the message type.
|
||||
/// </summary>
|
||||
public MessageType MessageType
|
||||
{
|
||||
get { return _messageType; }
|
||||
set { _messageType = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the message parameters.
|
||||
/// </summary>
|
||||
public List<object> Parameters
|
||||
{
|
||||
get { return _parameters; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor of the class.
|
||||
/// </summary>
|
||||
public TCPMessage()
|
||||
{
|
||||
_messageType = MessageType.Connect;
|
||||
_parameters = new List<object>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a string and create a Message structure.
|
||||
/// </summary>
|
||||
/// <param name="data">Raw data.</param>
|
||||
/// <returns>Parsed message structure.</returns>
|
||||
static public TCPMessage FromByteArray(byte[] data)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryWriter sw = new BinaryWriter(ms);
|
||||
sw.Write(data, 0, data.Length);
|
||||
sw.Flush();
|
||||
ms.Position = 0;
|
||||
|
||||
BinaryFormatter formatter = new BinaryFormatter();
|
||||
TCPMessage msg = formatter.Deserialize(ms) as TCPMessage;
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trasform the structure into a String.
|
||||
/// </summary>
|
||||
/// <returns>The structure in a String format.</returns>
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryFormatter formatter = new BinaryFormatter();
|
||||
formatter.Serialize(ms, this);
|
||||
ms.Position = 0;
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public enum MessageType
|
||||
{
|
||||
Connect,
|
||||
MaxUsers,
|
||||
SizeDump,
|
||||
Statistics,
|
||||
StateOld,
|
||||
|
||||
GetDebugMode,
|
||||
SetDebugMode,
|
||||
DebugState,
|
||||
PacketInfo,
|
||||
|
||||
Step,
|
||||
RunToCursor,
|
||||
RunToNextVSync
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("GSDumpGUI")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("PCSX2 Team")]
|
||||
[assembly: AssemblyProduct("GSDumpGUI")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ff0f400c-a2cc-4d81-be4a-43c53eed5025")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("GSDumpGUI")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("PCSX2 Team")]
|
||||
[assembly: AssemblyProduct("GSDumpGUI")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ff0f400c-a2cc-4d81-be4a-43c53eed5025")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
|
@ -1,70 +1,70 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GSDumpGUI.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GSDumpGUI.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon AppIcon {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("AppIcon", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GSDumpGUI.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GSDumpGUI.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon AppIcon {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("AppIcon", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +1,50 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GSDumpGUI.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string GSDXDir {
|
||||
get {
|
||||
return ((string)(this["GSDXDir"]));
|
||||
}
|
||||
set {
|
||||
this["GSDXDir"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string DumpDir {
|
||||
get {
|
||||
return ((string)(this["DumpDir"]));
|
||||
}
|
||||
set {
|
||||
this["DumpDir"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GSDumpGUI.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string GSDXDir {
|
||||
get {
|
||||
return ((string)(this["GSDXDir"]));
|
||||
}
|
||||
set {
|
||||
this["GSDXDir"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string DumpDir {
|
||||
get {
|
||||
return ((string)(this["DumpDir"]));
|
||||
}
|
||||
set {
|
||||
this["DumpDir"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="GSDumpGUI.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<userSettings>
|
||||
<GSDumpGUI.Properties.Settings>
|
||||
<setting name="GSDXDir" serializeAs="String">
|
||||
<value/>
|
||||
</setting>
|
||||
<setting name="DumpDir" serializeAs="String">
|
||||
<value/>
|
||||
</setting>
|
||||
</GSDumpGUI.Properties.Settings>
|
||||
</userSettings>
|
||||
<startup/></configuration>
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="GSDumpGUI.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<userSettings>
|
||||
<GSDumpGUI.Properties.Settings>
|
||||
<setting name="GSDXDir" serializeAs="String">
|
||||
<value/>
|
||||
</setting>
|
||||
<setting name="DumpDir" serializeAs="String">
|
||||
<value/>
|
||||
</setting>
|
||||
</GSDumpGUI.Properties.Settings>
|
||||
</userSettings>
|
||||
<startup/></configuration>
|
||||
|
|
Loading…
Reference in New Issue