wxSavestates branch: sync with trunk, preparing for re-integration.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxSavestates@4130 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-12-23 05:17:39 +00:00
commit 79caa6c665
70 changed files with 3441 additions and 449 deletions

View File

@ -45,6 +45,9 @@
#include <windows.h>
#include <intrin.h>
#include <winsock.h>
#include <malloc.h>
#include <limits.h>
/*
* In case windows.h doesn't define it (e.g. WinCE perhaps)
@ -54,23 +57,10 @@ typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
#endif
/*
* note: ETIMEDOUT is correctly defined in winsock.h
*/
#include <winsock.h>
/*
* In case ETIMEDOUT hasn't been defined above somehow.
* In case ETIMEDOUT hasn't been defined in winsock.h somehow.
*/
#ifndef ETIMEDOUT
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
#endif
#if !defined(malloc)
#include <malloc.h>
#endif
#if !defined(INT_MAX)
#include <limits.h>
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
#endif
/* use local include files during development */
@ -83,14 +73,6 @@ typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
#define INLINE
#endif
#if defined (__MINGW32__) || (_MSC_VER >= 1300)
#define PTW32_INTERLOCKED_LONG long
#define PTW32_INTERLOCKED_LPLONG long*
#else
#define PTW32_INTERLOCKED_LONG PVOID
#define PTW32_INTERLOCKED_LPLONG PVOID*
#endif
#if defined(__MINGW32__)
#include <stdint.h>
#elif defined(__BORLANDC__)
@ -338,9 +320,9 @@ struct ptw32_mcs_node_t_
{
struct ptw32_mcs_node_t_ **lock; /* ptr to tail of queue */
struct ptw32_mcs_node_t_ *next; /* ptr to successor in queue */
LONG readyFlag; /* set after lock is released by
HANDLE readyFlag; /* set after lock is released by
predecessor */
LONG nextFlag; /* set after 'next' ptr is set by
HANDLE nextFlag; /* set after 'next' ptr is set by
successor */
};
@ -668,18 +650,32 @@ extern "C"
#endif
/*
* Defaults. Could be overridden when building the inlined version of the dll.
* See ptw32_InterlockedCompareExchange.c
*/
// Default to inlining the pthreads versions... (air)
#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE
#define PTW32_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
static INLINE void* _InterlockedExchangePointer( void* volatile* target, void* value )
{
#ifdef _M_AMD64 // high-level atomic ops, please leave these 64 bit checks in place.
return (void*)_InterlockedExchange64( (LONG_PTR*)target, value );
#else
return (void*)_InterlockedExchange( (LONG_PTR*)target, (LONG_PTR)value );
#endif
}
#ifndef PTW32_INTERLOCKED_EXCHANGE
#define PTW32_INTERLOCKED_EXCHANGE _InterlockedExchange
static INLINE void* _InterlockedCompareExchangePointer( void* volatile* target, void* value, void* comparand )
{
#ifdef _M_AMD64 // high-level atomic ops, please leave these 64 bit checks in place.
return (void*)_InterlockedCompareExchange64( (LONG_PTR*)target, value, comparand );
#else
return (void*)_InterlockedCompareExchange( (LONG_PTR*)target, (LONG_PTR)value, (LONG_PTR)comparand );
#endif
}
static INLINE void* _InterlockedExchangeAddPointer( void* volatile* target, void* value )
{
#ifdef _M_AMD64 // high-level atomic ops, please leave these 64 bit checks in place.
return (void*)_InterlockedExchangeAdd64( (LONG_PTR*)target, (LONG_PTR)value );
#else
return (void*)_InterlockedExchangeAdd( (LONG_PTR*)target, (LONG_PTR)value );
#endif
}
/*

View File

@ -306,8 +306,9 @@ enum {
#endif
#endif
#ifndef HAVE_STRUCT_TIMESPEC
#if !defined( HAVE_STRUCT_TIMESPEC ) && !defined( _TIMESPEC_DEFINED )
#define HAVE_STRUCT_TIMESPEC 1
#define _TIMESPEC_DEFINED 1
struct timespec {
long tv_sec;
long tv_nsec;

View File

@ -84,13 +84,8 @@ pthread_barrier_wait (pthread_barrier_t * barrier)
*/
if (0 == result)
{
result = ((PTW32_INTERLOCKED_LONG) step ==
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG)
& (b->iStep),
(PTW32_INTERLOCKED_LONG)
(1L - step),
(PTW32_INTERLOCKED_LONG)
step) ?
result = ( step ==
_InterlockedCompareExchange ( &(b->iStep), (1L - step), step) ?
PTHREAD_BARRIER_SERIAL_THREAD : 0);
}

View File

@ -68,13 +68,9 @@ pthread_mutex_lock (pthread_mutex_t * mutex)
if (mx->kind == PTHREAD_MUTEX_NORMAL)
{
if ((LONG) PTW32_INTERLOCKED_EXCHANGE(
(LPLONG) &mx->lock_idx,
(LONG) 1) != 0)
if (_InterlockedExchange( &mx->lock_idx, 1) != 0)
{
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
(LPLONG) &mx->lock_idx,
(LONG) -1) != 0)
while (_InterlockedExchange( &mx->lock_idx, -1) != 0)
{
if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
{
@ -88,10 +84,7 @@ pthread_mutex_lock (pthread_mutex_t * mutex)
{
pthread_t self = pthread_self();
if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
(PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
(PTW32_INTERLOCKED_LONG) 1,
(PTW32_INTERLOCKED_LONG) 0) == 0)
if (_InterlockedCompareExchange(&mx->lock_idx, 1, 0) == 0)
{
mx->recursive_count = 1;
mx->ownerThread = self;
@ -111,9 +104,7 @@ pthread_mutex_lock (pthread_mutex_t * mutex)
}
else
{
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
(LPLONG) &mx->lock_idx,
(LONG) -1) != 0)
while (_InterlockedExchange(&mx->lock_idx, -1) != 0)
{
if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
{

View File

@ -133,13 +133,9 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
if (mx->kind == PTHREAD_MUTEX_NORMAL)
{
if ((LONG) PTW32_INTERLOCKED_EXCHANGE(
(LPLONG) &mx->lock_idx,
(LONG) 1) != 0)
if (_InterlockedExchange(&mx->lock_idx, 1) != 0)
{
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
(LPLONG) &mx->lock_idx,
(LONG) -1) != 0)
while (_InterlockedExchange(&mx->lock_idx, -1) != 0)
{
if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
{
@ -152,10 +148,7 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
{
pthread_t self = pthread_self();
if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
(PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
(PTW32_INTERLOCKED_LONG) 1,
(PTW32_INTERLOCKED_LONG) 0) == 0)
if (_InterlockedCompareExchange(&mx->lock_idx, 1, 0) == 0)
{
mx->recursive_count = 1;
mx->ownerThread = self;
@ -175,9 +168,7 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
}
else
{
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
(LPLONG) &mx->lock_idx,
(LONG) -1) != 0)
while (_InterlockedExchange(&mx->lock_idx, -1) != 0)
{
if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
{

View File

@ -63,10 +63,7 @@ pthread_mutex_trylock (pthread_mutex_t * mutex)
mx = *mutex;
if (0 == (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE (
(PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
(PTW32_INTERLOCKED_LONG) 1,
(PTW32_INTERLOCKED_LONG) 0))
if (0 == (LONG) _InterlockedCompareExchange(&mx->lock_idx, 1, 0))
{
if (mx->kind != PTHREAD_MUTEX_NORMAL)
{

View File

@ -60,8 +60,7 @@ pthread_mutex_unlock (pthread_mutex_t * mutex)
{
LONG idx;
idx = (LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx,
(LONG) 0);
idx = _InterlockedExchange (&mx->lock_idx, 0);
if (idx != 0)
{
if (idx < 0)
@ -92,8 +91,7 @@ pthread_mutex_unlock (pthread_mutex_t * mutex)
{
mx->ownerThread.p = NULL;
if ((LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx,
(LONG) 0) < 0)
if (_InterlockedExchange (&mx->lock_idx, 0) < 0)
{
/* Someone may be waiting on that mutex */
if (SetEvent (mx->event) == 0)

View File

@ -54,13 +54,8 @@ pthread_spin_destroy (pthread_spinlock_t * lock)
{
result = pthread_mutex_destroy (&(s->u.mutex));
}
else if ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED !=
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG)
& (s->interlock),
(PTW32_INTERLOCKED_LONG)
PTW32_OBJECT_INVALID,
(PTW32_INTERLOCKED_LONG)
PTW32_SPIN_UNLOCKED))
else if (PTW32_SPIN_UNLOCKED !=
_InterlockedCompareExchange(&(s->interlock), PTW32_OBJECT_INVALID, PTW32_SPIN_UNLOCKED))
{
result = EINVAL;
}

View File

@ -59,13 +59,8 @@ pthread_spin_lock (pthread_spinlock_t * lock)
s = *lock;
while ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED ==
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) &
(s->interlock),
(PTW32_INTERLOCKED_LONG)
PTW32_SPIN_LOCKED,
(PTW32_INTERLOCKED_LONG)
PTW32_SPIN_UNLOCKED))
while (PTW32_SPIN_LOCKED ==
_InterlockedCompareExchange(&(s->interlock), PTW32_SPIN_LOCKED, PTW32_SPIN_UNLOCKED))
{
}

View File

@ -60,12 +60,7 @@ pthread_spin_trylock (pthread_spinlock_t * lock)
s = *lock;
switch ((long)
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) &
(s->interlock),
(PTW32_INTERLOCKED_LONG)
PTW32_SPIN_LOCKED,
(PTW32_INTERLOCKED_LONG)
PTW32_SPIN_UNLOCKED))
_InterlockedCompareExchange(&(s->interlock), PTW32_SPIN_LOCKED, PTW32_SPIN_UNLOCKED))
{
case PTW32_SPIN_UNLOCKED:
return 0;

View File

@ -55,12 +55,7 @@ pthread_spin_unlock (pthread_spinlock_t * lock)
}
switch ((long)
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) &
(s->interlock),
(PTW32_INTERLOCKED_LONG)
PTW32_SPIN_UNLOCKED,
(PTW32_INTERLOCKED_LONG)
PTW32_SPIN_LOCKED))
_InterlockedCompareExchange (&(s->interlock), PTW32_SPIN_UNLOCKED, PTW32_SPIN_LOCKED))
{
case PTW32_SPIN_LOCKED:
return 0;

View File

@ -98,13 +98,11 @@
* set flag to -1 otherwise. Note that -1 cannot be a valid handle value.
*/
INLINE void
ptw32_mcs_flag_set (LONG * flag)
ptw32_mcs_flag_set (HANDLE * flag)
{
HANDLE e = (HANDLE)PTW32_INTERLOCKED_COMPARE_EXCHANGE(
(PTW32_INTERLOCKED_LPLONG)flag,
(PTW32_INTERLOCKED_LONG)-1,
(PTW32_INTERLOCKED_LONG)0);
if ((HANDLE)0 != e)
HANDLE e = (HANDLE)_InterlockedCompareExchangePointer(flag, (HANDLE)-1, (HANDLE)0);
if (e)
{
/* another thread has already stored an event handle in the flag */
SetEvent(e);
@ -118,24 +116,21 @@ ptw32_mcs_flag_set (LONG * flag)
* set, and proceed without creating an event otherwise.
*/
INLINE void
ptw32_mcs_flag_wait (LONG * flag)
ptw32_mcs_flag_wait (HANDLE * flag)
{
if (0 == InterlockedExchangeAdd((LPLONG)flag, 0)) /* MBR fence */
if (0 == _InterlockedExchangeAddPointer(flag, NULL)) /* MBR fence */
{
/* the flag is not set. create event. */
HANDLE e = CreateEvent(NULL, PTW32_FALSE, PTW32_FALSE, NULL);
if (0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE(
(PTW32_INTERLOCKED_LPLONG)flag,
(PTW32_INTERLOCKED_LONG)e,
(PTW32_INTERLOCKED_LONG)0))
{
/* stored handle in the flag. wait on it now. */
WaitForSingleObject(e, INFINITE);
}
if (0 == _InterlockedCompareExchangePointer(flag, e, 0))
{
/* stored handle in the flag. wait on it now. */
WaitForSingleObject(e, INFINITE);
}
CloseHandle(e);
CloseHandle(e);
}
}
@ -158,8 +153,7 @@ ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node)
node->next = 0; /* initially, no successor */
/* queue for the lock */
pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE((LPLONG)lock,
(LONG)node);
pred = (ptw32_mcs_local_node_t *)_InterlockedExchangePointer(lock, node);
if (0 != pred)
{
@ -190,9 +184,7 @@ ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node)
/* no known successor */
if (node == (ptw32_mcs_local_node_t *)
PTW32_INTERLOCKED_COMPARE_EXCHANGE((PTW32_INTERLOCKED_LPLONG)lock,
(PTW32_INTERLOCKED_LONG)0,
(PTW32_INTERLOCKED_LONG)node))
_InterlockedCompareExchangePointer(lock, 0, node))
{
/* no successor, lock is free now */
return;
@ -201,7 +193,7 @@ ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node)
/* wait for successor */
ptw32_mcs_flag_wait(&node->nextFlag);
next = (ptw32_mcs_local_node_t *)
InterlockedExchangeAdd((LPLONG)&node->next, 0); /* MBR fence */
_InterlockedExchangeAddPointer(&node->next, NULL); /* MBR fence */
}
/* pass the lock */

View File

@ -73,7 +73,7 @@ ptw32_cancel_self (void)
}
static void CALLBACK
ptw32_cancel_callback (DWORD unused)
ptw32_cancel_callback (DWORD_PTR unused)
{
ptw32_throw (PTW32_EPS_CANCEL);

View File

@ -94,6 +94,9 @@ ptw32_processTerminate (void)
tp = tpNext;
}
ptw32_threadReuseTop = PTW32_THREAD_REUSE_EMPTY;
ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
LeaveCriticalSection (&ptw32_thread_reuse_lock);
/*

View File

@ -72,15 +72,15 @@ ptw32_throw (DWORD exception)
* explicit thread exit here after cleaning up POSIX
* residue (i.e. cleanup handlers, POSIX thread handle etc).
*/
unsigned exitCode = 0;
void* exitCode = 0;
switch (exception)
{
case PTW32_EPS_CANCEL:
exitCode = (unsigned) PTHREAD_CANCELED;
exitCode = PTHREAD_CANCELED;
break;
case PTW32_EPS_EXIT:
exitCode = (unsigned) sp->exitStatus;;
exitCode = sp->exitStatus;
break;
}
@ -91,7 +91,7 @@ ptw32_throw (DWORD exception)
#endif
#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__)
_endthreadex (exitCode);
_endthreadex ((unsigned)exitCode);
#else
_endthread ();
#endif

View File

@ -65,28 +65,3 @@ endif(EXISTS "${PROJECT_SOURCE_DIR}/pcsx2" AND pcsx2_core)
if(EXISTS "${PROJECT_SOURCE_DIR}/plugins")
add_subdirectory(plugins)
endif(EXISTS "${PROJECT_SOURCE_DIR}/plugins")
#-------------------------------------------------------------------------------
# Resources
#-------------------------------------------------------------------------------
# Specify all binary images to convert them into c/c++ header files.
#
#-------------------------------------------------------------------------------
# add resources here
set(resourceList AppIcon16.png
AppIcon32.png
AppIcon64.png
BackgroundLogo.png
ButtonIcon_Camera.png
ConfigIcon_Cpu.png
ConfigIcon_Gamefixes.png
ConfigIcon_MemoryCard.png
ConfigIcon_Paths.png
ConfigIcon_Plugins.png
ConfigIcon_Speedhacks.png
ConfigIcon_Video.png
Dualshock.jpg)
createResourceTarget(${resourceList})
#-------------------------------------------------------------------------------

View File

@ -1,30 +1,5 @@
# additonal cmake macros and functions
#-------------------------------------------------------------------------------
# createResourceTarget
#-------------------------------------------------------------------------------
# This function is used to generate header files, used as resources.
# A list of Resources taken as input parameter.
#-------------------------------------------------------------------------------
function(createResourceTarget)
# working directory
set(workdir ${PROJECT_SOURCE_DIR}/pcsx2/gui/Resources)
# create dummy target depending on bin2cpp
add_custom_target(Resources
DEPENDS bin2cpp)
# create a custom command for every resource file
foreach(entry IN LISTS ARGV)
# create custom command and assign to target Resources
add_custom_command(TARGET Resources POST_BUILD
COMMAND bin2cpp ${entry}
WORKING_DIRECTORY ${workdir})
endforeach(entry)
endfunction(createResourceTarget)
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# detectOperatingSystem
#-------------------------------------------------------------------------------

View File

@ -363,6 +363,24 @@ set(pcsx2GuiHeaders
gui/RecentIsoList.h
)
# Gui resources headers
set(pcsx2GuiResources
gui/Resources/AppIcon16.h
gui/Resources/AppIcon32.h
gui/Resources/AppIcon64.h
gui/Resources/BackgroundLogo.h
gui/Resources/ConfigIcon_Appearance.h
gui/Resources/ButtonIcon_Camera.h
gui/Resources/ConfigIcon_Cpu.h
gui/Resources/ConfigIcon_Gamefixes.h
gui/Resources/ConfigIcon_MemoryCard.h
gui/Resources/ConfigIcon_Paths.h
gui/Resources/ConfigIcon_Plugins.h
gui/Resources/ConfigIcon_Speedhacks.h
gui/Resources/ConfigIcon_Video.h
gui/Resources/Dualshock.h
)
# IPU sources
set(pcsx2IPUSources
IPU/IPU.cpp
@ -568,6 +586,7 @@ set(Common
${pcsx2DebugToolsSources}
${pcsx2DebugToolsSources}
${pcsx2GuiSources}
${pcsx2GuiResources}
${pcsx2GuiHeaders}
${pcsx2IPUSources}
${pcsx2IPUHeaders}
@ -618,8 +637,21 @@ add_executable(${Output}
${Common}
${Platform})
# add dependencies
add_dependencies(${Output} Resources)
# Generate the resources files
add_custom_command(OUTPUT "gui/Resources/AppIcon16.h" COMMAND bin2cpp "gui/Resources/AppIcon16.png")
add_custom_command(OUTPUT "gui/Resources/AppIcon32.h" COMMAND bin2cpp "gui/Resources/AppIcon32.png")
add_custom_command(OUTPUT "gui/Resources/AppIcon64.h" COMMAND bin2cpp "gui/Resources/AppIcon64.png")
add_custom_command(OUTPUT "gui/Resources/BackgroundLogo.h" COMMAND bin2cpp "gui/Resources/BackgroundLogo.png")
add_custom_command(OUTPUT "gui/Resources/ButtonIcon_Camera.h" COMMAND bin2cpp "gui/Resources/ButtonIcon_Camera.png")
add_custom_command(OUTPUT "gui/Resources/ConfigIcon_Appearance.h" COMMAND bin2cpp "gui/Resources/ConfigIcon_Appearance.png")
add_custom_command(OUTPUT "gui/Resources/ConfigIcon_Cpu.h" COMMAND bin2cpp "gui/Resources/ConfigIcon_Cpu.png")
add_custom_command(OUTPUT "gui/Resources/ConfigIcon_Gamefixes.h" COMMAND bin2cpp "gui/Resources/ConfigIcon_Gamefixes.png")
add_custom_command(OUTPUT "gui/Resources/ConfigIcon_MemoryCard.h" COMMAND bin2cpp "gui/Resources/ConfigIcon_MemoryCard.png")
add_custom_command(OUTPUT "gui/Resources/ConfigIcon_Paths.h" COMMAND bin2cpp "gui/Resources/ConfigIcon_Paths.png")
add_custom_command(OUTPUT "gui/Resources/ConfigIcon_Plugins.h" COMMAND bin2cpp "gui/Resources/ConfigIcon_Plugins.png")
add_custom_command(OUTPUT "gui/Resources/ConfigIcon_Speedhacks.h" COMMAND bin2cpp "gui/Resources/ConfigIcon_Speedhacks.png")
add_custom_command(OUTPUT "gui/Resources/ConfigIcon_Video.h" COMMAND bin2cpp "gui/Resources/ConfigIcon_Video.png")
add_custom_command(OUTPUT "gui/Resources/Dualshock.h" COMMAND bin2cpp "gui/Resources/Dualshock.jpg")
# link target with project internal libraries
target_link_libraries(${Output} Utilities x86emitter)

View File

@ -161,6 +161,7 @@ intra:
macroblock_modes = GETBITS(1);
//I suspect (as this is actually a 2 bit command) that this should be getbits(2)
//additionally, we arent dumping any bits here when i think we should be, need a game to test. (Refraction)
DevCon.Warning(" Rare MPEG command! ");
if (macroblock_modes == 0) return 0; // error
return (MACROBLOCK_INTRA | (1 << 16));

View File

@ -510,6 +510,11 @@
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Appearance.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Cpu.h" />
<Unit filename="../gui/Resources/ConfigIcon_Cpu.png">
<Option compile="1" />

View File

@ -190,14 +190,15 @@ struct AppImageIds
Gamefixes,
MemoryCard,
Video,
Cpu;
Cpu,
Appearance;
ConfigIds()
{
Paths = Plugins =
Speedhacks = Gamefixes =
Video = Cpu =
MemoryCard = -1;
Paths = Plugins =
Speedhacks = Gamefixes =
Video = Cpu =
MemoryCard = Appearance = -1;
}
} Config;

View File

@ -360,7 +360,8 @@ AppConfig::AppConfig()
: MainGuiPosition( wxDefaultPosition )
, SysSettingsTabName( L"Cpu" )
, McdSettingsTabName( L"none" )
, AppSettingsTabName( L"Plugins" )
, ComponentsTabName( L"Plugins" )
, AppSettingsTabName( L"Appearance" )
, GameDatabaseTabName( L"none" )
, DeskTheme( L"default" )
{
@ -466,6 +467,7 @@ void AppConfig::LoadSaveRootItems( IniInterface& ini )
IniEntry( MainGuiPosition );
IniEntry( SysSettingsTabName );
IniEntry( McdSettingsTabName );
IniEntry( ComponentsTabName );
IniEntry( AppSettingsTabName );
IniEntry( GameDatabaseTabName );
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );

View File

@ -192,6 +192,7 @@ public:
// by it's UTF/ASCII name).
wxString SysSettingsTabName;
wxString McdSettingsTabName;
wxString ComponentsTabName;
wxString AppSettingsTabName;
wxString GameDatabaseTabName;

View File

@ -31,6 +31,7 @@
#include "Resources/ConfigIcon_Paths.h"
#include "Resources/ConfigIcon_Plugins.h"
#include "Resources/ConfigIcon_MemoryCard.h"
#include "Resources/ConfigIcon_Appearance.h"
#include "Resources/AppIcon16.h"
#include "Resources/AppIcon32.h"
@ -184,6 +185,7 @@ wxImageList& Pcsx2App::GetImgList_Config()
FancyLoadMacro( MemoryCard );
FancyLoadMacro( Video );
FancyLoadMacro( Cpu );
FancyLoadMacro( Appearance );
}
return *images;
}

View File

@ -90,23 +90,18 @@ namespace Dialogs
};
// --------------------------------------------------------------------------------------
// LanguageSelectionDialog
// InterfaceConfigDialog
// --------------------------------------------------------------------------------------
class LanguageSelectionDialog : public BaseConfigurationDialog
class InterfaceConfigDialog : public BaseConfigurationDialog
{
public:
virtual ~LanguageSelectionDialog() throw() {}
LanguageSelectionDialog(wxWindow* parent=NULL);
static wxString GetNameStatic() { return L"LanguageSelector"; }
virtual ~InterfaceConfigDialog() throw() {}
InterfaceConfigDialog(wxWindow* parent=NULL);
static wxString GetNameStatic() { return L"InterfaceConfig"; }
wxString GetDialogName() const { return GetNameStatic(); }
protected:
virtual wxString& GetConfSettingsTabName() const
{
pxFailDev("Language selector does not have a listbook or settings tab.");
static wxString fail;
return fail;
}
virtual wxString& GetConfSettingsTabName() const { return g_Conf->AppSettingsTabName; }
};
// --------------------------------------------------------------------------------------
@ -162,7 +157,7 @@ namespace Dialogs
wxString GetDialogName() const { return GetNameStatic(); }
protected:
virtual wxString& GetConfSettingsTabName() const { return g_Conf->AppSettingsTabName; }
virtual wxString& GetConfSettingsTabName() const { return g_Conf->ComponentsTabName; }
};
// --------------------------------------------------------------------------------------

View File

@ -97,7 +97,6 @@ Dialogs::ComponentsConfigDialog::ComponentsConfigDialog(wxWindow* parent)
AddPage<PluginSelectorPanel> ( pxL("Plugins"), cfgid.Plugins );
AddPage<BiosSelectorPanel> ( pxL("BIOS"), cfgid.Cpu );
AddPage<StandardPathsPanel> ( pxL("Folders"), cfgid.Paths );
AddListbook();
AddOkCancel();
@ -106,12 +105,20 @@ Dialogs::ComponentsConfigDialog::ComponentsConfigDialog(wxWindow* parent)
wxGetApp().PostMethod( CheckPluginsOverrides );
}
Dialogs::LanguageSelectionDialog::LanguageSelectionDialog(wxWindow *parent)
Dialogs::InterfaceConfigDialog::InterfaceConfigDialog(wxWindow *parent)
: BaseConfigurationDialog( parent, AddAppName(_("Language Selector - %s")), 400 )
{
ScopedBusyCursor busy( Cursor_ReallyBusy );
*this += new Panels::LanguageSelectionPanel( this ) | pxCenter;
CreateListbook( wxGetApp().GetImgList_Config() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
wxDialogWithHelpers::AddOkCancel( NULL, false );
AddPage<StandardPathsPanel> ( pxL("Appearance"), cfgid.Appearance );
AddPage<StandardPathsPanel> ( pxL("Folders"), cfgid.Paths );
AddListbook();
AddOkCancel();
//*this += new Panels::LanguageSelectionPanel( this ) | pxCenter;
//wxDialogWithHelpers::AddOkCancel( NULL, false );
}

View File

@ -39,9 +39,12 @@ void MSW_ListView_SetIconSpacing( wxListbook& listbook, int width )
// way over generous. This little bit of Win32-specific code ensures proper icon spacing, scaled
// to the size of the frame's ideal width.
ListView_SetIconSpacing( (HWND)listbook.GetListView()->GetHWND(),
(width / listbook.GetPageCount()) - 4, g_Conf->Listbook_ImageSize+32 // y component appears to be ignored
);
if (listbook.GetPageCount())
{
ListView_SetIconSpacing( (HWND)listbook.GetListView()->GetHWND(),
(width / listbook.GetPageCount()) - 4, g_Conf->Listbook_ImageSize+32 // y component appears to be ignored
);
}
#endif
}

View File

@ -450,7 +450,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
if (IsDebugBuild)
{
m_menuConfig.Append(MenuId_Config_GameDatabase, _("Game Database Editor") );
m_menuConfig.Append(MenuId_Config_Language, _("Language...") );
m_menuConfig.Append(MenuId_Config_Language, _("Appearance...") );
}
m_menuConfig.AppendSeparator();

View File

@ -74,8 +74,8 @@ void MainEmuFrame::Menu_SelectPluginsBios_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Language_Click(wxCommandEvent &event)
{
//AppOpenDialog<LanguageSelectionDialog>( this );
LanguageSelectionDialog(this).ShowModal();
//AppOpenDialog<InterfaceConfigDialog>( this );
InterfaceConfigDialog(this).ShowModal();
}
static void WipeSettings()

View File

@ -34,6 +34,10 @@ RecentIsoManager::RecentIsoManager( wxMenu* menu )
{
m_cursel = 0;
m_Separator = NULL;
IniLoader loader;
LoadListFrom(loader);
Connect( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(RecentIsoManager::OnChangedSelection) );
}
@ -59,10 +63,8 @@ void RecentIsoManager::OnChangedSelection( wxCommandEvent& evt )
m_cursel = i;
// TODO: Dialog asking for hotswap or reset!!!!
ScopedCoreThreadPopup stopped_core;
//SysUpdateIsoSrcFile( m_Items[i].Filename );
#ifdef __LINUX__
// Likely not what was intended, but it compiles for the moment...
SwapOrReset_Iso( NULL, stopped_core, m_Items[i].Filename, GetMsg_IsoImageChanged());
@ -70,6 +72,7 @@ void RecentIsoManager::OnChangedSelection( wxCommandEvent& evt )
// Getting a window from the menu?
SwapOrReset_Iso( m_Menu->GetWindow(), stopped_core, m_Items[i].Filename, GetMsg_IsoImageChanged());
#endif
stopped_core.AllowResume();
}
@ -157,6 +160,27 @@ void RecentIsoManager::InsertIntoMenu( int id )
curitem.ItemPtr->Check();
}
void RecentIsoManager::LoadListFrom( IniInterface& ini )
{
if (!ini.IsOk()) return;
ini.GetConfig().SetRecordDefaults( false );
RemoveAllFromMenu();
m_MaxLength = g_Conf->RecentIsoCount;
ScopedIniGroup groupie( ini, L"RecentIso" );
for( uint i=0; i<m_MaxLength; ++i )
{
wxString loadtmp;
ini.Entry( pxsFmt( L"Filename%02d", i ), loadtmp );
if( !loadtmp.IsEmpty() ) Add( loadtmp );
}
Add( g_Conf->CurrentIso );
ini.GetConfig().SetRecordDefaults( true );
}
void RecentIsoManager::AppStatusEvent_OnSettingsApplied()
{
// TODO : Implement application of Recent Iso List "maximum" history option
@ -166,36 +190,26 @@ void RecentIsoManager::AppStatusEvent_OnSettingsLoadSave( const AppSettingsEvent
{
IniInterface& ini( evt.GetIni() );
ini.GetConfig().SetRecordDefaults( false );
if( ini.IsSaving() )
{
// Wipe existing recent iso list if we're saving, because our size might have changed
// and that could leave some residual entries in the config.
ini.GetConfig().SetRecordDefaults( false );
ini.GetConfig().DeleteGroup( L"RecentIso" );
ScopedIniGroup groupie( ini, L"RecentIso" );
int cnt = m_Items.size();
for( int i=0; i<cnt; ++i )
{
ini.Entry( wxsFormat( L"Filename%02d", i ), m_Items[i].Filename );
ini.Entry( pxsFmt( L"Filename%02d", i ), m_Items[i].Filename );
}
ini.GetConfig().SetRecordDefaults( true );
}
else
{
RemoveAllFromMenu();
m_MaxLength = g_Conf->RecentIsoCount;
ScopedIniGroup groupie( ini, L"RecentIso" );
for( uint i=0; i<m_MaxLength; ++i )
{
wxString loadtmp;
ini.Entry( wxsFormat( L"Filename%02d", i ), loadtmp );
if( !loadtmp.IsEmpty() ) Add( loadtmp );
}
Add( g_Conf->CurrentIso );
LoadListFrom(ini);
}
ini.GetConfig().SetRecordDefaults( true );
}

View File

@ -58,6 +58,7 @@ public:
protected:
void InsertIntoMenu( int id );
void OnChangedSelection( wxCommandEvent& evt );
void LoadListFrom( IniInterface& ini );
void AppStatusEvent_OnSettingsLoadSave( const AppSettingsEventInfo& ini );
void AppStatusEvent_OnSettingsApplied();

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -166,6 +166,7 @@ static __ri const char* _eelog_GetHwName( u32 addr, T val )
EasyCase(SIF1_CHCR);
EasyCase(SIF1_MADR);
EasyCase(SIF1_QWC);
EasyCase(SIF1_TADR);
EasyCase(SIF2_CHCR);
EasyCase(SIF2_MADR);

View File

@ -2234,6 +2234,40 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\gui\Resources\ConfigIcon_Appearance.png"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine="&quot;$(InputDir)\bin2cpp.cmd&quot; $(InputFileName)&#x0D;&#x0A;"
Outputs="&quot;$(InputDir)\$(InputName).h"
/>
</FileConfiguration>
<FileConfiguration
Name="Devel|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Compiling Bitmap Resource..."
CommandLine="&quot;$(InputDir)\bin2cpp.cmd&quot; $(InputFileName)&#x0D;&#x0A;"
Outputs="&quot;$(InputDir)\$(InputName).h"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Compiling Bitmap Resource..."
CommandLine="&quot;$(InputDir)\bin2cpp.cmd&quot; $(InputFileName)&#x0D;&#x0A;"
Outputs="&quot;$(InputDir)\$(InputName).h"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\gui\Resources\ConfigIcon_Cpu.png"
>

View File

@ -229,6 +229,9 @@ bool GSDevice11::Create(GSWnd* wnd)
}
}
if (m_msaa_desc.Count == 1)
m_msaa = 0;
// convert
D3D11_INPUT_ELEMENT_DESC il_convert[] =

View File

@ -91,10 +91,10 @@ bool GSDevice9::Create(GSWnd* wnd)
if(!m_d3d) return false;
if (TestDepthFormat(m_d3d, D3DFMT_D32F_LOCKABLE))
m_depth_format = D3DFMT_D32F_LOCKABLE;
else if (TestDepthFormat(m_d3d, D3DFMT_D32))
if (TestDepthFormat(m_d3d, D3DFMT_D32))
m_depth_format = D3DFMT_D32;
else if (TestDepthFormat(m_d3d, D3DFMT_D32F_LOCKABLE))
m_depth_format = D3DFMT_D32F_LOCKABLE;
else if (TestDepthFormat(m_d3d, D3DFMT_D24S8))
m_depth_format = D3DFMT_D24S8;
else
@ -155,6 +155,9 @@ bool GSDevice9::Create(GSWnd* wnd)
}
}
if (m_msaa_desc.Count == 1)
m_msaa = 0;
//
if(!Reset(1, 1))

View File

@ -85,7 +85,9 @@ void GSSettingsDlg::OnInit()
ComboBoxAppend(IDC_RESOLUTION, "Please select...", (LPARAM)&m_modes.back(), true);
if(CComPtr<IDirect3D9> d3d = Direct3DCreate9(D3D_SDK_VERSION))
CComPtr<IDirect3D9> d3d;
d3d.Attach(Direct3DCreate9(D3D_SDK_VERSION));
if(d3d)
{
uint32 w = theApp.GetConfig("ModeWidth", 0);
uint32 h = theApp.GetConfig("ModeHeight", 0);

View File

@ -63,6 +63,7 @@ extern int Interpolation;
extern int ReverbBoost;
extern int numSpeakers;
extern bool EffectsDisabled;
extern bool postprocess_filter_enabled;
extern u32 OutputModule;
extern int SndOutLatencyMS;

View File

@ -88,6 +88,9 @@ extern void SysMessage(const wchar_t *fmt, ...);
# define SPU2_LOG
#endif
// Uncomment to enable debug keys on numpad (0 to 5)
//#define DEBUG_KEYS
#include "Utilities/Exceptions.h"
#include "Utilities/SafeArray.h"

View File

@ -43,6 +43,7 @@ int Interpolation = 1;
bool EffectsDisabled = false;
int ReverbBoost = 0;
bool postprocess_filter_enabled = 1;
// OUTPUT
u32 OutputModule = 0;

View File

@ -69,6 +69,7 @@ static __forceinline bool RegDump() { return _RegDump & DebugEnabled; }*/
extern int Interpolation;
extern int ReverbBoost;
extern bool EffectsDisabled;
extern bool postprocess_filter_enabled;
extern int AutoDMAPlayRate[2];

View File

@ -723,6 +723,80 @@ StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input,
return TD + ApplyVolume( RV*temp, FxVol );
}
// Filters that work on the final output to de-alias and equlize it.
// Taken from http://nenolod.net/projects/upse/
#define OVERALL_SCALE (0.87f)
StereoOut32 Apply_Frequency_Response_Filter(StereoOut32 &SoundStream)
{
static FrequencyResponseFilter FRF = FrequencyResponseFilter();
s32 in, out;
s32 l, r;
s32 mid, side;
l = SoundStream.Left;
r = SoundStream.Right;
mid = l + r;
side = l - r;
in = mid;
out = FRF.la0 * in + FRF.la1 * FRF.lx1 + FRF.la2 * FRF.lx2 - FRF.lb1 * FRF.ly1 - FRF.lb2 * FRF.ly2;
FRF.lx2 = FRF.lx1;
FRF.lx1 = in;
FRF.ly2 = FRF.ly1;
FRF.ly1 = out;
mid = out;
l = ((0.5) * (OVERALL_SCALE)) * (mid + side);
r = ((0.5) * (OVERALL_SCALE)) * (mid - side);
in = l;
out = FRF.ha0 * in + FRF.ha1 * FRF.History_One_In.Left + FRF.ha2 * FRF.History_Two_In.Left - FRF.hb1 * FRF.History_One_Out.Left - FRF.hb2 * FRF.History_Two_Out.Left;
FRF.History_Two_In.Left = FRF.History_One_In.Left; FRF.History_One_In.Left = in;
FRF.History_Two_Out.Left = FRF.History_One_Out.Left; FRF.History_One_Out.Left = out;
l = out;
in = r;
out = FRF.ha0 * in + FRF.ha1 * FRF.History_One_In.Right + FRF.ha2 * FRF.History_Two_In.Right - FRF.hb1 * FRF.History_One_Out.Right - FRF.hb2 * FRF.History_Two_Out.Right;
FRF.History_Two_In.Right = FRF.History_One_In.Right; FRF.History_One_In.Right = in;
FRF.History_Two_Out.Right = FRF.History_One_Out.Right; FRF.History_One_Out.Right = out;
r = out;
//clamp_mix(l);
//clamp_mix(r);
SoundStream.Left = l;
SoundStream.Right = r;
return SoundStream;
}
StereoOut32 Apply_Dealias_Filter(StereoOut32 &SoundStream)
{
static StereoOut32 Old = StereoOut32::Empty;
s32 l, r;
l = SoundStream.Left;
r = SoundStream.Right;
l += (l - Old.Left);
r += (r - Old.Right);
Old.Left = SoundStream.Left;
Old.Right = SoundStream.Right;
SoundStream.Left = l;
SoundStream.Right = r;
return SoundStream;
}
// used to throttle the output rate of cache stat reports
static int p_cachestat_counter=0;
@ -780,11 +854,18 @@ __forceinline void Mix()
Out.Left = MulShr32( Out.Left<<(SndOutVolumeShift+1), Cores[1].MasterVol.Left.Value );
Out.Right = MulShr32( Out.Right<<(SndOutVolumeShift+1), Cores[1].MasterVol.Right.Value );
#ifdef DEBUG_KEYS
if(postprocess_filter_enabled)
#endif
{
Out = Apply_Dealias_Filter ( Out );
Out = Apply_Frequency_Response_Filter ( Out );
}
// Final Clamp!
// Like any good audio system, the PS2 pumps the volume and incurs some distortion in its
// output, giving us a nice thumpy sound at times. So we add 1 above (2x volume pump) and
// then clamp it all here.
Out = clamp_mix( Out, SndOutVolumeShift );
}

View File

@ -78,6 +78,48 @@ struct StereoOut32
};
struct FrequencyResponseFilter
{
static FrequencyResponseFilter Empty;
StereoOut32 History_One_In;
StereoOut32 History_One_Out;
StereoOut32 History_Two_In;
StereoOut32 History_Two_Out;
s32 lx1;
s32 lx2;
s32 ly1;
s32 ly2;
float la0, la1, la2, lb1, lb2;
float ha0, ha1, ha2, hb1, hb2;
FrequencyResponseFilter() :
History_One_In( 0, 0 ),
History_One_Out( 0, 0 ),
History_Two_In( 0, 0 ),
History_Two_Out( 0, 0 ),
lx1 ( 0 ),
lx2 ( 0 ),
ly1 ( 0 ),
ly2 ( 0 ),
la0 ( 1.00320890889339290000 ),
la1 ( -1.97516434134506300000 ),
la2 ( 0.97243484967313087000 ),
lb1 ( -1.97525280404731810000 ),
lb2 ( 0.97555529586426892000 ),
ha0 ( 1.52690772687271160000 ),
ha1 ( -1.62653918974914990000 ),
ha2 ( 0.57997976029249387000 ),
hb1 ( -0.80955590379048203000 ),
hb2 ( 0.28990420120653748000 )
{
}
};
extern void Mix();
extern s32 clamp_mix( s32 x, u8 bitshift=0 );

View File

@ -26,8 +26,6 @@
# include "svnrev.h"
#endif
// Uncomment to enable debug keys
//#define DEBUG_KEYS
// PCSX2 expects ASNI, not unicode, so this MUST always be char...
static char libraryName[256];
@ -511,7 +509,7 @@ static bool numpad_plus = false, numpad_plus_old = false;
#ifdef DEBUG_KEYS
static u32 lastTicks;
static bool lState[5];
static bool lState[6];
#endif
EXPORT_C_(void) SPU2async(u32 cycles)
@ -530,17 +528,23 @@ EXPORT_C_(void) SPU2async(u32 cycles)
#ifdef DEBUG_KEYS
u32 curTicks = GetTickCount();
if((curTicks - lastTicks) >= 100)
if((curTicks - lastTicks) >= 50)
{
int oldI = Interpolation;
bool cState[5];
for(int i=0;i<5;i++)
bool cState[6];
for(int i=0;i<6;i++)
{
cState[i] = !!(GetAsyncKeyState(VK_NUMPAD0+i)&0x8000);
if(cState[i] && !lState[i])
if((cState[i] && !lState[i]) && i != 5)
Interpolation = i;
if((cState[i] && !lState[i]) && i == 5)
{
postprocess_filter_enabled = !postprocess_filter_enabled;
printf("Post process filters %s \n", postprocess_filter_enabled? "enabled" : "disabled");
}
lState[i] = cState[i];
}

View File

@ -37,6 +37,7 @@ int Interpolation = 1;
*/
int ReverbBoost = 0;
bool EffectsDisabled = false;
bool postprocess_filter_enabled = 1;
// OUTPUT
int SndOutLatencyMS = 150;

View File

@ -234,7 +234,8 @@ void DisplayAdvancedDialog()
dialog = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dialog), "ZZOgl PG Advanced Config");
gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 600);
// A good value for the heigh will be 1000 instead of 800 but I'm afraid that some people still uses small screen...
gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 800);
gtk_window_set_modal(GTK_WINDOW(dialog), true);
advanced_box = gtk_vbox_new(false, 5);

View File

@ -42,6 +42,42 @@ u32 s_uClampData[2] = {0, };
//u32 results[65535] = {0, };
// Note that not all the registers are currently handled, even if they write values out.
// For reference, I'm starting a list of unhandled flags here. I'm sure I missed some,
// so feel free to add to this, or remove ones that are handled that I missed.
// Cases where these values are set would be useful, too.
//
// In GIFRegHandlerFOG, I don't see gs.vertexregs.f being used anywhere afterwards.
// GIFRegHandlerTEX1 doesn't look like anything other then mmag and mmin are handled.
// This includes:
// lcm - the lod (level of detail) calculation method. If 0, it's (log2(1/|Q|)<<L)+K), whereas if it is one, it's just K.
// mxl - This is what MIPMAP level we use. The default is 0, and any other level uses miptbp0 & 1 to get the texture width.
// mtba - this is the base address specification for MIPMAP level 1+.
// l - Yeah, this is for the LOD calculation.
// k - This too.
// This largely sums up as that we don't support MIPMAP level 1+ (much like GSdx), and LOD.
//
// In GIFRegHandlerSCANMSK, it doesn't look like gs.smask is used, though it may have been in the old resolve code.
// Lets see: 00 is normal drawing, 01 is reserved, 10 prohibits drawing to even y coords, and 11 prohibits drawing to odd y coords.
//
// In GIFRegHandlerMIPTBP1 & 2, both miptbp0 & miptbp1 look unused, which isn't suprising, given mxl not being checked.
//
// GIFRegHandlerDIMX doesn't even have any code in it!
// This is supposed to read in the matrix for dithering.
//
// In GIFRegHandlerDTHE, nothing is done with gs.dthe.
// This goes right with the last one, because dthe is set to 1 when dithering with the dthe matrix.
// In GIFRegHandlerCOLCLAMP, gs.colclamp is not used.
// This is color clamping on the RGB value. If it's 0, it is set to mask, the lower 8 bits are enabled, and it wraps around. At 1, it is clamped from 0-255.
//#define SPAM_UNUSED_REGISTERS
#ifdef SPAM_UNUSED_REGISTERS
#define REG_LOG ZZLog::Error_Log
#else
#define REG_LOG 0 &&
#endif
void __gifCall GIFPackedRegHandlerNull(const u32* data)
{
FUNCLOG
@ -109,6 +145,7 @@ void __gifCall GIFPackedRegHandlerFOG(const u32* data)
{
FUNCLOG
gs.vertexregs.f = (data[3] & 0xff0) >> 4;
if (gs.vertexregs.f != 0) REG_LOG("GIFPackedRegHandlerFOG == %d", gs.vertexregs.f);
}
void __gifCall GIFPackedRegHandlerA_D(const u32* data)
@ -273,6 +310,8 @@ void __gifCall GIFRegHandlerFOG(const u32* data)
FUNCLOG
//gs.gsvertex[gs.primIndex].f = (data[1] >> 24); // shift to upper bits
gs.vertexregs.f = data[1] >> 24;
if (gs.vertexregs.f != 0) REG_LOG("GIFPackedRegHandlerFOG == %d", gs.vertexregs.f);
}
void __gifCall GIFRegHandlerXYZF3(const u32* data)
@ -320,6 +359,11 @@ void __gifCall GIFRegHandlerTEX1(const u32* data)
tex1.mtba = (data[0] >> 9) & 0x1;
tex1.l = (data[0] >> 19) & 0x3;
tex1.k = (data[1] >> 4) & 0xff;
#ifdef SPAM_UNUSED_REGISTERS
REG_LOG("Lcm = %d, l = %d, k = %d", tex1.lcm, tex1.l, tex1.k);
if (tex1.mxl != 0) REG_LOG("MIPMAP level set to %d, which is unsupported.");
#endif
}
template <u32 ctxt>
@ -420,6 +464,7 @@ void __gifCall GIFRegHandlerSCANMSK(const u32* data)
// ResolveZ(&vb[0]);
gs.smask = data[0] & 0x3;
REG_LOG("Scanmsk == %d", gs.smask);
}
template <u32 ctxt>
@ -433,6 +478,13 @@ void __gifCall GIFRegHandlerMIPTBP1(const u32* data)
miptbp0.tbw[1] = (data[1] >> 2) & 0x3f;
miptbp0.tbp[2] = (data[1] >> 8) & 0x3fff;
miptbp0.tbw[2] = (data[1] >> 22) & 0x3f;
#ifdef SPAM_UNUSED_REGISTERS
if ((miptbp0.tbp[0] != 0) || (miptbp0.tbp[1] != 0) || (miptbp0.tbp[2] != 0))
{
REG_LOG("MIPTBP1: 0:%d(%d) 1:%d(%d) 2:%d(%d).", \
miptbp0.tbp[0], miptbp0.tbw[0], miptbp0.tbp[1], miptbp0.tbw[1], miptbp0.tbp[2], miptbp0.tbw[2]);
}
#endif
}
template <u32 ctxt>
@ -446,6 +498,13 @@ void __gifCall GIFRegHandlerMIPTBP2(const u32* data)
miptbp1.tbw[1] = (data[1] >> 2) & 0x3f;
miptbp1.tbp[2] = (data[1] >> 8) & 0x3fff;
miptbp1.tbw[2] = (data[1] >> 22) & 0x3f;
#ifdef SPAM_UNUSED_REGISTERS
if ((miptbp1.tbp[0] != 0) || (miptbp1.tbp[1] != 0) || (miptbp1.tbp[2] != 0))
{
REG_LOG("MIPTBP2: 0:%d(%d) 1:%d(%d) 2:%d(%d).", \
miptbp1.tbp[0], miptbp1.tbw[0], miptbp1.tbp[1], miptbp1.tbw[1], miptbp1.tbp[2], miptbp1.tbw[2]);
}
#endif
}
void __gifCall GIFRegHandlerTEXA(const u32* data)
@ -535,12 +594,17 @@ void __gifCall GIFRegHandlerDTHE(const u32* data)
{
FUNCLOG
gs.dthe = data[0] & 0x1;
if (gs.dthe != 0) REG_LOG("Dithering set. (but not implemented.)");
}
void __gifCall GIFRegHandlerCOLCLAMP(const u32* data)
{
FUNCLOG
gs.colclamp = data[0] & 0x1;
if (gs.colclamp == 0)
REG_LOG("COLCLAMP == MASK");
else
REG_LOG("COLCLAMP == CLAMP");
}
template <u32 ctxt>

View File

@ -188,7 +188,7 @@ inline bool CreateImportantCheck()
if (!IsGLExt("GL_EXT_framebuffer_object"))
{
ZZLog::Error_Log("*********\nZZogl: ERROR: Need GL_EXT_framebufer_object for multiple render targets\nZZogl: *********");
ZZLog::Error_Log("*********\nZZogl: ERROR: Need GL_EXT_framebuffer_object for multiple render targets\nZZogl: *********");
bSuccess = false;
}

View File

@ -26,6 +26,7 @@
#include "targets.h"
#include "ZZoglFlushHack.h"
#include "ZZoglShaders.h"
#include "ZZClut.h"
#include <math.h>
//------------------ Defines
@ -337,14 +338,9 @@ inline void VisualBufferMessage(int context)
curvb.tex0.th, curvb.tex0.tcc, curvb.tex0.tfx, curvb.tex0.cbp,
curvb.tex0.cpsm, curvb.tex0.csm, curvb.tex0.csa, curvb.tex0.cld);
char* Name;
// if (g_bSaveTex) {
// if (g_bSaveTex == 1)
Name = NamedSaveTex(&curvb.tex0, 1);
// else
// Name = NamedSaveTex(&curvb.tex0, 0);
ZZLog::Error_Log("TGA name '%s'.", Name);
free(Name);
// }
ZZLog::Debug_Log("buffer %ld.\n", BufferNumber);
#endif
}
@ -730,57 +726,19 @@ inline void FlushDecodeClut(VB& curvb, GLuint& ptexclut)
if (ptexclut != 0)
{
int nClutOffset = 0, clutsize;
int clutsize;
int entries = PSMT_IS8CLUT(curvb.tex0.psm) ? 256 : 16;
if (curvb.tex0.csm && curvb.tex0.csa)
ZZLog::Debug_Log("ERROR, csm1.");
if (PSMT_IS32BIT(curvb.tex0.cpsm)) // 32 bit
{
nClutOffset = 64 * curvb.tex0.csa;
if (PSMT_IS32BIT(curvb.tex0.cpsm)) {
clutsize = min(entries, 256 - curvb.tex0.csa * 16) * 4;
}
else
{
nClutOffset = 64 * (curvb.tex0.csa & 15) + (curvb.tex0.csa >= 16 ? 2 : 0);
ClutBuffer_to_Array<u32>((u32*)&data[0], curvb.tex0.csa, clutsize);
} else {
clutsize = min(entries, 512 - curvb.tex0.csa * 16) * 2;
}
if (PSMT_IS32BIT(curvb.tex0.cpsm)) // 32 bit
{
memcpy_amd(&data[0], g_pbyGSClut + nClutOffset, clutsize);
}
else
{
u16* pClutBuffer = (u16*)(g_pbyGSClut + nClutOffset);
u16* pclut = (u16*) & data[0];
int left = ((u32)nClutOffset & 2) ? 0 : ((nClutOffset & 0x3ff) / 2) + clutsize - 512;
if (left > 0) clutsize -= left;
while (clutsize > 0)
{
pclut[0] = pClutBuffer[0];
pclut++;
pClutBuffer += 2;
clutsize -= 2;
}
if (left > 0)
{
pClutBuffer = (u16*)(g_pbyGSClut + 2);
while (left > 0)
{
pclut[0] = pClutBuffer[0];
left -= 2;
pClutBuffer += 2;
pclut++;
}
}
}
ClutBuffer_to_Array<u16>((u16*)&data[0], curvb.tex0.csa, clutsize);
}
GLenum tempType = PSMT_ISHALF_STORAGE(curvb.tex0) ? GL_UNSIGNED_SHORT_5_5_5_1 : GL_UNSIGNED_BYTE;
Texture2D(4, 256, 1, GL_RGBA, tempType, &data[0]);
@ -987,6 +945,7 @@ inline FRAGMENTSHADER* FlushMadeNewTarget(VB& curvb, int exactcolor, int context
// save the texture
if (g_bSaveTex)
{
// FIXME: I suspect one of g_bSaveTex test variable is wrong
if (g_bSaveTex == 1)
{
SaveTex(&curvb.tex0, 1);

View File

@ -395,6 +395,8 @@ SaveTex(tex0Info* ptex, int usevid)
glBindTexture(GL_TEXTURE_RECTANGLE_NV, pmemtarg->ptex->tex);
srcdata.resize(4 * pmemtarg->texW * pmemtarg->texH);
// FIXME strangely this function call seem to crash pcsx2 on atelier of iris 1
// Note: fmt is GL_UNSIGNED_SHORT_1_5_5_5_REV
glGetTexImage(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, pmemtarg->fmt, &srcdata[0]);
u32 offset = MemorySize(pmemtarg->realy);
@ -613,6 +615,9 @@ SaveTex(tex0Info* ptex, int usevid)
snprintf(Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber);
SaveTGA(Name, ptex->tw, ptex->th, &data[0]);
TexNumber++;
if (TexNumber > MAX_NUMBER_SAVED_TGA) TexNumber = 0;
}
@ -621,13 +626,10 @@ SaveTex(tex0Info* ptex, int usevid)
char* NamedSaveTex(tex0Info* ptex, int usevid)
{
SaveTex(ptex, usevid);
char* Name = (char*)malloc(TGA_FILE_NAME_MAX_LENGTH);
snprintf(Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber);
TexNumber++;
if (TexNumber > MAX_NUMBER_SAVED_TGA) TexNumber = 0;
return Name;
}

View File

@ -475,6 +475,9 @@ void CRenderTarget::Update(int context, CRenderTarget* pdepth)
texframe.tw = fbw;
texframe.th = fbh;
texframe.psm = psm;
// FIXME some field are not initialized...
// in particular the clut related one
assert(!PSMT_ISCLUT(psm));
// write color and zero out stencil buf, always 0 context!
// force bilinear if using AA
@ -966,6 +969,9 @@ void CDepthTarget::Update(int context, CRenderTarget* prndr)
texframe.tw = fbw;
texframe.th = fbh;
texframe.psm = psm;
// FIXME some field are not initialized...
// in particular the clut related one
assert(!PSMT_ISCLUT(psm));
DisableAllgl();
@ -2017,96 +2023,93 @@ CMemoryTarget* CMemoryTargetMngr::GetMemoryTarget(const tex0Info& tex0, int forc
assert(targ->clutsize > 0);
}
else
{
if (tex0.psm == PSMT16Z || tex0.psm == PSMT16SZ)
{
ptexdata = (u8*)_aligned_malloc(4 * targ->texH * targ->texW, 16);
has_data = true;
else if (tex0.psm == PSMT16Z || tex0.psm == PSMT16SZ)
{
ptexdata = (u8*)_aligned_malloc(4 * targ->texH * targ->texW, 16);
has_data = true;
// needs to be 8 bit, use xmm for unpacking
u16* dst = (u16*)ptexdata;
u16* src = (u16*)(MemoryAddress(targ->realy));
// needs to be 8 bit, use xmm for unpacking
u16* dst = (u16*)ptexdata;
u16* src = (u16*)(MemoryAddress(targ->realy));
#ifdef ZEROGS_SSE2
assert(((u32)(uptr)dst) % 16 == 0);
// FIXME Uncomment to test intrinsic versions (instead of asm)
// perf improvement vs asm:
// 1/ gcc updates both pointer with 1 addition
// 2/ Bypass the cache for the store
assert(((u32)(uptr)dst) % 16 == 0);
// FIXME Uncomment to test intrinsic versions (instead of asm)
// perf improvement vs asm:
// 1/ gcc updates both pointer with 1 addition
// 2/ Bypass the cache for the store
#define NEW_INTRINSIC_VERSION
#ifdef NEW_INTRINSIC_VERSION
__m128i zero_128 = _mm_setzero_si128();
// NOTE: future performance improvement
// SSE4.1 support uncacheable load 128bits. Maybe it can
// avoid some cache pollution
// NOTE2: I create multiple _n variable to mimic the previous ASM behavior
// but I'm not sure there are real gains.
for (int i = targ->height * GPU_TEXWIDTH/16 ; i > 0 ; --i)
{
// Convert 16 bits pixels to 32bits (zero extended)
// Batch 64 bytes (32 pixels) at once.
__m128i pixels_1 = _mm_load_si128((__m128i*)src);
__m128i pixels_2 = _mm_load_si128((__m128i*)(src+8));
__m128i pixels_3 = _mm_load_si128((__m128i*)(src+16));
__m128i pixels_4 = _mm_load_si128((__m128i*)(src+24));
__m128i zero_128 = _mm_setzero_si128();
// NOTE: future performance improvement
// SSE4.1 support uncacheable load 128bits. Maybe it can
// avoid some cache pollution
// NOTE2: I create multiple _n variable to mimic the previous ASM behavior
// but I'm not sure there are real gains.
for (int i = targ->height * GPU_TEXWIDTH/16 ; i > 0 ; --i)
{
// Convert 16 bits pixels to 32bits (zero extended)
// Batch 64 bytes (32 pixels) at once.
__m128i pixels_1 = _mm_load_si128((__m128i*)src);
__m128i pixels_2 = _mm_load_si128((__m128i*)(src+8));
__m128i pixels_3 = _mm_load_si128((__m128i*)(src+16));
__m128i pixels_4 = _mm_load_si128((__m128i*)(src+24));
__m128i pix_low_1 = _mm_unpacklo_epi16(pixels_1, zero_128);
__m128i pix_high_1 = _mm_unpackhi_epi16(pixels_1, zero_128);
__m128i pix_low_2 = _mm_unpacklo_epi16(pixels_2, zero_128);
__m128i pix_high_2 = _mm_unpackhi_epi16(pixels_2, zero_128);
__m128i pix_low_1 = _mm_unpacklo_epi16(pixels_1, zero_128);
__m128i pix_high_1 = _mm_unpackhi_epi16(pixels_1, zero_128);
__m128i pix_low_2 = _mm_unpacklo_epi16(pixels_2, zero_128);
__m128i pix_high_2 = _mm_unpackhi_epi16(pixels_2, zero_128);
// Note: bypass cache
_mm_stream_si128((__m128i*)dst, pix_low_1);
_mm_stream_si128((__m128i*)(dst+8), pix_high_1);
_mm_stream_si128((__m128i*)(dst+16), pix_low_2);
_mm_stream_si128((__m128i*)(dst+24), pix_high_2);
// Note: bypass cache
_mm_stream_si128((__m128i*)dst, pix_low_1);
_mm_stream_si128((__m128i*)(dst+8), pix_high_1);
_mm_stream_si128((__m128i*)(dst+16), pix_low_2);
_mm_stream_si128((__m128i*)(dst+24), pix_high_2);
__m128i pix_low_3 = _mm_unpacklo_epi16(pixels_3, zero_128);
__m128i pix_high_3 = _mm_unpackhi_epi16(pixels_3, zero_128);
__m128i pix_low_4 = _mm_unpacklo_epi16(pixels_4, zero_128);
__m128i pix_high_4 = _mm_unpackhi_epi16(pixels_4, zero_128);
__m128i pix_low_3 = _mm_unpacklo_epi16(pixels_3, zero_128);
__m128i pix_high_3 = _mm_unpackhi_epi16(pixels_3, zero_128);
__m128i pix_low_4 = _mm_unpacklo_epi16(pixels_4, zero_128);
__m128i pix_high_4 = _mm_unpackhi_epi16(pixels_4, zero_128);
// Note: bypass cache
_mm_stream_si128((__m128i*)(dst+32), pix_low_3);
_mm_stream_si128((__m128i*)(dst+40), pix_high_3);
_mm_stream_si128((__m128i*)(dst+48), pix_low_4);
_mm_stream_si128((__m128i*)(dst+56), pix_high_4);
// Note: bypass cache
_mm_stream_si128((__m128i*)(dst+32), pix_low_3);
_mm_stream_si128((__m128i*)(dst+40), pix_high_3);
_mm_stream_si128((__m128i*)(dst+48), pix_low_4);
_mm_stream_si128((__m128i*)(dst+56), pix_high_4);
src += 32;
dst += 64;
}
// It is advise to use a fence instruction after non temporal move (mm_stream) instruction...
// store fence insures that previous store are finish before execute new one.
_mm_sfence();
src += 32;
dst += 64;
}
// It is advise to use a fence instruction after non temporal move (mm_stream) instruction...
// store fence insures that previous store are finish before execute new one.
_mm_sfence();
#else
SSE2_UnswizzleZ16Target(dst, src, targ->height * GPU_TEXWIDTH / 16);
SSE2_UnswizzleZ16Target(dst, src, targ->height * GPU_TEXWIDTH / 16);
#endif
#else // ZEROGS_SSE2
for (int i = 0; i < targ->height; ++i)
{
for (int j = 0; j < GPU_TEXWIDTH; ++j)
{
dst[0] = src[0];
dst[1] = 0;
dst[2] = src[1];
dst[3] = 0;
dst += 4;
src += 2;
}
}
for (int i = 0; i < targ->height; ++i)
{
for (int j = 0; j < GPU_TEXWIDTH; ++j)
{
dst[0] = src[0];
dst[1] = 0;
dst[2] = src[1];
dst[3] = 0;
dst += 4;
src += 2;
}
}
#endif // ZEROGS_SSE2
}
else
{
ptexdata = targ->ptex->memptr;
// We really don't want to deallocate memptr. As a reminder...
has_data = false;
}
}
}
else
{
ptexdata = targ->ptex->memptr;
// We really don't want to deallocate memptr. As a reminder...
has_data = false;
}
// create the texture
GL_REPORT_ERRORD();

View File

@ -7,33 +7,58 @@ 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)
{
IntPtr pt = Process.GetCurrentProcess().MainWindowHandle;
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();
@ -49,27 +74,315 @@ namespace GSDumpGUI
String Operation = args[2];
Int32 Renderer = Convert.ToInt32(args[3]);
GSDXWrapper wrap = new GSDXWrapper();
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;
if (Renderer != -1)
wrap.GSReplayDump(Renderer + " " + DumpPath);
else
wrap.GSReplayDump(DumpPath);
}
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;
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];
nodes.Add(tn2);
break;
case "ReadFIFO2":
TreeNode tn3 = new TreeNode();
tn3.Name = parts[0];
tn3.Text = parts[0] + " - " + parts[1];
nodes.Add(tn3);
break;
case "VSync":
TreeNode tn = new TreeNode();
tn.Name = parts[0];
tn.Text = parts[0] + " - " + parts[1];
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];
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;
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.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();
}
}), new object[] { null});
}
}
}

View File

@ -35,7 +35,6 @@
this.cmdBrowseDumps = new System.Windows.Forms.Button();
this.lblDumpDirectory = new System.Windows.Forms.Label();
this.txtDumpsDirectory = new System.Windows.Forms.TextBox();
this.cmdSaveAndReload = new System.Windows.Forms.Button();
this.lstGSDX = new System.Windows.Forms.ListBox();
this.lstDumps = new System.Windows.Forms.ListBox();
this.lblDumps = new System.Windows.Forms.Label();
@ -52,21 +51,50 @@
this.rdaDX10SW = new System.Windows.Forms.RadioButton();
this.lblOverride = new System.Windows.Forms.Label();
this.rdaNone = new System.Windows.Forms.RadioButton();
this.lblInternalLog = new System.Windows.Forms.Label();
this.txtIntLog = new System.Windows.Forms.TextBox();
this.lblDebugger = new System.Windows.Forms.Label();
this.lstProcesses = new System.Windows.Forms.ListBox();
this.lblChild = new System.Windows.Forms.Label();
this.lblDumpSize = new System.Windows.Forms.Label();
this.txtDumpSize = new System.Windows.Forms.Label();
this.txtGIFPackets = new System.Windows.Forms.Label();
this.lblGIFPackets = new System.Windows.Forms.Label();
this.txtPath1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.txtPath2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.txtPath3 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.txtVSync = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.txtReadFifo = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.txtRegisters = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.chkDebugMode = new System.Windows.Forms.CheckBox();
this.lblGif = new System.Windows.Forms.Label();
this.btnStep = new System.Windows.Forms.Button();
this.btnRunToSelection = new System.Windows.Forms.Button();
this.treTreeView = new System.Windows.Forms.TreeView();
this.cmdGoToStart = new System.Windows.Forms.Button();
this.cmdGoToNextVSync = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.pctBox)).BeginInit();
this.SuspendLayout();
//
// txtGSDXDirectory
//
this.txtGSDXDirectory.Location = new System.Drawing.Point(624, 26);
this.txtGSDXDirectory.Location = new System.Drawing.Point(703, 25);
this.txtGSDXDirectory.Name = "txtGSDXDirectory";
this.txtGSDXDirectory.Size = new System.Drawing.Size(243, 20);
this.txtGSDXDirectory.TabIndex = 0;
this.txtGSDXDirectory.TabStop = false;
this.txtGSDXDirectory.Leave += new System.EventHandler(this.txtGSDXDirectory_Leave);
//
// lblDirectory
//
this.lblDirectory.AutoSize = true;
this.lblDirectory.Location = new System.Drawing.Point(627, 10);
this.lblDirectory.Location = new System.Drawing.Point(706, 9);
this.lblDirectory.Name = "lblDirectory";
this.lblDirectory.Size = new System.Drawing.Size(82, 13);
this.lblDirectory.TabIndex = 1;
@ -74,7 +102,7 @@
//
// cmdBrowseGSDX
//
this.cmdBrowseGSDX.Location = new System.Drawing.Point(873, 24);
this.cmdBrowseGSDX.Location = new System.Drawing.Point(952, 23);
this.cmdBrowseGSDX.Name = "cmdBrowseGSDX";
this.cmdBrowseGSDX.Size = new System.Drawing.Size(29, 23);
this.cmdBrowseGSDX.TabIndex = 2;
@ -85,7 +113,7 @@
//
// cmdBrowseDumps
//
this.cmdBrowseDumps.Location = new System.Drawing.Point(873, 67);
this.cmdBrowseDumps.Location = new System.Drawing.Point(952, 66);
this.cmdBrowseDumps.Name = "cmdBrowseDumps";
this.cmdBrowseDumps.Size = new System.Drawing.Size(29, 23);
this.cmdBrowseDumps.TabIndex = 5;
@ -97,7 +125,7 @@
// lblDumpDirectory
//
this.lblDumpDirectory.AutoSize = true;
this.lblDumpDirectory.Location = new System.Drawing.Point(624, 54);
this.lblDumpDirectory.Location = new System.Drawing.Point(703, 53);
this.lblDumpDirectory.Name = "lblDumpDirectory";
this.lblDumpDirectory.Size = new System.Drawing.Size(85, 13);
this.lblDumpDirectory.TabIndex = 4;
@ -105,29 +133,19 @@
//
// txtDumpsDirectory
//
this.txtDumpsDirectory.Location = new System.Drawing.Point(624, 70);
this.txtDumpsDirectory.Location = new System.Drawing.Point(703, 69);
this.txtDumpsDirectory.Name = "txtDumpsDirectory";
this.txtDumpsDirectory.Size = new System.Drawing.Size(243, 20);
this.txtDumpsDirectory.TabIndex = 3;
this.txtDumpsDirectory.TabStop = false;
//
// cmdSaveAndReload
//
this.cmdSaveAndReload.Location = new System.Drawing.Point(626, 97);
this.cmdSaveAndReload.Name = "cmdSaveAndReload";
this.cmdSaveAndReload.Size = new System.Drawing.Size(276, 23);
this.cmdSaveAndReload.TabIndex = 6;
this.cmdSaveAndReload.TabStop = false;
this.cmdSaveAndReload.Text = "Save And Reload";
this.cmdSaveAndReload.UseVisualStyleBackColor = true;
this.cmdSaveAndReload.Click += new System.EventHandler(this.cmdSave_Click);
this.txtDumpsDirectory.Leave += new System.EventHandler(this.txtDumpsDirectory_Leave);
//
// lstGSDX
//
this.lstGSDX.FormattingEnabled = true;
this.lstGSDX.Location = new System.Drawing.Point(319, 24);
this.lstGSDX.Location = new System.Drawing.Point(367, 24);
this.lstGSDX.Name = "lstGSDX";
this.lstGSDX.Size = new System.Drawing.Size(301, 225);
this.lstGSDX.Size = new System.Drawing.Size(330, 199);
this.lstGSDX.TabIndex = 1;
//
// lstDumps
@ -135,7 +153,7 @@
this.lstDumps.FormattingEnabled = true;
this.lstDumps.Location = new System.Drawing.Point(12, 24);
this.lstDumps.Name = "lstDumps";
this.lstDumps.Size = new System.Drawing.Size(301, 225);
this.lstDumps.Size = new System.Drawing.Size(349, 199);
this.lstDumps.TabIndex = 0;
this.lstDumps.SelectedIndexChanged += new System.EventHandler(this.lstDumps_SelectedIndexChanged);
//
@ -151,7 +169,7 @@
// GsdxList
//
this.GsdxList.AutoSize = true;
this.GsdxList.Location = new System.Drawing.Point(316, 9);
this.GsdxList.Location = new System.Drawing.Point(364, 9);
this.GsdxList.Name = "GsdxList";
this.GsdxList.Size = new System.Drawing.Size(56, 13);
this.GsdxList.TabIndex = 10;
@ -159,7 +177,7 @@
//
// cmdStart
//
this.cmdStart.Location = new System.Drawing.Point(720, 192);
this.cmdStart.Location = new System.Drawing.Point(802, 164);
this.cmdStart.Name = "cmdStart";
this.cmdStart.Size = new System.Drawing.Size(182, 58);
this.cmdStart.TabIndex = 11;
@ -170,7 +188,7 @@
//
// cmdConfigGSDX
//
this.cmdConfigGSDX.Location = new System.Drawing.Point(720, 130);
this.cmdConfigGSDX.Location = new System.Drawing.Point(802, 102);
this.cmdConfigGSDX.Name = "cmdConfigGSDX";
this.cmdConfigGSDX.Size = new System.Drawing.Size(88, 56);
this.cmdConfigGSDX.TabIndex = 12;
@ -181,27 +199,27 @@
//
// txtLog
//
this.txtLog.Location = new System.Drawing.Point(269, 275);
this.txtLog.Location = new System.Drawing.Point(269, 249);
this.txtLog.Multiline = true;
this.txtLog.Name = "txtLog";
this.txtLog.ReadOnly = true;
this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtLog.Size = new System.Drawing.Size(633, 208);
this.txtLog.Size = new System.Drawing.Size(351, 208);
this.txtLog.TabIndex = 13;
this.txtLog.TabStop = false;
//
// lblLog
//
this.lblLog.AutoSize = true;
this.lblLog.Location = new System.Drawing.Point(266, 259);
this.lblLog.Location = new System.Drawing.Point(266, 233);
this.lblLog.Name = "lblLog";
this.lblLog.Size = new System.Drawing.Size(25, 13);
this.lblLog.Size = new System.Drawing.Size(58, 13);
this.lblLog.TabIndex = 14;
this.lblLog.Text = "Log";
this.lblLog.Text = "Log GSDX";
//
// cmdOpenIni
//
this.cmdOpenIni.Location = new System.Drawing.Point(814, 130);
this.cmdOpenIni.Location = new System.Drawing.Point(896, 102);
this.cmdOpenIni.Name = "cmdOpenIni";
this.cmdOpenIni.Size = new System.Drawing.Size(88, 56);
this.cmdOpenIni.TabIndex = 15;
@ -212,7 +230,7 @@
//
// pctBox
//
this.pctBox.Location = new System.Drawing.Point(12, 262);
this.pctBox.Location = new System.Drawing.Point(12, 236);
this.pctBox.Name = "pctBox";
this.pctBox.Size = new System.Drawing.Size(248, 221);
this.pctBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
@ -223,7 +241,7 @@
// rdaDX9HW
//
this.rdaDX9HW.AutoSize = true;
this.rdaDX9HW.Location = new System.Drawing.Point(626, 165);
this.rdaDX9HW.Location = new System.Drawing.Point(708, 137);
this.rdaDX9HW.Name = "rdaDX9HW";
this.rdaDX9HW.Size = new System.Drawing.Size(68, 17);
this.rdaDX9HW.TabIndex = 18;
@ -235,7 +253,7 @@
// rdaDX10HW
//
this.rdaDX10HW.AutoSize = true;
this.rdaDX10HW.Location = new System.Drawing.Point(626, 188);
this.rdaDX10HW.Location = new System.Drawing.Point(708, 160);
this.rdaDX10HW.Name = "rdaDX10HW";
this.rdaDX10HW.Size = new System.Drawing.Size(74, 17);
this.rdaDX10HW.TabIndex = 19;
@ -247,7 +265,7 @@
// rdaDX9SW
//
this.rdaDX9SW.AutoSize = true;
this.rdaDX9SW.Location = new System.Drawing.Point(626, 211);
this.rdaDX9SW.Location = new System.Drawing.Point(708, 183);
this.rdaDX9SW.Name = "rdaDX9SW";
this.rdaDX9SW.Size = new System.Drawing.Size(67, 17);
this.rdaDX9SW.TabIndex = 20;
@ -259,7 +277,7 @@
// rdaDX10SW
//
this.rdaDX10SW.AutoSize = true;
this.rdaDX10SW.Location = new System.Drawing.Point(626, 234);
this.rdaDX10SW.Location = new System.Drawing.Point(708, 206);
this.rdaDX10SW.Name = "rdaDX10SW";
this.rdaDX10SW.Size = new System.Drawing.Size(73, 17);
this.rdaDX10SW.TabIndex = 21;
@ -271,7 +289,7 @@
// lblOverride
//
this.lblOverride.AutoSize = true;
this.lblOverride.Location = new System.Drawing.Point(621, 130);
this.lblOverride.Location = new System.Drawing.Point(703, 102);
this.lblOverride.Name = "lblOverride";
this.lblOverride.Size = new System.Drawing.Size(94, 13);
this.lblOverride.TabIndex = 22;
@ -281,7 +299,7 @@
//
this.rdaNone.AutoSize = true;
this.rdaNone.Checked = true;
this.rdaNone.Location = new System.Drawing.Point(625, 146);
this.rdaNone.Location = new System.Drawing.Point(707, 118);
this.rdaNone.Name = "rdaNone";
this.rdaNone.Size = new System.Drawing.Size(51, 17);
this.rdaNone.TabIndex = 23;
@ -291,11 +309,308 @@
this.rdaNone.UseVisualStyleBackColor = true;
this.rdaNone.CheckedChanged += new System.EventHandler(this.rda_CheckedChanged);
//
// lblInternalLog
//
this.lblInternalLog.AutoSize = true;
this.lblInternalLog.Location = new System.Drawing.Point(626, 233);
this.lblInternalLog.Name = "lblInternalLog";
this.lblInternalLog.Size = new System.Drawing.Size(63, 13);
this.lblInternalLog.TabIndex = 25;
this.lblInternalLog.Text = "Log Internal";
//
// txtIntLog
//
this.txtIntLog.Location = new System.Drawing.Point(629, 249);
this.txtIntLog.Multiline = true;
this.txtIntLog.Name = "txtIntLog";
this.txtIntLog.ReadOnly = true;
this.txtIntLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtIntLog.Size = new System.Drawing.Size(351, 208);
this.txtIntLog.TabIndex = 24;
this.txtIntLog.TabStop = false;
//
// lblDebugger
//
this.lblDebugger.AutoSize = true;
this.lblDebugger.Location = new System.Drawing.Point(417, 470);
this.lblDebugger.Name = "lblDebugger";
this.lblDebugger.Size = new System.Drawing.Size(54, 13);
this.lblDebugger.TabIndex = 26;
this.lblDebugger.Text = "Debugger";
//
// lstProcesses
//
this.lstProcesses.FormattingEnabled = true;
this.lstProcesses.Location = new System.Drawing.Point(12, 502);
this.lstProcesses.Name = "lstProcesses";
this.lstProcesses.Size = new System.Drawing.Size(248, 277);
this.lstProcesses.TabIndex = 27;
this.lstProcesses.SelectedIndexChanged += new System.EventHandler(this.lstProcesses_SelectedIndexChanged);
//
// lblChild
//
this.lblChild.AutoSize = true;
this.lblChild.Location = new System.Drawing.Point(9, 487);
this.lblChild.Name = "lblChild";
this.lblChild.Size = new System.Drawing.Size(82, 13);
this.lblChild.TabIndex = 28;
this.lblChild.Text = "Child Processes";
//
// lblDumpSize
//
this.lblDumpSize.AutoSize = true;
this.lblDumpSize.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblDumpSize.Location = new System.Drawing.Point(279, 487);
this.lblDumpSize.Name = "lblDumpSize";
this.lblDumpSize.Size = new System.Drawing.Size(67, 13);
this.lblDumpSize.TabIndex = 29;
this.lblDumpSize.Text = "Dump Size";
//
// txtDumpSize
//
this.txtDumpSize.AutoSize = true;
this.txtDumpSize.Location = new System.Drawing.Point(279, 502);
this.txtDumpSize.Name = "txtDumpSize";
this.txtDumpSize.Size = new System.Drawing.Size(0, 13);
this.txtDumpSize.TabIndex = 30;
//
// txtGIFPackets
//
this.txtGIFPackets.AutoSize = true;
this.txtGIFPackets.Location = new System.Drawing.Point(279, 539);
this.txtGIFPackets.Name = "txtGIFPackets";
this.txtGIFPackets.Size = new System.Drawing.Size(0, 13);
this.txtGIFPackets.TabIndex = 33;
//
// lblGIFPackets
//
this.lblGIFPackets.AutoSize = true;
this.lblGIFPackets.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblGIFPackets.Location = new System.Drawing.Point(279, 523);
this.lblGIFPackets.Name = "lblGIFPackets";
this.lblGIFPackets.Size = new System.Drawing.Size(110, 13);
this.lblGIFPackets.TabIndex = 32;
this.lblGIFPackets.Text = "Total GIF Packets";
//
// txtPath1
//
this.txtPath1.AutoSize = true;
this.txtPath1.Location = new System.Drawing.Point(279, 578);
this.txtPath1.Name = "txtPath1";
this.txtPath1.Size = new System.Drawing.Size(0, 13);
this.txtPath1.TabIndex = 35;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(279, 560);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(114, 13);
this.label2.TabIndex = 34;
this.label2.Text = "Path1 GIF Packets";
//
// txtPath2
//
this.txtPath2.AutoSize = true;
this.txtPath2.Location = new System.Drawing.Point(279, 618);
this.txtPath2.Name = "txtPath2";
this.txtPath2.Size = new System.Drawing.Size(0, 13);
this.txtPath2.TabIndex = 37;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(279, 601);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(114, 13);
this.label3.TabIndex = 36;
this.label3.Text = "Path2 GIF Packets";
//
// txtPath3
//
this.txtPath3.AutoSize = true;
this.txtPath3.Location = new System.Drawing.Point(279, 653);
this.txtPath3.Name = "txtPath3";
this.txtPath3.Size = new System.Drawing.Size(0, 13);
this.txtPath3.TabIndex = 39;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label5.Location = new System.Drawing.Point(279, 635);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(114, 13);
this.label5.TabIndex = 38;
this.label5.Text = "Path3 GIF Packets";
//
// txtVSync
//
this.txtVSync.AutoSize = true;
this.txtVSync.Location = new System.Drawing.Point(279, 690);
this.txtVSync.Name = "txtVSync";
this.txtVSync.Size = new System.Drawing.Size(0, 13);
this.txtVSync.TabIndex = 41;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label4.Location = new System.Drawing.Point(279, 671);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(91, 13);
this.label4.TabIndex = 40;
this.label4.Text = "Vsync Packets";
//
// txtReadFifo
//
this.txtReadFifo.AutoSize = true;
this.txtReadFifo.Location = new System.Drawing.Point(279, 724);
this.txtReadFifo.Name = "txtReadFifo";
this.txtReadFifo.Size = new System.Drawing.Size(0, 13);
this.txtReadFifo.TabIndex = 43;
//
// label7
//
this.label7.AutoSize = true;
this.label7.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label7.Location = new System.Drawing.Point(279, 709);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(114, 13);
this.label7.TabIndex = 42;
this.label7.Text = "ReadFIFO Packets";
//
// txtRegisters
//
this.txtRegisters.AutoSize = true;
this.txtRegisters.Location = new System.Drawing.Point(279, 764);
this.txtRegisters.Name = "txtRegisters";
this.txtRegisters.Size = new System.Drawing.Size(0, 13);
this.txtRegisters.TabIndex = 45;
//
// label6
//
this.label6.AutoSize = true;
this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label6.Location = new System.Drawing.Point(279, 744);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(110, 13);
this.label6.TabIndex = 44;
this.label6.Text = "Registers Packets";
//
// chkDebugMode
//
this.chkDebugMode.AutoSize = true;
this.chkDebugMode.Enabled = false;
this.chkDebugMode.Location = new System.Drawing.Point(629, 501);
this.chkDebugMode.Name = "chkDebugMode";
this.chkDebugMode.Size = new System.Drawing.Size(88, 17);
this.chkDebugMode.TabIndex = 46;
this.chkDebugMode.Text = "Debug Mode";
this.chkDebugMode.UseVisualStyleBackColor = true;
this.chkDebugMode.CheckedChanged += new System.EventHandler(this.chkDebugMode_CheckedChanged);
//
// lblGif
//
this.lblGif.AutoSize = true;
this.lblGif.Enabled = false;
this.lblGif.Location = new System.Drawing.Point(417, 487);
this.lblGif.Name = "lblGif";
this.lblGif.Size = new System.Drawing.Size(66, 13);
this.lblGif.TabIndex = 48;
this.lblGif.Text = "GIF Packets";
//
// btnStep
//
this.btnStep.Enabled = false;
this.btnStep.Location = new System.Drawing.Point(629, 575);
this.btnStep.Name = "btnStep";
this.btnStep.Size = new System.Drawing.Size(108, 40);
this.btnStep.TabIndex = 49;
this.btnStep.TabStop = false;
this.btnStep.Text = "Step";
this.btnStep.UseVisualStyleBackColor = true;
this.btnStep.Click += new System.EventHandler(this.btnStep_Click);
//
// btnRunToSelection
//
this.btnRunToSelection.Enabled = false;
this.btnRunToSelection.Location = new System.Drawing.Point(629, 621);
this.btnRunToSelection.Name = "btnRunToSelection";
this.btnRunToSelection.Size = new System.Drawing.Size(108, 40);
this.btnRunToSelection.TabIndex = 50;
this.btnRunToSelection.TabStop = false;
this.btnRunToSelection.Text = "Run To Selection";
this.btnRunToSelection.UseVisualStyleBackColor = true;
this.btnRunToSelection.Click += new System.EventHandler(this.btnRunToSelection_Click);
//
// treTreeView
//
this.treTreeView.Enabled = false;
this.treTreeView.Location = new System.Drawing.Point(420, 503);
this.treTreeView.Name = "treTreeView";
this.treTreeView.Size = new System.Drawing.Size(200, 276);
this.treTreeView.TabIndex = 51;
//
// cmdGoToStart
//
this.cmdGoToStart.Enabled = false;
this.cmdGoToStart.Location = new System.Drawing.Point(629, 529);
this.cmdGoToStart.Name = "cmdGoToStart";
this.cmdGoToStart.Size = new System.Drawing.Size(108, 40);
this.cmdGoToStart.TabIndex = 52;
this.cmdGoToStart.TabStop = false;
this.cmdGoToStart.Text = "Go to Start";
this.cmdGoToStart.UseVisualStyleBackColor = true;
this.cmdGoToStart.Click += new System.EventHandler(this.cmdGoToStart_Click);
//
// cmdGoToNextVSync
//
this.cmdGoToNextVSync.Enabled = false;
this.cmdGoToNextVSync.Location = new System.Drawing.Point(629, 671);
this.cmdGoToNextVSync.Name = "cmdGoToNextVSync";
this.cmdGoToNextVSync.Size = new System.Drawing.Size(108, 40);
this.cmdGoToNextVSync.TabIndex = 53;
this.cmdGoToNextVSync.TabStop = false;
this.cmdGoToNextVSync.Text = "Go to next VSync";
this.cmdGoToNextVSync.UseVisualStyleBackColor = true;
this.cmdGoToNextVSync.Click += new System.EventHandler(this.cmdGoToNextVSync_Click);
//
// GSDumpGUI
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(906, 495);
this.ClientSize = new System.Drawing.Size(988, 790);
this.Controls.Add(this.cmdGoToNextVSync);
this.Controls.Add(this.cmdGoToStart);
this.Controls.Add(this.treTreeView);
this.Controls.Add(this.btnRunToSelection);
this.Controls.Add(this.btnStep);
this.Controls.Add(this.lblGif);
this.Controls.Add(this.chkDebugMode);
this.Controls.Add(this.txtRegisters);
this.Controls.Add(this.label6);
this.Controls.Add(this.txtReadFifo);
this.Controls.Add(this.label7);
this.Controls.Add(this.txtVSync);
this.Controls.Add(this.label4);
this.Controls.Add(this.txtPath3);
this.Controls.Add(this.label5);
this.Controls.Add(this.txtPath2);
this.Controls.Add(this.label3);
this.Controls.Add(this.txtPath1);
this.Controls.Add(this.label2);
this.Controls.Add(this.txtGIFPackets);
this.Controls.Add(this.lblGIFPackets);
this.Controls.Add(this.txtDumpSize);
this.Controls.Add(this.lblDumpSize);
this.Controls.Add(this.lstProcesses);
this.Controls.Add(this.lblChild);
this.Controls.Add(this.lblDebugger);
this.Controls.Add(this.lblInternalLog);
this.Controls.Add(this.txtIntLog);
this.Controls.Add(this.rdaNone);
this.Controls.Add(this.lblOverride);
this.Controls.Add(this.rdaDX10SW);
@ -312,7 +627,6 @@
this.Controls.Add(this.GsdxList);
this.Controls.Add(this.lblDumps);
this.Controls.Add(this.lstDumps);
this.Controls.Add(this.cmdSaveAndReload);
this.Controls.Add(this.cmdBrowseDumps);
this.Controls.Add(this.lblDumpDirectory);
this.Controls.Add(this.txtDumpsDirectory);
@ -341,7 +655,6 @@
private System.Windows.Forms.Button cmdBrowseDumps;
private System.Windows.Forms.Label lblDumpDirectory;
private System.Windows.Forms.TextBox txtDumpsDirectory;
private System.Windows.Forms.Button cmdSaveAndReload;
private System.Windows.Forms.ListBox lstGSDX;
private System.Windows.Forms.ListBox lstDumps;
private System.Windows.Forms.Label lblDumps;
@ -358,6 +671,34 @@
private System.Windows.Forms.RadioButton rdaDX10SW;
private System.Windows.Forms.Label lblOverride;
private System.Windows.Forms.RadioButton rdaNone;
private System.Windows.Forms.Label lblInternalLog;
private System.Windows.Forms.TextBox txtIntLog;
private System.Windows.Forms.Label lblDebugger;
private System.Windows.Forms.Label lblChild;
public System.Windows.Forms.ListBox lstProcesses;
private System.Windows.Forms.Label lblDumpSize;
public System.Windows.Forms.Label txtDumpSize;
public System.Windows.Forms.Label txtGIFPackets;
private System.Windows.Forms.Label lblGIFPackets;
public System.Windows.Forms.Label txtPath1;
private System.Windows.Forms.Label label2;
public System.Windows.Forms.Label txtPath2;
private System.Windows.Forms.Label label3;
public System.Windows.Forms.Label txtPath3;
private System.Windows.Forms.Label label5;
public System.Windows.Forms.Label txtVSync;
private System.Windows.Forms.Label label4;
public System.Windows.Forms.Label txtReadFifo;
private System.Windows.Forms.Label label7;
public System.Windows.Forms.Label txtRegisters;
private System.Windows.Forms.Label label6;
public System.Windows.Forms.CheckBox chkDebugMode;
public System.Windows.Forms.TreeView treTreeView;
public System.Windows.Forms.Label lblGif;
public System.Windows.Forms.Button btnStep;
public System.Windows.Forms.Button btnRunToSelection;
public System.Windows.Forms.Button cmdGoToStart;
public System.Windows.Forms.Button cmdGoToNextVSync;
}
}

View File

@ -10,6 +10,7 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.Security;
using TCPLibrary.MessageBased.Core;
namespace GSDumpGUI
{
@ -63,6 +64,8 @@ namespace GSDumpGUI
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;
@ -79,11 +82,24 @@ namespace GSDumpGUI
if (GSDXWrapper.IsValidGSDX(itm))
{
wrap.Load(itm);
lstGSDX.Items.Add(Path.GetFileName(itm) + " | " + wrap.PSEGetLibName());
txtIntLog.Text += "\"" + itm + "\" correctly identified as " + wrap.PSEGetLibName() + Environment.NewLine;
wrap.Unload();
}
else
{
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)
@ -91,9 +107,13 @@ namespace GSDumpGUI
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"));
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)
@ -111,6 +131,8 @@ namespace GSDumpGUI
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory;
if (fbd.ShowDialog() == DialogResult.OK)
txtGSDXDirectory.Text = fbd.SelectedPath;
SaveConfig();
ReloadGSDXs();
}
private void cmdBrowseDumps_Click(object sender, EventArgs e)
@ -120,21 +142,7 @@ namespace GSDumpGUI
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory;
if (fbd.ShowDialog() == DialogResult.OK)
txtDumpsDirectory.Text = fbd.SelectedPath;
}
private void cmdSave_Click(object sender, EventArgs e)
{
if (System.IO.Directory.Exists(txtDumpsDirectory.Text))
Properties.Settings.Default.DumpDir = txtDumpsDirectory.Text;
else
MessageBox.Show("Select a correct directory for dumps", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (System.IO.Directory.Exists(txtGSDXDirectory.Text))
Properties.Settings.Default.GSDXDir = txtGSDXDirectory.Text;
else
MessageBox.Show("Select a correct directory for GSDX", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Properties.Settings.Default.Save();
SaveConfig();
ReloadGSDXs();
}
@ -181,6 +189,25 @@ namespace GSDumpGUI
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];
@ -325,5 +352,95 @@ namespace GSDumpGUI
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);
}
}
}

View File

@ -28,6 +28,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -36,7 +37,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
@ -54,9 +55,21 @@
<Compile Include="Forms\frmMain.Designer.cs">
<DependentUpon>frmMain.cs</DependentUpon>
</Compile>
<Compile Include="Library\GSDump\GSData\GSData.cs" />
<Compile Include="Library\GSDump\GSDump.cs" />
<Compile Include="Library\GSDump\GSData\GSTransfer.cs" />
<Compile Include="Library\GSDXWrapper.cs" />
<Compile Include="Library\NativeMethods.cs" />
<Compile Include="Core\Program.cs" />
<Compile Include="Library\TCPLibrary\Message\BaseMessageClient.cs" />
<Compile Include="Library\TCPLibrary\Message\BaseMessageClientS.cs" />
<Compile Include="Library\TCPLibrary\Message\BaseMessageServer.cs" />
<Compile Include="Library\TCPLibrary\Base\CancelArgs.cs" />
<Compile Include="Library\TCPLibrary\Base\Client.cs" />
<Compile Include="Library\TCPLibrary\Base\ClientS.cs" />
<Compile Include="Library\TCPLibrary\Base\Data.cs" />
<Compile Include="Library\TCPLibrary\Base\Server.cs" />
<Compile Include="Library\TCPLibrary\Message\TCPMessage.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Forms\frmMain.resx">
<DependentUpon>frmMain.cs</DependentUpon>

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GSDumpGUI", "GSDumpGUI.csproj", "{825E4311-652D-4A1E-8AA1-F6D81B186E33}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{825E4311-652D-4A1E-8AA1-F6D81B186E33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{825E4311-652D-4A1E-8AA1-F6D81B186E33}.Debug|Any CPU.Build.0 = Debug|Any CPU
{825E4311-652D-4A1E-8AA1-F6D81B186E33}.Release|Any CPU.ActiveCfg = Release|Any CPU
{825E4311-652D-4A1E-8AA1-F6D81B186E33}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -2,49 +2,100 @@
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 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 GSDXWrapper
{
private delegate void GSReplay(IntPtr HWND, IntPtr HInstance, String File, Boolean Show);
private delegate void GSConfigure();
private delegate IntPtr PSEgetLibName();
static public bool DumpTooOld = false;
private GSReplay gsReplay;
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 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;
static public Boolean IsValidGSDX(String DLL)
{
NativeMethods.SetErrorMode(0x8007);
Boolean Ris = true;
Directory.SetCurrentDirectory(Path.GetDirectoryName(DLL));
IntPtr hmod = NativeMethods.LoadLibrary(DLL);
if (hmod.ToInt64() > 0)
{
IntPtr funcaddrReplay = NativeMethods.GetProcAddress(hmod, "GSReplay");
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
IntPtr funcaddrGIF = NativeMethods.GetProcAddress(hmod, "GSgifTransfer");
IntPtr funcaddrVSync = NativeMethods.GetProcAddress(hmod, "GSvsync");
IntPtr funcaddrSetBaseMem = NativeMethods.GetProcAddress(hmod, "GSsetBaseMem");
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");
NativeMethods.FreeLibrary(hmod);
if (!((funcaddrConfig.ToInt64() > 0) && (funcaddrLibName.ToInt64() > 0) && (funcaddrReplay.ToInt64() > 0)))
if (!((funcaddrConfig.ToInt64() > 0) && (funcaddrLibName.ToInt64() > 0) && (funcaddrGIF.ToInt64() > 0)))
{
Int32 id = NativeMethods.GetLastError();
System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "test.txt", DLL + " failed to load. Error " + id);
System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", DLL + " failed to load. Error " + id + Environment.NewLine);
Ris = false;
}
}
else
{
Int32 id = NativeMethods.GetLastError();
System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "test.txt", DLL + " failed to load. Error " + id + Environment.NewLine);
System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", DLL + " failed to load. Error " + id + Environment.NewLine);
Ris = false;
}
NativeMethods.SetErrorMode(0x0000);
return Ris;
}
@ -53,6 +104,7 @@ namespace GSDumpGUI
{
this.DLL = DLL;
NativeMethods.SetErrorMode(0x8007);
if (!IsValidGSDX(DLL))
throw new Exception("Invalid GSDX DLL");
@ -60,16 +112,44 @@ namespace GSDumpGUI
Unload();
Loaded = true;
Directory.SetCurrentDirectory(Path.GetDirectoryName(DLL));
IntPtr hmod = NativeMethods.LoadLibrary(DLL);
if (hmod.ToInt64() > 0)
{
IntPtr funcaddrReplay = NativeMethods.GetProcAddress(hmod, "GSReplay");
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
gsReplay = (GSReplay)Marshal.GetDelegateForFunctionPointer(funcaddrReplay, typeof(GSReplay));
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 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");
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.GSreadFIFO2 = (GSreadFIFO2)Marshal.GetDelegateForFunctionPointer(funcaddrGSreadFIFO2, typeof(GSreadFIFO2));
this.GSinit = (GSinit)Marshal.GetDelegateForFunctionPointer(funcaddrinit, typeof(GSinit));
DLLAddr = hmod;
}
NativeMethods.SetErrorMode(0x0000);
@ -88,18 +168,225 @@ namespace GSDumpGUI
gsConfigure.Invoke();
}
public void GSReplayDump(String DumpFilename)
{
if (!Loaded)
throw new Exception("GSDX is not loaded");
gsReplay.Invoke(new IntPtr(0), new IntPtr(0), DumpFilename, false);
}
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);
int lastVSyncField;
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;
}
Marshal.Copy(dump.Registers, 0, new IntPtr(pointer), 8192);
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;
GSData g = new GSData();
g.id = GSType.VSync;
g.data = new byte[1];
g.data[0] = 0;
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;
i = -1;
break;
case MessageType.RunToCursor:
RunTo = (int)Mess.Parameters[0];
i = -1;
break;
case MessageType.RunToNextVSync:
RunTo = dump.Data.FindIndex(i, a => a.id == GSType.VSync);
i = -1;
break;
default:
break;
}
Marshal.Copy(dump.Registers, 0, new IntPtr(pointer), 8192);
GSfreeze(0, new IntPtr(fr));
}
}
}
else
{
Step(itm, pointer);
}
}
}
GSclose();
GSshutdown();
}
}
}
}
private unsafe void Step(GSData itm, byte* registers)
{
/*"C:\Users\Alessio\Desktop\Plugins\Dll\gsdx-sse4-r3878.dll" "C:\Users\Alessio\Desktop\Plugins\Dumps\gsdx_20101219182059.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(itm.data[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();
}
else
{
}
Data.Add(act);
}
return Data;
}
}
}

View File

@ -0,0 +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
}
}

View File

@ -0,0 +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
}
}

View File

@ -0,0 +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;
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
using System.Drawing;
namespace GSDumpGUI
{
@ -35,5 +36,36 @@ namespace GSDumpGUI
[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;
}
}

View File

@ -0,0 +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;
}
}
}

View File

@ -0,0 +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.");
}
}
}

View File

@ -0,0 +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);
}
}
}
}

View File

@ -0,0 +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;
}
}
}

View File

@ -0,0 +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);
}
}
}

View File

@ -0,0 +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()));
}
}
}

View File

@ -0,0 +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()));
}
}
}

View File

@ -0,0 +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()));
}
}
}

View File

@ -0,0 +1,124 @@
/*
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,
Step,
RunToCursor,
RunToNextVSync
}
}